Controller Blueprints MS
authorSingal, Kapil (ks220y) <ks220y@att.com>
Thu, 9 Aug 2018 20:47:29 +0000 (20:47 +0000)
committerMuthuramalingam, Brinda Santh(bs2796) <bs2796@att.com>
Fri, 10 Aug 2018 18:48:54 +0000 (18:48 +0000)
Creating the base directory structure for Controller Blueprints MicroService

Change-Id: I1ccf7fc76446048af3b2822f9155bb634657aee3
Issue-ID: CCSDK-410
Signed-off-by: Singal, Kapil (ks220y) <ks220y@att.com>
295 files changed:
ms/controllerblueprints/.gitignore [new file with mode: 0644]
ms/controllerblueprints/README.md [new file with mode: 0755]
ms/controllerblueprints/README_FIRST.txt [new file with mode: 0644]
ms/controllerblueprints/application/etc/SecurityFilterExpressions.cfg [new file with mode: 0644]
ms/controllerblueprints/application/etc/SecurityFilterExpressionsPool.properties [new file with mode: 0644]
ms/controllerblueprints/application/etc/run.source [new file with mode: 0644]
ms/controllerblueprints/application/load/blueprints/baseconfiguration/Definitions/activation-blueprint.json [new file with mode: 0644]
ms/controllerblueprints/application/load/blueprints/baseconfiguration/Mappings/baseconfig-mapping.json [new file with mode: 0644]
ms/controllerblueprints/application/load/blueprints/baseconfiguration/Plans/ActivateProcess.bpmn [new file with mode: 0644]
ms/controllerblueprints/application/load/blueprints/baseconfiguration/Scripts/SamplePythonComponentNode.py [new file with mode: 0644]
ms/controllerblueprints/application/load/blueprints/baseconfiguration/Scripts/__init__.py [new file with mode: 0644]
ms/controllerblueprints/application/load/blueprints/baseconfiguration/TOSCA-Metadata/TOSCA.meta [new file with mode: 0644]
ms/controllerblueprints/application/load/blueprints/baseconfiguration/Templates/baseconfig-template.vtl [new file with mode: 0644]
ms/controllerblueprints/application/load/blueprints/baseconfiguration/__init__.py [new file with mode: 0644]
ms/controllerblueprints/application/load/model_type/artifact_type/artifact-mapping-resource.json [new file with mode: 0644]
ms/controllerblueprints/application/load/model_type/artifact_type/artifact-script-python.json [new file with mode: 0644]
ms/controllerblueprints/application/load/model_type/artifact_type/artifact-template-velocity.json [new file with mode: 0644]
ms/controllerblueprints/application/load/model_type/artifact_type/tosca.artifacts.Implementation.json [new file with mode: 0644]
ms/controllerblueprints/application/load/model_type/data_type/datatype-property.json [new file with mode: 0644]
ms/controllerblueprints/application/load/model_type/data_type/datatype-resource-assignment.json [new file with mode: 0644]
ms/controllerblueprints/application/load/model_type/data_type/dt-license-key.json [new file with mode: 0644]
ms/controllerblueprints/application/load/model_type/data_type/dt-v4-aggregate.json [new file with mode: 0644]
ms/controllerblueprints/application/load/model_type/data_type/tosca.datatypes.Credential.json [new file with mode: 0644]
ms/controllerblueprints/application/load/model_type/node_type/artifact-config-template.json [new file with mode: 0644]
ms/controllerblueprints/application/load/model_type/node_type/component-config-generator.json [new file with mode: 0644]
ms/controllerblueprints/application/load/model_type/node_type/component-netconf-executor.json [new file with mode: 0644]
ms/controllerblueprints/application/load/model_type/node_type/component-resource-assignment.json [new file with mode: 0644]
ms/controllerblueprints/application/load/model_type/node_type/dg-activate-netconf.json [new file with mode: 0644]
ms/controllerblueprints/application/load/model_type/node_type/dg-config-generator.json [new file with mode: 0644]
ms/controllerblueprints/application/load/model_type/node_type/dg-resource-assign-activate.json [new file with mode: 0644]
ms/controllerblueprints/application/load/model_type/node_type/dg-resource-assignment.json [new file with mode: 0644]
ms/controllerblueprints/application/load/model_type/node_type/vnf-netconf-device.json [new file with mode: 0644]
ms/controllerblueprints/application/opt/app/onap/config/application.properties [new file with mode: 0644]
ms/controllerblueprints/application/opt/app/onap/config/logback.xml [new file with mode: 0644]
ms/controllerblueprints/application/pom.xml [new file with mode: 0644]
ms/controllerblueprints/application/src/assembly/distribution.xml [new file with mode: 0644]
ms/controllerblueprints/application/src/main/dc/docker-compose.yaml [new file with mode: 0644]
ms/controllerblueprints/application/src/main/docker/Dockerfile [new file with mode: 0644]
ms/controllerblueprints/application/src/main/docker/startService.sh [new file with mode: 0644]
ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/ApplicationConstants.java [new file with mode: 0644]
ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/ControllerBluprintsApplication.java [new file with mode: 0644]
ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/ControllerBluprintsFilterConfiguration.java [new file with mode: 0644]
ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/CorsConfig.java [new file with mode: 0644]
ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/DatabaseConfig.java [new file with mode: 0644]
ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/JerseyConfiguration.java [new file with mode: 0644]
ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/WebMvcConfiguration.java [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/sql/data.sql [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/sql/schema-local.sql [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/sql/schema.sql [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/css/print.css [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/css/reset.css [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/css/screen.css [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/css/style.css [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/css/typography.css [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/fonts/DroidSans-Bold.ttf [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/fonts/DroidSans.ttf [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/collapse.gif [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/expand.gif [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/explorer_icons.png [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/favicon-16x16.png [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/favicon-32x32.png [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/favicon.ico [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/logo_small.png [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/pet_store_api.png [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/throbber.gif [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/wordnik_api.png [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/index.html [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/ca.js [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/el.js [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/en.js [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/es.js [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/fr.js [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/geo.js [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/it.js [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/ja.js [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/ko-kr.js [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/pl.js [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/pt.js [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/ru.js [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/tr.js [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/translator.js [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/zh-cn.js [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/backbone-min.js [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/es5-shim.js [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/handlebars-4.0.5.js [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/highlight.9.1.0.pack.js [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/highlight.9.1.0.pack_extended.js [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/jquery-1.8.0.min.js [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/jquery.ba-bbq.min.js [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/jquery.slideto.min.js [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/jquery.wiggle.min.js [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/js-yaml.min.js [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/jsoneditor.min.js [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/lodash.min.js [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/marked.js [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/object-assign-pollyfill.js [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/sanitize-html.min.js [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/swagger-oauth.js [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/o2c.html [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/swagger-ui.js [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/swagger-ui.min.js [new file with mode: 0644]
ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/swagger.json [new file with mode: 0644]
ms/controllerblueprints/application/src/test/java/org/onap/ccsdk/apps/controllerblueprints/ControllerBluprintsApplicationTest.java [new file with mode: 0644]
ms/controllerblueprints/application/src/test/resources/application.properties [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/blueprints/baseconfiguration/Definitions/activation-blueprint.json [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/blueprints/baseconfiguration/Mappings/baseconfig-mapping.json [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/blueprints/baseconfiguration/Plans/ActivateProcess.bpmn [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/blueprints/baseconfiguration/Scripts/SamplePythonComponentNode.py [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/blueprints/baseconfiguration/Scripts/__init__.py [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/blueprints/baseconfiguration/TOSCA-Metadata/TOSCA.meta [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/blueprints/baseconfiguration/Templates/baseconfig-template.vtl [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/blueprints/baseconfiguration/__init__.py [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/blueprints/simple-baseconfig/Definitions/sample-nodetype.json [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/blueprints/simple-baseconfig/Definitions/simple-baseconfig.json [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/blueprints/simple-baseconfig/Mappings/baseconfig-mapping.json [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/blueprints/simple-baseconfig/Plans/ActivateProcess.bpmn [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/blueprints/simple-baseconfig/Scripts/SamplePythonComponentNode.py [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/blueprints/simple-baseconfig/Scripts/__init__.py [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/blueprints/simple-baseconfig/TOSCA-Metadata/TOSCA.meta [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/blueprints/simple-baseconfig/Templates/base-config-template.vtl [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/blueprints/simple-baseconfig/Templates/baseconfig-template.vtl [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/blueprints/simple-baseconfig/Templates/licence-template.vtl [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/blueprints/simple-baseconfig/__init__.py [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/model_type/artifact_type/artifact-mapping-resource.json [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/model_type/artifact_type/artifact-script-python.json [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/model_type/artifact_type/artifact-template-velocity.json [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/model_type/artifact_type/tosca.artifacts.Implementation.json [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/model_type/data_type/datatype-property.json [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/model_type/data_type/datatype-resource-assignment.json [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/model_type/data_type/dt-license-key.json [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/model_type/data_type/dt-v4-aggregate.json [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/model_type/data_type/tosca.datatypes.Credential.json [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/model_type/node_type/artifact-config-template.json [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/model_type/node_type/component-config-generator.json [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/model_type/node_type/component-netconf-executor.json [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/model_type/node_type/component-resource-assignment.json [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/model_type/node_type/dg-activate-netconf.json [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/model_type/node_type/dg-config-generator.json [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/model_type/node_type/dg-resource-assign-activate.json [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/model_type/node_type/dg-resource-assignment.json [new file with mode: 0644]
ms/controllerblueprints/modules/core/load/model_type/node_type/vnf-netconf-device.json [new file with mode: 0644]
ms/controllerblueprints/modules/core/pom.xml [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/BluePrintConstants.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/BluePrintException.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/BluePrintTypes.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/ConfigModelConstant.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/CustomFunctions.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/OrchestratorException.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/data/BluePrintExpressionData.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/data/BluePrintModel.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/factory/BluePrintEnhancerFactory.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/factory/BluePrintParserFactory.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/factory/BluePrintValidatorFactory.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintChainedService.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintContext.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintEnhancerRepoService.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintEnhancerService.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintExpressionService.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintParserService.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintRuntimeService.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintValidatorService.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/PropertyAssignmentService.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/BluePrintMetadataUtils.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/BluePrintRuntimeUtils.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/JacksonUtils.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/ResourceResolverUtils.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/ServiceTemplateUtils.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/TopologicalSortingUtils.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/CustomFunctionsTest.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintContextTest.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintEnhancerRepoFileServiceTest.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintEnhancerServiceTest.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintExpressionServiceTest.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintParserFactoryTest.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintRuntimeServiceTest.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintValidatorDefaultServiceTest.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/BluePrintMetadataUtilsTest.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/JacksonUtilsTest.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/TopologicalSortingUtilsTest.kt [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/test/resources/componentnode/default.json [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/test/resources/data/default-context.json [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/test/resources/dictionary/dictionary_schema.json [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/test/resources/properties/convert.json [new file with mode: 0644]
ms/controllerblueprints/modules/core/src/test/resources/properties/default.json [new file with mode: 0644]
ms/controllerblueprints/modules/pom.xml [new file with mode: 0644]
ms/controllerblueprints/modules/resource-dict/pom.xml [new file with mode: 0644]
ms/controllerblueprints/modules/resource-dict/src/main/java/org/onap/ccsdk/apps/controllerblueprints/resource/dict/ResourceAssignment.java [new file with mode: 0644]
ms/controllerblueprints/modules/resource-dict/src/main/java/org/onap/ccsdk/apps/controllerblueprints/resource/dict/data/DecryptionRule.java [new file with mode: 0644]
ms/controllerblueprints/modules/resource-dict/src/main/java/org/onap/ccsdk/apps/controllerblueprints/resource/dict/data/DictionaryDefinition.java [new file with mode: 0644]
ms/controllerblueprints/modules/resource-dict/src/main/java/org/onap/ccsdk/apps/controllerblueprints/resource/dict/data/DictionaryDependency.java [new file with mode: 0644]
ms/controllerblueprints/modules/resource-dict/src/main/java/org/onap/ccsdk/apps/controllerblueprints/resource/dict/data/SourceDb.java [new file with mode: 0644]
ms/controllerblueprints/modules/resource-dict/src/main/java/org/onap/ccsdk/apps/controllerblueprints/resource/dict/data/SourceDefault.java [new file with mode: 0644]
ms/controllerblueprints/modules/resource-dict/src/main/java/org/onap/ccsdk/apps/controllerblueprints/resource/dict/data/SourceInput.java [new file with mode: 0644]
ms/controllerblueprints/modules/resource-dict/src/main/java/org/onap/ccsdk/apps/controllerblueprints/resource/dict/data/SourceMdsal.java [new file with mode: 0644]
ms/controllerblueprints/modules/resource-dict/src/main/java/org/onap/ccsdk/apps/controllerblueprints/resource/dict/utils/ResourceDictionaryUtils.java [new file with mode: 0644]
ms/controllerblueprints/modules/resource-dict/src/main/java/org/onap/ccsdk/apps/controllerblueprints/resource/dict/validator/ResourceAssignmentValidator.java [new file with mode: 0644]
ms/controllerblueprints/modules/resource-dict/src/test/java/org/onap/ccsdk/apps/controllerblueprints/resource/dict/util/ResourceDictionaryUtilsTest.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/blueprints/baseconfiguration/Definitions/activation-blueprint.json [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/blueprints/baseconfiguration/Mappings/baseconfig-mapping.json [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/blueprints/baseconfiguration/Plans/ActivateProcess.bpmn [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/blueprints/baseconfiguration/Scripts/SamplePythonComponentNode.py [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/blueprints/baseconfiguration/Scripts/__init__.py [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/blueprints/baseconfiguration/TOSCA-Metadata/TOSCA.meta [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/blueprints/baseconfiguration/Templates/baseconfig-template.vtl [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/blueprints/baseconfiguration/__init__.py [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/blueprints/vrr-test/Definitions/vrr-test.json [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/blueprints/vrr-test/TOSCA-Metadata/TOSCA.meta [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/blueprints/vrr-test/Templates/base-config-template.vtl [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/blueprints/vrr-test/Templates/licence-template.vtl [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/blueprints/vrr-test/__init__.py [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/model_type/artifact_type/artifact-mapping-resource.json [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/model_type/artifact_type/artifact-script-python.json [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/model_type/artifact_type/artifact-template-velocity.json [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/model_type/data_type/datatype-property.json [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/model_type/data_type/datatype-resource-assignment.json [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/model_type/data_type/dt-license-key.json [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/model_type/data_type/dt-v4-aggregate.json [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/model_type/node_type/artifact-config-template.json [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/model_type/node_type/component-config-generator.json [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/model_type/node_type/component-netconf-edit.json [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/model_type/node_type/component-netconf-executor.json [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/model_type/node_type/component-netconf-get.json [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/model_type/node_type/component-resource-assignment.json [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/model_type/node_type/component-transaction-netconf.json [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/model_type/node_type/dg-activate-netconf.json [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/model_type/node_type/dg-config-generator.json [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/model_type/node_type/dg-resource-assign-activate.json [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/model_type/node_type/dg-resource-assignment.json [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/model_type/node_type/vnf-netconf-device.json [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/resource_dictionary/action-name.json [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/resource_dictionary/bundle-id.json [new file with mode: 0644]
ms/controllerblueprints/modules/service/load/resource_dictionary/v4-ip-type.json [new file with mode: 0644]
ms/controllerblueprints/modules/service/pom.xml [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/AutoResourceMappingService.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/BluePrintEnhancerRepoDBService.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/BluePrintEnhancerService.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/ConfigModelCreateService.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/ConfigModelService.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/ConfigModelValidatorService.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/DataBaseInitService.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/ModelTypeService.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/ResourceDictionaryService.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/SchemaGeneratorService.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/ServiceTemplateService.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/common/ApplicationConstants.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/common/ErrorMessage.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/common/ServiceExceptionMapper.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/common/SwaggerGenerator.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/domain/ConfigModel.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/domain/ConfigModelContent.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/domain/ConfigModelSearch.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/domain/ModelType.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/domain/ResourceDictionary.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/model/AutoMapResponse.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/repository/ConfigModelContentRepository.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/repository/ConfigModelRepository.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/repository/ConfigModelSearchRepository.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/repository/ModelTypeRepository.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/repository/ResourceDictionaryRepository.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ConfigModelRest.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ConfigModelRestImpl.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ModelTypeRest.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ModelTypeRestImpl.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ResourceDictionaryRest.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ResourceDictionaryRestImpl.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ServiceTemplateRest.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ServiceTemplateRestImpl.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/utils/ConfigModelUtils.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/validator/ModelTypeValidator.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/validator/ResourceDictionaryValidator.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/validator/ServiceTemplateValidator.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/resources/service_template/default_netconf.json [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/resources/sql/data.sql [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/resources/sql/schema-local.sql [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/main/resources/sql/schema.sql [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/test/java/org/onap/ccsdk/apps/controllerblueprints/DatabaseConfig.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/test/java/org/onap/ccsdk/apps/controllerblueprints/JerseyConfiguration.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/test/java/org/onap/ccsdk/apps/controllerblueprints/TestApplication.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/test/java/org/onap/ccsdk/apps/controllerblueprints/TestConfiguration.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/test/java/org/onap/ccsdk/apps/controllerblueprints/service/common/SchemaGeneratorServiceTest.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/test/java/org/onap/ccsdk/apps/controllerblueprints/service/common/ServiceTemplateValidationTest.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/test/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ConfigModelRestTest.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/test/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ModelTypeRestTest.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/test/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ResourceDictionaryRestTest.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/test/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ServiceTemplateRestTest.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/test/java/org/onap/ccsdk/apps/controllerblueprints/service/utils/ConfigModelUtilsTest.java [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/test/resources/application.properties [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/test/resources/enhance/enhance-template.json [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/test/resources/enhance/enhanced-template.json [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/test/resources/resourcedictionary/automap.json [new file with mode: 0644]
ms/controllerblueprints/modules/service/src/test/resources/resourcedictionary/default_definition.json [new file with mode: 0644]
ms/controllerblueprints/parent/pom.xml [new file with mode: 0644]
ms/controllerblueprints/pom.xml [new file with mode: 0644]
ms/controllerblueprints/repoproject.txt [new file with mode: 0644]
ms/controllerblueprints/time.txt [new file with mode: 0644]

diff --git a/ms/controllerblueprints/.gitignore b/ms/controllerblueprints/.gitignore
new file mode 100644 (file)
index 0000000..b808e84
--- /dev/null
@@ -0,0 +1,22 @@
+/target/\r
+/logs/\r
+.classpath\r
+.settings/\r
+\r
+# Target dirs in all projects\r
+**/target-ide/*\r
+**/target/*\r
+**/logs/*\r
+**/tokens/*\r
+\r
+# Added for Intellij IDEA IDE\r
+**/debug-logs/*\r
+**/.idea/*\r
+**/*.iml\r
+**/*.project\r
+**/.springBeans\r
+\r
+\r
+**/*versionsBackup\r
+**/blackDuckHub*\r
+**/*.jsonld
\ No newline at end of file
diff --git a/ms/controllerblueprints/README.md b/ms/controllerblueprints/README.md
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/ms/controllerblueprints/README_FIRST.txt b/ms/controllerblueprints/README_FIRST.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/ms/controllerblueprints/application/etc/SecurityFilterExpressions.cfg b/ms/controllerblueprints/application/etc/SecurityFilterExpressions.cfg
new file mode 100644 (file)
index 0000000..8185daa
--- /dev/null
@@ -0,0 +1,71 @@
+(>)\d{3,4}(<\/.*security>) $1xxxx$2
+(>)\d{11,12}(\d{4}<\/.*creditCardNumber>) $1xxxxxxxxxxxx$2
+(>)\d+(\d{4}<\/.*socialSecurityNumber.*>) $1xxxxx$2
+(>)\d{5}(\d{4}<\/.*ssn>) $1xxxxx$2
+(>)\d*(\d{3}<\/.*idNumber>) $1xxxxxx$2
+(>)\d{11,12}(\d{4}<\/cardNumber>) $1xxxxxxxxxxxx$2
+(>)[^>]*(<\/[^>]*[pP]assword>) $1xxxxxx$2
+(>)\d{3,4}(<\/cvv>) $1xxx$2
+(Card\sNumber\s=\s)\d{11,12}(\d{4}) $1xxxxxxxxxxxx$2
+(CVV\s=\s)... $1xxx
+(SSN\s=\s)\d{9} $1xxxxxxxxx
+(>)\d{11,12}(\d{4}<\/ccNum>) $1xxxxxxxxxxxx$2
+(>)\d{3,4}(<\/cvvNumber>) $1xxx$2
+(ccNum\s*=\s*)\d{11,12}(\d{4}) $1xxxxxxxxxxxx$2
+(cvvNumber\s*=\s*)\d{3,4} $1xxx$2
+(>).*(<\/passcode>) $1xxxxxx$2
+(password\s*=\s*)\S+ $1xxxxxx
+(>)\d{5}(\d{4}<\/.*businessTaxId>) $1xxxxx$2
+(tax_id\sin\srecord=\s)\d{5}(\d{4}) $1xxxxx$2
+(tax_id\sin\srequest=\s)\d{5}(\d{4}) $1xxxxx$2
+(socialSecurityNumber\s*=\s*)\d+(\d{4}) $1xxxxx$2
+(SSN\sin\srecord=)\d+(\d{4}) $1xxxxx$2
+(ssn7\s*)\d+(\d{4}) $1xxxxx$2
+(>)\d+(\d{4}<\/cam:taxId>) $1xxxxx$2
+(>)\d+(\d{4}<\/.*routingNumber>) $1xxxxx$2
+(>)\d+(\d{4}<\/bankTRN>) $1xxxxx$2
+(>)\d+(\d{4}<\/draftAccount>) $1xxxxx$2
+(SSN\sin\srequest\s=)\d+(\d{4}) $1xxxxx$2
+(Input\sto\sCasTux\sCtrl:\sSSN\s)\d+(\d{4}) $1xxxxx$2
+(businessTaxId\s)\d+(\d{4}) $1xxxxx$2
+(InquireSingleCredit\sTax_ID_Input\sin\sresponse=\s)\d+(\d{4}) $1xxxxx$2
+(<com:ssNumber>)\d+(\d{4}<\/com:ssNumber>) $1xxxxx$2
+(SsNumber:\s)\d+(\d{4}) $1xxxxx$2
+(BusinessTaxId:\s)\d+(\d{4}) $1xxxxx$2
+(<acc:passcode>).*(<\/acc:passcode>) $1xxxxxx$2
+(>)\d{4}(<\/.*creditCardExpirationDate>) $1xxxx$2
+(birthDate>)\d+(-)\d+(-)\d+(<\/.*birthDate>) $1xxxx$2xx$3xx$4
+(photoIdNumber>)\d+(\d{4}<\/.*photoIdNumber) $1xxxxxxxxxxxxxxx$2
+(socialSecurityNumber>)\d+(\d{4}<\/.*socialSecurityNumber) $1xxxxx$2
+(cardExpirationDate>)\d+(-)\d+(-)\d+(<\/.*cardExpirationDate>) $1xxxx$2xx$3xx$4
+(securityCode>)\d+(<\/.*securityCode>) $1xxxx$2
+(photo_id_nbr>)\d+(\d{4}<\/.*photo_id_nbr) $1xxxxxxxxxxxxxxx$2
+(social_security_nbr>)\d+(\d{4}<\/.*social_security_nbr) $1xxxxx$2
+(birth_date>)\d+(/)\d+(/)\d+(<\/.*birth_date>) $1xx$2xx$3xxxx$4
+(dateOfBirth>)\d+(/)\d+(/)\d+(<\/.*dateOfBirth>) $1xx$2xx$3xxxx$4
+(dateOfBirth>)\d+(-)\d+(-)\d+(<\/.*dateOfBirth>) $1xxxx$2xx$3xx$4
+(dateOfBirth>)\d+(-)\d+(-)\d+(Z<\/.*dateOfBirth>) $1xxxx$2xx$3xx$4
+(dateOfBirth>)\d+(/)\d+(/)\d+(Z<\/.*dateOfBirth>) $1xx$2xx$3xxxx$4
+(>)\w*(\w{3}<\/.*idNumber>) $1xxxxxx$2
+(taxId>)\d+(\d{4}<\/.*taxId>) $1xxxxx$2
+(accountNumber>)\d{12,19}(\d{4}<\/.*accountNumber>) $1xxxxxxxxxxxxxxx$2
+(>)[^>]*(<\/[^>]*ethnicity>) $1xxxxxx$2
+(>)[^>]*(<\/[^>]*RACE>) $1x$2
+(>)[^>]*(<\/[^>]*minority>) $1x$2
+(>)[^>]*(<\/[^>]*MINORITY>) $1x$2
+(BIRTH_DATE>)\d+(-)\d+(-)\d+(<\/.*BIRTH_DATE>) $1xx$2xx$3xxxx$4
+(custom07>)\d+(-)\d+(-)\d+(<\/.*custom07>) $1xx$2xx$3xxxx$4
+(&gt;)\d{11,12}(\d{4}&lt;\/.*creditCardNumber&gt;) $1xxxxxxxxxxxx$2
+(&gt;)\d{3,4}(&lt;\/.*security&gt;) $1xxxx$2
+(&gt;)\d{11,12}(\d{4}&lt;\/.*:.*creditCardNumber&gt;) $1xxxxxxxxxxxx$2
+(&gt;)\d{3,4}(&lt;\/.*:.*security&gt;) $1xxxx$2
+(>)\d{3,4}(<\/.*cVVCode>) $1xxxx$2
+(&gt;)\d{3,4}(&lt;\/.*cVVCode&gt;) $1xxxx$2
+(&gt;)\d{3,4}(&lt;\/.*:.*cVVCode&gt;) $1xxxx$2
+(&gt;).*(&lt;\/userPassword&gt;) $1xxxxxxx$2
+(&gt;).*(&lt;\/.*:userPassword&gt;) $1xxxxxx$2
+(&gt;).*(&lt;\/userPassword&gt;) $1xxxxxxx$2
+(\"userPassword\"\s*:\s*\")(.*?)(\") $1xxxxxx$3
+(\"cng:userPassword\"\s*:\s*\")(.*?)(\") $1xxxxxx$3
+(\"userPassword\"\s*:\s*)(\d+)(,|\s|}|]) $1xxxxxx$3
+(\"cng:userPassword\"\s*:\s*)(\d+)(,|\s|}|]) $1xxxxxx$3
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/etc/SecurityFilterExpressionsPool.properties b/ms/controllerblueprints/application/etc/SecurityFilterExpressionsPool.properties
new file mode 100644 (file)
index 0000000..acfaa45
--- /dev/null
@@ -0,0 +1,22 @@
+#
+# Copyright © 2017-2018 AT&T Intellectual Property.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+MaxActive=150
+#TimeBetweenEvictionRunsMillis=10
+
+#Min and Max idle are only used if TimeBetweenEvictionRunsMillis is set to a value > 0
+#MaxIdle=10
+#MinIdle=5
diff --git a/ms/controllerblueprints/application/etc/run.source b/ms/controllerblueprints/application/etc/run.source
new file mode 100644 (file)
index 0000000..cba5e1d
--- /dev/null
@@ -0,0 +1,16 @@
+java -classpath "/etc:${APP_HOME}/lib/*:/lib/*:/src:/schema:/generated-sources:${APP_CONFIG_HOME}:${APP_HOME}" \
+-DappName=${APPLICATIONNAME} -DappVersion=${BUNDLEVERSION} \
+-DrouteOffer=${ROUTEOFFER} \
+-DVERSION_ROUTEOFFER_ENVCONTEXT=${BUNDLEVERSION}/${STICKYSELECTORKEY}/${ENVCONTEXT} \
+-DSecurityFilePath=/etc \
+-DREST_NAME_NORMALIZER_PATTERN_FILE=/etc/PatternInputs.txt \
+-Dms_name=org.onap.ccsdk.apps.controllerblueprints.ControllerBlueprints \
+-Dlogging.config=${APP_CONFIG_HOME}/logback.xml \
+-Djava.security.egd=file:/dev/./urandom \
+-DAPPNAME=${APP_NAME} -DAPPENV=${APP_ENV} -DAPPVERSION=${APP_VERSION} -DNAMESPACE=${NAMESPACE} \
+-Dspring.config.location=${APP_CONFIG_HOME}/ \
+-Dspring.datasource.url=${DB_URL} \
+-Dspring.datasource.username=${DB_USER} \
+-Dspring.datasource.password=${DB_PASSWORD} \
+-Dblueprints.load.initial-data=${INIT_DATA_LOAD} \
+org.onap.ccsdk.apps.controllerblueprints.ControllerBluprintsApplication
diff --git a/ms/controllerblueprints/application/load/blueprints/baseconfiguration/Definitions/activation-blueprint.json b/ms/controllerblueprints/application/load/blueprints/baseconfiguration/Definitions/activation-blueprint.json
new file mode 100644 (file)
index 0000000..635e177
--- /dev/null
@@ -0,0 +1,411 @@
+{\r
+  "metadata": {\r
+    "template_author": "Brinda Santh Muthuramalingam",\r
+    "author-email": "brindasanth@gmail.com",\r
+    "user-groups" : "ADMIN, OPERATION",\r
+    "template_name": "baseconfiguration",\r
+    "template_version": "1.0.0",\r
+    "template_tags": "brinda, tosca"\r
+  },\r
+  "topology_template": {\r
+    "inputs": {\r
+      "request-id": {\r
+        "required": true,\r
+        "type": "string"\r
+      },\r
+      "action-name": {\r
+        "required": true,\r
+        "type": "string"\r
+      },\r
+      "scope-type": {\r
+        "required": true,\r
+        "type": "string"\r
+      },\r
+      "hostname": {\r
+        "required": true,\r
+        "type": "string"\r
+      }\r
+    },\r
+    "node_templates": {\r
+      "activate-process": {\r
+        "type": "bpmn-activate",\r
+        "properties": {\r
+          "process-name": { "get_input" : "action-name" },\r
+          "version" : { "get_property" : ["SELF", "process-name"] },\r
+          "content": { "get_artifact" : ["SELF", "activate-process"] }\r
+        },\r
+        "artifacts": {\r
+          "activate-process": {\r
+            "type": "artifact-bpmn-camunda",\r
+            "file": "Plans/ActivateProcess.bpmn"\r
+          }\r
+        }\r
+      },\r
+      "resource-assignment": {\r
+        "type": "component-resource-assignment",\r
+        "properties":{\r
+          "request-id": ["1234", "1234"]\r
+        },\r
+        "interfaces": {\r
+          "DefaultComponentNode": {\r
+            "operations": {\r
+              "process": {\r
+                "inputs": {\r
+                  "action-name": { "get_input" : "action-name" },\r
+                  "resource-type": "vnf-type",\r
+                  "request-id": { "get_input" : "request-id" },\r
+                  "resource-id": { "get_input" : "hostname" },\r
+                  "template-content": { "get_artifact" : ["SELF", "baseconfig-template"] },\r
+                  "mapping-content": { "get_artifact" : ["SELF", "baseconfig-mapping"] }\r
+                },\r
+                "outputs": {\r
+                  "resource-assignment-params": "",\r
+                  "status": ""\r
+                }\r
+              }\r
+            }\r
+          }\r
+        },\r
+        "artifacts": {\r
+          "baseconfig-template": {\r
+            "type": "artifact-template-velocity",\r
+            "file": "Templates/baseconfig-template.vtl"\r
+          },\r
+          "baseconfig-mapping": {\r
+            "type": "artifact-mapping-resource",\r
+            "file": "Mappings/baseconfig-mapping.json"\r
+          }\r
+        }\r
+      },\r
+      "resource-assignment-py": {\r
+        "type": "component-resource-assignment",\r
+        "properties":{\r
+          "request-id": ["1234", "1234"]\r
+        },\r
+        "interfaces": {\r
+          "DefaultComponentNode": {\r
+            "operations": {\r
+              "process": {\r
+                "implementation" :{\r
+                  "primary" : "component-script"\r
+                },\r
+                "inputs": {\r
+                  "action-name": { "get_input" : "action-name" }\r
+                },\r
+                "outputs": {\r
+                  "resource-assignment-params": "",\r
+                  "status": ""\r
+                }\r
+              }\r
+            }\r
+          }\r
+        },\r
+        "artifacts": {\r
+          "component-script": {\r
+            "type": "artifact-script-python",\r
+            "file": "Scripts/baseconfig-template.vtl"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "workflows":{\r
+      "activate-process":{\r
+        "steps" : {\r
+            "call-resource-assignment" : {\r
+              "description" : "Invoke Resource Assignment Component",\r
+              "target" : "resource-assignment",\r
+              "activities" : [\r
+                {\r
+                  "call_operation": "ResourceAssignmentNode.process"\r
+                }\r
+              ],\r
+              "on_success" : [\r
+                "download-baseconfig"\r
+              ]\r
+            },\r
+          "download-baseconfig" : {\r
+            "description" : "Call Download Base Config Component",\r
+            "target" : "activate-netconf",\r
+            "activities" : [\r
+              {\r
+                "call_operation": "NetconfTransactionNode.process"\r
+              }\r
+            ],\r
+            "on_success" : [\r
+              "download-licence"\r
+            ]\r
+          },\r
+          "download-licence" : {\r
+            "description" : "Call Download Licence Component",\r
+            "target" : "activate-netconf",\r
+            "activities" : [\r
+              {\r
+                "call_operation": "NetconfTransactionNode.process"\r
+              }\r
+            ]\r
+          }\r
+        }\r
+      }\r
+    }\r
+  },\r
+  "artifact_types": {\r
+    "artifact-template-velocity": {\r
+      "description": " Velocity Template used for Configuration",\r
+      "version": "1.0.0",\r
+      "file_ext": [\r
+        "vtl"\r
+      ],\r
+      "derived_from": "tosca.artifacts.Implementation"\r
+    },\r
+    "artifact-mapping-resource": {\r
+      "description": " Velocity Template Resource Mapping File used along with Configuration template",\r
+      "version": "1.0.0",\r
+      "file_ext": [\r
+        "json"\r
+      ],\r
+      "derived_from": "tosca.artifacts.Implementation"\r
+    },\r
+    "artifact-script-kotlin": {\r
+      "description": " Kotlin Script Template used for Configuration",\r
+      "version": "1.0.0",\r
+      "file_ext": [\r
+        "kt"\r
+      ],\r
+      "derived_from": "tosca.artifacts.Implementation"\r
+    },\r
+    "artifact-script-python": {\r
+      "description": " Kotlin Script Template used for Configuration",\r
+      "version": "1.0.0",\r
+      "file_ext": [\r
+        "py"\r
+      ],\r
+      "derived_from": "tosca.artifacts.Implementation"\r
+    },\r
+    "artifact-bpmn-camunda": {\r
+      "description": " Camunda BPM File",\r
+      "version": "1.0.0",\r
+      "file_ext": [\r
+        "bpmn"\r
+      ],\r
+      "derived_from": "tosca.artifacts.Implementation"\r
+    },\r
+    "artifact-component-jar": {\r
+      "description": "Component Jar",\r
+      "version": "1.0.0",\r
+      "file_ext": [\r
+        "jar"\r
+      ],\r
+      "derived_from": "tosca.artifacts.Implementation"\r
+    }\r
+  },\r
+  "node_types": {\r
+    "bpmn-activate": {\r
+      "description": "This is BPMN Activate node type",\r
+      "version": "1.0.0",\r
+      "properties": {\r
+        "content": {\r
+          "required": false,\r
+          "type": "string"\r
+        },\r
+        "process-name": {\r
+          "required": false,\r
+          "type": "string"\r
+        },\r
+        "version": {\r
+          "required": false,\r
+          "type": "string",\r
+          "default" : "LATEST"\r
+        }\r
+      },\r
+      "derived_from": "tosca.nodes.Component"\r
+    },\r
+    "tosca.nodes.Component": {\r
+      "description": "This is Resource Assignment Component API",\r
+      "version": "1.0.0",\r
+      "properties": {\r
+        "type": {\r
+          "description": "Request Id used to store the generated configuration, in the database along with the template-name",\r
+          "required": false,\r
+          "type": "string"\r
+        }\r
+      },\r
+      "interfaces": {\r
+        "DefaultOperation": {\r
+          "operations": {\r
+            "validate": {\r
+              "inputs": {\r
+                "action-name": {\r
+                  "description": "validate for action",\r
+                  "required": false,\r
+                  "type": "string"\r
+                }\r
+              }\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "artifacts" :{\r
+        "component-jar": {\r
+          "description": "Component Jar",\r
+          "type": "artifact-component-jar",\r
+          "file": "Component/basecomponent.jar"\r
+        }\r
+      },\r
+      "derived_from": "tosca.nodes.Root"\r
+    },\r
+    "tosca.nodes.component.Python": {\r
+      "description": "This is Resource Assignment Python Component API",\r
+      "version": "1.0.0",\r
+      "properties": {\r
+        "type": {\r
+          "description": "Request Id used to store the generated configuration, in the database along with the template-name",\r
+          "required": false,\r
+          "type": "string"\r
+        }\r
+      },\r
+      "interfaces": {\r
+        "DefaultOperation": {\r
+          "operations": {\r
+            "validate": {\r
+              "inputs": {\r
+                "action-name": {\r
+                  "description": "validate for action",\r
+                  "required": false,\r
+                  "type": "string"\r
+                }\r
+              }\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "artifacts" :{\r
+        "component-jar": {\r
+          "description": "Component Jar",\r
+          "type": "artifact-component-jar",\r
+          "file": "Component/basecomponent.jar"\r
+        }\r
+      },\r
+      "derived_from": "tosca.nodes.Root"\r
+    },\r
+    "component-resource-assignment": {\r
+      "description": "This is Resource Assignment Component API",\r
+      "version": "1.0.0",\r
+      "properties": {\r
+        "request-id": {\r
+          "description": "Request Id used to store the generated configuration, in the database along with the template-name",\r
+          "required": true,\r
+          "type": "string"\r
+        }\r
+      },\r
+      "interfaces": {\r
+        "DefaultComponentNode": {\r
+          "operations": {\r
+            "process": {\r
+              "inputs": {\r
+                "action-name": {\r
+                  "description": "Recipe Name to get from Database, Either (message & mask-info ) or ( resource-id & resource-type & action-name & template-name ) should be present. Message will be given higest priority",\r
+                  "required": false,\r
+                  "type": "string"\r
+                },\r
+                "resource-type": {\r
+                  "required": false,\r
+                  "type": "string"\r
+                },\r
+                "request-id": {\r
+                  "description": "Request Id used to store the generated configuration, in the database along with the template-name",\r
+                  "required": true,\r
+                  "type": "string"\r
+                },\r
+                "resource-id": {\r
+                  "description": "Id used to pull the data content from the data base. Either template-data or resource-id should be present",\r
+                  "required": true,\r
+                  "type": "string"\r
+                },\r
+                "template-content": {\r
+                  "description": "Id used to pull the data content from the data base. Either template-data or resource-id should be present",\r
+                  "required": true,\r
+                  "type": "string"\r
+                },\r
+                "mapping-content": {\r
+                  "description": "Id used to pull the data content from the data base. Either template-data or resource-id should be present",\r
+                  "required": true,\r
+                  "type": "string"\r
+                }\r
+              },\r
+              "outputs": {\r
+                "resource-assignment-params": {\r
+                  "required": true,\r
+                  "type": "string"\r
+                },\r
+                "status": {\r
+                  "required": true,\r
+                  "type": "string"\r
+                }\r
+              }\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "derived_from": "tosca.nodes.Component"\r
+    },\r
+    "component-resource-assignment-python": {\r
+      "description": "This is Resource Assignment Component API",\r
+      "version": "1.0.0",\r
+      "properties": {\r
+        "request-id": {\r
+          "description": "Request Id used to store the generated configuration, in the database along with the template-name",\r
+          "required": true,\r
+          "type": "string"\r
+        }\r
+      },\r
+      "interfaces": {\r
+        "DefaultComponentNode": {\r
+          "operations": {\r
+            "process": {\r
+              "inputs": {\r
+                "action-name": {\r
+                  "description": "Recipe Name to get from Database, Either (message & mask-info ) or ( resource-id & resource-type & action-name & template-name ) should be present. Message will be given higest priority",\r
+                  "required": false,\r
+                  "type": "string"\r
+                }\r
+              },\r
+              "outputs": {\r
+                "resource-assignment-params": {\r
+                  "required": true,\r
+                  "type": "string"\r
+                },\r
+                "status": {\r
+                  "required": true,\r
+                  "type": "string"\r
+                }\r
+              }\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "derived_from": "tosca.nodes.component.Python"\r
+    }\r
+  },\r
+  "data_types": {\r
+    "sample-property" : {\r
+      "description": "This is sample data type",\r
+      "version": "1.0.0",\r
+      "properties": {\r
+        "content": {\r
+          "required": false,\r
+          "type": "string"\r
+        },\r
+        "process-name": {\r
+          "required": false,\r
+          "type": "string"\r
+        },\r
+        "version": {\r
+          "required": false,\r
+          "type": "string",\r
+          "default" : "LATEST"\r
+        }\r
+      },\r
+      "derived_from" : "tosca.datatypes.Root"\r
+    }\r
+  }\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/load/blueprints/baseconfiguration/Mappings/baseconfig-mapping.json b/ms/controllerblueprints/application/load/blueprints/baseconfiguration/Mappings/baseconfig-mapping.json
new file mode 100644 (file)
index 0000000..6abfb51
--- /dev/null
@@ -0,0 +1,3 @@
+{\r
+  "assignments": "Sample Assignments"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/load/blueprints/baseconfiguration/Plans/ActivateProcess.bpmn b/ms/controllerblueprints/application/load/blueprints/baseconfiguration/Plans/ActivateProcess.bpmn
new file mode 100644 (file)
index 0000000..5e94c0f
--- /dev/null
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL"\r
+                  xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"\r
+                  xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"\r
+                  xmlns:camunda="http://camunda.org/schema/1.0/bpmn"\r
+                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1"\r
+                  targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="1.11.2">\r
+    <bpmn:process id="ActivateProcess" isExecutable="true">\r
+        <bpmn:startEvent id="StartEvent_1">\r
+            <bpmn:outgoing>SequenceFlow_0l0dq58</bpmn:outgoing>\r
+        </bpmn:startEvent>\r
+        <bpmn:endEvent id="EndEvent_1pr0kil">\r
+            <bpmn:incoming>SequenceFlow_1ay0k6p</bpmn:incoming>\r
+        </bpmn:endEvent>\r
+        <bpmn:sequenceFlow id="SequenceFlow_0l0dq58" sourceRef="StartEvent_1" targetRef="activate_device_task"/>\r
+        <bpmn:sequenceFlow id="SequenceFlow_1ay0k6p" sourceRef="activate_device_task" targetRef="EndEvent_1pr0kil"/>\r
+        <bpmn:serviceTask id="activate_device_task" name="Activate Device"\r
+                          camunda:delegateExpression="${componentDelegateService}">\r
+            <bpmn:extensionElements>\r
+                <camunda:inputOutput>\r
+                    <camunda:inputParameter name="selector"><![CDATA[resource-assignment\r
+]]></camunda:inputParameter>\r
+                </camunda:inputOutput>\r
+            </bpmn:extensionElements>\r
+            <bpmn:incoming>SequenceFlow_0l0dq58</bpmn:incoming>\r
+            <bpmn:outgoing>SequenceFlow_1ay0k6p</bpmn:outgoing>\r
+        </bpmn:serviceTask>\r
+    </bpmn:process>\r
+    <bpmndi:BPMNDiagram id="BPMNDiagram_1">\r
+        <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="ActivateProcess">\r
+            <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">\r
+                <dc:Bounds x="175" y="143" width="36" height="36"/>\r
+                <bpmndi:BPMNLabel>\r
+                    <dc:Bounds x="148" y="179" width="90" height="20"/>\r
+                </bpmndi:BPMNLabel>\r
+            </bpmndi:BPMNShape>\r
+            <bpmndi:BPMNShape id="EndEvent_1pr0kil_di" bpmnElement="EndEvent_1pr0kil">\r
+                <dc:Bounds x="575" y="114" width="36" height="36"/>\r
+                <bpmndi:BPMNLabel>\r
+                    <dc:Bounds x="593" y="154" width="0" height="12"/>\r
+                </bpmndi:BPMNLabel>\r
+            </bpmndi:BPMNShape>\r
+            <bpmndi:BPMNEdge id="SequenceFlow_0l0dq58_di" bpmnElement="SequenceFlow_0l0dq58">\r
+                <di:waypoint xsi:type="dc:Point" x="211" y="161"/>\r
+                <di:waypoint xsi:type="dc:Point" x="273" y="161"/>\r
+                <di:waypoint xsi:type="dc:Point" x="273" y="149"/>\r
+                <di:waypoint xsi:type="dc:Point" x="334" y="149"/>\r
+                <bpmndi:BPMNLabel>\r
+                    <dc:Bounds x="288" y="149" width="0" height="12"/>\r
+                </bpmndi:BPMNLabel>\r
+            </bpmndi:BPMNEdge>\r
+            <bpmndi:BPMNEdge id="SequenceFlow_1ay0k6p_di" bpmnElement="SequenceFlow_1ay0k6p">\r
+                <di:waypoint xsi:type="dc:Point" x="434" y="149"/>\r
+                <di:waypoint xsi:type="dc:Point" x="505" y="149"/>\r
+                <di:waypoint xsi:type="dc:Point" x="505" y="132"/>\r
+                <di:waypoint xsi:type="dc:Point" x="575" y="132"/>\r
+                <bpmndi:BPMNLabel>\r
+                    <dc:Bounds x="520" y="134.5" width="0" height="12"/>\r
+                </bpmndi:BPMNLabel>\r
+            </bpmndi:BPMNEdge>\r
+            <bpmndi:BPMNShape id="ServiceTask_0e8ek4f_di" bpmnElement="activate_device_task">\r
+                <dc:Bounds x="334" y="109" width="100" height="80"/>\r
+            </bpmndi:BPMNShape>\r
+        </bpmndi:BPMNPlane>\r
+    </bpmndi:BPMNDiagram>\r
+</bpmn:definitions>\r
diff --git a/ms/controllerblueprints/application/load/blueprints/baseconfiguration/Scripts/SamplePythonComponentNode.py b/ms/controllerblueprints/application/load/blueprints/baseconfiguration/Scripts/SamplePythonComponentNode.py
new file mode 100644 (file)
index 0000000..eb198c7
--- /dev/null
@@ -0,0 +1,8 @@
+from com.brvith.orchestrator.core.interfaces import ComponentNode\r
+\r
+class SamplePythonComponentNode(ComponentNode):\r
+    def prepare(self, context, componentContext):\r
+        return None\r
+\r
+    def prepare(self, context, componentContext):\r
+        return None
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/load/blueprints/baseconfiguration/Scripts/__init__.py b/ms/controllerblueprints/application/load/blueprints/baseconfiguration/Scripts/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/ms/controllerblueprints/application/load/blueprints/baseconfiguration/TOSCA-Metadata/TOSCA.meta b/ms/controllerblueprints/application/load/blueprints/baseconfiguration/TOSCA-Metadata/TOSCA.meta
new file mode 100644 (file)
index 0000000..fb38c15
--- /dev/null
@@ -0,0 +1,8 @@
+TOSCA-Meta-File-Version: 1.0.0\r
+CSAR-Version: 1.0\r
+Created-By: Brinda Santh M\r
+Entry-Definitions: Definitions/activation-blueprint.json\r
+Template-Tags: Brinda Santh, activation-blueprint\r
+\r
+Name: Plans/ActivateProcess.bpmn\r
+Content-Type: application/vnd.oasis.bpmn\r
diff --git a/ms/controllerblueprints/application/load/blueprints/baseconfiguration/Templates/baseconfig-template.vtl b/ms/controllerblueprints/application/load/blueprints/baseconfiguration/Templates/baseconfig-template.vtl
new file mode 100644 (file)
index 0000000..026c591
--- /dev/null
@@ -0,0 +1 @@
+This is Sample Velocity Template
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/load/blueprints/baseconfiguration/__init__.py b/ms/controllerblueprints/application/load/blueprints/baseconfiguration/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/ms/controllerblueprints/application/load/model_type/artifact_type/artifact-mapping-resource.json b/ms/controllerblueprints/application/load/model_type/artifact_type/artifact-mapping-resource.json
new file mode 100644 (file)
index 0000000..0a3261b
--- /dev/null
@@ -0,0 +1,8 @@
+{\r
+  "description": " Velocity Template Resource Mapping File used along with Configuration template",\r
+  "version": "1.0.0",\r
+  "file_ext": [\r
+    "json"\r
+  ],\r
+  "derived_from": "tosca.artifacts.Implementation"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/load/model_type/artifact_type/artifact-script-python.json b/ms/controllerblueprints/application/load/model_type/artifact_type/artifact-script-python.json
new file mode 100644 (file)
index 0000000..b48d2b6
--- /dev/null
@@ -0,0 +1,8 @@
+{\r
+  "description": " Kotlin Script Template used for Configuration",\r
+  "version": "1.0.0",\r
+  "file_ext": [\r
+    "py"\r
+  ],\r
+  "derived_from": "tosca.artifacts.Implementation"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/load/model_type/artifact_type/artifact-template-velocity.json b/ms/controllerblueprints/application/load/model_type/artifact_type/artifact-template-velocity.json
new file mode 100644 (file)
index 0000000..9395d39
--- /dev/null
@@ -0,0 +1,8 @@
+{\r
+  "description": " Velocity Template used for Configuration",\r
+  "version": "1.0.0",\r
+  "file_ext": [\r
+    "vtl"\r
+  ],\r
+  "derived_from": "tosca.artifacts.Implementation"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/load/model_type/artifact_type/tosca.artifacts.Implementation.json b/ms/controllerblueprints/application/load/model_type/artifact_type/tosca.artifacts.Implementation.json
new file mode 100644 (file)
index 0000000..5a7c956
--- /dev/null
@@ -0,0 +1,5 @@
+{\r
+  "description": "TOSCA base type for implementation artifacts",\r
+  "version": "1.0.0",\r
+  "derived_from": "tosca.artifacts.Root"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/load/model_type/data_type/datatype-property.json b/ms/controllerblueprints/application/load/model_type/data_type/datatype-property.json
new file mode 100644 (file)
index 0000000..5584b10
--- /dev/null
@@ -0,0 +1,27 @@
+{\r
+       "version": "1.0.0",\r
+       "description": "This is Entry point Input Data Type, which is dynamic datatype, The parameter names will be populated during the Design time for each inputs",\r
+       "properties": {\r
+               "type": {\r
+                       "required": true,\r
+                       "type": "string"\r
+               },\r
+               "description": {\r
+                       "required": false,\r
+                       "type": "string"\r
+               },\r
+               "required": {\r
+                       "required": false,\r
+                       "type": "boolean"\r
+               },\r
+               "default": {\r
+                       "required": false,\r
+                       "type": "string"\r
+               },\r
+               "entry_schema": {\r
+                       "required": false,\r
+                       "type": "string"\r
+               }\r
+       },\r
+       "derived_from": "tosca.datatypes.Root"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/load/model_type/data_type/datatype-resource-assignment.json b/ms/controllerblueprints/application/load/model_type/data_type/datatype-resource-assignment.json
new file mode 100644 (file)
index 0000000..cc9816e
--- /dev/null
@@ -0,0 +1,46 @@
+{\r
+       "version": "1.0.0",\r
+       "description": "This is Resource Assignment Data Type",\r
+       "properties": {\r
+               "property": {\r
+                       "required": true,\r
+                       "type": "datatype-property"\r
+               },\r
+               "input-param": {\r
+                       "required": true,\r
+                       "type": "boolean"\r
+               },\r
+               "dictionary-name": {\r
+                       "required": false,\r
+                       "type": "string"\r
+               },\r
+               "dictionary-source": {\r
+                       "required": false,\r
+                       "type": "string"\r
+               },\r
+               "dependencies": {\r
+                       "required": true,\r
+                       "type": "list",\r
+                       "entry_schema": {\r
+                               "type": "string"\r
+                       }\r
+               },\r
+               "status": {\r
+                       "required": false,\r
+                       "type": "string"\r
+               },\r
+               "message": {\r
+                       "required": false,\r
+                       "type": "string"\r
+               },\r
+               "updated-date": {\r
+                       "required": false,\r
+                       "type": "string"\r
+               },\r
+               "updated-by": {\r
+                       "required": false,\r
+                       "type": "string"\r
+               }\r
+       },\r
+       "derived_from": "tosca.datatypes.Root"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/load/model_type/data_type/dt-license-key.json b/ms/controllerblueprints/application/load/model_type/data_type/dt-license-key.json
new file mode 100644 (file)
index 0000000..e9c312b
--- /dev/null
@@ -0,0 +1,11 @@
+{\r
+       "version": "1.0.0",\r
+       "description": "This is dt-plicense-key Data Type",\r
+       "properties": {\r
+               "license-key": {\r
+                       "required": true,\r
+                       "type": "string"\r
+               }\r
+       },\r
+       "derived_from": "tosca.datatypes.Root"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/load/model_type/data_type/dt-v4-aggregate.json b/ms/controllerblueprints/application/load/model_type/data_type/dt-v4-aggregate.json
new file mode 100644 (file)
index 0000000..842a7f8
--- /dev/null
@@ -0,0 +1,15 @@
+{\r
+       "version": "1.0.0",\r
+       "description": "This is dt-v4-aggregate Data Type",\r
+       "properties": {\r
+               "ipv4-address": {\r
+                       "required": true,\r
+                       "type": "string"\r
+               },\r
+               "ipv4-plen": {\r
+                       "required": false,\r
+                       "type": "integer"\r
+               }\r
+       },\r
+       "derived_from": "tosca.datatypes.Root"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/load/model_type/data_type/tosca.datatypes.Credential.json b/ms/controllerblueprints/application/load/model_type/data_type/tosca.datatypes.Credential.json
new file mode 100644 (file)
index 0000000..820a551
--- /dev/null
@@ -0,0 +1,31 @@
+{\r
+  "version": "1.0.0",\r
+  "description": "Credential",\r
+  "properties": {\r
+    "protocol": {\r
+      "required": false,\r
+      "type": "string"\r
+    },\r
+    "token_type": {\r
+      "required": true,\r
+      "type": "string",\r
+      "default" : "password"\r
+    },\r
+    "token": {\r
+      "required": false,\r
+      "type": "string"\r
+    },\r
+    "keys": {\r
+      "required": false,\r
+      "type": "list",\r
+      "entry_schema": {\r
+        "type": "string"\r
+      }\r
+    },\r
+    "user": {\r
+      "required": false,\r
+      "type": "string"\r
+    }\r
+  },\r
+  "derived_from": "tosca.datatypes.Root"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/load/model_type/node_type/artifact-config-template.json b/ms/controllerblueprints/application/load/model_type/node_type/artifact-config-template.json
new file mode 100644 (file)
index 0000000..be9bbfc
--- /dev/null
@@ -0,0 +1,37 @@
+{\r
+       "description": "This is Configuration Velocity Template",\r
+       "version": "1.0.0",\r
+       "properties": {\r
+               "action-names": {\r
+                       "required": true,\r
+                       "type": "list",\r
+                       "entry_schema": {\r
+                               "type": "string"\r
+                       }\r
+               }\r
+       },\r
+       "capabilities": {\r
+               "content": {\r
+                       "type": "tosca.capability.Content",\r
+                       "properties": {\r
+                               "content": {\r
+                                       "required": true,\r
+                                       "type": "string"\r
+                               }\r
+                       }\r
+               },\r
+               "mapping": {\r
+                       "type": "tosca.capability.Mapping",\r
+                       "properties": {\r
+                               "mapping": {\r
+                                       "required": false,\r
+                                       "type": "list",\r
+                                       "entry_schema": {\r
+                                               "type": "datatype-resource-assignment"\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       },\r
+       "derived_from": "tosca.nodes.Artifact"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/load/model_type/node_type/component-config-generator.json b/ms/controllerblueprints/application/load/model_type/node_type/component-config-generator.json
new file mode 100644 (file)
index 0000000..764f9e8
--- /dev/null
@@ -0,0 +1,72 @@
+{\r
+       "description": "This is Generate Configuration Component API",\r
+       "version": "1.0.0",\r
+       "capabilities": {\r
+               "component-node": {\r
+                       "type": "tosca.capabilities.Node"\r
+               }\r
+       },\r
+       "interfaces": {\r
+               "org-openecomp-sdnc-config-generator-service-ConfigGeneratorNode": {\r
+                       "operations": {\r
+                               "process": {\r
+                                       "inputs": {\r
+                                               "template-data": {\r
+                                                       "description": "Conditional : JSON string which is used to mash with template. Either template-data or ( resource-id and resource-type ) should be present",\r
+                                                       "required": false,\r
+                                                       "type": "string"\r
+                                               },\r
+                                               "template-content": {\r
+                                                       "description": "Conditional : Dynamic Template used to generate Configuration.",\r
+                                                       "required": false,\r
+                                                       "type": "string"\r
+                                               },\r
+                                               "resource-type": {\r
+                                                       "description": "Conditional : resource-type used to pull the data content from the data base. Either template-data or ( resource-id and resource-type ) should be present",\r
+                                                       "required": false,\r
+                                                       "type": "string"\r
+                                               },\r
+                                               "request-id": {\r
+                                                       "description": "Request Id used to store the generated configuration, in the database along with the template-name",\r
+                                                       "required": true,\r
+                                                       "type": "string"\r
+                                               },\r
+                                               "resource-id": {\r
+                                                       "description": "Conditional : Id used to pull the data content from the data base. Either template-data or ( resource-id and resource-type ) should be present",\r
+                                                       "required": false,\r
+                                                       "type": "string"\r
+                                               },\r
+                                               "action-name": {\r
+                                                       "description": "Conditional : Action Name to get from Database, Either (message & mask-info ) or ( resource-id & resource-type & action-name & template-name ) should be present. Message will be given higest priority",\r
+                                                       "required": false,\r
+                                                       "type": "string"\r
+                                               },\r
+                                               "template-name": {\r
+                                                       "description": "Conditional : Name of the Artifact Node Template, to get the template Content. If template-content is present, then content wont be reterived from the Artifact Node Template.",\r
+                                                       "required": true,\r
+                                                       "type": "string"\r
+                                               }\r
+                                       },\r
+                                       "outputs": {\r
+                                               "generated-config": {\r
+                                                       "description": "Generated Configuration for the Template adn Resource Data",\r
+                                                       "required": true,\r
+                                                       "type": "string"\r
+                                               },\r
+                                               "mask-info": {\r
+                                                       "description": "If template contains mask encription keys, then this mask-info field will be generated, This JSON Content alligns to the bean org.onap.ccsdk.apps.controllerblueprints.core.data.custom.MaskInfo ",\r
+                                                       "required": false,\r
+                                                       "type": "string"\r
+                                               },\r
+                                               "status": {\r
+                                                       "description": "Status of the Component Execution ( success or failure )",\r
+                                                       "required": true,\r
+                                                       "type": "string"\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       },\r
+       "derived_from": "tosca.nodes.Component"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/load/model_type/node_type/component-netconf-executor.json b/ms/controllerblueprints/application/load/model_type/node_type/component-netconf-executor.json
new file mode 100644 (file)
index 0000000..aed667a
--- /dev/null
@@ -0,0 +1,79 @@
+{\r
+  "description": "This is Netconf Transaction Configuration Component API",\r
+  "version": "1.0.0",\r
+  "capabilities": {\r
+    "component-node": {\r
+      "type": "tosca.capabilities.Node"\r
+    }\r
+  },\r
+  "requirements": {\r
+    "netconf-connection": {\r
+      "capability": "netconf",\r
+      "node": "vnf-netconf-device",\r
+      "relationship": "tosca.relationships.ConnectsTo"\r
+    }\r
+  },\r
+  "interfaces": {\r
+    "org-openecomp-sdnc-netconf-adaptor-service-NetconfExecutorNode": {\r
+      "operations": {\r
+        "process": {\r
+          "inputs": {\r
+            "request-id": {\r
+              "description": "Request Id used to store the generated configuration, in the database along with the template-name",\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "service-template-name": {\r
+              "description": "Service Template Name",\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "service-template-version": {\r
+              "description": "Service Template Version",\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "action-name": {\r
+              "description": "Action Name to get from Database, Either (message & mask-info ) or ( resource-id & resource-type & action-name & template-name ) should be present. Message will be given higest priority",\r
+              "required": false,\r
+              "type": "string"\r
+            },\r
+            "resource-type": {\r
+              "description": "Resource Type to get from Database, Either (message & mask-info ) or( resource-id & resource-type & action-name & template-name ) should be present. Message will be given higest priority",\r
+              "required": false,\r
+              "type": "string"\r
+            },\r
+            "resource-id": {\r
+              "description": "Resource Id to get from Database, Either (message & mask-info ) or ( resource-id & resource-type & action-name & template-name ) should be present. Message will be given higest priority",\r
+              "required": false,\r
+              "type": "string"\r
+            },\r
+            "reservation-id": {\r
+                               "description": "Reservation Id used to send to NPM",\r
+                               "required": false,\r
+                               "type": "string"\r
+                       },\r
+            "execution-script": {\r
+              "description": "Python Script to Execute for this Component action, It should refer any one of Prython Artifact Definition for this Node Template.",\r
+              "required": true,\r
+              "type": "string"\r
+            }\r
+          },\r
+          "outputs": {\r
+            "response-data": {\r
+              "description": "Execution Response Data in JSON format.",\r
+              "required": false,\r
+              "type": "string"\r
+            },\r
+            "status": {\r
+              "description": "Status of the Component Execution ( success or failure )",\r
+              "required": true,\r
+              "type": "string"\r
+            }\r
+          }\r
+        }\r
+      }\r
+    }\r
+  },\r
+  "derived_from": "tosca.nodes.Component"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/load/model_type/node_type/component-resource-assignment.json b/ms/controllerblueprints/application/load/model_type/node_type/component-resource-assignment.json
new file mode 100644 (file)
index 0000000..34c0284
--- /dev/null
@@ -0,0 +1,68 @@
+{\r
+  "description": "This is Resource Assignment Component API",\r
+  "version": "1.0.0",\r
+  "capabilities": {\r
+    "component-node": {\r
+      "type": "tosca.capabilities.Node"\r
+    }\r
+  },\r
+  "interfaces": {\r
+    "org-openecomp-sdnc-config-assignment-service-ConfigAssignmentNode": {\r
+      "operations": {\r
+        "process": {\r
+          "inputs": {\r
+            "service-template-name": {\r
+              "description": "Service Template Name.",\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "service-template-version": {\r
+              "description": "Service Template Version.",\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "resource-type": {\r
+              "description": "Request type.",\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "template-names": {\r
+              "description": "Name of the artifact Node Templates, to get the template Content.",\r
+              "required": true,\r
+              "type": "list",\r
+              "entry_schema": {\r
+                "type": "string"\r
+              }\r
+            },\r
+            "request-id": {\r
+              "description": "Request Id, Unique Id for the request.",\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "resource-id": {\r
+              "description": "Resource Id.",\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "action-name": {\r
+              "description": "Action Name of the process",\r
+              "required": true,\r
+              "type": "string"\r
+            }\r
+          },\r
+          "outputs": {\r
+            "resource-assignment-params": {\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "status": {\r
+              "required": true,\r
+              "type": "string"\r
+            }\r
+          }\r
+        }\r
+      }\r
+    }\r
+  },\r
+  "derived_from": "tosca.nodes.Component"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/load/model_type/node_type/dg-activate-netconf.json b/ms/controllerblueprints/application/load/model_type/node_type/dg-activate-netconf.json
new file mode 100644 (file)
index 0000000..c638df0
--- /dev/null
@@ -0,0 +1,66 @@
+{
+       "description": "This is Download Netconf Directed Graph",
+       "version": "1.0.0",
+       "properties": {
+               "mode": {
+                       "required": false,
+                       "type": "string",
+                       "default": "sync"
+               },
+               "version": {
+                       "required": false,
+                       "type": "string",
+                       "default": "LATEST"
+               },
+               "is-start-flow": {
+                       "required": false,
+                       "type": "boolean",
+                       "default": "false"
+               }
+       },
+       "capabilities": {
+               "dg-node": {
+                       "type": "tosca.capabilities.Node"
+               },
+               "content": {
+                       "type": "tosca.capability.Content",
+                       "properties": {
+                               "type": {
+                                       "required": false,
+                                       "type": "string",
+                                       "default": "json"
+                               },
+                               "content": {
+                                       "required": true,
+                                       "type": "string"
+                               }
+                       }
+               }
+       },
+       "requirements": {
+               "component-dependency": {
+                       "capability": "component-node",
+                       "node": "component-netconf-executor",
+                       "relationship": "tosca.relationships.DependsOn"
+               }
+       },
+       "interfaces": {
+               "CONFIG": {
+                       "operations": {
+                               "ActivateNetconf": {
+                                       "inputs": {
+                                               "params": {
+                                                       "required": false,
+                                                       "type": "list",
+                                                       "entry_schema": {
+                                                               "type": "datatype-property"
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+       },
+       
+       "derived_from": "tosca.nodes.DG"
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/load/model_type/node_type/dg-config-generator.json b/ms/controllerblueprints/application/load/model_type/node_type/dg-config-generator.json
new file mode 100644 (file)
index 0000000..28bace0
--- /dev/null
@@ -0,0 +1,65 @@
+{\r
+       "description": "This is Activate DG for Config Generator Directed Graph",\r
+       "version": "1.0.0",\r
+       "properties": {\r
+               "mode": {\r
+                       "required": false,\r
+                       "type": "string",\r
+                       "default": "sync"\r
+               },\r
+               "version": {\r
+                       "required": false,\r
+                       "type": "string",\r
+                       "default": "LATEST"\r
+               },\r
+               "is-start-flow": {\r
+                       "required": false,\r
+                       "type": "boolean",\r
+                       "default": "false"\r
+               }\r
+       },\r
+       "capabilities": {\r
+               "dg-node": {\r
+                       "type": "tosca.capabilities.Node"\r
+               },\r
+               "content": {\r
+                       "type": "tosca.capability.Content",\r
+                       "properties": {\r
+                               "type": {\r
+                                       "required": false,\r
+                                       "type": "string",\r
+                                       "default": "json"\r
+                               },\r
+                               "content": {\r
+                                       "required": true,\r
+                                       "type": "string"\r
+                               }\r
+                       }\r
+               }\r
+       },\r
+       "requirements": {\r
+               "component-dependency": {\r
+                       "capability": "component-node",\r
+                       "node": "component-config-generator",\r
+                       "relationship": "tosca.relationships.DependsOn"\r
+               }\r
+       },\r
+       "interfaces": {\r
+               "CONFIG": {\r
+                       "operations": {\r
+                               "GenerateConfiguration": {\r
+                                       "inputs": {\r
+                                               "params": {\r
+                                                       "required": false,\r
+                                                       "type": "list",\r
+                                                       "entry_schema": {\r
+                                                               "type": "datatype-property"\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       },\r
+       "derived_from": "tosca.nodes.DG"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/load/model_type/node_type/dg-resource-assign-activate.json b/ms/controllerblueprints/application/load/model_type/node_type/dg-resource-assign-activate.json
new file mode 100644 (file)
index 0000000..e98fa5a
--- /dev/null
@@ -0,0 +1,70 @@
+{\r
+       "description": "This is Resource Assign and Activate Netconf Directed Graph",\r
+       "version": "1.0.0",\r
+       "properties": {\r
+               "mode": {\r
+                       "required": false,\r
+                       "type": "string",\r
+                       "default": "sync"\r
+               },\r
+               "version": {\r
+                       "required": false,\r
+                       "type": "string",\r
+                       "default": "LATEST"\r
+               },\r
+               "is-start-flow": {\r
+                       "required": false,\r
+                       "type": "boolean",\r
+                       "default": "false"\r
+               }\r
+       },\r
+       "capabilities": {\r
+               "dg-node": {\r
+                       "type": "tosca.capabilities.Node"\r
+               },\r
+               "content": {\r
+                       "type": "tosca.capability.Content",\r
+                       "properties": {\r
+                               "type": {\r
+                                       "required": false,\r
+                                       "type": "string",\r
+                                       "default": "json"\r
+                               },\r
+                               "content": {\r
+                                       "required": false,\r
+                                       "type": "string"\r
+                               }\r
+                       }\r
+               }\r
+       },\r
+       "requirements": {\r
+               "ra-component": {\r
+                       "capability": "component-node",\r
+                       "node": "component-resource-assignment",\r
+                       "relationship": "tosca.relationships.DependsOn"\r
+               },\r
+               "netconf-component": {\r
+                       "capability": "component-node",\r
+                       "node": "component-netconf-executor",\r
+                       "relationship": "tosca.relationships.DependsOn"\r
+               }\r
+       },\r
+       "interfaces": {\r
+               "CONFIG": {\r
+                       "operations": {\r
+                               "ResourceAssignAndActivate": {\r
+                                       "inputs": {\r
+                                               "params": {\r
+                                                       "required": false,\r
+                                                       "type": "list",\r
+                                                       "entry_schema": {\r
+                                                               "type": "datatype-property"\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       },\r
+       "derived_from": "tosca.nodes.DG"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/load/model_type/node_type/dg-resource-assignment.json b/ms/controllerblueprints/application/load/model_type/node_type/dg-resource-assignment.json
new file mode 100644 (file)
index 0000000..36fbb68
--- /dev/null
@@ -0,0 +1,65 @@
+{\r
+       "description": "This is Resource Assignment Directed Graph",\r
+       "version": "1.0.0",\r
+       "properties": {\r
+               "mode": {\r
+                       "required": false,\r
+                       "type": "string",\r
+                       "default": "sync"\r
+               },\r
+               "version": {\r
+                       "required": false,\r
+                       "type": "string",\r
+                       "default": "LATEST"\r
+               },\r
+               "is-start-flow": {\r
+                       "required": false,\r
+                       "type": "boolean",\r
+                       "default": "false"\r
+               }\r
+       },\r
+       "capabilities": {\r
+               "dg-node": {\r
+                       "type": "tosca.capabilities.Node"\r
+               },\r
+               "content": {\r
+                       "type": "tosca.capability.Content",\r
+                       "properties": {\r
+                               "type": {\r
+                                       "required": false,\r
+                                       "type": "string",\r
+                                       "default": "json"\r
+                               },\r
+                               "content": {\r
+                                       "required": false,\r
+                                       "type": "string"\r
+                               }\r
+                       }\r
+               }\r
+       },\r
+       "requirements": {\r
+               "component-dependency": {\r
+                       "capability": "component-node",\r
+                       "node": "component-resource-assignment",\r
+                       "relationship": "tosca.relationships.DependsOn"\r
+               }\r
+       },\r
+       "interfaces": {\r
+               "CONFIG": {\r
+                       "operations": {\r
+                               "ResourceAssignment": {\r
+                                       "inputs": {\r
+                                               "params": {\r
+                                                       "required": false,\r
+                                                       "type": "list",\r
+                                                       "entry_schema": {\r
+                                                               "type": "datatype-property"\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       },\r
+       "derived_from": "tosca.nodes.DG"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/load/model_type/node_type/vnf-netconf-device.json b/ms/controllerblueprints/application/load/model_type/node_type/vnf-netconf-device.json
new file mode 100644 (file)
index 0000000..54573ba
--- /dev/null
@@ -0,0 +1,42 @@
+{\r
+       "description": "This is VNF Device with Netconf  Capability",\r
+       "version": "1.0.0",\r
+       "capabilities": {\r
+               "netconf": {\r
+                       "type": "tosca.capability.Netconf",\r
+                       "properties": {\r
+                               "login-key": {\r
+                                       "required": true,\r
+                                       "type": "string",\r
+                                       "default": "sdnc"\r
+                               },\r
+                               "login-account": {\r
+                                       "required": true,\r
+                                       "type": "string",\r
+                                       "default": "sdnc-tacacs"\r
+                               },\r
+                               "source": {\r
+                                       "required": true,\r
+                                       "type": "string",\r
+                                       "default": "npm"\r
+                               },\r
+                               "target-ip-address": {\r
+                                       "required": true,\r
+                                       "type": "string"\r
+                               },\r
+                               "port-number": {\r
+                                       "required": true,\r
+                                       "type": "integer",\r
+                                       "default": 830\r
+                               },\r
+                               "connection-time-out": {\r
+                                       "required": false,\r
+                                       "type": "integer",\r
+                                       "default": 30\r
+                               }\r
+                       }\r
+               }\r
+       },\r
+       "derived_from": "tosca.nodes.Vnf"\r
+       \r
+}\r
diff --git a/ms/controllerblueprints/application/opt/app/onap/config/application.properties b/ms/controllerblueprints/application/opt/app/onap/config/application.properties
new file mode 100644 (file)
index 0000000..202017d
--- /dev/null
@@ -0,0 +1,75 @@
+#
+# Copyright © 2017-2018 AT&T Intellectual Property.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+info.build.artifact=@project.artifactId@
+info.build.name=@project.name@
+info.build.description=@project.description@
+info.build.version=@project.version@
+info.build.groupId=@project.groupId@
+logging.level.root=info
+
+server.contextPath=/
+server.servlet-path=/
+spring.jersey.application-path=/api/controller-blueprints/v1
+server.routingPath=/api
+
+mots.application.acronym=MOTS_ID
+platform.identifier=AJSC7_JERSEY
+#spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
+
+#logging.pattern.console=%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr($ threadId: {PID:- }){magenta} %clr(---){faint} %clr([ hostname: %X{hostname} serviceName: %X{serviceName} version: %X{version} transactionId: %X{transactionId} requestTimeStamp: %X{requestTimestamp}  responseTimeStamp: %X{responseTimestamp} duration: %X{duration}]){yellow} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wex
+
+#The max number of active threads in this pool
+server.tomcat.max-threads=200
+#The minimum number of threads always kept alive
+server.tomcat.min-Spare-Threads=25
+#The number of milliseconds before an idle thread shutsdown, unless the number of active threads are less or equal to minSpareThreads
+server.tomcat.max-idle-time=60000
+
+#for changing the tomcat port...
+#server.port=8081
+
+#Servlet context parameters
+server.context_parameters.p-name=value #context parameter with p-name as key and value as value.
+
+# make this true for AAF authentication and place cadi.properties into etc folder
+aaf.enabled=false
+
+# set to true to enable version proxy
+#ivp.enabled=false
+
+logging.level.org.springframework.web=INFO
+logging.level.org.hibernate.SQL=warn
+logging.level.org.hibernate.type.descriptor.sql=debug
+
+spring.jpa.properties.hibernate.show_sql=true
+spring.jpa.properties.hibernate.use_sql_comments=true
+spring.jpa.properties.hibernate.format_sql=true
+
+# spring.datasource.url, spring.datasource.username,spring.datasource.password  may be overridden by ENV variables
+spring.datasource.url=jdbc:mysql://localhost:3306/sdnctl
+spring.datasource.username=sdnctl
+spring.datasource.password=sdnctl
+spring.datasource.driver-class-name=com.mysql.jdbc.Driver
+spring.jpa.show-sql = true
+spring.jpa.hibernate.ddl-auto = none
+spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
+spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
+
+#Load Blueprints
+# blueprints.load.initial-data may be overridden by ENV variables
+blueprints.load.initial-data=true
+blueprints.load.path=load
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/opt/app/onap/config/logback.xml b/ms/controllerblueprints/application/opt/app/onap/config/logback.xml
new file mode 100644 (file)
index 0000000..cdd20c8
--- /dev/null
@@ -0,0 +1,36 @@
+<!--\r
+  ~ Copyright © 2017-2018 AT&T Intellectual Property.\r
+  ~\r
+  ~ Licensed under the Apache License, Version 2.0 (the "License");\r
+  ~ you may not use this file except in compliance with the License.\r
+  ~ You may obtain a copy of the License at\r
+  ~\r
+  ~     http://www.apache.org/licenses/LICENSE-2.0\r
+  ~\r
+  ~ Unless required by applicable law or agreed to in writing, software\r
+  ~ distributed under the License is distributed on an "AS IS" BASIS,\r
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+  ~ See the License for the specific language governing permissions and\r
+  ~ limitations under the License.\r
+  -->\r
+\r
+<configuration>\r
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">\r
+        <!-- encoders are assigned the type\r
+             ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->\r
+        <encoder>\r
+            <pattern>%d{HH:mm:ss.SSS} %-5level %logger{100} - %msg%n</pattern>\r
+        </encoder>\r
+    </appender>\r
+\r
+\r
+    <logger name="org.springframework" level="info"/>\r
+    <logger name="org.springframework.web" level="debug"/>\r
+    <logger name="org.hibernate" level="error"/>\r
+    <logger name="org.onap.ccsdk.apps.controllerblueprints" level="info"/>\r
+\r
+    <root level="warn">\r
+        <appender-ref ref="STDOUT"/>\r
+    </root>\r
+\r
+</configuration>\r
diff --git a/ms/controllerblueprints/application/pom.xml b/ms/controllerblueprints/application/pom.xml
new file mode 100644 (file)
index 0000000..cab45e2
--- /dev/null
@@ -0,0 +1,242 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+  ~ Copyright © 2017-2018 AT&T Intellectual Property.\r
+  ~\r
+  ~ Licensed under the Apache License, Version 2.0 (the "License");\r
+  ~ you may not use this file except in compliance with the License.\r
+  ~ You may obtain a copy of the License at\r
+  ~\r
+  ~     http://www.apache.org/licenses/LICENSE-2.0\r
+  ~\r
+  ~ Unless required by applicable law or agreed to in writing, software\r
+  ~ distributed under the License is distributed on an "AS IS" BASIS,\r
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+  ~ See the License for the specific language governing permissions and\r
+  ~ limitations under the License.\r
+  -->\r
+\r
+<project\r
+        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"\r
+        xmlns="http://maven.apache.org/POM/4.0.0"\r
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
+    <modelVersion>4.0.0</modelVersion>\r
+    <parent>\r
+        <groupId>org.onap.ccsdk.apps</groupId>\r
+        <artifactId>controllerblueprints-parent</artifactId>\r
+        <version>0.3.0-SNAPSHOT</version>\r
+        <relativePath>../parent</relativePath>\r
+    </parent>\r
+    <artifactId>controllerblueprints-application</artifactId>\r
+    <name>Controller Blueprints Application</name>\r
+    <properties>\r
+        <swagger.directory>${basedir}/src/main/resources/swagger-ui/dist</swagger.directory>\r
+        <java.version>1.8</java.version>\r
+        <docker.registry>xxxxxxxxx:5100</docker.registry>\r
+        <assembly.id>distribution</assembly.id>\r
+        <build.number>local</build.number>\r
+        <name.space>org.onap.ccsdk.apps</name.space>     <!-- <name.space>${namespace}</name.space> -->\r
+        <grm.namespace>org.onap.ccsdk.apps</grm.namespace>\r
+        <archetypeVersion>200.0.49</archetypeVersion>\r
+        <serviceArtifactName>controllerblueprints</serviceArtifactName>\r
+\r
+        <!-- Sonar -->\r
+        <sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>\r
+        <sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>\r
+        <sonar.surefire.reportsPath>${basedir}/target/surefire-reports</sonar.surefire.reportsPath>\r
+        <sonar.failsafe.reportsPath>${basedir}/target/failsafe-reports</sonar.failsafe.reportsPath>\r
+        <jacoco.path>${basedir}/target/jacoco_report</jacoco.path>\r
+        <jacoco.itPath>${basedir}/target/jacoco_itReport</jacoco.itPath>\r
+        <sonar.jacoco.reportPath>${basedir}/target/jacoco-ut.exec</sonar.jacoco.reportPath>\r
+        <sonar.jacoco.itReportPath>${basedir}/target/jacoco-it.exec</sonar.jacoco.itReportPath>\r
+        <sonar.language>java</sonar.language>\r
+        <ilib.version>2.0.7</ilib.version>\r
+        <!--<skip.assembly>false</skip.assembly>-->\r
+        <!--<skip.swagger.generation>false</skip.swagger.generation>-->\r
+    </properties>\r
+\r
+    <dependencies>\r
+\r
+        <dependency>\r
+            <groupId>org.onap.ccsdk.apps</groupId>\r
+            <artifactId>controllerblueprints-service</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.springframework.boot</groupId>\r
+            <artifactId>spring-boot-starter-actuator</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.springframework.boot</groupId>\r
+            <artifactId>spring-boot-devtools</artifactId>\r
+            <optional>true</optional>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>com.h2database</groupId>\r
+            <artifactId>h2</artifactId>\r
+            <scope>runtime</scope>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.springframework.boot</groupId>\r
+            <artifactId>spring-boot-starter-test</artifactId>\r
+            <scope>test</scope>\r
+        </dependency>\r
+    </dependencies>\r
+    <build>\r
+        <resources>\r
+            <resource>\r
+                <!--config and resource files -->\r
+                <directory>${basedir}/etc</directory>\r
+                <targetPath>${basedir}/target/etc</targetPath>\r
+                <filtering>true</filtering>\r
+                <includes>\r
+                    <include>**/*</include>\r
+                </includes>\r
+            </resource>\r
+            <resource>\r
+                <!--config and resource files -->\r
+                <directory>${basedir}/src/main/resources</directory>\r
+                <targetPath>${basedir}/target/src/main/resources</targetPath>\r
+                <filtering>true</filtering>\r
+                <includes>\r
+                    <include>**/*</include>\r
+                </includes>\r
+            </resource>\r
+            <resource>\r
+                <directory>src/main/resources</directory>\r
+                <includes>\r
+                    <include>**/*</include>\r
+                </includes>\r
+                <filtering>true</filtering>\r
+            </resource>\r
+            <resource>\r
+                <directory>src/main/docker</directory>\r
+                <targetPath>${basedir}/target</targetPath>\r
+                <includes>\r
+                    <include>**/*</include>\r
+                </includes>\r
+                <filtering>true</filtering>\r
+            </resource>\r
+        </resources>\r
+        <plugins>\r
+            <plugin>\r
+                <groupId>org.jacoco</groupId>\r
+                <artifactId>jacoco-maven-plugin</artifactId>\r
+                <version>0.7.5.201505241946</version>\r
+                <executions>\r
+                    <!-- Prepares the property pointing to the JaCoCo runtime agent which\r
+                        is passed as VM argument when Maven the Surefire plugin is executed. -->\r
+                    <execution>\r
+                        <id>pre-unit-test</id>\r
+                        <goals>\r
+                            <goal>prepare-agent</goal>\r
+                        </goals>\r
+                        <configuration>\r
+                            <!-- Sets the path to the file which contains the execution data. -->\r
+                            <destFile>${sonar.jacoco.reportPath}</destFile>\r
+                            <propertyName>surefireArgLine</propertyName>\r
+                        </configuration>\r
+                    </execution>\r
+                    <!-- Ensures that the code coverage report for unit tests is created\r
+                        after unit tests have been run. -->\r
+                    <execution>\r
+                        <id>post-unit-test</id>\r
+                        <phase>test</phase>\r
+                        <goals>\r
+                            <goal>report</goal>\r
+                        </goals>\r
+                        <configuration>\r
+                            <!-- Sets the path to the file which contains the execution data. -->\r
+                            <dataFile>${sonar.jacoco.reportPath}</dataFile>\r
+                            <!-- Sets the output directory for the code coverage report. -->\r
+                            <outputDirectory>${jacoco.path}</outputDirectory>\r
+                        </configuration>\r
+                    </execution>\r
+                </executions>\r
+            </plugin>\r
+            <plugin>\r
+                <groupId>com.github.kongchen</groupId>\r
+                <artifactId>swagger-maven-plugin</artifactId>\r
+                <version>3.1.7</version>\r
+                <configuration>\r
+                    <!-- <skipSwaggerGeneration>${skip.swagger.generation}</skipSwaggerGeneration>-->\r
+                    <apiSources>\r
+                        <apiSource>\r
+                            <schemes>\r
+                                <scheme>http</scheme>\r
+                                <scheme>https</scheme>\r
+                            </schemes>\r
+                            <locations>\r
+                                <location>org.onap.ccsdk.apps.controllerblueprints</location>\r
+                            </locations>\r
+                            <basePath>/api/controller-blueprints/v1</basePath>\r
+                            <info>\r
+                                <title>Controller Blueprint Service</title>\r
+                                <version>${project.version}</version>\r
+                            </info>\r
+                            <swaggerDirectory>${swagger.directory}</swaggerDirectory>\r
+                        </apiSource>\r
+                    </apiSources>\r
+                </configuration>\r
+                <executions>\r
+                    <execution>\r
+                        <!-- <phase>compile</phase> -->\r
+                        <phase>package</phase>\r
+                        <goals>\r
+                            <goal>generate</goal>\r
+                        </goals>\r
+                    </execution>\r
+                </executions>\r
+            </plugin>\r
+            <plugin>\r
+                <groupId>org.apache.maven.plugins</groupId>\r
+                <artifactId>maven-antrun-plugin</artifactId>\r
+                <executions>\r
+                    <execution>\r
+                        <id>ant-test</id>\r
+                        <phase>package</phase>\r
+                        <configuration>\r
+                            <tasks>\r
+                                <fixcrlf srcdir="${basedir}" eol="unix"\r
+                                         includes="**/*.sh, **/*.source"/>\r
+                            </tasks>\r
+                        </configuration>\r
+                        <goals>\r
+                            <goal>run</goal>\r
+                        </goals>\r
+                    </execution>\r
+                </executions>\r
+            </plugin>\r
+            <plugin>\r
+                <!--build the final artifact for docker deployment -->\r
+                <artifactId>maven-assembly-plugin</artifactId>\r
+                <version>3.0.0</version>\r
+                <configuration>\r
+                    <!-- <skipAssembly>${skip.assembly}</skipAssembly>-->\r
+                    <outputDirectory>target</outputDirectory>\r
+                    <descriptors>\r
+                        <descriptor>src/assembly/distribution.xml</descriptor>\r
+                    </descriptors>\r
+                    <tarLongFileMode>posix</tarLongFileMode>\r
+                </configuration>\r
+                <executions>\r
+                    <execution>\r
+                        <id>${assembly.id}</id>\r
+                        <phase>package</phase>\r
+                        <goals>\r
+                            <goal>single</goal>\r
+                        </goals>\r
+                    </execution>\r
+                </executions>\r
+            </plugin>\r
+            <plugin>\r
+                <artifactId>maven-compiler-plugin</artifactId>\r
+                <version>3.1</version>\r
+                <configuration>\r
+                    <!-- <skip>${skip.compile}</skip>-->\r
+                    <source>1.8</source>\r
+                    <target>1.8</target>\r
+                </configuration>\r
+            </plugin>\r
+        </plugins>\r
+    </build>\r
+</project>\r
+\r
diff --git a/ms/controllerblueprints/application/src/assembly/distribution.xml b/ms/controllerblueprints/application/src/assembly/distribution.xml
new file mode 100644 (file)
index 0000000..adfb52d
--- /dev/null
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright © 2017-2018 AT&T Intellectual Property.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+          xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
+    <!-- create a tar.gz file containing the projects dependencies -->
+    <id>${assembly.id}</id>
+    <formats>
+        <format>tar.gz</format>
+    </formats>
+    <dependencySets>
+        <dependencySet>
+            <outputDirectory>/opt/app/onap/lib</outputDirectory>
+            <excludes>
+                <exclude>org.slf4j:slf4j-log4j12</exclude>
+                <exclude>javax.servlet:servlet-api</exclude>
+                <exclude>javax.servlet:javax.servlet-api</exclude>
+                <exclude>j2ee:j2ee</exclude>
+                <exclude>log4j:log4j</exclude>
+                <exclude>com.sun:j2ee</exclude>
+                <exclude>log4j:apache-log4j-extras</exclude>
+                <exclude>org.slf4j:slf4j-simple</exclude>
+            </excludes>
+        </dependencySet>
+    </dependencySets>
+    <fileSets>
+        <fileSet>
+            <directory>${project.basedir}/src/main/resources</directory>
+            <includes>
+                <include>application.properties</include>
+            </includes>
+            <outputDirectory>/</outputDirectory>
+            <useDefaultExcludes>true</useDefaultExcludes>
+        </fileSet>
+        <fileSet>
+            <directory>${project.basedir}/src/main/docker</directory>
+            <includes>
+                <include>Dockerfile</include>
+                <include>startService.sh</include>
+            </includes>
+            <outputDirectory>/</outputDirectory>
+            <useDefaultExcludes>true</useDefaultExcludes>
+        </fileSet>
+        <fileSet>
+            <directory>${project.basedir}/src/main/groovy</directory>
+            <outputDirectory>src/main/groovy</outputDirectory>
+            <useDefaultExcludes>true</useDefaultExcludes>
+        </fileSet>
+        <fileSet>
+            <directory>${project.basedir}/src/main/resources</directory>
+            <outputDirectory>src/main/resources</outputDirectory>
+            <useDefaultExcludes>true</useDefaultExcludes>
+        </fileSet>
+        <fileSet>
+            <directory>${project.basedir}/etc</directory>
+            <outputDirectory>/etc</outputDirectory>
+            <useDefaultExcludes>true</useDefaultExcludes>
+        </fileSet>
+        <fileSet>
+            <directory>${project.basedir}/load</directory>
+            <outputDirectory>load</outputDirectory>
+            <useDefaultExcludes>true</useDefaultExcludes>
+        </fileSet>
+    </fileSets>
+</assembly>
diff --git a/ms/controllerblueprints/application/src/main/dc/docker-compose.yaml b/ms/controllerblueprints/application/src/main/dc/docker-compose.yaml
new file mode 100644 (file)
index 0000000..5696d02
--- /dev/null
@@ -0,0 +1,36 @@
+version: '3.3'\r
+\r
+services:\r
+   db:\r
+     image: mysql:5.7.22\r
+     container_name: cb-mysql\r
+     ports:\r
+       - "3307:3306"\r
+     volumes:\r
+       - ~/vm_mysql:/var/lib/mysql\r
+     restart: always\r
+     environment:\r
+       MYSQL_ROOT_PASSWORD: sdnctl\r
+       MYSQL_DATABASE: sdnctl\r
+       MYSQL_USER: sdnctl\r
+       MYSQL_PASSWORD: sdnctl\r
+   controller-blueprints:\r
+     depends_on:\r
+       - db\r
+     image: onap/controllerblueprints:1.0.0\r
+     container_name: cb-rest\r
+     ports:\r
+       - "8080:8080"\r
+     restart: always\r
+     volumes:\r
+       - ~/share/vm_ms/controllerblueprints/config:/opt/app/onap/config\r
+       - ~/share/vm_ms/controllerblueprints/logs:/logs\r
+     environment:\r
+       DB_URL: jdbc:mysql://db:3306/sdnctl\r
+       DB_USER: sdnctl\r
+       DB_PASSWORD: sdnctl\r
+       INIT_DATA_LOAD: "true"\r
+       APP_CONFIG_HOME: /opt/app/onap/config\r
+       BUNDLEVERSION: 1.0.0\r
+       STICKYSELECTORKEY:\r
+       ENVCONTEXT: DEV
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/src/main/docker/Dockerfile b/ms/controllerblueprints/application/src/main/docker/Dockerfile
new file mode 100644 (file)
index 0000000..06304e1
--- /dev/null
@@ -0,0 +1,17 @@
+FROM anapsix/alpine-java:8_jdk
+
+RUN apk add --no-cache curl
+
+COPY startService.sh /startService.sh
+RUN chmod 777 /startService.sh && dos2unix /startService.sh
+
+COPY @project.build.finalName@-@assembly.id@.tar.gz /source.tar.gz
+
+RUN (mkdir -p /source /opt/app/onap) && (tar -xzf /source.tar.gz -C /source) \
+&& (mv /source/@project.build.finalName@ /source/app) \
+&& (cp -rf /source/app/opt/app/onap/lib /opt/app/onap/) \
+&& (cp -rf /source/app/etc /) \
+&& (cp -rf /source/app/load /) \
+&& (rm -rf /source)
+
+ENTRYPOINT /startService.sh
diff --git a/ms/controllerblueprints/application/src/main/docker/startService.sh b/ms/controllerblueprints/application/src/main/docker/startService.sh
new file mode 100644 (file)
index 0000000..7077c22
--- /dev/null
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+nodeName=ControllerBlueprints_1.0.0_$(cat /proc/self/cgroup | grep docker | sed s/\\//\\n/g | tail -1)
+
+echo "APP Config HOME : ${APP_CONFIG_HOME}"
+export APP_HOME=/opt/app/onap
+
+source /etc/run.source
diff --git a/ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/ApplicationConstants.java b/ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/ApplicationConstants.java
new file mode 100644 (file)
index 0000000..3172ed3
--- /dev/null
@@ -0,0 +1,27 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints;\r
+\r
+/**\r
+ * ApplicationConstants.java Purpose: Provide ControllerBluprintsApplication Constant Information\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+public final class ApplicationConstants {\r
+\r
+}\r
diff --git a/ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/ControllerBluprintsApplication.java b/ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/ControllerBluprintsApplication.java
new file mode 100644 (file)
index 0000000..96d82e7
--- /dev/null
@@ -0,0 +1,38 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints;\r
+\r
+import org.springframework.boot.SpringApplication;\r
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;\r
+import org.springframework.boot.autoconfigure.SpringBootApplication;\r
+import org.springframework.context.annotation.ComponentScan;\r
+\r
+/**\r
+ *\r
+ *\r
+ * @author Brinda Santh\r
+ */\r
+@SpringBootApplication\r
+@ComponentScan(basePackages = {"org.onap.ccsdk.apps.controllerblueprints"})\r
+@EnableAutoConfiguration\r
+public class ControllerBluprintsApplication {\r
+\r
+    public static void main(String[] args) {\r
+        SpringApplication.run(ControllerBluprintsApplication.class, args);\r
+    }\r
+\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/ControllerBluprintsFilterConfiguration.java b/ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/ControllerBluprintsFilterConfiguration.java
new file mode 100644 (file)
index 0000000..6f4bfc9
--- /dev/null
@@ -0,0 +1,37 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints;\r
+\r
+\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+import org.springframework.beans.factory.annotation.Value;\r
+import org.springframework.context.annotation.Configuration;\r
+/**\r
+ *\r
+ *\r
+ * @author Brinda Santh\r
+ */\r
+@Configuration\r
+public class ControllerBluprintsFilterConfiguration {\r
+    private static Logger log = LoggerFactory.getLogger(JerseyConfiguration.class);\r
+\r
+    @Value("${server.routingPath:#{null}}")\r
+    private String routingPath;\r
+\r
+\r
+}\r
diff --git a/ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/CorsConfig.java b/ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/CorsConfig.java
new file mode 100644 (file)
index 0000000..0d9ab16
--- /dev/null
@@ -0,0 +1,52 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints;\r
+\r
+\r
+import org.springframework.context.annotation.Bean;\r
+import org.springframework.context.annotation.Configuration;\r
+import org.springframework.web.cors.CorsConfiguration;\r
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;\r
+import org.springframework.web.filter.CorsFilter;\r
+\r
+/**\r
+ * CorsConfig.java Purpose: Provide Configuration Generator CorsConfig Information\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+@Configuration\r
+public class CorsConfig {\r
+    /**\r
+     * This is a CORS Implementation for different Orgin GUI to access.\r
+     *\r
+     * @return CorsFilter\r
+     */\r
+    @Bean\r
+    public CorsFilter corsFilter() {\r
+        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();\r
+        CorsConfiguration config = new CorsConfiguration();\r
+        config.setAllowCredentials(true);\r
+        config.addAllowedOrigin("*");\r
+        config.addAllowedHeader("*");\r
+        config.addAllowedMethod("*");\r
+        source.registerCorsConfiguration("/**", config);\r
+        return new CorsFilter(source);\r
+    }\r
+\r
+\r
+}\r
diff --git a/ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/DatabaseConfig.java b/ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/DatabaseConfig.java
new file mode 100644 (file)
index 0000000..5b154ff
--- /dev/null
@@ -0,0 +1,61 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints;\r
+\r
+import org.springframework.boot.autoconfigure.domain.EntityScan;\r
+import org.springframework.context.annotation.Bean;\r
+import org.springframework.context.annotation.Configuration;\r
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;\r
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;\r
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;\r
+import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;\r
+import org.springframework.transaction.annotation.EnableTransactionManagement;\r
+\r
+import javax.sql.DataSource;\r
+\r
+/**\r
+ * DatabaseConfig.java Purpose: Provide Configuration Generator DatabaseConfig Information\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+@Configuration\r
+@EntityScan("org.onap.ccsdk.apps.controllerblueprints.service.domain")\r
+@EnableTransactionManagement\r
+@EnableJpaRepositories("org.onap.ccsdk.apps.controllerblueprints.service.repository")\r
+@EnableJpaAuditing\r
+public class DatabaseConfig {\r
+    /**\r
+     * This is a entityManagerFactory method\r
+     *\r
+     * @param dataSource\r
+     * @return LocalContainerEntityManagerFactoryBean\r
+     */\r
+\r
+    @Bean\r
+    public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {\r
+        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();\r
+        vendorAdapter.setGenerateDdl(true);\r
+        vendorAdapter.setShowSql(false);\r
+        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();\r
+        factory.setJpaVendorAdapter(vendorAdapter);\r
+        factory.setPackagesToScan("org.onap.ccsdk.apps.controllerblueprints.service.domain");\r
+        factory.setDataSource(dataSource);\r
+        return factory;\r
+    }\r
+\r
+}\r
diff --git a/ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/JerseyConfiguration.java b/ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/JerseyConfiguration.java
new file mode 100644 (file)
index 0000000..a3b0faf
--- /dev/null
@@ -0,0 +1,102 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints;\r
+\r
+\r
+import com.fasterxml.jackson.annotation.JsonInclude;\r
+import com.fasterxml.jackson.databind.DeserializationFeature;\r
+import com.fasterxml.jackson.databind.MapperFeature;\r
+import com.fasterxml.jackson.databind.ObjectMapper;\r
+import com.fasterxml.jackson.databind.SerializationFeature;\r
+import io.swagger.jaxrs.config.BeanConfig;\r
+import io.swagger.jaxrs.listing.ApiListingResource;\r
+import io.swagger.jaxrs.listing.SwaggerSerializers;\r
+import org.glassfish.jersey.server.ResourceConfig;\r
+import org.glassfish.jersey.servlet.ServletProperties;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.common.ServiceExceptionMapper;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.rs.ConfigModelRestImpl;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.rs.ModelTypeRestImpl;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.rs.ResourceDictionaryRestImpl;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.rs.ServiceTemplateRestImpl;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+import org.springframework.beans.factory.annotation.Autowired;\r
+import org.springframework.context.annotation.Bean;\r
+import org.springframework.context.annotation.Primary;\r
+import org.springframework.stereotype.Component;\r
+\r
+import javax.ws.rs.core.MediaType;\r
+\r
+/**\r
+ *\r
+ *\r
+ * @author Brinda Santh\r
+ */\r
+@Component\r
+public class JerseyConfiguration extends ResourceConfig {\r
+    private static Logger log = LoggerFactory.getLogger(JerseyConfiguration.class);\r
+    /**\r
+     *\r
+     */\r
+    @Autowired\r
+    public JerseyConfiguration() {\r
+        register(ConfigModelRestImpl.class);\r
+        register(ModelTypeRestImpl.class);\r
+        register(ResourceDictionaryRestImpl.class);\r
+        register(ServiceTemplateRestImpl.class);\r
+        register(ServiceExceptionMapper.class);\r
+        property(ServletProperties.FILTER_FORWARD_ON_404, true);\r
+        configureSwagger();\r
+    }\r
+\r
+    /**\r
+     *\r
+     * @return ObjectMapper\r
+     */\r
+    @Bean\r
+    @Primary\r
+    public ObjectMapper objectMapper() {\r
+        ObjectMapper objectMapper = new ObjectMapper();\r
+        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);\r
+        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);\r
+        objectMapper.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES);\r
+        objectMapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);\r
+        objectMapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);\r
+        return objectMapper;\r
+    }\r
+\r
+    /**\r
+     *\r
+     */\r
+    private void configureSwagger() {\r
+        register(ApiListingResource.class);\r
+        register(SwaggerSerializers.class);\r
+        BeanConfig beanConfig = new BeanConfig();\r
+        beanConfig.setVersion("1.0.0");\r
+        beanConfig.setSchemes(new String[]{"http", "https"});\r
+        beanConfig.setBasePath("/api/controller-blueprints/v1");\r
+        beanConfig.setTitle("Controller Blueprints API");\r
+        beanConfig.setDescription("Controller BluePrints API");\r
+        beanConfig.getSwagger().addConsumes(MediaType.APPLICATION_JSON);\r
+        beanConfig.getSwagger().addProduces(MediaType.APPLICATION_JSON);\r
+        beanConfig.setResourcePackage("org.onap.ccsdk.apps.controllerblueprints");\r
+        beanConfig.setPrettyPrint(true);\r
+        beanConfig.setScan(true);\r
+    }\r
+\r
+\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/WebMvcConfiguration.java b/ms/controllerblueprints/application/src/main/java/org/onap/ccsdk/apps/controllerblueprints/WebMvcConfiguration.java
new file mode 100644 (file)
index 0000000..a690c05
--- /dev/null
@@ -0,0 +1,37 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints;\r
+\r
+import org.springframework.context.annotation.Configuration;\r
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;\r
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;\r
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;\r
+\r
+/**\r
+ *\r
+ * WebMvcConfiguration WebMvcConfiguration\r
+ * @author Brinda Santh\r
+ */\r
+@Configuration\r
+@EnableWebMvc\r
+public class WebMvcConfiguration extends WebMvcConfigurerAdapter {\r
+    @Override\r
+    public void addResourceHandlers(ResourceHandlerRegistry registry) {\r
+        registry.addResourceHandler("/swagger-ui/**").addResourceLocations("classpath:/swagger-ui/dist/");\r
+    }\r
+\r
+}\r
diff --git a/ms/controllerblueprints/application/src/main/resources/sql/data.sql b/ms/controllerblueprints/application/src/main/resources/sql/data.sql
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/ms/controllerblueprints/application/src/main/resources/sql/schema-local.sql b/ms/controllerblueprints/application/src/main/resources/sql/schema-local.sql
new file mode 100644 (file)
index 0000000..1ba9c36
--- /dev/null
@@ -0,0 +1,87 @@
+-- drop table sdnctl.MODEL_TYPE;\r
+-- drop table sdnctl.RESOURCE_DICTIONARY;\r
+-- drop table sdnctl.CONFIG_MODEL_CONTENT;\r
+-- drop table sdnctl.CONFIG_MODEL;\r
+\r
+-- -----------------------------------------------------\r
+-- table CONFIG_MODEL\r
+-- -----------------------------------------------------\r
+CREATE TABLE IF NOT EXISTS sdnctl.CONFIG_MODEL (\r
+  config_model_id              INT(11) NOT NULL AUTO_INCREMENT,\r
+  service_uuid                         VARCHAR(50) NULL DEFAULT NULL,\r
+  distribution_id              VARCHAR(50) NULL DEFAULT NULL,\r
+  service_name                         VARCHAR(255) NULL DEFAULT NULL,\r
+  service_description          VARCHAR(255) NULL DEFAULT NULL,\r
+  resource_uuid                VARCHAR(255) NULL DEFAULT NULL,\r
+  resource_instance_name       VARCHAR(255) NULL DEFAULT NULL,\r
+  resource_name                varchar(255) null default null,\r
+  resource_version             varchar(50) null default null,\r
+  resource_type                varchar(50) null default null,\r
+  artifact_uuid                varchar(50) null default null,\r
+  artifact_type                varchar(50) not null,\r
+  artifact_version             varchar(25) not null,\r
+  artifact_description                 longtext null default null,\r
+  internal_version             int(11) null default null,\r
+  creation_date                datetime not null default current_timestamp,\r
+  artifact_name                varchar(100) not null,\r
+  published                    varchar(1) not null,\r
+  updated_by                   varchar(100) not null,\r
+  tags                                 longtext null default null,\r
+  primary key PK_CONFIG_MODEL (config_model_id),\r
+  UNIQUE KEY UK_CONFIG_MODEL (artifact_name , artifact_version)\r
+) ENGINE=InnoDB;\r
+\r
+\r
+-- -----------------------------------------------------\r
+-- table CONFIG_MODEL_CONTENT\r
+-- -----------------------------------------------------\r
+CREATE TABLE IF NOT EXISTS sdnctl.CONFIG_MODEL_CONTENT (\r
+  config_model_content_id      INT(11) NOT NULL AUTO_INCREMENT, \r
+  config_model_id              INT NOT NULL,\r
+  name                                 VARCHAR(100) NOT NULL,\r
+  content_type                         VARCHAR(50) NOT NULL,\r
+  description                  LONGTEXT NULL DEFAULT NULL,\r
+  updated_date                         DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,\r
+  content                      LONGTEXT NULL DEFAULT NULL,\r
+  PRIMARY KEY PK_CONFIG_MODEL_CONTENT (config_model_content_id),\r
+  UNIQUE KEY UK_CONFIG_MODEL_CONTENT (config_model_id, name, content_type),\r
+  FOREIGN KEY FK_CONFIG_MODEL_CONTENT (config_model_id) REFERENCES sdnctl.CONFIG_MODEL(config_model_id) ON DELETE CASCADE\r
+) ENGINE=InnoDB;\r
+\r
+-- -----------------------------------------------------\r
+-- table MODEL_TYPE\r
+-- -----------------------------------------------------\r
+CREATE TABLE IF NOT EXISTS sdnctl.MODEL_TYPE (\r
+  model_name           VARCHAR(100) NOT NULL,\r
+  derived_from                 VARCHAR(100) NOT NULL,\r
+  definition_type      VARCHAR(100) NOT NULL,\r
+  definition           LONGTEXT NOT NULL,\r
+  version              VARCHAR(10) NOT NULL,\r
+  description          LONGTEXT NOT NULL,\r
+  tags                         LONGTEXT NULL DEFAULT NULL,  \r
+  creation_date        DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,\r
+  updated_by           VARCHAR(100) NOT NULL,\r
+  PRIMARY KEY PK_MODEL_TYPE (model_name),\r
+  INDEX IX_MODEL_TYPE (model_name)\r
+) ENGINE=InnoDB;\r
+\r
+\r
+-- -----------------------------------------------------\r
+-- table RESOURCE_DICTIONARY\r
+-- -----------------------------------------------------\r
+CREATE TABLE IF NOT EXISTS sdnctl.RESOURCE_DICTIONARY (\r
+  name                         VARCHAR(100) NOT NULL,\r
+  resource_path        VARCHAR(500) NOT NULL,  \r
+  resource_type        VARCHAR(100) NOT NULL,\r
+  data_type            VARCHAR(100) NOT NULL,\r
+  entry_schema                 VARCHAR(100) NULL DEFAULT NULL,\r
+  valid_values                 LONGTEXT NULL DEFAULT NULL,\r
+  sample_value                 LONGTEXT NULL DEFAULT NULL,\r
+  definition           LONGTEXT NOT NULL,\r
+  description          LONGTEXT NOT NULL,\r
+  tags                         LONGTEXT NOT NULL,  \r
+  creation_date        DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,\r
+  updated_by           VARCHAR(100) NOT NULL,\r
+  primary key PK_RESOURCE_DICTIONARY (name),\r
+  INDEX IX_RESOURCE_DICTIONARY (name)\r
+) ENGINE=InnoDB;
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/src/main/resources/sql/schema.sql b/ms/controllerblueprints/application/src/main/resources/sql/schema.sql
new file mode 100644 (file)
index 0000000..b884cf3
--- /dev/null
@@ -0,0 +1,82 @@
+-- -----------------------------------------------------\r
+-- table CONFIG_MODEL\r
+-- -----------------------------------------------------\r
+CREATE TABLE IF NOT EXISTS configurator.CONFIG_MODEL (\r
+  config_model_id              INT(11) NOT NULL AUTO_INCREMENT,\r
+  service_uuid                         VARCHAR(50) NULL DEFAULT NULL,\r
+  distribution_id              VARCHAR(50) NULL DEFAULT NULL,\r
+  service_name                         VARCHAR(255) NULL DEFAULT NULL,\r
+  service_description          VARCHAR(255) NULL DEFAULT NULL,\r
+  resource_uuid                VARCHAR(255) NULL DEFAULT NULL,\r
+  resource_instance_name       VARCHAR(255) NULL DEFAULT NULL,\r
+  resource_name                varchar(255) null default null,\r
+  resource_version             varchar(50) null default null,\r
+  resource_type                varchar(50) null default null,\r
+  artifact_uuid                varchar(50) null default null,\r
+  artifact_type                varchar(50) not null,\r
+  artifact_version             varchar(25) not null,\r
+  artifact_description                 longtext null default null,\r
+  internal_version             int(11) null default null,\r
+  creation_date                datetime not null default current_timestamp,\r
+  artifact_name                varchar(100) not null,\r
+  published                    varchar(1) not null,\r
+  updated_by                   varchar(100) not null,\r
+  tags                                 longtext null default null,\r
+  primary key PK_CONFIG_MODEL (config_model_id),\r
+  UNIQUE KEY UK_CONFIG_MODEL (artifact_name , artifact_version)\r
+) ENGINE=InnoDB;\r
+\r
+\r
+-- -----------------------------------------------------\r
+-- table CONFIG_MODEL_CONTENT\r
+-- -----------------------------------------------------\r
+CREATE TABLE IF NOT EXISTS configurator.CONFIG_MODEL_CONTENT (\r
+  config_model_content_id      INT(11) NOT NULL AUTO_INCREMENT, \r
+  config_model_id              INT NOT NULL,\r
+  name                                 VARCHAR(100) NOT NULL,\r
+  content_type                         VARCHAR(50) NOT NULL,\r
+  description                  LONGTEXT NULL DEFAULT NULL,\r
+  updated_date                         DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,\r
+  content                      LONGTEXT NULL DEFAULT NULL,\r
+  PRIMARY KEY PK_CONFIG_MODEL_CONTENT (config_model_content_id),\r
+  UNIQUE KEY UK_CONFIG_MODEL_CONTENT (config_model_id, name, content_type),\r
+  FOREIGN KEY FK_CONFIG_MODEL_CONTENT (config_model_id) REFERENCES configurator.CONFIG_MODEL(config_model_id) ON DELETE CASCADE\r
+) ENGINE=InnoDB;\r
+\r
+-- -----------------------------------------------------\r
+-- table MODEL_TYPE\r
+-- -----------------------------------------------------\r
+CREATE TABLE IF NOT EXISTS configurator.MODEL_TYPE (\r
+  model_name           VARCHAR(100) NOT NULL,\r
+  derived_from                 VARCHAR(100) NOT NULL,\r
+  definition_type      VARCHAR(100) NOT NULL,\r
+  definition           LONGTEXT NOT NULL,\r
+  version              VARCHAR(10) NOT NULL,\r
+  description          LONGTEXT NOT NULL,\r
+  tags                         LONGTEXT NULL DEFAULT NULL,  \r
+  creation_date        DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,\r
+  updated_by           VARCHAR(100) NOT NULL,\r
+  PRIMARY KEY PK_MODEL_TYPE (model_name),\r
+  INDEX IX_MODEL_TYPE (model_name)\r
+) ENGINE=InnoDB;\r
+\r
+\r
+-- -----------------------------------------------------\r
+-- table RESOURCE_DICTIONARY\r
+-- -----------------------------------------------------\r
+CREATE TABLE IF NOT EXISTS configurator.RESOURCE_DICTIONARY (\r
+  name                         VARCHAR(100) NOT NULL,\r
+  resource_path        VARCHAR(500) NOT NULL,  \r
+  resource_type        VARCHAR(100) NOT NULL,\r
+  data_type            VARCHAR(100) NOT NULL,\r
+  entry_schema                 VARCHAR(100) NULL DEFAULT NULL,\r
+  valid_values                 LONGTEXT NULL DEFAULT NULL,\r
+  sample_value                 LONGTEXT NULL DEFAULT NULL,\r
+  definition           LONGTEXT NOT NULL,\r
+  description          LONGTEXT NOT NULL,\r
+  tags                         LONGTEXT NOT NULL,  \r
+  creation_date        DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,\r
+  updated_by           VARCHAR(100) NOT NULL,\r
+  primary key PK_RESOURCE_DICTIONARY (name),\r
+  INDEX IX_RESOURCE_DICTIONARY (name)\r
+) ENGINE=InnoDB;\r
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/css/print.css b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/css/print.css
new file mode 100644 (file)
index 0000000..f341f43
--- /dev/null
@@ -0,0 +1 @@
+.swagger-section pre code{display:block;padding:.5em;background:#f0f0f0}.swagger-section pre .clojure .built_in,.swagger-section pre .lisp .title,.swagger-section pre .nginx .title,.swagger-section pre .subst,.swagger-section pre .tag .title,.swagger-section pre code{color:#000}.swagger-section pre .addition,.swagger-section pre .aggregate,.swagger-section pre .apache .cbracket,.swagger-section pre .apache .tag,.swagger-section pre .bash .variable,.swagger-section pre .constant,.swagger-section pre .django .variable,.swagger-section pre .erlang_repl .function_or_atom,.swagger-section pre .flow,.swagger-section pre .markdown .header,.swagger-section pre .parent,.swagger-section pre .preprocessor,.swagger-section pre .ruby .symbol,.swagger-section pre .ruby .symbol .string,.swagger-section pre .rules .value,.swagger-section pre .rules .value .number,.swagger-section pre .smalltalk .class,.swagger-section pre .stream,.swagger-section pre .string,.swagger-section pre .tag .value,.swagger-section pre .template_tag,.swagger-section pre .tex .command,.swagger-section pre .tex .special,.swagger-section pre .title{color:#800}.swagger-section pre .annotation,.swagger-section pre .chunk,.swagger-section pre .comment,.swagger-section pre .diff .header,.swagger-section pre .markdown .blockquote,.swagger-section pre .template_comment{color:#888}.swagger-section pre .change,.swagger-section pre .date,.swagger-section pre .go .constant,.swagger-section pre .literal,.swagger-section pre .markdown .bullet,.swagger-section pre .markdown .link_url,.swagger-section pre .number,.swagger-section pre .regexp,.swagger-section pre .smalltalk .char,.swagger-section pre .smalltalk .symbol{color:#080}.swagger-section pre .apache .sqbracket,.swagger-section pre .array,.swagger-section pre .attr_selector,.swagger-section pre .clojure .attribute,.swagger-section pre .coffeescript .property,.swagger-section pre .decorator,.swagger-section pre .deletion,.swagger-section pre .doctype,.swagger-section pre .envvar,.swagger-section pre .erlang_repl .reserved,.swagger-section pre .filter .argument,.swagger-section pre .important,.swagger-section pre .javadoc,.swagger-section pre .label,.swagger-section pre .localvars,.swagger-section pre .markdown .link_label,.swagger-section pre .nginx .built_in,.swagger-section pre .pi,.swagger-section pre .prompt,.swagger-section pre .pseudo,.swagger-section pre .ruby .string,.swagger-section pre .shebang,.swagger-section pre .tex .formula,.swagger-section pre .vhdl .attribute{color:#88f}.swagger-section pre .aggregate,.swagger-section pre .apache .tag,.swagger-section pre .bash .variable,.swagger-section pre .built_in,.swagger-section pre .css .tag,.swagger-section pre .go .typename,.swagger-section pre .id,.swagger-section pre .javadoctag,.swagger-section pre .keyword,.swagger-section pre .markdown .strong,.swagger-section pre .phpdoc,.swagger-section pre .request,.swagger-section pre .smalltalk .class,.swagger-section pre .status,.swagger-section pre .tex .command,.swagger-section pre .title,.swagger-section pre .winutils,.swagger-section pre .yardoctag{font-weight:700}.swagger-section pre .markdown .emphasis{font-style:italic}.swagger-section pre .nginx .built_in{font-weight:400}.swagger-section pre .coffeescript .javascript,.swagger-section pre .javascript .xml,.swagger-section pre .tex .formula,.swagger-section pre .xml .cdata,.swagger-section pre .xml .css,.swagger-section pre .xml .javascript,.swagger-section pre .xml .vbscript{opacity:.5}.swagger-section .hljs{display:block;overflow-x:auto;padding:.5em;background:#f0f0f0}.swagger-section .hljs,.swagger-section .hljs-subst{color:#444}.swagger-section .hljs-attribute,.swagger-section .hljs-doctag,.swagger-section .hljs-keyword,.swagger-section .hljs-meta-keyword,.swagger-section .hljs-name,.swagger-section .hljs-selector-tag{font-weight:700}.swagger-section .hljs-addition,.swagger-section .hljs-built_in,.swagger-section .hljs-bullet,.swagger-section .hljs-code,.swagger-section .hljs-literal{color:#1f811f}.swagger-section .hljs-link,.swagger-section .hljs-regexp,.swagger-section .hljs-selector-attr,.swagger-section .hljs-selector-pseudo,.swagger-section .hljs-symbol,.swagger-section .hljs-template-variable,.swagger-section .hljs-variable{color:#bc6060}.swagger-section .hljs-deletion,.swagger-section .hljs-number,.swagger-section .hljs-quote,.swagger-section .hljs-selector-class,.swagger-section .hljs-selector-id,.swagger-section .hljs-string,.swagger-section .hljs-template-tag,.swagger-section .hljs-type{color:#800}.swagger-section .hljs-section,.swagger-section .hljs-title{color:#800;font-weight:700}.swagger-section .hljs-comment{color:#888}.swagger-section .hljs-meta{color:#2b6ea1}.swagger-section .hljs-emphasis{font-style:italic}.swagger-section .hljs-strong{font-weight:700}.swagger-section .swagger-ui-wrap{line-height:1;font-family:Droid Sans,sans-serif;min-width:760px;max-width:960px;margin-left:auto;margin-right:auto}.swagger-section .swagger-ui-wrap b,.swagger-section .swagger-ui-wrap strong{font-family:Droid Sans,sans-serif;font-weight:700}.swagger-section .swagger-ui-wrap blockquote,.swagger-section .swagger-ui-wrap q{quotes:none}.swagger-section .swagger-ui-wrap p{line-height:1.4em;padding:0 0 10px;color:#333}.swagger-section .swagger-ui-wrap blockquote:after,.swagger-section .swagger-ui-wrap blockquote:before,.swagger-section .swagger-ui-wrap q:after,.swagger-section .swagger-ui-wrap q:before{content:none}.swagger-section .swagger-ui-wrap .heading_with_menu h1,.swagger-section .swagger-ui-wrap .heading_with_menu h2,.swagger-section .swagger-ui-wrap .heading_with_menu h3,.swagger-section .swagger-ui-wrap .heading_with_menu h4,.swagger-section .swagger-ui-wrap .heading_with_menu h5,.swagger-section .swagger-ui-wrap .heading_with_menu h6{display:block;clear:none;float:left;-ms-box-sizing:border-box;box-sizing:border-box;width:60%}.swagger-section .swagger-ui-wrap table{border-collapse:collapse;border-spacing:0}.swagger-section .swagger-ui-wrap table thead tr th{padding:5px;font-size:.9em;color:#666;border-bottom:1px solid #999}.swagger-section .swagger-ui-wrap table tbody tr:last-child td{border-bottom:none}.swagger-section .swagger-ui-wrap table tbody tr.offset{background-color:#f0f0f0}.swagger-section .swagger-ui-wrap table tbody tr td{padding:6px;font-size:.9em;border-bottom:1px solid #ccc;vertical-align:top;line-height:1.3em}.swagger-section .swagger-ui-wrap ol{margin:0 0 10px;padding:0 0 0 18px;list-style-type:decimal}.swagger-section .swagger-ui-wrap ol li{padding:5px 0;font-size:.9em;color:#333}.swagger-section .swagger-ui-wrap ol,.swagger-section .swagger-ui-wrap ul{list-style:none}.swagger-section .swagger-ui-wrap h1 a,.swagger-section .swagger-ui-wrap h2 a,.swagger-section .swagger-ui-wrap h3 a,.swagger-section .swagger-ui-wrap h4 a,.swagger-section .swagger-ui-wrap h5 a,.swagger-section .swagger-ui-wrap h6 a{text-decoration:none}.swagger-section .swagger-ui-wrap h1 a:hover,.swagger-section .swagger-ui-wrap h2 a:hover,.swagger-section .swagger-ui-wrap h3 a:hover,.swagger-section .swagger-ui-wrap h4 a:hover,.swagger-section .swagger-ui-wrap h5 a:hover,.swagger-section .swagger-ui-wrap h6 a:hover{text-decoration:underline}.swagger-section .swagger-ui-wrap h1 span.divider,.swagger-section .swagger-ui-wrap h2 span.divider,.swagger-section .swagger-ui-wrap h3 span.divider,.swagger-section .swagger-ui-wrap h4 span.divider,.swagger-section .swagger-ui-wrap h5 span.divider,.swagger-section .swagger-ui-wrap h6 span.divider{color:#aaa}.swagger-section .swagger-ui-wrap a{color:#547f00}.swagger-section .swagger-ui-wrap a img{border:none}.swagger-section .swagger-ui-wrap article,.swagger-section .swagger-ui-wrap aside,.swagger-section .swagger-ui-wrap details,.swagger-section .swagger-ui-wrap figcaption,.swagger-section .swagger-ui-wrap figure,.swagger-section .swagger-ui-wrap footer,.swagger-section .swagger-ui-wrap header,.swagger-section .swagger-ui-wrap hgroup,.swagger-section .swagger-ui-wrap menu,.swagger-section .swagger-ui-wrap nav,.swagger-section .swagger-ui-wrap section,.swagger-section .swagger-ui-wrap summary{display:block}.swagger-section .swagger-ui-wrap pre{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;background-color:#fcf6db;border:1px solid #e5e0c6;padding:10px}.swagger-section .swagger-ui-wrap pre code{line-height:1.6em;background:none}.swagger-section .swagger-ui-wrap .content>.content-type>div>label{clear:both;display:block;color:#0f6ab4;font-size:1.1em;margin:0;padding:15px 0 5px}.swagger-section .swagger-ui-wrap .content pre{font-size:12px;margin-top:5px;padding:5px}.swagger-section .swagger-ui-wrap .icon-btn{cursor:pointer}.swagger-section .swagger-ui-wrap .info_title{padding-bottom:10px;font-weight:700;font-size:25px}.swagger-section .swagger-ui-wrap .footer{margin-top:20px}.swagger-section .swagger-ui-wrap div.big p,.swagger-section .swagger-ui-wrap p.big{font-size:1em;margin-bottom:10px}.swagger-section .swagger-ui-wrap form.fullwidth ol li.numeric input,.swagger-section .swagger-ui-wrap form.fullwidth ol li.string input,.swagger-section .swagger-ui-wrap form.fullwidth ol li.text textarea,.swagger-section .swagger-ui-wrap form.fullwidth ol li.url input{width:500px!important}.swagger-section .swagger-ui-wrap .info_license,.swagger-section .swagger-ui-wrap .info_tos{padding-bottom:5px}.swagger-section .swagger-ui-wrap .message-fail{color:#c00}.swagger-section .swagger-ui-wrap .info_email,.swagger-section .swagger-ui-wrap .info_name,.swagger-section .swagger-ui-wrap .info_url{padding-bottom:5px}.swagger-section .swagger-ui-wrap .info_description{padding-bottom:10px;font-size:15px}.swagger-section .swagger-ui-wrap .markdown ol li,.swagger-section .swagger-ui-wrap .markdown ul li{padding:3px 0;line-height:1.4em;color:#333}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input,.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input,.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input{display:block;padding:4px;width:auto;clear:both}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input.title,.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input.title,.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input.title{font-size:1.3em}.swagger-section .swagger-ui-wrap table.fullwidth{width:100%}.swagger-section .swagger-ui-wrap .model-signature{font-family:Droid Sans,sans-serif;font-size:1em;line-height:1.5em}.swagger-section .swagger-ui-wrap .model-signature .signature-nav a{text-decoration:none;color:#aaa}.swagger-section .swagger-ui-wrap .model-signature .signature-nav a:hover{text-decoration:underline;color:#000}.swagger-section .swagger-ui-wrap .model-signature .signature-nav .selected{color:#000;text-decoration:none}.swagger-section .swagger-ui-wrap .model-signature .propType{color:#55a}.swagger-section .swagger-ui-wrap .model-signature pre:hover{background-color:#ffd}.swagger-section .swagger-ui-wrap .model-signature pre{font-size:.85em;line-height:1.2em;overflow:auto;height:200px;resize:vertical;cursor:pointer}.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav{display:block;min-width:230px;margin:0;padding:0}.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li:last-child{padding-right:0;border-right:none}.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li{float:left;margin:0 5px 5px 0;padding:2px 5px 2px 0;border-right:1px solid #ddd}.swagger-section .swagger-ui-wrap .model-signature .propOpt{color:#555}.swagger-section .swagger-ui-wrap .model-signature .snippet small{font-size:.75em}.swagger-section .swagger-ui-wrap .model-signature .propOptKey{font-style:italic}.swagger-section .swagger-ui-wrap .model-signature .description .strong{font-weight:700;color:#000;font-size:.9em}.swagger-section .swagger-ui-wrap .model-signature .description div{font-size:.9em;line-height:1.5em;margin-left:1em}.swagger-section .swagger-ui-wrap .model-signature .description .stronger{font-weight:700;color:#000}.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper{border-spacing:0;position:absolute;background-color:#fff;border:1px solid #bbb;display:none;font-size:11px;max-width:400px;line-height:30px;color:#000;padding:5px;margin-left:10px}.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper th{text-align:center;background-color:#eee;border:1px solid #bbb;font-size:11px;color:#666;font-weight:700;padding:5px;line-height:15px}.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper .optionName{font-weight:700}.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown>p:first-child,.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown>p:last-child{display:inline}.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown>p:not(:first-child):before{display:block;content:""}.swagger-section .swagger-ui-wrap .model-signature .description span:last-of-type.propDesc.markdown>p:only-child{margin-right:-3px}.swagger-section .swagger-ui-wrap .model-signature .propName{font-weight:700}.swagger-section .swagger-ui-wrap .model-signature .signature-container{clear:both}.swagger-section .swagger-ui-wrap .body-textarea{width:300px;height:100px;border:1px solid #aaa}.swagger-section .swagger-ui-wrap .markdown li code,.swagger-section .swagger-ui-wrap .markdown p code{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;background-color:#f0f0f0;color:#000;padding:1px 3px}.swagger-section .swagger-ui-wrap .required{font-weight:700}.swagger-section .swagger-ui-wrap .editor_holder{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;font-size:.9em}.swagger-section .swagger-ui-wrap .editor_holder label{font-weight:400!important}.swagger-section .swagger-ui-wrap .editor_holder label.required{font-weight:700!important}.swagger-section .swagger-ui-wrap input.parameter{width:300px;border:1px solid #aaa}.swagger-section .swagger-ui-wrap h1{color:#000;font-size:1.5em;line-height:1.3em;padding:10px 0;font-family:Droid Sans,sans-serif;font-weight:700}.swagger-section .swagger-ui-wrap .heading_with_menu{float:none;clear:both;overflow:hidden;display:block}.swagger-section .swagger-ui-wrap .heading_with_menu ul{display:block;clear:none;float:right;-ms-box-sizing:border-box;box-sizing:border-box;margin-top:10px}.swagger-section .swagger-ui-wrap h2{color:#000;font-size:1.3em;padding:10px 0}.swagger-section .swagger-ui-wrap h2 a{color:#000}.swagger-section .swagger-ui-wrap h2 span.sub{font-size:.7em;color:#999;font-style:italic}.swagger-section .swagger-ui-wrap h2 span.sub a{color:#777}.swagger-section .swagger-ui-wrap span.weak{color:#666}.swagger-section .swagger-ui-wrap .message-success{color:#89bf04}.swagger-section .swagger-ui-wrap caption,.swagger-section .swagger-ui-wrap td,.swagger-section .swagger-ui-wrap th{text-align:left;font-weight:400;vertical-align:middle}.swagger-section .swagger-ui-wrap .code{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.text textarea{font-family:Droid Sans,sans-serif;height:250px;padding:4px;display:block;clear:both}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.select select{display:block;clear:both}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean{float:none;clear:both;overflow:hidden;display:block}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean label{display:block;float:left;clear:none;margin:0;padding:0}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean input{display:block;float:left;clear:none;margin:0 5px 0 0}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.required label{color:#000}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label{display:block;clear:both;width:auto;padding:0 0 3px;color:#666}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label abbr{padding-left:3px;color:#888}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li p.inline-hints{margin-left:0;font-style:italic;font-size:.9em;margin:0}.swagger-section .swagger-ui-wrap form.formtastic fieldset.buttons{margin:0;padding:0}.swagger-section .swagger-ui-wrap span.blank,.swagger-section .swagger-ui-wrap span.empty{color:#888;font-style:italic}.swagger-section .swagger-ui-wrap .markdown h3{color:#547f00}.swagger-section .swagger-ui-wrap .markdown h4{color:#666}.swagger-section .swagger-ui-wrap .markdown pre{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;background-color:#fcf6db;border:1px solid #e5e0c6;padding:10px;margin:0 0 10px}.swagger-section .swagger-ui-wrap .markdown pre code{line-height:1.6em;overflow:auto}.swagger-section .swagger-ui-wrap div.gist{margin:20px 0 25px!important}.swagger-section .swagger-ui-wrap ul#resources{font-family:Droid Sans,sans-serif;font-size:.9em}.swagger-section .swagger-ui-wrap ul#resources li.resource{border-bottom:1px solid #ddd}.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading h2 a,.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading h2 a{color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading ul.options li a,.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading ul.options li a{color:#555}.swagger-section .swagger-ui-wrap ul#resources li.resource:last-child{border-bottom:none}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading{border:1px solid transparent;float:none;clear:both;overflow:hidden;display:block}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options{overflow:hidden;padding:0;display:block;clear:none;float:right;margin:14px 10px 0 0}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li{float:left;clear:none;margin:0;padding:2px 10px;border-right:1px solid #ddd;color:#666;font-size:.9em}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a{color:#aaa;text-decoration:none}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover{text-decoration:underline;color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a.active,.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:active,.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover{text-decoration:underline}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.first,.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:first-child{padding-left:0}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:last-child{padding-right:0;border-right:none}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options.first,.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options:first-child{padding-left:0}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2{color:#999;padding-left:0;display:block;clear:none;float:left;font-family:Droid Sans,sans-serif;font-weight:700}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a{color:#999}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a:hover{color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation{float:none;clear:both;overflow:hidden;display:block;margin:0 0 10px;padding:0}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading{float:none;clear:both;overflow:hidden;display:block;margin:0;padding:0}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3{display:block;clear:none;float:left;width:auto;margin:0;padding:0;line-height:1.1em;color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path{padding-left:10px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a{color:#000;text-decoration:none}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a.toggleOperation.deprecated{text-decoration:line-through}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a:hover{text-decoration:underline}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.http_method a{text-transform:uppercase;text-decoration:none;color:#fff;display:inline-block;width:50px;font-size:.7em;text-align:center;padding:7px 0 4px;border-radius:2px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span{margin:0;padding:0}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options{overflow:hidden;padding:0;display:block;clear:none;float:right;margin:6px 10px 0 0}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li{float:left;clear:none;margin:0;padding:2px 10px;font-size:.9em}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a{text-decoration:none}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a .markdown p{color:inherit;padding:0;line-height:inherit}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a .nickname{color:#aaa;padding:0;line-height:inherit}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li.access{color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content{border-top:none;padding:10px;border-bottom-left-radius:6px;border-bottom-right-radius:6px;margin:0 0 20px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content h4{font-size:1.1em;margin:0;padding:15px 0 5px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header{float:none;clear:both;overflow:hidden;display:block}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header a{padding:4px 0 0 10px;display:inline-block;font-size:.9em}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header input.submit{display:block;clear:none;float:left;padding:6px 8px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header span.response_throbber{background-image:url(../images/throbber.gif);width:128px;height:16px;display:block;clear:none;float:right}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form input[type=text].error{outline:2px solid #000;outline-color:#c00}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form select[name=parameterContentType]{max-width:300px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.response div.block pre{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;padding:10px;font-size:.9em;max-height:400px;overflow-y:auto}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading{background-color:#f9f2e9;border:1px solid #f0e0ca}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading h3 span.http_method a{background-color:#c5862b}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#f0e0ca;color:#c5862b}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li a{color:#c5862b}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content{background-color:#faf5ee;border:1px solid #f0e0ca}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content h4{color:#c5862b}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content div.sandbox_header a{color:#dcb67f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading{background-color:#fcffcd;border:1px solid #000;border-color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading h3 span.http_method a{text-transform:uppercase;background-color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#ffd20f;color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li a{color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content{background-color:#fcffcd;border:1px solid #000;border-color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content h4{color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content div.sandbox_header a{color:#6fc992}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading{background-color:#f5e8e8;border:1px solid #e8c6c7}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading h3 span.http_method a{text-transform:uppercase;background-color:#a41e22}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#e8c6c7;color:#a41e22}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li a{color:#a41e22}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content{background-color:#f7eded;border:1px solid #e8c6c7}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content h4{color:#a41e22}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content div.sandbox_header a{color:#c8787a}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading{background-color:#e7f6ec;border:1px solid #c3e8d1}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading h3 span.http_method a{background-color:#10a54a}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#c3e8d1;color:#10a54a}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li a{color:#10a54a}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content{background-color:#ebf7f0;border:1px solid #c3e8d1}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content h4{color:#10a54a}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content div.sandbox_header a{color:#6fc992}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading{background-color:#fce9e3;border:1px solid #f5d5c3}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading h3 span.http_method a{background-color:#d38042}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#f0cecb;color:#d38042}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li a{color:#d38042}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content{background-color:#faf0ef;border:1px solid #f0cecb}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content h4{color:#d38042}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content div.sandbox_header a{color:#dcb67f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading{background-color:#e7f0f7;border:1px solid #c3d9ec}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading h3 span.http_method a{background-color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#c3d9ec;color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li a{color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content{background-color:#ebf3f9;border:1px solid #c3d9ec}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content h4{color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content div.sandbox_header a{color:#6fa5d2}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading{background-color:#e7f0f7;border:1px solid #c3d9ec}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading h3 span.http_method a{background-color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#c3d9ec;color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li a{color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content{background-color:#ebf3f9;border:1px solid #c3d9ec}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content h4{color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content div.sandbox_header a{color:#6fa5d2}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content{border-top:none}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li:last-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li:last-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li:last-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li:last-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li:last-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li:last-child{padding-right:0;border-right:none}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a.active,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:active,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:hover{text-decoration:underline}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations.first,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations:first-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li.first,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li:first-child{padding-left:0}.swagger-section .swagger-ui-wrap p#colophon{margin:0 15px 40px;padding:10px 0;font-size:.8em;border-top:1px solid #ddd;font-family:Droid Sans,sans-serif;color:#999;font-style:italic}.swagger-section .swagger-ui-wrap p#colophon a{text-decoration:none;color:#547f00}.swagger-section .swagger-ui-wrap h3{color:#000;font-size:1.1em;padding:10px 0}.swagger-section .swagger-ui-wrap .markdown ol,.swagger-section .swagger-ui-wrap .markdown ul{font-family:Droid Sans,sans-serif;margin:5px 0 10px;padding:0 0 0 18px;list-style-type:disc}.swagger-section .swagger-ui-wrap form.form_box{background-color:#ebf3f9;border:1px solid #c3d9ec;padding:10px}.swagger-section .swagger-ui-wrap form.form_box label{color:#0f6ab4!important}.swagger-section .swagger-ui-wrap form.form_box input[type=submit]{display:block;padding:10px}.swagger-section .swagger-ui-wrap form.form_box p.weak{font-size:.8em}.swagger-section .swagger-ui-wrap form.form_box p{font-size:.9em;padding:0 0 15px;color:#7e7b6d}.swagger-section .swagger-ui-wrap form.form_box p a{color:#646257}.swagger-section .swagger-ui-wrap form.form_box p strong{color:#000}.swagger-section .swagger-ui-wrap .operation-status td.markdown>p:last-child{padding-bottom:0}.swagger-section .title{font-style:bold}.swagger-section .secondary_form{display:none}.swagger-section .main_image{display:block;margin-left:auto;margin-right:auto}.swagger-section .oauth_body{margin-left:100px;margin-right:100px}.swagger-section .oauth_submit{text-align:center;display:inline-block}.swagger-section .authorize-wrapper{margin:15px 0 10px}.swagger-section .authorize-wrapper_operation{float:right}.swagger-section .authorize__btn:hover{text-decoration:underline;cursor:pointer}.swagger-section .authorize__btn_operation:hover .authorize-scopes{display:block}.swagger-section .authorize-scopes{position:absolute;margin-top:20px;background:#fff;border:1px solid #ccc;border-radius:5px;display:none;font-size:13px;max-width:300px;line-height:30px;color:#000;padding:5px}.swagger-section .authorize-scopes .authorize__scope{text-decoration:none}.swagger-section .authorize__btn_operation{height:18px;vertical-align:middle;display:inline-block;background:url(../images/explorer_icons.png) no-repeat}.swagger-section .authorize__btn_operation_login{background-position:0 0;width:18px;margin-top:-6px;margin-left:4px}.swagger-section .authorize__btn_operation_logout{background-position:-30px 0;width:18px;margin-top:-6px;margin-left:4px}.swagger-section #auth_container{color:#fff;display:inline-block;border:none;padding:5px;width:87px;height:13px}.swagger-section #auth_container .authorize__btn{color:#fff}.swagger-section .auth_container{padding:0 0 10px;margin-bottom:5px;border-bottom:1px solid #ccc;font-size:.9em}.swagger-section .auth_container .auth__title{color:#547f00;font-size:1.2em}.swagger-section .auth_container .basic_auth__label{display:inline-block;width:60px}.swagger-section .auth_container .auth__description{color:#999;margin-bottom:5px}.swagger-section .auth_container .auth__button{margin-top:10px;height:30px}.swagger-section .auth_container .key_auth__field{margin:5px 0}.swagger-section .auth_container .key_auth__label{display:inline-block;width:60px}.swagger-section .api-popup-dialog{position:absolute;display:none}.swagger-section .api-popup-dialog-wrapper{z-index:2;width:500px;background:#fff;padding:20px;border:1px solid #ccc;border-radius:5px;font-size:13px;color:#777;position:fixed;top:50%;left:50%;transform:translate(-50%,-50%)}.swagger-section .api-popup-dialog-shadow{position:fixed;top:0;left:0;width:100%;height:100%;opacity:.2;background-color:gray;z-index:1}.swagger-section .api-popup-dialog .api-popup-title{font-size:24px;padding:10px 0}.swagger-section .api-popup-dialog .error-msg{padding-left:5px;padding-bottom:5px}.swagger-section .api-popup-dialog .api-popup-content{max-height:500px;overflow-y:auto}.swagger-section .api-popup-dialog .api-popup-authbtn,.swagger-section .api-popup-dialog .api-popup-cancel{height:30px}.swagger-section .api-popup-scopes{padding:10px 20px}.swagger-section .api-popup-scopes li{padding:5px 0;line-height:20px}.swagger-section .api-popup-scopes li input{position:relative;top:2px}.swagger-section .api-popup-scopes .api-scope-desc{padding-left:20px;font-style:italic}.swagger-section .api-popup-actions{padding-top:10px}.swagger-section fieldset{padding-bottom:10px;padding-left:20px}#header{display:none}.swagger-section .swagger-ui-wrap .model-signature pre{max-height:none}.swagger-section .swagger-ui-wrap .body-textarea,.swagger-section .swagger-ui-wrap input.parameter{width:100px}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options{display:none}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content{display:block!important}
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/css/reset.css b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/css/reset.css
new file mode 100644 (file)
index 0000000..fab4c29
--- /dev/null
@@ -0,0 +1 @@
+a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:after,blockquote:before,q:after,q:before{content:"";content:none}table{border-collapse:collapse;border-spacing:0}
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/css/screen.css b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/css/screen.css
new file mode 100644 (file)
index 0000000..b3c5774
--- /dev/null
@@ -0,0 +1 @@
+.swagger-section pre code{display:block;padding:.5em;background:#f0f0f0}.swagger-section pre .clojure .built_in,.swagger-section pre .lisp .title,.swagger-section pre .nginx .title,.swagger-section pre .subst,.swagger-section pre .tag .title,.swagger-section pre code{color:#000}.swagger-section pre .addition,.swagger-section pre .aggregate,.swagger-section pre .apache .cbracket,.swagger-section pre .apache .tag,.swagger-section pre .bash .variable,.swagger-section pre .constant,.swagger-section pre .django .variable,.swagger-section pre .erlang_repl .function_or_atom,.swagger-section pre .flow,.swagger-section pre .markdown .header,.swagger-section pre .parent,.swagger-section pre .preprocessor,.swagger-section pre .ruby .symbol,.swagger-section pre .ruby .symbol .string,.swagger-section pre .rules .value,.swagger-section pre .rules .value .number,.swagger-section pre .smalltalk .class,.swagger-section pre .stream,.swagger-section pre .string,.swagger-section pre .tag .value,.swagger-section pre .template_tag,.swagger-section pre .tex .command,.swagger-section pre .tex .special,.swagger-section pre .title{color:#800}.swagger-section pre .annotation,.swagger-section pre .chunk,.swagger-section pre .comment,.swagger-section pre .diff .header,.swagger-section pre .markdown .blockquote,.swagger-section pre .template_comment{color:#888}.swagger-section pre .change,.swagger-section pre .date,.swagger-section pre .go .constant,.swagger-section pre .literal,.swagger-section pre .markdown .bullet,.swagger-section pre .markdown .link_url,.swagger-section pre .number,.swagger-section pre .regexp,.swagger-section pre .smalltalk .char,.swagger-section pre .smalltalk .symbol{color:#080}.swagger-section pre .apache .sqbracket,.swagger-section pre .array,.swagger-section pre .attr_selector,.swagger-section pre .clojure .attribute,.swagger-section pre .coffeescript .property,.swagger-section pre .decorator,.swagger-section pre .deletion,.swagger-section pre .doctype,.swagger-section pre .envvar,.swagger-section pre .erlang_repl .reserved,.swagger-section pre .filter .argument,.swagger-section pre .important,.swagger-section pre .javadoc,.swagger-section pre .label,.swagger-section pre .localvars,.swagger-section pre .markdown .link_label,.swagger-section pre .nginx .built_in,.swagger-section pre .pi,.swagger-section pre .prompt,.swagger-section pre .pseudo,.swagger-section pre .ruby .string,.swagger-section pre .shebang,.swagger-section pre .tex .formula,.swagger-section pre .vhdl .attribute{color:#88f}.swagger-section pre .aggregate,.swagger-section pre .apache .tag,.swagger-section pre .bash .variable,.swagger-section pre .built_in,.swagger-section pre .css .tag,.swagger-section pre .go .typename,.swagger-section pre .id,.swagger-section pre .javadoctag,.swagger-section pre .keyword,.swagger-section pre .markdown .strong,.swagger-section pre .phpdoc,.swagger-section pre .request,.swagger-section pre .smalltalk .class,.swagger-section pre .status,.swagger-section pre .tex .command,.swagger-section pre .title,.swagger-section pre .winutils,.swagger-section pre .yardoctag{font-weight:700}.swagger-section pre .markdown .emphasis{font-style:italic}.swagger-section pre .nginx .built_in{font-weight:400}.swagger-section pre .coffeescript .javascript,.swagger-section pre .javascript .xml,.swagger-section pre .tex .formula,.swagger-section pre .xml .cdata,.swagger-section pre .xml .css,.swagger-section pre .xml .javascript,.swagger-section pre .xml .vbscript{opacity:.5}.swagger-section .hljs{display:block;overflow-x:auto;padding:.5em;background:#f0f0f0}.swagger-section .hljs,.swagger-section .hljs-subst{color:#444}.swagger-section .hljs-attribute,.swagger-section .hljs-doctag,.swagger-section .hljs-keyword,.swagger-section .hljs-meta-keyword,.swagger-section .hljs-name,.swagger-section .hljs-selector-tag{font-weight:700}.swagger-section .hljs-addition,.swagger-section .hljs-built_in,.swagger-section .hljs-bullet,.swagger-section .hljs-code,.swagger-section .hljs-literal{color:#1f811f}.swagger-section .hljs-link,.swagger-section .hljs-regexp,.swagger-section .hljs-selector-attr,.swagger-section .hljs-selector-pseudo,.swagger-section .hljs-symbol,.swagger-section .hljs-template-variable,.swagger-section .hljs-variable{color:#bc6060}.swagger-section .hljs-deletion,.swagger-section .hljs-number,.swagger-section .hljs-quote,.swagger-section .hljs-selector-class,.swagger-section .hljs-selector-id,.swagger-section .hljs-string,.swagger-section .hljs-template-tag,.swagger-section .hljs-type{color:#800}.swagger-section .hljs-section,.swagger-section .hljs-title{color:#800;font-weight:700}.swagger-section .hljs-comment{color:#888}.swagger-section .hljs-meta{color:#2b6ea1}.swagger-section .hljs-emphasis{font-style:italic}.swagger-section .hljs-strong{font-weight:700}.swagger-section .swagger-ui-wrap{line-height:1;font-family:Droid Sans,sans-serif;min-width:760px;max-width:960px;margin-left:auto;margin-right:auto}.swagger-section .swagger-ui-wrap b,.swagger-section .swagger-ui-wrap strong{font-family:Droid Sans,sans-serif;font-weight:700}.swagger-section .swagger-ui-wrap blockquote,.swagger-section .swagger-ui-wrap q{quotes:none}.swagger-section .swagger-ui-wrap p{line-height:1.4em;padding:0 0 10px;color:#333}.swagger-section .swagger-ui-wrap blockquote:after,.swagger-section .swagger-ui-wrap blockquote:before,.swagger-section .swagger-ui-wrap q:after,.swagger-section .swagger-ui-wrap q:before{content:none}.swagger-section .swagger-ui-wrap .heading_with_menu h1,.swagger-section .swagger-ui-wrap .heading_with_menu h2,.swagger-section .swagger-ui-wrap .heading_with_menu h3,.swagger-section .swagger-ui-wrap .heading_with_menu h4,.swagger-section .swagger-ui-wrap .heading_with_menu h5,.swagger-section .swagger-ui-wrap .heading_with_menu h6{display:block;clear:none;float:left;-ms-box-sizing:border-box;box-sizing:border-box;width:60%}.swagger-section .swagger-ui-wrap table{border-collapse:collapse;border-spacing:0}.swagger-section .swagger-ui-wrap table thead tr th{padding:5px;font-size:.9em;color:#666;border-bottom:1px solid #999}.swagger-section .swagger-ui-wrap table tbody tr:last-child td{border-bottom:none}.swagger-section .swagger-ui-wrap table tbody tr.offset{background-color:#f0f0f0}.swagger-section .swagger-ui-wrap table tbody tr td{padding:6px;font-size:.9em;border-bottom:1px solid #ccc;vertical-align:top;line-height:1.3em}.swagger-section .swagger-ui-wrap ol{margin:0 0 10px;padding:0 0 0 18px;list-style-type:decimal}.swagger-section .swagger-ui-wrap ol li{padding:5px 0;font-size:.9em;color:#333}.swagger-section .swagger-ui-wrap ol,.swagger-section .swagger-ui-wrap ul{list-style:none}.swagger-section .swagger-ui-wrap h1 a,.swagger-section .swagger-ui-wrap h2 a,.swagger-section .swagger-ui-wrap h3 a,.swagger-section .swagger-ui-wrap h4 a,.swagger-section .swagger-ui-wrap h5 a,.swagger-section .swagger-ui-wrap h6 a{text-decoration:none}.swagger-section .swagger-ui-wrap h1 a:hover,.swagger-section .swagger-ui-wrap h2 a:hover,.swagger-section .swagger-ui-wrap h3 a:hover,.swagger-section .swagger-ui-wrap h4 a:hover,.swagger-section .swagger-ui-wrap h5 a:hover,.swagger-section .swagger-ui-wrap h6 a:hover{text-decoration:underline}.swagger-section .swagger-ui-wrap h1 span.divider,.swagger-section .swagger-ui-wrap h2 span.divider,.swagger-section .swagger-ui-wrap h3 span.divider,.swagger-section .swagger-ui-wrap h4 span.divider,.swagger-section .swagger-ui-wrap h5 span.divider,.swagger-section .swagger-ui-wrap h6 span.divider{color:#aaa}.swagger-section .swagger-ui-wrap a{color:#547f00}.swagger-section .swagger-ui-wrap a img{border:none}.swagger-section .swagger-ui-wrap article,.swagger-section .swagger-ui-wrap aside,.swagger-section .swagger-ui-wrap details,.swagger-section .swagger-ui-wrap figcaption,.swagger-section .swagger-ui-wrap figure,.swagger-section .swagger-ui-wrap footer,.swagger-section .swagger-ui-wrap header,.swagger-section .swagger-ui-wrap hgroup,.swagger-section .swagger-ui-wrap menu,.swagger-section .swagger-ui-wrap nav,.swagger-section .swagger-ui-wrap section,.swagger-section .swagger-ui-wrap summary{display:block}.swagger-section .swagger-ui-wrap pre{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;background-color:#fcf6db;border:1px solid #e5e0c6;padding:10px}.swagger-section .swagger-ui-wrap pre code{line-height:1.6em;background:none}.swagger-section .swagger-ui-wrap .content>.content-type>div>label{clear:both;display:block;color:#0f6ab4;font-size:1.1em;margin:0;padding:15px 0 5px}.swagger-section .swagger-ui-wrap .content pre{font-size:12px;margin-top:5px;padding:5px}.swagger-section .swagger-ui-wrap .icon-btn{cursor:pointer}.swagger-section .swagger-ui-wrap .info_title{padding-bottom:10px;font-weight:700;font-size:25px}.swagger-section .swagger-ui-wrap .footer{margin-top:20px}.swagger-section .swagger-ui-wrap div.big p,.swagger-section .swagger-ui-wrap p.big{font-size:1em;margin-bottom:10px}.swagger-section .swagger-ui-wrap form.fullwidth ol li.numeric input,.swagger-section .swagger-ui-wrap form.fullwidth ol li.string input,.swagger-section .swagger-ui-wrap form.fullwidth ol li.text textarea,.swagger-section .swagger-ui-wrap form.fullwidth ol li.url input{width:500px!important}.swagger-section .swagger-ui-wrap .info_license,.swagger-section .swagger-ui-wrap .info_tos{padding-bottom:5px}.swagger-section .swagger-ui-wrap .message-fail{color:#c00}.swagger-section .swagger-ui-wrap .info_email,.swagger-section .swagger-ui-wrap .info_name,.swagger-section .swagger-ui-wrap .info_url{padding-bottom:5px}.swagger-section .swagger-ui-wrap .info_description{padding-bottom:10px;font-size:15px}.swagger-section .swagger-ui-wrap .markdown ol li,.swagger-section .swagger-ui-wrap .markdown ul li{padding:3px 0;line-height:1.4em;color:#333}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input,.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input,.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input{display:block;padding:4px;width:auto;clear:both}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input.title,.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input.title,.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input.title{font-size:1.3em}.swagger-section .swagger-ui-wrap table.fullwidth{width:100%}.swagger-section .swagger-ui-wrap .model-signature{font-family:Droid Sans,sans-serif;font-size:1em;line-height:1.5em}.swagger-section .swagger-ui-wrap .model-signature .signature-nav a{text-decoration:none;color:#aaa}.swagger-section .swagger-ui-wrap .model-signature .signature-nav a:hover{text-decoration:underline;color:#000}.swagger-section .swagger-ui-wrap .model-signature .signature-nav .selected{color:#000;text-decoration:none}.swagger-section .swagger-ui-wrap .model-signature .propType{color:#55a}.swagger-section .swagger-ui-wrap .model-signature pre:hover{background-color:#ffd}.swagger-section .swagger-ui-wrap .model-signature pre{font-size:.85em;line-height:1.2em;overflow:auto;height:200px;resize:vertical;cursor:pointer}.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav{display:block;min-width:230px;margin:0;padding:0}.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li:last-child{padding-right:0;border-right:none}.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li{float:left;margin:0 5px 5px 0;padding:2px 5px 2px 0;border-right:1px solid #ddd}.swagger-section .swagger-ui-wrap .model-signature .propOpt{color:#555}.swagger-section .swagger-ui-wrap .model-signature .snippet small{font-size:.75em}.swagger-section .swagger-ui-wrap .model-signature .propOptKey{font-style:italic}.swagger-section .swagger-ui-wrap .model-signature .description .strong{font-weight:700;color:#000;font-size:.9em}.swagger-section .swagger-ui-wrap .model-signature .description div{font-size:.9em;line-height:1.5em;margin-left:1em}.swagger-section .swagger-ui-wrap .model-signature .description .stronger{font-weight:700;color:#000}.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper{border-spacing:0;position:absolute;background-color:#fff;border:1px solid #bbb;display:none;font-size:11px;max-width:400px;line-height:30px;color:#000;padding:5px;margin-left:10px}.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper th{text-align:center;background-color:#eee;border:1px solid #bbb;font-size:11px;color:#666;font-weight:700;padding:5px;line-height:15px}.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper .optionName{font-weight:700}.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown>p:first-child,.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown>p:last-child{display:inline}.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown>p:not(:first-child):before{display:block;content:""}.swagger-section .swagger-ui-wrap .model-signature .description span:last-of-type.propDesc.markdown>p:only-child{margin-right:-3px}.swagger-section .swagger-ui-wrap .model-signature .propName{font-weight:700}.swagger-section .swagger-ui-wrap .model-signature .signature-container{clear:both}.swagger-section .swagger-ui-wrap .body-textarea{width:300px;height:100px;border:1px solid #aaa}.swagger-section .swagger-ui-wrap .markdown li code,.swagger-section .swagger-ui-wrap .markdown p code{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;background-color:#f0f0f0;color:#000;padding:1px 3px}.swagger-section .swagger-ui-wrap .required{font-weight:700}.swagger-section .swagger-ui-wrap .editor_holder{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;font-size:.9em}.swagger-section .swagger-ui-wrap .editor_holder label{font-weight:400!important}.swagger-section .swagger-ui-wrap .editor_holder label.required{font-weight:700!important}.swagger-section .swagger-ui-wrap input.parameter{width:300px;border:1px solid #aaa}.swagger-section .swagger-ui-wrap h1{color:#000;font-size:1.5em;line-height:1.3em;padding:10px 0;font-family:Droid Sans,sans-serif;font-weight:700}.swagger-section .swagger-ui-wrap .heading_with_menu{float:none;clear:both;overflow:hidden;display:block}.swagger-section .swagger-ui-wrap .heading_with_menu ul{display:block;clear:none;float:right;-ms-box-sizing:border-box;box-sizing:border-box;margin-top:10px}.swagger-section .swagger-ui-wrap h2{color:#000;font-size:1.3em;padding:10px 0}.swagger-section .swagger-ui-wrap h2 a{color:#000}.swagger-section .swagger-ui-wrap h2 span.sub{font-size:.7em;color:#999;font-style:italic}.swagger-section .swagger-ui-wrap h2 span.sub a{color:#777}.swagger-section .swagger-ui-wrap span.weak{color:#666}.swagger-section .swagger-ui-wrap .message-success{color:#89bf04}.swagger-section .swagger-ui-wrap caption,.swagger-section .swagger-ui-wrap td,.swagger-section .swagger-ui-wrap th{text-align:left;font-weight:400;vertical-align:middle}.swagger-section .swagger-ui-wrap .code{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.text textarea{font-family:Droid Sans,sans-serif;height:250px;padding:4px;display:block;clear:both}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.select select{display:block;clear:both}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean{float:none;clear:both;overflow:hidden;display:block}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean label{display:block;float:left;clear:none;margin:0;padding:0}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean input{display:block;float:left;clear:none;margin:0 5px 0 0}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.required label{color:#000}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label{display:block;clear:both;width:auto;padding:0 0 3px;color:#666}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label abbr{padding-left:3px;color:#888}.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li p.inline-hints{margin-left:0;font-style:italic;font-size:.9em;margin:0}.swagger-section .swagger-ui-wrap form.formtastic fieldset.buttons{margin:0;padding:0}.swagger-section .swagger-ui-wrap span.blank,.swagger-section .swagger-ui-wrap span.empty{color:#888;font-style:italic}.swagger-section .swagger-ui-wrap .markdown h3{color:#547f00}.swagger-section .swagger-ui-wrap .markdown h4{color:#666}.swagger-section .swagger-ui-wrap .markdown pre{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;background-color:#fcf6db;border:1px solid #e5e0c6;padding:10px;margin:0 0 10px}.swagger-section .swagger-ui-wrap .markdown pre code{line-height:1.6em;overflow:auto}.swagger-section .swagger-ui-wrap div.gist{margin:20px 0 25px!important}.swagger-section .swagger-ui-wrap ul#resources{font-family:Droid Sans,sans-serif;font-size:.9em}.swagger-section .swagger-ui-wrap ul#resources li.resource{border-bottom:1px solid #ddd}.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading h2 a,.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading h2 a{color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading ul.options li a,.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading ul.options li a{color:#555}.swagger-section .swagger-ui-wrap ul#resources li.resource:last-child{border-bottom:none}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading{border:1px solid transparent;float:none;clear:both;overflow:hidden;display:block}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options{overflow:hidden;padding:0;display:block;clear:none;float:right;margin:14px 10px 0 0}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li{float:left;clear:none;margin:0;padding:2px 10px;border-right:1px solid #ddd;color:#666;font-size:.9em}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a{color:#aaa;text-decoration:none}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover{text-decoration:underline;color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a.active,.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:active,.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover{text-decoration:underline}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.first,.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:first-child{padding-left:0}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:last-child{padding-right:0;border-right:none}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options.first,.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options:first-child{padding-left:0}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2{color:#999;padding-left:0;display:block;clear:none;float:left;font-family:Droid Sans,sans-serif;font-weight:700}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a{color:#999}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a:hover{color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation{float:none;clear:both;overflow:hidden;display:block;margin:0 0 10px;padding:0}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading{float:none;clear:both;overflow:hidden;display:block;margin:0;padding:0}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3{display:block;clear:none;float:left;width:auto;margin:0;padding:0;line-height:1.1em;color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path{padding-left:10px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a{color:#000;text-decoration:none}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a.toggleOperation.deprecated{text-decoration:line-through}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a:hover{text-decoration:underline}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.http_method a{text-transform:uppercase;text-decoration:none;color:#fff;display:inline-block;width:50px;font-size:.7em;text-align:center;padding:7px 0 4px;border-radius:2px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span{margin:0;padding:0}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options{overflow:hidden;padding:0;display:block;clear:none;float:right;margin:6px 10px 0 0}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li{float:left;clear:none;margin:0;padding:2px 10px;font-size:.9em}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a{text-decoration:none}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a .markdown p{color:inherit;padding:0;line-height:inherit}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a .nickname{color:#aaa;padding:0;line-height:inherit}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li.access{color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content{border-top:none;padding:10px;border-bottom-left-radius:6px;border-bottom-right-radius:6px;margin:0 0 20px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content h4{font-size:1.1em;margin:0;padding:15px 0 5px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header{float:none;clear:both;overflow:hidden;display:block}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header a{padding:4px 0 0 10px;display:inline-block;font-size:.9em}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header input.submit{display:block;clear:none;float:left;padding:6px 8px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header span.response_throbber{background-image:url(../images/throbber.gif);width:128px;height:16px;display:block;clear:none;float:right}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form input[type=text].error{outline:2px solid #000;outline-color:#c00}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form select[name=parameterContentType]{max-width:300px}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.response div.block pre{font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;padding:10px;font-size:.9em;max-height:400px;overflow-y:auto}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading{background-color:#f9f2e9;border:1px solid #f0e0ca}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading h3 span.http_method a{background-color:#c5862b}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#f0e0ca;color:#c5862b}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li a{color:#c5862b}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content{background-color:#faf5ee;border:1px solid #f0e0ca}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content h4{color:#c5862b}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content div.sandbox_header a{color:#dcb67f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading{background-color:#fcffcd;border:1px solid #000;border-color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading h3 span.http_method a{text-transform:uppercase;background-color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#ffd20f;color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li a{color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content{background-color:#fcffcd;border:1px solid #000;border-color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content h4{color:#ffd20f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content div.sandbox_header a{color:#6fc992}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading{background-color:#f5e8e8;border:1px solid #e8c6c7}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading h3 span.http_method a{text-transform:uppercase;background-color:#a41e22}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#e8c6c7;color:#a41e22}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li a{color:#a41e22}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content{background-color:#f7eded;border:1px solid #e8c6c7}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content h4{color:#a41e22}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content div.sandbox_header a{color:#c8787a}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading{background-color:#e7f6ec;border:1px solid #c3e8d1}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading h3 span.http_method a{background-color:#10a54a}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#c3e8d1;color:#10a54a}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li a{color:#10a54a}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content{background-color:#ebf7f0;border:1px solid #c3e8d1}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content h4{color:#10a54a}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content div.sandbox_header a{color:#6fc992}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading{background-color:#fce9e3;border:1px solid #f5d5c3}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading h3 span.http_method a{background-color:#d38042}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#f0cecb;color:#d38042}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li a{color:#d38042}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content{background-color:#faf0ef;border:1px solid #f0cecb}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content h4{color:#d38042}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content div.sandbox_header a{color:#dcb67f}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading{background-color:#e7f0f7;border:1px solid #c3d9ec}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading h3 span.http_method a{background-color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#c3d9ec;color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li a{color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content{background-color:#ebf3f9;border:1px solid #c3d9ec}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content h4{color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content div.sandbox_header a{color:#6fa5d2}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading{background-color:#e7f0f7;border:1px solid #c3d9ec}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading h3 span.http_method a{background-color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li{border-right:1px solid #ddd;border-right-color:#c3d9ec;color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li a{color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content{background-color:#ebf3f9;border:1px solid #c3d9ec}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content h4{color:#0f6ab4}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content div.sandbox_header a{color:#6fa5d2}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content{border-top:none}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li:last-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li:last-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li:last-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li:last-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li:last-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li.last,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li:last-child{padding-right:0;border-right:none}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a.active,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:active,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:hover{text-decoration:underline}.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations.first,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations:first-child,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li.first,.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li:first-child{padding-left:0}.swagger-section .swagger-ui-wrap p#colophon{margin:0 15px 40px;padding:10px 0;font-size:.8em;border-top:1px solid #ddd;font-family:Droid Sans,sans-serif;color:#999;font-style:italic}.swagger-section .swagger-ui-wrap p#colophon a{text-decoration:none;color:#547f00}.swagger-section .swagger-ui-wrap h3{color:#000;font-size:1.1em;padding:10px 0}.swagger-section .swagger-ui-wrap .markdown ol,.swagger-section .swagger-ui-wrap .markdown ul{font-family:Droid Sans,sans-serif;margin:5px 0 10px;padding:0 0 0 18px;list-style-type:disc}.swagger-section .swagger-ui-wrap form.form_box{background-color:#ebf3f9;border:1px solid #c3d9ec;padding:10px}.swagger-section .swagger-ui-wrap form.form_box label{color:#0f6ab4!important}.swagger-section .swagger-ui-wrap form.form_box input[type=submit]{display:block;padding:10px}.swagger-section .swagger-ui-wrap form.form_box p.weak{font-size:.8em}.swagger-section .swagger-ui-wrap form.form_box p{font-size:.9em;padding:0 0 15px;color:#7e7b6d}.swagger-section .swagger-ui-wrap form.form_box p a{color:#646257}.swagger-section .swagger-ui-wrap form.form_box p strong{color:#000}.swagger-section .swagger-ui-wrap .operation-status td.markdown>p:last-child{padding-bottom:0}.swagger-section .title{font-style:bold}.swagger-section .secondary_form{display:none}.swagger-section .main_image{display:block;margin-left:auto;margin-right:auto}.swagger-section .oauth_body{margin-left:100px;margin-right:100px}.swagger-section .oauth_submit{text-align:center;display:inline-block}.swagger-section .authorize-wrapper{margin:15px 0 10px}.swagger-section .authorize-wrapper_operation{float:right}.swagger-section .authorize__btn:hover{text-decoration:underline;cursor:pointer}.swagger-section .authorize__btn_operation:hover .authorize-scopes{display:block}.swagger-section .authorize-scopes{position:absolute;margin-top:20px;background:#fff;border:1px solid #ccc;border-radius:5px;display:none;font-size:13px;max-width:300px;line-height:30px;color:#000;padding:5px}.swagger-section .authorize-scopes .authorize__scope{text-decoration:none}.swagger-section .authorize__btn_operation{height:18px;vertical-align:middle;display:inline-block;background:url(../images/explorer_icons.png) no-repeat}.swagger-section .authorize__btn_operation_login{background-position:0 0;width:18px;margin-top:-6px;margin-left:4px}.swagger-section .authorize__btn_operation_logout{background-position:-30px 0;width:18px;margin-top:-6px;margin-left:4px}.swagger-section #auth_container{color:#fff;display:inline-block;border:none;padding:5px;width:87px;height:13px}.swagger-section #auth_container .authorize__btn{color:#fff}.swagger-section .auth_container{padding:0 0 10px;margin-bottom:5px;border-bottom:1px solid #ccc;font-size:.9em}.swagger-section .auth_container .auth__title{color:#547f00;font-size:1.2em}.swagger-section .auth_container .basic_auth__label{display:inline-block;width:60px}.swagger-section .auth_container .auth__description{color:#999;margin-bottom:5px}.swagger-section .auth_container .auth__button{margin-top:10px;height:30px}.swagger-section .auth_container .key_auth__field{margin:5px 0}.swagger-section .auth_container .key_auth__label{display:inline-block;width:60px}.swagger-section .api-popup-dialog{position:absolute;display:none}.swagger-section .api-popup-dialog-wrapper{z-index:2;width:500px;background:#fff;padding:20px;border:1px solid #ccc;border-radius:5px;font-size:13px;color:#777;position:fixed;top:50%;left:50%;transform:translate(-50%,-50%)}.swagger-section .api-popup-dialog-shadow{position:fixed;top:0;left:0;width:100%;height:100%;opacity:.2;background-color:gray;z-index:1}.swagger-section .api-popup-dialog .api-popup-title{font-size:24px;padding:10px 0}.swagger-section .api-popup-dialog .error-msg{padding-left:5px;padding-bottom:5px}.swagger-section .api-popup-dialog .api-popup-content{max-height:500px;overflow-y:auto}.swagger-section .api-popup-dialog .api-popup-authbtn,.swagger-section .api-popup-dialog .api-popup-cancel{height:30px}.swagger-section .api-popup-scopes{padding:10px 20px}.swagger-section .api-popup-scopes li{padding:5px 0;line-height:20px}.swagger-section .api-popup-scopes li input{position:relative;top:2px}.swagger-section .api-popup-scopes .api-scope-desc{padding-left:20px;font-style:italic}.swagger-section .api-popup-actions{padding-top:10px}.swagger-section fieldset{padding-bottom:10px;padding-left:20px}.swagger-section .access,.swagger-section .auth{float:right}.swagger-section .api-ic{height:18px;vertical-align:middle;display:inline-block;background:url(../images/explorer_icons.png) no-repeat}.swagger-section .api-ic .api_information_panel{position:relative;margin-top:20px;margin-left:-5px;background:#fff;border:1px solid #ccc;border-radius:5px;display:none;font-size:13px;max-width:300px;line-height:30px;color:#000;padding:5px}.swagger-section .api-ic .api_information_panel p .api-msg-enabled{color:green}.swagger-section .api-ic .api_information_panel p .api-msg-disabled{color:red}.swagger-section .api-ic:hover .api_information_panel{position:absolute;display:block}.swagger-section .ic-info{background-position:0 0;width:18px;margin-top:-6px;margin-left:4px}.swagger-section .ic-warning{background-position:-60px 0;width:18px;margin-top:-6px;margin-left:4px}.swagger-section .ic-error{background-position:-30px 0;width:18px;margin-top:-6px;margin-left:4px}.swagger-section .ic-off{background-position:-90px 0;width:58px;margin-top:-4px;cursor:pointer}.swagger-section .ic-on{background-position:-160px 0;width:58px;margin-top:-4px;cursor:pointer}.swagger-section #header{background-color:#89bf04;padding:9px 14px 19px;height:23px;min-width:775px}.swagger-section #input_baseUrl{width:400px}.swagger-section #api_selector{display:block;clear:none;float:right}.swagger-section #api_selector .input{display:inline-block;clear:none;margin:0 10px 0 0}.swagger-section #api_selector input{font-size:.9em;padding:3px;margin:0}.swagger-section #input_apiKey{width:200px}.swagger-section #auth_container .authorize__btn,.swagger-section #explore{display:block;text-decoration:none;font-weight:700;padding:6px 8px;font-size:.9em;color:#fff;background-color:#547f00;border-radius:4px}.swagger-section #auth_container .authorize__btn:hover,.swagger-section #explore:hover{background-color:#547f00}.swagger-section #header #logo{font-size:1.5em;font-weight:700;text-decoration:none;color:#fff}.swagger-section #header #logo .logo__img{display:block;float:left;margin-top:2px}.swagger-section #header #logo .logo__title{display:inline-block;padding:5px 0 0 10px}.swagger-section #content_message{margin:10px 15px;font-style:italic;color:#999}.swagger-section #message-bar{min-height:30px;text-align:center;padding-top:10px}.swagger-section .swagger-collapse:before{content:"-"}.swagger-section .swagger-expand:before{content:"+"}.swagger-section .error{outline-color:#c00;background-color:#f2dede}
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/css/style.css b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/css/style.css
new file mode 100644 (file)
index 0000000..52907e4
--- /dev/null
@@ -0,0 +1 @@
+.swagger-section #header a#logo{font-size:1.5em;font-weight:700;text-decoration:none;padding:20px 0 20px 40px}#text-head{font-size:80px;font-family:Roboto,sans-serif;color:#fff;float:right;margin-right:20%}.navbar-fixed-top .navbar-brand,.navbar-fixed-top .navbar-nav,.navbar-header{height:auto}.navbar-inverse{background-color:#000;border-color:#000}#navbar-brand{margin-left:20%}.navtext{font-size:10px}.h1,h1{font-size:60px}.navbar-default .navbar-header .navbar-brand{color:#a2dfee}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a{color:#393939;font-family:Arvo,serif;font-size:1.5em}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a:hover{color:#000}.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2{color:#525252;padding-left:0;display:block;clear:none;float:left;font-family:Arvo,serif;font-weight:700}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#0a0a0a}.container1{width:1500px;margin:auto;margin-top:0;background-repeat:no-repeat;background-position:-40px -20px;margin-bottom:210px}.container-inner{width:1200px;margin:auto;background-color:hsla(192,8%,88%,.75);padding-bottom:40px;padding-top:40px;border-radius:15px}.header-content{padding:0;width:1000px}.title1{font-size:80px;font-family:Vollkorn,serif;color:#404040;text-align:center;padding-top:40px;padding-bottom:100px}#icon{margin-top:-18px}.subtext{font-size:25px;font-style:italic;color:#08b;text-align:right;padding-right:250px}.bg-primary{background-color:#00468b}.navbar-default .nav>li>a,.navbar-default .nav>li>a:focus,.navbar-default .nav>li>a:focus:hover,.navbar-default .nav>li>a:hover{color:#08b}.text-faded{font-size:25px;font-family:Vollkorn,serif}.section-heading{font-family:Vollkorn,serif;font-size:45px;padding-bottom:10px}hr{border-color:#00468b;padding-bottom:10px}.description{margin-top:20px;padding-bottom:200px}.description li{font-family:Vollkorn,serif;font-size:25px;color:#525252;margin-left:28%;padding-top:5px}.gap{margin-top:200px}.troubleshootingtext{color:hsla(0,0%,100%,.7);padding-left:30%}.troubleshootingtext li{list-style-type:circle;font-size:25px;padding-bottom:5px}.overlay{position:absolute;top:0;left:0;width:100%;height:100%;z-index:1}.block.response_body.json:hover{cursor:pointer}.backdrop{color:blue}#myModal{height:100%}.modal-backdrop{bottom:0;position:fixed}.curl{padding:10px;font-family:Anonymous Pro,Menlo,Consolas,Bitstream Vera Sans Mono,Courier New,monospace;font-size:.9em;max-height:400px;margin-top:5px;overflow-y:auto;background-color:#fcf6db;border:1px solid #e5e0c6;border-radius:4px}.curl_title{font-size:1.1em;margin:0;padding:15px 0 5px;font-family:Open Sans,Helvetica Neue,Arial,sans-serif;font-weight:500;line-height:1.1}.footer{display:none}.swagger-section .swagger-ui-wrap h2{padding:0}h2{margin:0;margin-bottom:5px}.markdown p,.swagger-section .swagger-ui-wrap .code{font-size:15px;font-family:Arvo,serif}.swagger-section .swagger-ui-wrap b{font-family:Arvo,serif}#signin:hover{cursor:pointer}.dropdown-menu{padding:15px}.navbar-right .dropdown-menu{left:0;right:auto}#signinbutton{width:100%;height:32px;font-size:13px;font-weight:700;color:#08b}.navbar-default .nav>li .details{color:#000;text-transform:none;font-size:15px;font-weight:400;font-family:Open Sans,sans-serif;font-style:italic;line-height:20px;top:-2px}.navbar-default .nav>li .details:hover{color:#000}#signout{width:100%;height:32px;font-size:13px;font-weight:700;color:#08b}
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/css/typography.css b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/css/typography.css
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/fonts/DroidSans-Bold.ttf b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/fonts/DroidSans-Bold.ttf
new file mode 100644 (file)
index 0000000..036c4d1
Binary files /dev/null and b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/fonts/DroidSans-Bold.ttf differ
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/fonts/DroidSans.ttf b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/fonts/DroidSans.ttf
new file mode 100644 (file)
index 0000000..e517a0c
Binary files /dev/null and b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/fonts/DroidSans.ttf differ
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/collapse.gif b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/collapse.gif
new file mode 100644 (file)
index 0000000..8843e8c
Binary files /dev/null and b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/collapse.gif differ
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/expand.gif b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/expand.gif
new file mode 100644 (file)
index 0000000..477bf13
Binary files /dev/null and b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/expand.gif differ
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/explorer_icons.png b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/explorer_icons.png
new file mode 100644 (file)
index 0000000..be43b27
Binary files /dev/null and b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/explorer_icons.png differ
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/favicon-16x16.png b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/favicon-16x16.png
new file mode 100644 (file)
index 0000000..0f7e13b
Binary files /dev/null and b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/favicon-16x16.png differ
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/favicon-32x32.png b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/favicon-32x32.png
new file mode 100644 (file)
index 0000000..b0a3352
Binary files /dev/null and b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/favicon-32x32.png differ
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/favicon.ico b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/favicon.ico
new file mode 100644 (file)
index 0000000..8b60bcf
Binary files /dev/null and b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/favicon.ico differ
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/logo_small.png b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/logo_small.png
new file mode 100644 (file)
index 0000000..ce3908e
Binary files /dev/null and b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/logo_small.png differ
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/pet_store_api.png b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/pet_store_api.png
new file mode 100644 (file)
index 0000000..1192ad8
Binary files /dev/null and b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/pet_store_api.png differ
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/throbber.gif b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/throbber.gif
new file mode 100644 (file)
index 0000000..0639388
Binary files /dev/null and b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/throbber.gif differ
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/wordnik_api.png b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/wordnik_api.png
new file mode 100644 (file)
index 0000000..dc0ddab
Binary files /dev/null and b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/images/wordnik_api.png differ
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/index.html b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/index.html
new file mode 100644 (file)
index 0000000..a0c53b0
--- /dev/null
@@ -0,0 +1,125 @@
+<!DOCTYPE html>
+<!--
+  ~ Modifications Copyright © 2017-2018 AT&T Intellectual Property.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<html>
+<head>
+  <meta charset="UTF-8">
+  <meta http-equiv="x-ua-compatible" content="IE=edge">
+  <title>Swagger UI</title>
+  <link rel="icon" type="image/png" href="images/favicon-32x32.png" sizes="32x32" />
+  <link rel="icon" type="image/png" href="images/favicon-16x16.png" sizes="16x16" />
+  <link href='css/typography.css' media='screen' rel='stylesheet' type='text/css'/>
+  <link href='css/reset.css' media='screen' rel='stylesheet' type='text/css'/>
+  <link href='css/screen.css' media='screen' rel='stylesheet' type='text/css'/>
+  <link href='css/reset.css' media='print' rel='stylesheet' type='text/css'/>
+  <link href='css/print.css' media='print' rel='stylesheet' type='text/css'/>
+
+  <script src='lib/object-assign-pollyfill.js' type='text/javascript'></script>
+  <script src='lib/jquery-1.8.0.min.js' type='text/javascript'></script>
+  <script src='lib/jquery.slideto.min.js' type='text/javascript'></script>
+  <script src='lib/jquery.wiggle.min.js' type='text/javascript'></script>
+  <script src='lib/jquery.ba-bbq.min.js' type='text/javascript'></script>
+  <script src='lib/handlebars-4.0.5.js' type='text/javascript'></script>
+  <script src='lib/lodash.min.js' type='text/javascript'></script>
+  <script src='lib/backbone-min.js' type='text/javascript'></script>
+  <script src='swagger-ui.js' type='text/javascript'></script>
+  <script src='lib/highlight.9.1.0.pack.js' type='text/javascript'></script>
+  <script src='lib/highlight.9.1.0.pack_extended.js' type='text/javascript'></script>
+  <script src='lib/jsoneditor.min.js' type='text/javascript'></script>
+  <script src='lib/marked.js' type='text/javascript'></script>
+  <script src='lib/swagger-oauth.js' type='text/javascript'></script>
+
+  <!-- Some basic translations -->
+  <!-- <script src='lang/translator.js' type='text/javascript'></script> -->
+  <!-- <script src='lang/ru.js' type='text/javascript'></script> -->
+  <!-- <script src='lang/en.js' type='text/javascript'></script> -->
+
+  <script type="text/javascript">
+    $(function () {
+      var url = window.location.search.match(/url=([^&]+)/);
+      if (url && url.length > 1) {
+        url = decodeURIComponent(url[1]);
+      } else {
+        //url = "http://localhost:8080/api/controller-blueprints/v1/swagger.json";
+        url = "../swagger.json";
+      }
+
+      hljs.configure({
+        highlightSizeThreshold: 5000
+      });
+
+      // Pre load translate...
+      if(window.SwaggerTranslator) {
+        window.SwaggerTranslator.translate();
+      }
+      window.swaggerUi = new SwaggerUi({
+        url: url,
+        dom_id: "swagger-ui-container",
+        supportedSubmitMethods: ['get', 'post', 'put', 'delete', 'patch'],
+        onComplete: function(swaggerApi, swaggerUi){
+          if(typeof initOAuth == "function") {
+            initOAuth({
+              clientId: "your-client-id",
+              clientSecret: "your-client-secret-if-required",
+              realm: "your-realms",
+              appName: "your-app-name",
+              scopeSeparator: " ",
+              additionalQueryStringParams: {}
+            });
+          }
+
+          if(window.SwaggerTranslator) {
+            window.SwaggerTranslator.translate();
+          }
+        },
+        onFailure: function(data) {
+          log("Unable to Load SwaggerUI");
+        },
+        docExpansion: "none",
+        jsonEditor: false,
+        defaultModelRendering: 'schema',
+        showRequestHeaders: false,
+        showOperationIds: false
+      });
+
+      window.swaggerUi.load();
+
+      function log() {
+        if ('console' in window) {
+          console.log.apply(console, arguments);
+        }
+      }
+  });
+  </script>
+</head>
+
+<body class="swagger-section">
+<div id='header'>
+  <div class="swagger-ui-wrap">
+    <a id="logo" href="http://swagger.io"><img class="logo__img" alt="swagger" height="30" width="30" src="images/logo_small.png" /><span class="logo__title">swagger</span></a>
+    <form id='api_selector'>
+      <div class='input'><input placeholder="http://example.com/api" id="input_baseUrl" name="baseUrl" type="text"/></div>
+      <div id='auth_container'></div>
+      <div class='input'><a id="explore" class="header__btn" href="#" data-sw-translate>Explore</a></div>
+    </form>
+  </div>
+</div>
+
+<div id="message-bar" class="swagger-ui-wrap" data-sw-translate>&nbsp;</div>
+<div id="swagger-ui-container" class="swagger-ui-wrap"></div>
+</body>
+</html>
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/ca.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/ca.js
new file mode 100644 (file)
index 0000000..f8c815a
--- /dev/null
@@ -0,0 +1,53 @@
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+    "Warning: Deprecated":"Advertència: Obsolet",
+    "Implementation Notes":"Notes d'implementació",
+    "Response Class":"Classe de la Resposta",
+    "Status":"Estatus",
+    "Parameters":"Paràmetres",
+    "Parameter":"Paràmetre",
+    "Value":"Valor",
+    "Description":"Descripció",
+    "Parameter Type":"Tipus del Paràmetre",
+    "Data Type":"Tipus de la Dada",
+    "Response Messages":"Missatges de la Resposta",
+    "HTTP Status Code":"Codi d'Estatus HTTP",
+    "Reason":"Raó",
+    "Response Model":"Model de la Resposta",
+    "Request URL":"URL de la Sol·licitud",
+    "Response Body":"Cos de la Resposta",
+    "Response Code":"Codi de la Resposta",
+    "Response Headers":"Capçaleres de la Resposta",
+    "Hide Response":"Amagar Resposta",
+    "Try it out!":"Prova-ho!",
+    "Show/Hide":"Mostrar/Amagar",
+    "List Operations":"Llista Operacions",
+    "Expand Operations":"Expandir Operacions",
+    "Raw":"Cru",
+    "can't parse JSON.  Raw result":"no puc analitzar el JSON.  Resultat cru",
+    "Example Value":"Valor d'Exemple",
+    "Model Schema":"Esquema del Model",
+    "Model":"Model",
+    "apply":"aplicar",
+    "Username":"Nom d'usuari",
+    "Password":"Contrasenya",
+    "Terms of service":"Termes del servei",
+    "Created by":"Creat per",
+    "See more at":"Veure més en",
+    "Contact the developer":"Contactar amb el desenvolupador",
+    "api version":"versió de la api",
+    "Response Content Type":"Tipus de Contingut de la Resposta",
+    "fetching resource":"recollint recurs",
+    "fetching resource list":"recollins llista de recursos",
+    "Explore":"Explorant",
+    "Show Swagger Petstore Example Apis":"Mostrar API d'Exemple Swagger Petstore",
+    "Can't read from server.  It may not have the appropriate access-control-origin settings.":"No es pot llegir del servidor. Potser no teniu la configuració de control d'accés apropiada.",
+    "Please specify the protocol for":"Si us plau, especifiqueu el protocol per a",
+    "Can't read swagger JSON from":"No es pot llegir el JSON de swagger des de",
+    "Finished Loading Resource Information. Rendering Swagger UI":"Finalitzada la càrrega del recurs informatiu. Renderitzant Swagger UI",
+    "Unable to read api":"No es pot llegir l'api",
+    "from path":"des de la ruta",
+    "server returned":"el servidor ha retornat"
+});
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/el.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/el.js
new file mode 100644 (file)
index 0000000..fcd1ffd
--- /dev/null
@@ -0,0 +1,56 @@
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+    "Warning: Deprecated":"Προειδοποίηση: Έχει αποσυρθεί",
+    "Implementation Notes":"Σημειώσεις Υλοποίησης",
+    "Response Class":"Απόκριση",
+    "Status":"Κατάσταση",
+    "Parameters":"Παράμετροι",
+    "Parameter":"Παράμετρος",
+    "Value":"Τιμή",
+    "Description":"Περιγραφή",
+    "Parameter Type":"Τύπος Παραμέτρου",
+    "Data Type":"Τύπος Δεδομένων",
+    "Response Messages":"Μηνύματα Απόκρισης",
+    "HTTP Status Code":"Κωδικός Κατάστασης HTTP",
+    "Reason":"Αιτιολογία",
+    "Response Model":"Μοντέλο Απόκρισης",
+    "Request URL":"URL Αιτήματος",
+    "Response Body":"Σώμα Απόκρισης",
+    "Response Code":"Κωδικός Απόκρισης",
+    "Response Headers":"Επικεφαλίδες Απόκρισης",
+    "Hide Response":"Απόκρυψη Απόκρισης",
+    "Headers":"Επικεφαλίδες",
+    "Try it out!":"Δοκιμάστε το!",
+    "Show/Hide":"Εμφάνιση/Απόκρυψη",
+    "List Operations":"Λίστα Λειτουργιών",
+    "Expand Operations":"Ανάπτυξη Λειτουργιών",
+    "Raw":"Ακατέργαστο",
+    "can't parse JSON.  Raw result":"αδυναμία ανάλυσης JSON.  Ακατέργαστο αποτέλεσμα",
+    "Example Value":"Παράδειγμα Τιμής",
+    "Model Schema":"Σχήμα Μοντέλου",
+    "Model":"Μοντέλο",
+    "Click to set as parameter value":"Πατήστε για να θέσετε τιμή παραμέτρου",
+    "apply":"εφαρμογή",
+    "Username":"Όνομα χρήση",
+    "Password":"Κωδικός πρόσβασης",
+    "Terms of service":"Όροι χρήσης",
+    "Created by":"Δημιουργήθηκε από",
+    "See more at":"Δείτε περισσότερα στο",
+    "Contact the developer":"Επικοινωνήστε με τον προγραμματιστή",
+    "api version":"έκδοση api",
+    "Response Content Type":"Τύπος Περιεχομένου Απόκρισης",
+    "Parameter content type:":"Τύπος περιεχομένου παραμέτρου:",
+    "fetching resource":"παραλαβή πόρου",
+    "fetching resource list":"παραλαβή λίστας πόρων",
+    "Explore":"Εξερεύνηση",
+    "Show Swagger Petstore Example Apis":"Εμφάνιση Api Δειγμάτων Petstore του Swagger",
+    "Can't read from server.  It may not have the appropriate access-control-origin settings.":"Αδυναμία ανάγνωσης από τον εξυπηρετητή.  Μπορεί να μην έχει κατάλληλες ρυθμίσεις για access-control-origin.",
+    "Please specify the protocol for":"Παρακαλώ προσδιορίστε το πρωτόκολλο για",
+    "Can't read swagger JSON from":"Αδυναμία ανάγνωσης swagger JSON από",
+    "Finished Loading Resource Information. Rendering Swagger UI":"Ολοκλήρωση Φόρτωσης Πληροφορικών Πόρου. Παρουσίαση Swagger UI",
+    "Unable to read api":"Αδυναμία ανάγνωσης api",
+    "from path":"από το μονοπάτι",
+    "server returned":"ο εξυπηρετηρής επέστρεψε"
+});
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/en.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/en.js
new file mode 100644 (file)
index 0000000..9183136
--- /dev/null
@@ -0,0 +1,56 @@
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+    "Warning: Deprecated":"Warning: Deprecated",
+    "Implementation Notes":"Implementation Notes",
+    "Response Class":"Response Class",
+    "Status":"Status",
+    "Parameters":"Parameters",
+    "Parameter":"Parameter",
+    "Value":"Value",
+    "Description":"Description",
+    "Parameter Type":"Parameter Type",
+    "Data Type":"Data Type",
+    "Response Messages":"Response Messages",
+    "HTTP Status Code":"HTTP Status Code",
+    "Reason":"Reason",
+    "Response Model":"Response Model",
+    "Request URL":"Request URL",
+    "Response Body":"Response Body",
+    "Response Code":"Response Code",
+    "Response Headers":"Response Headers",
+    "Hide Response":"Hide Response",
+    "Headers":"Headers",
+    "Try it out!":"Try it out!",
+    "Show/Hide":"Show/Hide",
+    "List Operations":"List Operations",
+    "Expand Operations":"Expand Operations",
+    "Raw":"Raw",
+    "can't parse JSON.  Raw result":"can't parse JSON.  Raw result",
+    "Example Value":"Example Value",
+    "Model Schema":"Model Schema",
+    "Model":"Model",
+    "Click to set as parameter value":"Click to set as parameter value",
+    "apply":"apply",
+    "Username":"Username",
+    "Password":"Password",
+    "Terms of service":"Terms of service",
+    "Created by":"Created by",
+    "See more at":"See more at",
+    "Contact the developer":"Contact the developer",
+    "api version":"api version",
+    "Response Content Type":"Response Content Type",
+    "Parameter content type:":"Parameter content type:",
+    "fetching resource":"fetching resource",
+    "fetching resource list":"fetching resource list",
+    "Explore":"Explore",
+    "Show Swagger Petstore Example Apis":"Show Swagger Petstore Example Apis",
+    "Can't read from server.  It may not have the appropriate access-control-origin settings.":"Can't read from server.  It may not have the appropriate access-control-origin settings.",
+    "Please specify the protocol for":"Please specify the protocol for",
+    "Can't read swagger JSON from":"Can't read swagger JSON from",
+    "Finished Loading Resource Information. Rendering Swagger UI":"Finished Loading Resource Information. Rendering Swagger UI",
+    "Unable to read api":"Unable to read api",
+    "from path":"from path",
+    "server returned":"server returned"
+});
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/es.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/es.js
new file mode 100644 (file)
index 0000000..13fa015
--- /dev/null
@@ -0,0 +1,53 @@
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+    "Warning: Deprecated":"Advertencia: Obsoleto",
+    "Implementation Notes":"Notas de implementación",
+    "Response Class":"Clase de la Respuesta",
+    "Status":"Status",
+    "Parameters":"Parámetros",
+    "Parameter":"Parámetro",
+    "Value":"Valor",
+    "Description":"Descripción",
+    "Parameter Type":"Tipo del Parámetro",
+    "Data Type":"Tipo del Dato",
+    "Response Messages":"Mensajes de la Respuesta",
+    "HTTP Status Code":"Código de Status HTTP",
+    "Reason":"Razón",
+    "Response Model":"Modelo de la Respuesta",
+    "Request URL":"URL de la Solicitud",
+    "Response Body":"Cuerpo de la Respuesta",
+    "Response Code":"Código de la Respuesta",
+    "Response Headers":"Encabezados de la Respuesta",
+    "Hide Response":"Ocultar Respuesta",
+    "Try it out!":"Pruébalo!",
+    "Show/Hide":"Mostrar/Ocultar",
+    "List Operations":"Listar Operaciones",
+    "Expand Operations":"Expandir Operaciones",
+    "Raw":"Crudo",
+    "can't parse JSON.  Raw result":"no puede parsear el JSON.  Resultado crudo",
+    "Example Value":"Valor de Ejemplo",
+    "Model Schema":"Esquema del Modelo",
+    "Model":"Modelo",
+    "apply":"aplicar",
+    "Username":"Nombre de usuario",
+    "Password":"Contraseña",
+    "Terms of service":"Términos de Servicio",
+    "Created by":"Creado por",
+    "See more at":"Ver más en",
+    "Contact the developer":"Contactar al desarrollador",
+    "api version":"versión de la api",
+    "Response Content Type":"Tipo de Contenido (Content Type) de la Respuesta",
+    "fetching resource":"buscando recurso",
+    "fetching resource list":"buscando lista del recurso",
+    "Explore":"Explorar",
+    "Show Swagger Petstore Example Apis":"Mostrar Api Ejemplo de Swagger Petstore",
+    "Can't read from server.  It may not have the appropriate access-control-origin settings.":"No se puede leer del servidor. Tal vez no tiene la configuración de control de acceso de origen (access-control-origin) apropiado.",
+    "Please specify the protocol for":"Por favor, especificar el protocola para",
+    "Can't read swagger JSON from":"No se puede leer el JSON de swagger desde",
+    "Finished Loading Resource Information. Rendering Swagger UI":"Finalizada la carga del recurso de Información. Mostrando Swagger UI",
+    "Unable to read api":"No se puede leer la api",
+    "from path":"desde ruta",
+    "server returned":"el servidor retornó"
+});
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/fr.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/fr.js
new file mode 100644 (file)
index 0000000..388dff1
--- /dev/null
@@ -0,0 +1,54 @@
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+    "Warning: Deprecated":"Avertissement : Obsolète",
+    "Implementation Notes":"Notes d'implémentation",
+    "Response Class":"Classe de la réponse",
+    "Status":"Statut",
+    "Parameters":"Paramètres",
+    "Parameter":"Paramètre",
+    "Value":"Valeur",
+    "Description":"Description",
+    "Parameter Type":"Type du paramètre",
+    "Data Type":"Type de données",
+    "Response Messages":"Messages de la réponse",
+    "HTTP Status Code":"Code de statut HTTP",
+    "Reason":"Raison",
+    "Response Model":"Modèle de réponse",
+    "Request URL":"URL appelée",
+    "Response Body":"Corps de la réponse",
+    "Response Code":"Code de la réponse",
+    "Response Headers":"En-têtes de la réponse",
+    "Hide Response":"Cacher la réponse",
+    "Headers":"En-têtes",
+    "Try it out!":"Testez !",
+    "Show/Hide":"Afficher/Masquer",
+    "List Operations":"Liste des opérations",
+    "Expand Operations":"Développer les opérations",
+    "Raw":"Brut",
+    "can't parse JSON.  Raw result":"impossible de décoder le JSON.  Résultat brut",
+    "Example Value":"Exemple la valeur",
+    "Model Schema":"Définition du modèle",
+    "Model":"Modèle",
+    "apply":"appliquer",
+    "Username":"Nom d'utilisateur",
+    "Password":"Mot de passe",
+    "Terms of service":"Conditions de service",
+    "Created by":"Créé par",
+    "See more at":"Voir plus sur",
+    "Contact the developer":"Contacter le développeur",
+    "api version":"version de l'api",
+    "Response Content Type":"Content Type de la réponse",
+    "fetching resource":"récupération de la ressource",
+    "fetching resource list":"récupération de la liste de ressources",
+    "Explore":"Explorer",
+    "Show Swagger Petstore Example Apis":"Montrer les Apis de l'exemple Petstore de Swagger",
+    "Can't read from server.  It may not have the appropriate access-control-origin settings.":"Impossible de lire à partir du serveur. Il se peut que les réglages access-control-origin ne soient pas appropriés.",
+    "Please specify the protocol for":"Veuillez spécifier un protocole pour",
+    "Can't read swagger JSON from":"Impossible de lire le JSON swagger à partir de",
+    "Finished Loading Resource Information. Rendering Swagger UI":"Chargement des informations terminé. Affichage de Swagger UI",
+    "Unable to read api":"Impossible de lire l'api",
+    "from path":"à partir du chemin",
+    "server returned":"réponse du serveur"
+});
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/geo.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/geo.js
new file mode 100644 (file)
index 0000000..609c20d
--- /dev/null
@@ -0,0 +1,56 @@
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+    "Warning: Deprecated":"ყურადღება: აღარ გამოიყენება",
+    "Implementation Notes":"იმპლემენტაციის აღწერა",
+    "Response Class":"რესპონს კლასი",
+    "Status":"სტატუსი",
+    "Parameters":"პარამეტრები",
+    "Parameter":"პარამეტრი",
+    "Value":"მნიშვნელობა",
+    "Description":"აღწერა",
+    "Parameter Type":"პარამეტრის ტიპი",
+    "Data Type":"მონაცემის ტიპი",
+    "Response Messages":"პასუხი",
+    "HTTP Status Code":"HTTP სტატუსი",
+    "Reason":"მიზეზი",
+    "Response Model":"რესპონს მოდელი",
+    "Request URL":"მოთხოვნის URL",
+    "Response Body":"პასუხის სხეული",
+    "Response Code":"პასუხის კოდი",
+    "Response Headers":"პასუხის ჰედერები",
+    "Hide Response":"დამალე პასუხი",
+    "Headers":"ჰედერები",
+    "Try it out!":"ცადე !",
+    "Show/Hide":"გამოჩენა/დამალვა",
+    "List Operations":"ოპერაციების სია",
+    "Expand Operations":"ოპერაციები ვრცლად",
+    "Raw":"ნედლი",
+    "can't parse JSON.  Raw result":"JSON-ის დამუშავება ვერ მოხერხდა.  ნედლი პასუხი",
+    "Example Value":"მაგალითი",
+    "Model Schema":"მოდელის სტრუქტურა",
+    "Model":"მოდელი",
+    "Click to set as parameter value":"პარამეტრისთვის მნიშვნელობის მისანიჭებლად, დააკლიკე",
+    "apply":"გამოყენება",
+    "Username":"მოხმარებელი",
+    "Password":"პაროლი",
+    "Terms of service":"მომსახურების პირობები",
+    "Created by":"შექმნა",
+    "See more at":"ნახე ვრცლად",
+    "Contact the developer":"დაუკავშირდი დეველოპერს",
+    "api version":"api ვერსია",
+    "Response Content Type":"პასუხის კონტენტის ტიპი",
+    "Parameter content type:":"პარამეტრის კონტენტის ტიპი:",
+    "fetching resource":"რესურსების მიღება",
+    "fetching resource list":"რესურსების სიის მიღება",
+    "Explore":"ნახვა",
+    "Show Swagger Petstore Example Apis":"ნახე Swagger Petstore სამაგალითო Api",
+    "Can't read from server.  It may not have the appropriate access-control-origin settings.":"სერვერთან დაკავშირება ვერ ხერხდება.  შეამოწმეთ access-control-origin.",
+    "Please specify the protocol for":"მიუთითეთ პროტოკოლი",
+    "Can't read swagger JSON from":"swagger JSON წაკითხვა ვერ მოხერხდა",
+    "Finished Loading Resource Information. Rendering Swagger UI":"რესურსების ჩატვირთვა სრულდება. Swagger UI რენდერდება",
+    "Unable to read api":"api წაკითხვა ვერ მოხერხდა",
+    "from path":"მისამართიდან",
+    "server returned":"სერვერმა დააბრუნა"
+});
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/it.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/it.js
new file mode 100644 (file)
index 0000000..8529c2a
--- /dev/null
@@ -0,0 +1,52 @@
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+    "Warning: Deprecated":"Attenzione: Deprecato",
+    "Implementation Notes":"Note di implementazione",
+    "Response Class":"Classe della risposta",
+    "Status":"Stato",
+    "Parameters":"Parametri",
+    "Parameter":"Parametro",
+    "Value":"Valore",
+    "Description":"Descrizione",
+    "Parameter Type":"Tipo di parametro",
+    "Data Type":"Tipo di dato",
+    "Response Messages":"Messaggi della risposta",
+    "HTTP Status Code":"Codice stato HTTP",
+    "Reason":"Motivo",
+    "Response Model":"Modello di risposta",
+    "Request URL":"URL della richiesta",
+    "Response Body":"Corpo della risposta",
+    "Response Code":"Oggetto della risposta",
+    "Response Headers":"Intestazioni della risposta",
+    "Hide Response":"Nascondi risposta",
+    "Try it out!":"Provalo!",
+    "Show/Hide":"Mostra/Nascondi",
+    "List Operations":"Mostra operazioni",
+    "Expand Operations":"Espandi operazioni",
+    "Raw":"Grezzo (raw)",
+    "can't parse JSON.  Raw result":"non è possibile parsare il JSON. Risultato grezzo (raw).",
+    "Model Schema":"Schema del modello",
+    "Model":"Modello",
+    "apply":"applica",
+    "Username":"Nome utente",
+    "Password":"Password",
+    "Terms of service":"Condizioni del servizio",
+    "Created by":"Creato da",
+    "See more at":"Informazioni aggiuntive:",
+    "Contact the developer":"Contatta lo sviluppatore",
+    "api version":"versione api",
+    "Response Content Type":"Tipo di contenuto (content type) della risposta",
+    "fetching resource":"recuperando la risorsa",
+    "fetching resource list":"recuperando lista risorse",
+    "Explore":"Esplora",
+    "Show Swagger Petstore Example Apis":"Mostra le api di esempio di Swagger Petstore",
+    "Can't read from server.  It may not have the appropriate access-control-origin settings.":"Non è possibile leggere dal server. Potrebbe non avere le impostazioni di controllo accesso origine (access-control-origin) appropriate.",
+    "Please specify the protocol for":"Si prega di specificare il protocollo per",
+    "Can't read swagger JSON from":"Impossibile leggere JSON swagger da:",
+    "Finished Loading Resource Information. Rendering Swagger UI":"Lettura informazioni risorse termianta. Swagger UI viene mostrata",
+    "Unable to read api":"Impossibile leggere la api",
+    "from path":"da cartella",
+    "server returned":"il server ha restituito"
+});
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/ja.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/ja.js
new file mode 100644 (file)
index 0000000..1cbeb37
--- /dev/null
@@ -0,0 +1,56 @@
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+    "Warning: Deprecated":"警告: 廃止予定",
+    "Implementation Notes":"実装メモ",
+    "Response Class":"レスポンスクラス",
+    "Status":"ステータス",
+    "Parameters":"パラメータ群",
+    "Parameter":"パラメータ",
+    "Value":"値",
+    "Description":"説明",
+    "Parameter Type":"パラメータタイプ",
+    "Data Type":"データタイプ",
+    "Response Messages":"レスポンスメッセージ",
+    "HTTP Status Code":"HTTPステータスコード",
+    "Reason":"理由",
+    "Response Model":"レスポンスモデル",
+    "Request URL":"リクエストURL",
+    "Response Body":"レスポンスボディ",
+    "Response Code":"レスポンスコード",
+    "Response Headers":"レスポンスヘッダ",
+    "Hide Response":"レスポンスを隠す",
+    "Headers":"ヘッダ",
+    "Try it out!":"実際に実行!",
+    "Show/Hide":"表示/非表示",
+    "List Operations":"操作一覧",
+    "Expand Operations":"操作の展開",
+    "Raw":"未加工",
+    "can't parse JSON.  Raw result":"JSONへ解釈できません.  未加工の結果",
+    "Example Value":"値の例",
+    "Model Schema":"モデルスキーマ",
+    "Model":"モデル",
+    "Click to set as parameter value":"パラメータ値と設定するにはクリック",
+    "apply":"実行",
+    "Username":"ユーザ名",
+    "Password":"パスワード",
+    "Terms of service":"サービス利用規約",
+    "Created by":"Created by",
+    "See more at":"詳細を見る",
+    "Contact the developer":"開発者に連絡",
+    "api version":"APIバージョン",
+    "Response Content Type":"レスポンス コンテンツタイプ",
+    "Parameter content type:":"パラメータコンテンツタイプ:",
+    "fetching resource":"リソースの取得",
+    "fetching resource list":"リソース一覧の取得",
+    "Explore":"調査",
+    "Show Swagger Petstore Example Apis":"SwaggerペットストアAPIの表示",
+    "Can't read from server.  It may not have the appropriate access-control-origin settings.":"サーバから読み込めません.  適切なaccess-control-origin設定を持っていない可能性があります.",
+    "Please specify the protocol for":"プロトコルを指定してください",
+    "Can't read swagger JSON from":"次からswagger JSONを読み込めません",
+    "Finished Loading Resource Information. Rendering Swagger UI":"リソース情報の読み込みが完了しました. Swagger UIを描画しています",
+    "Unable to read api":"APIを読み込めません",
+    "from path":"次のパスから",
+    "server returned":"サーバからの返答"
+});
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/ko-kr.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/ko-kr.js
new file mode 100644 (file)
index 0000000..03c7626
--- /dev/null
@@ -0,0 +1,53 @@
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+    "Warning: Deprecated":"경고:폐기예정됨",
+    "Implementation Notes":"구현 노트",
+    "Response Class":"응답 클래스",
+    "Status":"상태",
+    "Parameters":"매개변수들",
+    "Parameter":"매개변수",
+    "Value":"값",
+    "Description":"설명",
+    "Parameter Type":"매개변수 타입",
+    "Data Type":"데이터 타입",
+    "Response Messages":"응답 메세지",
+    "HTTP Status Code":"HTTP 상태 코드",
+    "Reason":"원인",
+    "Response Model":"응답 모델",
+    "Request URL":"요청 URL",
+    "Response Body":"응답 본문",
+    "Response Code":"응답 코드",
+    "Response Headers":"응답 헤더",
+    "Hide Response":"응답 숨기기",
+    "Headers":"헤더",
+    "Try it out!":"써보기!",
+    "Show/Hide":"보이기/숨기기",
+    "List Operations":"목록 작업",
+    "Expand Operations":"전개 작업",
+    "Raw":"원본",
+    "can't parse JSON.  Raw result":"JSON을 파싱할수 없음. 원본결과:",
+    "Model Schema":"모델 스키마",
+    "Model":"모델",
+    "apply":"적용",
+    "Username":"사용자 이름",
+    "Password":"암호",
+    "Terms of service":"이용약관",
+    "Created by":"작성자",
+    "See more at":"추가정보:",
+    "Contact the developer":"개발자에게 문의",
+    "api version":"api버전",
+    "Response Content Type":"응답Content Type",
+    "fetching resource":"리소스 가져오기",
+    "fetching resource list":"리소스 목록 가져오기",
+    "Explore":"탐색",
+    "Show Swagger Petstore Example Apis":"Swagger Petstore 예제 보기",
+    "Can't read from server.  It may not have the appropriate access-control-origin settings.":"서버로부터 읽어들일수 없습니다. access-control-origin 설정이 올바르지 않을수 있습니다.",
+    "Please specify the protocol for":"다음을 위한 프로토콜을 정하세요",
+    "Can't read swagger JSON from":"swagger JSON 을 다음으로 부터 읽을수 없습니다",
+    "Finished Loading Resource Information. Rendering Swagger UI":"리소스 정보 불러오기 완료. Swagger UI 랜더링",
+    "Unable to read api":"api를 읽을 수 없습니다.",
+    "from path":"다음 경로로 부터",
+    "server returned":"서버 응답함."
+});
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/pl.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/pl.js
new file mode 100644 (file)
index 0000000..ce41e91
--- /dev/null
@@ -0,0 +1,53 @@
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+    "Warning: Deprecated":"Uwaga: Wycofane",
+    "Implementation Notes":"Uwagi Implementacji",
+    "Response Class":"Klasa Odpowiedzi",
+    "Status":"Status",
+    "Parameters":"Parametry",
+    "Parameter":"Parametr",
+    "Value":"Wartość",
+    "Description":"Opis",
+    "Parameter Type":"Typ Parametru",
+    "Data Type":"Typ Danych",
+    "Response Messages":"Wiadomości Odpowiedzi",
+    "HTTP Status Code":"Kod Statusu HTTP",
+    "Reason":"Przyczyna",
+    "Response Model":"Model Odpowiedzi",
+    "Request URL":"URL Wywołania",
+    "Response Body":"Treść Odpowiedzi",
+    "Response Code":"Kod Odpowiedzi",
+    "Response Headers":"Nagłówki Odpowiedzi",
+    "Hide Response":"Ukryj Odpowiedź",
+    "Headers":"Nagłówki",
+    "Try it out!":"Wypróbuj!",
+    "Show/Hide":"Pokaż/Ukryj",
+    "List Operations":"Lista Operacji",
+    "Expand Operations":"Rozwiń Operacje",
+    "Raw":"Nieprzetworzone",
+    "can't parse JSON.  Raw result":"nie można przetworzyć pliku JSON.  Nieprzetworzone dane",
+    "Model Schema":"Schemat Modelu",
+    "Model":"Model",
+    "apply":"użyj",
+    "Username":"Nazwa użytkownika",
+    "Password":"Hasło",
+    "Terms of service":"Warunki używania",
+    "Created by":"Utworzone przez",
+    "See more at":"Zobacz więcej na",
+    "Contact the developer":"Kontakt z deweloperem",
+    "api version":"wersja api",
+    "Response Content Type":"Typ Zasobu Odpowiedzi",
+    "fetching resource":"ładowanie zasobu",
+    "fetching resource list":"ładowanie listy zasobów",
+    "Explore":"Eksploruj",
+    "Show Swagger Petstore Example Apis":"Pokaż Przykładowe Api Swagger Petstore",
+    "Can't read from server.  It may not have the appropriate access-control-origin settings.":"Brak połączenia z serwerem. Może on nie mieć odpowiednich ustawień access-control-origin.",
+    "Please specify the protocol for":"Proszę podać protokół dla",
+    "Can't read swagger JSON from":"Nie można odczytać swagger JSON z",
+    "Finished Loading Resource Information. Rendering Swagger UI":"Ukończono Ładowanie Informacji o Zasobie. Renderowanie Swagger UI",
+    "Unable to read api":"Nie można odczytać api",
+    "from path":"ze ścieżki",
+    "server returned":"serwer zwrócił"
+});
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/pt.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/pt.js
new file mode 100644 (file)
index 0000000..f2e7c13
--- /dev/null
@@ -0,0 +1,53 @@
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+    "Warning: Deprecated":"Aviso: Depreciado",
+    "Implementation Notes":"Notas de Implementação",
+    "Response Class":"Classe de resposta",
+    "Status":"Status",
+    "Parameters":"Parâmetros",
+    "Parameter":"Parâmetro",
+    "Value":"Valor",
+    "Description":"Descrição",
+    "Parameter Type":"Tipo de parâmetro",
+    "Data Type":"Tipo de dados",
+    "Response Messages":"Mensagens de resposta",
+    "HTTP Status Code":"Código de status HTTP",
+    "Reason":"Razão",
+    "Response Model":"Modelo resposta",
+    "Request URL":"URL requisição",
+    "Response Body":"Corpo da resposta",
+    "Response Code":"Código da resposta",
+    "Response Headers":"Cabeçalho da resposta",
+    "Headers":"Cabeçalhos",
+    "Hide Response":"Esconder resposta",
+    "Try it out!":"Tente agora!",
+    "Show/Hide":"Mostrar/Esconder",
+    "List Operations":"Listar operações",
+    "Expand Operations":"Expandir operações",
+    "Raw":"Cru",
+    "can't parse JSON.  Raw result":"Falha ao analisar JSON.  Resulto cru",
+    "Model Schema":"Modelo esquema",
+    "Model":"Modelo",
+    "apply":"Aplicar",
+    "Username":"Usuário",
+    "Password":"Senha",
+    "Terms of service":"Termos do serviço",
+    "Created by":"Criado por",
+    "See more at":"Veja mais em",
+    "Contact the developer":"Contate o desenvolvedor",
+    "api version":"Versão api",
+    "Response Content Type":"Tipo de conteúdo da resposta",
+    "fetching resource":"busca recurso",
+    "fetching resource list":"buscando lista de recursos",
+    "Explore":"Explorar",
+    "Show Swagger Petstore Example Apis":"Show Swagger Petstore Example Apis",
+    "Can't read from server.  It may not have the appropriate access-control-origin settings.":"Não é possível ler do servidor. Pode não ter as apropriadas configurações access-control-origin",
+    "Please specify the protocol for":"Por favor especifique o protocolo",
+    "Can't read swagger JSON from":"Não é possível ler o JSON Swagger de",
+    "Finished Loading Resource Information. Rendering Swagger UI":"Carregar informação de recurso finalizada. Renderizando Swagger UI",
+    "Unable to read api":"Não foi possível ler api",
+    "from path":"do caminho",
+    "server returned":"servidor retornou"
+});
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/ru.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/ru.js
new file mode 100644 (file)
index 0000000..592744e
--- /dev/null
@@ -0,0 +1,56 @@
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+    "Warning: Deprecated":"Предупреждение: Устарело",
+    "Implementation Notes":"Заметки",
+    "Response Class":"Пример ответа",
+    "Status":"Статус",
+    "Parameters":"Параметры",
+    "Parameter":"Параметр",
+    "Value":"Значение",
+    "Description":"Описание",
+    "Parameter Type":"Тип параметра",
+    "Data Type":"Тип данных",
+    "HTTP Status Code":"HTTP код",
+    "Reason":"Причина",
+    "Response Model":"Структура ответа",
+    "Request URL":"URL запроса",
+    "Response Body":"Тело ответа",
+    "Response Code":"HTTP код ответа",
+    "Response Headers":"Заголовки ответа",
+    "Hide Response":"Спрятать ответ",
+    "Headers":"Заголовки",
+    "Response Messages":"Что может прийти в ответ",
+    "Try it out!":"Попробовать!",
+    "Show/Hide":"Показать/Скрыть",
+    "List Operations":"Операции кратко",
+    "Expand Operations":"Операции подробно",
+    "Raw":"В сыром виде",
+    "can't parse JSON.  Raw result":"Не удается распарсить ответ:",
+    "Example Value":"Пример",
+    "Model Schema":"Структура",
+    "Model":"Описание",
+    "Click to set as parameter value":"Нажмите, чтобы испльзовать в качестве значения параметра",
+    "apply":"применить",
+    "Username":"Имя пользователя",
+    "Password":"Пароль",
+    "Terms of service":"Условия использования",
+    "Created by":"Разработано",
+    "See more at":"Еще тут",
+    "Contact the developer":"Связаться с разработчиком",
+    "api version":"Версия API",
+    "Response Content Type":"Content Type ответа",
+    "Parameter content type:":"Content Type параметра:",
+    "fetching resource":"Получение ресурса",
+    "fetching resource list":"Получение ресурсов",
+    "Explore":"Показать",
+    "Show Swagger Petstore Example Apis":"Показать примеры АПИ",
+    "Can't read from server. It may not have the appropriate access-control-origin settings.":"Не удается получить ответ от сервера. Возможно, проблема с настройками доступа",
+    "Please specify the protocol for":"Пожалуйста, укажите протокол для",
+    "Can't read swagger JSON from":"Не получается прочитать swagger json из",
+    "Finished Loading Resource Information. Rendering Swagger UI":"Загрузка информации о ресурсах завершена. Рендерим",
+    "Unable to read api":"Не удалось прочитать api",
+    "from path":"по адресу",
+    "server returned":"сервер сказал"
+});
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/tr.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/tr.js
new file mode 100644 (file)
index 0000000..16426a9
--- /dev/null
@@ -0,0 +1,53 @@
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+    "Warning: Deprecated":"Uyarı: Deprecated",
+    "Implementation Notes":"Gerçekleştirim Notları",
+    "Response Class":"Dönen Sınıf",
+    "Status":"Statü",
+    "Parameters":"Parametreler",
+    "Parameter":"Parametre",
+    "Value":"Değer",
+    "Description":"Açıklama",
+    "Parameter Type":"Parametre Tipi",
+    "Data Type":"Veri Tipi",
+    "Response Messages":"Dönüş Mesajı",
+    "HTTP Status Code":"HTTP Statü Kodu",
+    "Reason":"Gerekçe",
+    "Response Model":"Dönüş Modeli",
+    "Request URL":"İstek URL",
+    "Response Body":"Dönüş İçeriği",
+    "Response Code":"Dönüş Kodu",
+    "Response Headers":"Dönüş Üst Bilgileri",
+    "Hide Response":"Dönüşü Gizle",
+    "Headers":"Üst Bilgiler",
+    "Try it out!":"Dene!",
+    "Show/Hide":"Göster/Gizle",
+    "List Operations":"Operasyonları Listele",
+    "Expand Operations":"Operasyonları Aç",
+    "Raw":"Ham",
+    "can't parse JSON.  Raw result":"JSON çözümlenemiyor.  Ham sonuç",
+    "Model Schema":"Model Şema",
+    "Model":"Model",
+    "apply":"uygula",
+    "Username":"Kullanıcı Adı",
+    "Password":"Parola",
+    "Terms of service":"Servis şartları",
+    "Created by":"Oluşturan",
+    "See more at":"Daha fazlası için",
+    "Contact the developer":"Geliştirici ile İletişime Geçin",
+    "api version":"api versiyon",
+    "Response Content Type":"Dönüş İçerik Tipi",
+    "fetching resource":"kaynak getiriliyor",
+    "fetching resource list":"kaynak listesi getiriliyor",
+    "Explore":"Keşfet",
+    "Show Swagger Petstore Example Apis":"Swagger Petstore Örnek Api'yi Gör",
+    "Can't read from server.  It may not have the appropriate access-control-origin settings.":"Sunucudan okuma yapılamıyor. Sunucu access-control-origin ayarlarınızı kontrol edin.",
+    "Please specify the protocol for":"Lütfen istenen adres için protokol belirtiniz",
+    "Can't read swagger JSON from":"Swagger JSON bu kaynaktan okunamıyor",
+    "Finished Loading Resource Information. Rendering Swagger UI":"Kaynak baglantısı tamamlandı. Swagger UI gösterime hazırlanıyor",
+    "Unable to read api":"api okunamadı",
+    "from path":"yoldan",
+    "server returned":"sunucuya dönüldü"
+});
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/translator.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/translator.js
new file mode 100644 (file)
index 0000000..ffb879f
--- /dev/null
@@ -0,0 +1,39 @@
+'use strict';
+
+/**
+ * Translator for documentation pages.
+ *
+ * To enable translation you should include one of language-files in your index.html
+ * after <script src='lang/translator.js' type='text/javascript'></script>.
+ * For example - <script src='lang/ru.js' type='text/javascript'></script>
+ *
+ * If you wish to translate some new texts you should do two things:
+ * 1. Add a new phrase pair ("New Phrase": "New Translation") into your language file (for example lang/ru.js). It will be great if you add it in other language files too.
+ * 2. Mark that text it templates this way <anyHtmlTag data-sw-translate>New Phrase</anyHtmlTag> or <anyHtmlTag data-sw-translate value='New Phrase'/>.
+ * The main thing here is attribute data-sw-translate. Only inner html, title-attribute and value-attribute are going to translate.
+ *
+ */
+window.SwaggerTranslator = {
+
+    _words:[],
+
+    translate: function(sel) {
+      var $this = this;
+      sel = sel || '[data-sw-translate]';
+
+      $(sel).each(function() {
+        $(this).html($this._tryTranslate($(this).html()));
+
+        $(this).val($this._tryTranslate($(this).val()));
+        $(this).attr('title', $this._tryTranslate($(this).attr('title')));
+      });
+    },
+
+    _tryTranslate: function(word) {
+      return this._words[$.trim(word)] !== undefined ? this._words[$.trim(word)] : word;
+    },
+
+    learn: function(wordsMap) {
+      this._words = wordsMap;
+    }
+};
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/zh-cn.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lang/zh-cn.js
new file mode 100644 (file)
index 0000000..3af61ad
--- /dev/null
@@ -0,0 +1,56 @@
+'use strict';
+
+/* jshint quotmark: double */
+window.SwaggerTranslator.learn({
+    "Warning: Deprecated":"警告:已过时",
+    "Implementation Notes":"实现备注",
+    "Response Class":"响应类",
+    "Status":"状态",
+    "Parameters":"参数",
+    "Parameter":"参数",
+    "Value":"值",
+    "Description":"描述",
+    "Parameter Type":"参数类型",
+    "Data Type":"数据类型",
+    "Response Messages":"响应消息",
+    "HTTP Status Code":"HTTP状态码",
+    "Reason":"原因",
+    "Response Model":"响应模型",
+    "Request URL":"请求URL",
+    "Response Body":"响应体",
+    "Response Code":"响应码",
+    "Response Headers":"响应头",
+    "Hide Response":"隐藏响应",
+    "Headers":"头",
+    "Try it out!":"试一下!",
+    "Show/Hide":"显示/隐藏",
+    "List Operations":"显示操作",
+    "Expand Operations":"展开操作",
+    "Raw":"原始",
+    "can't parse JSON.  Raw result":"无法解析JSON. 原始结果",
+    "Example Value":"示例",
+    "Click to set as parameter value":"点击设置参数",
+    "Model Schema":"模型架构",
+    "Model":"模型",
+    "apply":"应用",
+    "Username":"用户名",
+    "Password":"密码",
+    "Terms of service":"服务条款",
+    "Created by":"创建者",
+    "See more at":"查看更多:",
+    "Contact the developer":"联系开发者",
+    "api version":"api版本",
+    "Response Content Type":"响应Content Type",
+    "Parameter content type:":"参数类型:",
+    "fetching resource":"正在获取资源",
+    "fetching resource list":"正在获取资源列表",
+    "Explore":"浏览",
+    "Show Swagger Petstore Example Apis":"显示 Swagger Petstore 示例 Apis",
+    "Can't read from server.  It may not have the appropriate access-control-origin settings.":"无法从服务器读取。可能没有正确设置access-control-origin。",
+    "Please specify the protocol for":"请指定协议:",
+    "Can't read swagger JSON from":"无法读取swagger JSON于",
+    "Finished Loading Resource Information. Rendering Swagger UI":"已加载资源信息。正在渲染Swagger UI",
+    "Unable to read api":"无法读取api",
+    "from path":"从路径",
+    "server returned":"服务器返回"
+});
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/backbone-min.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/backbone-min.js
new file mode 100644 (file)
index 0000000..8eff02e
--- /dev/null
@@ -0,0 +1 @@
+!function(t,e){if("function"==typeof define&&define.amd)define(["underscore","jquery","exports"],function(i,n,s){t.Backbone=e(t,s,i,n)});else if("undefined"!=typeof exports){var i=require("underscore");e(t,exports,i)}else t.Backbone=e(t,{},t._,t.jQuery||t.Zepto||t.ender||t.$)}(this,function(t,e,i,n){var s=t.Backbone,r=[],a=(r.push,r.slice);r.splice;e.VERSION="1.1.2",e.$=n,e.noConflict=function(){return t.Backbone=s,this},e.emulateHTTP=!1,e.emulateJSON=!1;var o=e.Events={on:function(t,e,i){if(!c(this,"on",t,[e,i])||!e)return this;this._events||(this._events={});var n=this._events[t]||(this._events[t]=[]);return n.push({callback:e,context:i,ctx:i||this}),this},once:function(t,e,n){if(!c(this,"once",t,[e,n])||!e)return this;var s=this,r=i.once(function(){s.off(t,r),e.apply(this,arguments)});return r._callback=e,this.on(t,r,n)},off:function(t,e,n){var s,r,a,o,h,u,l,d;if(!this._events||!c(this,"off",t,[e,n]))return this;if(!t&&!e&&!n)return this._events=void 0,this;for(o=t?[t]:i.keys(this._events),h=0,u=o.length;h<u;h++)if(t=o[h],a=this._events[t]){if(this._events[t]=s=[],e||n)for(l=0,d=a.length;l<d;l++)r=a[l],(e&&e!==r.callback&&e!==r.callback._callback||n&&n!==r.context)&&s.push(r);s.length||delete this._events[t]}return this},trigger:function(t){if(!this._events)return this;var e=a.call(arguments,1);if(!c(this,"trigger",t,e))return this;var i=this._events[t],n=this._events.all;return i&&u(i,e),n&&u(n,arguments),this},stopListening:function(t,e,n){var s=this._listeningTo;if(!s)return this;var r=!e&&!n;n||"object"!=typeof e||(n=this),t&&((s={})[t._listenId]=t);for(var a in s)t=s[a],t.off(e,n,this),(r||i.isEmpty(t._events))&&delete this._listeningTo[a];return this}},h=/\s+/,c=function(t,e,i,n){if(!i)return!0;if("object"==typeof i){for(var s in i)t[e].apply(t,[s,i[s]].concat(n));return!1}if(h.test(i)){for(var r=i.split(h),a=0,o=r.length;a<o;a++)t[e].apply(t,[r[a]].concat(n));return!1}return!0},u=function(t,e){var i,n=-1,s=t.length,r=e[0],a=e[1],o=e[2];switch(e.length){case 0:for(;++n<s;)(i=t[n]).callback.call(i.ctx);return;case 1:for(;++n<s;)(i=t[n]).callback.call(i.ctx,r);return;case 2:for(;++n<s;)(i=t[n]).callback.call(i.ctx,r,a);return;case 3:for(;++n<s;)(i=t[n]).callback.call(i.ctx,r,a,o);return;default:for(;++n<s;)(i=t[n]).callback.apply(i.ctx,e);return}},l={listenTo:"on",listenToOnce:"once"};i.each(l,function(t,e){o[e]=function(e,n,s){var r=this._listeningTo||(this._listeningTo={}),a=e._listenId||(e._listenId=i.uniqueId("l"));return r[a]=e,s||"object"!=typeof n||(s=this),e[t](n,s,this),this}}),o.bind=o.on,o.unbind=o.off,i.extend(e,o);var d=e.Model=function(t,e){var n=t||{};e||(e={}),this.cid=i.uniqueId("c"),this.attributes={},e.collection&&(this.collection=e.collection),e.parse&&(n=this.parse(n,e)||{}),n=i.defaults({},n,i.result(this,"defaults")),this.set(n,e),this.changed={},this.initialize.apply(this,arguments)};i.extend(d.prototype,o,{changed:null,validationError:null,idAttribute:"id",initialize:function(){},toJSON:function(t){return i.clone(this.attributes)},sync:function(){return e.sync.apply(this,arguments)},get:function(t){return this.attributes[t]},escape:function(t){return i.escape(this.get(t))},has:function(t){return null!=this.get(t)},set:function(t,e,n){var s,r,a,o,h,c,u,l;if(null==t)return this;if("object"==typeof t?(r=t,n=e):(r={})[t]=e,n||(n={}),!this._validate(r,n))return!1;a=n.unset,h=n.silent,o=[],c=this._changing,this._changing=!0,c||(this._previousAttributes=i.clone(this.attributes),this.changed={}),l=this.attributes,u=this._previousAttributes,this.idAttribute in r&&(this.id=r[this.idAttribute]);for(s in r)e=r[s],i.isEqual(l[s],e)||o.push(s),i.isEqual(u[s],e)?delete this.changed[s]:this.changed[s]=e,a?delete l[s]:l[s]=e;if(!h){o.length&&(this._pending=n);for(var d=0,f=o.length;d<f;d++)this.trigger("change:"+o[d],this,l[o[d]],n)}if(c)return this;if(!h)for(;this._pending;)n=this._pending,this._pending=!1,this.trigger("change",this,n);return this._pending=!1,this._changing=!1,this},unset:function(t,e){return this.set(t,void 0,i.extend({},e,{unset:!0}))},clear:function(t){var e={};for(var n in this.attributes)e[n]=void 0;return this.set(e,i.extend({},t,{unset:!0}))},hasChanged:function(t){return null==t?!i.isEmpty(this.changed):i.has(this.changed,t)},changedAttributes:function(t){if(!t)return!!this.hasChanged()&&i.clone(this.changed);var e,n=!1,s=this._changing?this._previousAttributes:this.attributes;for(var r in t)i.isEqual(s[r],e=t[r])||((n||(n={}))[r]=e);return n},previous:function(t){return null!=t&&this._previousAttributes?this._previousAttributes[t]:null},previousAttributes:function(){return i.clone(this._previousAttributes)},fetch:function(t){t=t?i.clone(t):{},void 0===t.parse&&(t.parse=!0);var e=this,n=t.success;return t.success=function(i){return!!e.set(e.parse(i,t),t)&&(n&&n(e,i,t),void e.trigger("sync",e,i,t))},U(this,t),this.sync("read",this,t)},save:function(t,e,n){var s,r,a,o=this.attributes;if(null==t||"object"==typeof t?(s=t,n=e):(s={})[t]=e,n=i.extend({validate:!0},n),s&&!n.wait){if(!this.set(s,n))return!1}else if(!this._validate(s,n))return!1;s&&n.wait&&(this.attributes=i.extend({},o,s)),void 0===n.parse&&(n.parse=!0);var h=this,c=n.success;return n.success=function(t){h.attributes=o;var e=h.parse(t,n);return n.wait&&(e=i.extend(s||{},e)),!(i.isObject(e)&&!h.set(e,n))&&(c&&c(h,t,n),void h.trigger("sync",h,t,n))},U(this,n),r=this.isNew()?"create":n.patch?"patch":"update","patch"===r&&(n.attrs=s),a=this.sync(r,this,n),s&&n.wait&&(this.attributes=o),a},destroy:function(t){t=t?i.clone(t):{};var e=this,n=t.success,s=function(){e.trigger("destroy",e,e.collection,t)};if(t.success=function(i){(t.wait||e.isNew())&&s(),n&&n(e,i,t),e.isNew()||e.trigger("sync",e,i,t)},this.isNew())return t.success(),!1;U(this,t);var r=this.sync("delete",this,t);return t.wait||s(),r},url:function(){var t=i.result(this,"urlRoot")||i.result(this.collection,"url")||j();return this.isNew()?t:t.replace(/([^\/])$/,"$1/")+encodeURIComponent(this.id)},parse:function(t,e){return t},clone:function(){return new this.constructor(this.attributes)},isNew:function(){return!this.has(this.idAttribute)},isValid:function(t){return this._validate({},i.extend(t||{},{validate:!0}))},_validate:function(t,e){if(!e.validate||!this.validate)return!0;t=i.extend({},this.attributes,t);var n=this.validationError=this.validate(t,e)||null;return!n||(this.trigger("invalid",this,n,i.extend(e,{validationError:n})),!1)}});var f=["keys","values","pairs","invert","pick","omit"];i.each(f,function(t){d.prototype[t]=function(){var e=a.call(arguments);return e.unshift(this.attributes),i[t].apply(i,e)}});var p=e.Collection=function(t,e){e||(e={}),e.model&&(this.model=e.model),void 0!==e.comparator&&(this.comparator=e.comparator),this._reset(),this.initialize.apply(this,arguments),t&&this.reset(t,i.extend({silent:!0},e))},g={add:!0,remove:!0,merge:!0},v={add:!0,remove:!1};i.extend(p.prototype,o,{model:d,initialize:function(){},toJSON:function(t){return this.map(function(e){return e.toJSON(t)})},sync:function(){return e.sync.apply(this,arguments)},add:function(t,e){return this.set(t,i.extend({merge:!1},e,v))},remove:function(t,e){var n=!i.isArray(t);t=n?[t]:i.clone(t),e||(e={});var s,r,a,o;for(s=0,r=t.length;s<r;s++)o=t[s]=this.get(t[s]),o&&(delete this._byId[o.id],delete this._byId[o.cid],a=this.indexOf(o),this.models.splice(a,1),this.length--,e.silent||(e.index=a,o.trigger("remove",o,this,e)),this._removeReference(o,e));return n?t[0]:t},set:function(t,e){e=i.defaults({},e,g),e.parse&&(t=this.parse(t,e));var n=!i.isArray(t);t=n?t?[t]:[]:i.clone(t);var s,r,a,o,h,c,u,l=e.at,f=this.model,p=this.comparator&&null==l&&e.sort!==!1,v=i.isString(this.comparator)?this.comparator:null,m=[],y=[],_={},b=e.add,w=e.merge,x=e.remove,E=!(p||!b||!x)&&[];for(s=0,r=t.length;s<r;s++){if(h=t[s]||{},a=h instanceof d?o=h:h[f.prototype.idAttribute||"id"],c=this.get(a))x&&(_[c.cid]=!0),w&&(h=h===o?o.attributes:h,e.parse&&(h=c.parse(h,e)),c.set(h,e),p&&!u&&c.hasChanged(v)&&(u=!0)),t[s]=c;else if(b){if(o=t[s]=this._prepareModel(h,e),!o)continue;m.push(o),this._addReference(o,e)}o=c||o,!E||!o.isNew()&&_[o.id]||E.push(o),_[o.id]=!0}if(x){for(s=0,r=this.length;s<r;++s)_[(o=this.models[s]).cid]||y.push(o);y.length&&this.remove(y,e)}if(m.length||E&&E.length)if(p&&(u=!0),this.length+=m.length,null!=l)for(s=0,r=m.length;s<r;s++)this.models.splice(l+s,0,m[s]);else{E&&(this.models.length=0);var k=E||m;for(s=0,r=k.length;s<r;s++)this.models.push(k[s])}if(u&&this.sort({silent:!0}),!e.silent){for(s=0,r=m.length;s<r;s++)(o=m[s]).trigger("add",o,this,e);(u||E&&E.length)&&this.trigger("sort",this,e)}return n?t[0]:t},reset:function(t,e){e||(e={});for(var n=0,s=this.models.length;n<s;n++)this._removeReference(this.models[n],e);return e.previousModels=this.models,this._reset(),t=this.add(t,i.extend({silent:!0},e)),e.silent||this.trigger("reset",this,e),t},push:function(t,e){return this.add(t,i.extend({at:this.length},e))},pop:function(t){var e=this.at(this.length-1);return this.remove(e,t),e},unshift:function(t,e){return this.add(t,i.extend({at:0},e))},shift:function(t){var e=this.at(0);return this.remove(e,t),e},slice:function(){return a.apply(this.models,arguments)},get:function(t){if(null!=t)return this._byId[t]||this._byId[t.id]||this._byId[t.cid]},at:function(t){return this.models[t]},where:function(t,e){return i.isEmpty(t)?e?void 0:[]:this[e?"find":"filter"](function(e){for(var i in t)if(t[i]!==e.get(i))return!1;return!0})},findWhere:function(t){return this.where(t,!0)},sort:function(t){if(!this.comparator)throw new Error("Cannot sort a set without a comparator");return t||(t={}),i.isString(this.comparator)||1===this.comparator.length?this.models=this.sortBy(this.comparator,this):this.models.sort(i.bind(this.comparator,this)),t.silent||this.trigger("sort",this,t),this},pluck:function(t){return i.invoke(this.models,"get",t)},fetch:function(t){t=t?i.clone(t):{},void 0===t.parse&&(t.parse=!0);var e=t.success,n=this;return t.success=function(i){var s=t.reset?"reset":"set";n[s](i,t),e&&e(n,i,t),n.trigger("sync",n,i,t)},U(this,t),this.sync("read",this,t)},create:function(t,e){if(e=e?i.clone(e):{},!(t=this._prepareModel(t,e)))return!1;e.wait||this.add(t,e);var n=this,s=e.success;return e.success=function(t,i){e.wait&&n.add(t,e),s&&s(t,i,e)},t.save(null,e),t},parse:function(t,e){return t},clone:function(){return new this.constructor(this.models)},_reset:function(){this.length=0,this.models=[],this._byId={}},_prepareModel:function(t,e){if(t instanceof d)return t;e=e?i.clone(e):{},e.collection=this;var n=new this.model(t,e);return n.validationError?(this.trigger("invalid",this,n.validationError,e),!1):n},_addReference:function(t,e){this._byId[t.cid]=t,null!=t.id&&(this._byId[t.id]=t),t.collection||(t.collection=this),t.on("all",this._onModelEvent,this)},_removeReference:function(t,e){this===t.collection&&delete t.collection,t.off("all",this._onModelEvent,this)},_onModelEvent:function(t,e,i,n){("add"!==t&&"remove"!==t||i===this)&&("destroy"===t&&this.remove(e,n),e&&t==="change:"+e.idAttribute&&(delete this._byId[e.previous(e.idAttribute)],null!=e.id&&(this._byId[e.id]=e)),this.trigger.apply(this,arguments))}});var m=["forEach","each","map","collect","reduce","foldl","inject","reduceRight","foldr","find","detect","filter","select","reject","every","all","some","any","include","contains","invoke","max","min","toArray","size","first","head","take","initial","rest","tail","drop","last","without","difference","indexOf","shuffle","lastIndexOf","isEmpty","chain","sample"];i.each(m,function(t){p.prototype[t]=function(){var e=a.call(arguments);return e.unshift(this.models),i[t].apply(i,e)}});var y=["groupBy","countBy","sortBy","indexBy"];i.each(y,function(t){p.prototype[t]=function(e,n){var s=i.isFunction(e)?e:function(t){return t.get(e)};return i[t](this.models,s,n)}});var _=e.View=function(t){this.cid=i.uniqueId("view"),t||(t={}),i.extend(this,i.pick(t,w)),this._ensureElement(),this.initialize.apply(this,arguments),this.delegateEvents()},b=/^(\S+)\s*(.*)$/,w=["model","collection","el","id","attributes","className","tagName","events"];i.extend(_.prototype,o,{tagName:"div",$:function(t){return this.$el.find(t)},initialize:function(){},render:function(){return this},remove:function(){return this.$el.remove(),this.stopListening(),this},setElement:function(t,i){return this.$el&&this.undelegateEvents(),this.$el=t instanceof e.$?t:e.$(t),this.el=this.$el[0],i!==!1&&this.delegateEvents(),this},delegateEvents:function(t){if(!t&&!(t=i.result(this,"events")))return this;this.undelegateEvents();for(var e in t){var n=t[e];if(i.isFunction(n)||(n=this[t[e]]),n){var s=e.match(b),r=s[1],a=s[2];n=i.bind(n,this),r+=".delegateEvents"+this.cid,""===a?this.$el.on(r,n):this.$el.on(r,a,n)}}return this},undelegateEvents:function(){return this.$el.off(".delegateEvents"+this.cid),this},_ensureElement:function(){if(this.el)this.setElement(i.result(this,"el"),!1);else{var t=i.extend({},i.result(this,"attributes"));this.id&&(t.id=i.result(this,"id")),this.className&&(t["class"]=i.result(this,"className"));var n=e.$("<"+i.result(this,"tagName")+">").attr(t);this.setElement(n,!1)}}}),e.sync=function(t,n,s){var r=E[t];i.defaults(s||(s={}),{emulateHTTP:e.emulateHTTP,emulateJSON:e.emulateJSON});var a={type:r,dataType:"json"};if(s.url||(a.url=i.result(n,"url")||j()),null!=s.data||!n||"create"!==t&&"update"!==t&&"patch"!==t||(a.contentType="application/json",a.data=JSON.stringify(s.attrs||n.toJSON(s))),s.emulateJSON&&(a.contentType="application/x-www-form-urlencoded",a.data=a.data?{model:a.data}:{}),s.emulateHTTP&&("PUT"===r||"DELETE"===r||"PATCH"===r)){a.type="POST",s.emulateJSON&&(a.data._method=r);var o=s.beforeSend;s.beforeSend=function(t){if(t.setRequestHeader("X-HTTP-Method-Override",r),o)return o.apply(this,arguments)}}"GET"===a.type||s.emulateJSON||(a.processData=!1),"PATCH"===a.type&&x&&(a.xhr=function(){return new ActiveXObject("Microsoft.XMLHTTP")});var h=s.xhr=e.ajax(i.extend(a,s));return n.trigger("request",n,h,s),h};var x=!("undefined"==typeof window||!window.ActiveXObject||window.XMLHttpRequest&&(new XMLHttpRequest).dispatchEvent),E={create:"POST",update:"PUT",patch:"PATCH","delete":"DELETE",read:"GET"};e.ajax=function(){return e.$.ajax.apply(e.$,arguments)};var k=e.Router=function(t){t||(t={}),t.routes&&(this.routes=t.routes),this._bindRoutes(),this.initialize.apply(this,arguments)},T=/\((.*?)\)/g,$=/(\(\?)?:\w+/g,S=/\*\w+/g,H=/[\-{}\[\]+?.,\\\^$|#\s]/g;i.extend(k.prototype,o,{initialize:function(){},route:function(t,n,s){i.isRegExp(t)||(t=this._routeToRegExp(t)),i.isFunction(n)&&(s=n,n=""),s||(s=this[n]);var r=this;return e.history.route(t,function(i){var a=r._extractParameters(t,i);r.execute(s,a),r.trigger.apply(r,["route:"+n].concat(a)),r.trigger("route",n,a),e.history.trigger("route",r,n,a)}),this},execute:function(t,e){t&&t.apply(this,e)},navigate:function(t,i){return e.history.navigate(t,i),this},_bindRoutes:function(){if(this.routes){this.routes=i.result(this,"routes");for(var t,e=i.keys(this.routes);null!=(t=e.pop());)this.route(t,this.routes[t])}},_routeToRegExp:function(t){return t=t.replace(H,"\\$&").replace(T,"(?:$1)?").replace($,function(t,e){return e?t:"([^/?]+)"}).replace(S,"([^?]*?)"),new RegExp("^"+t+"(?:\\?([\\s\\S]*))?$")},_extractParameters:function(t,e){var n=t.exec(e).slice(1);return i.map(n,function(t,e){return e===n.length-1?t||null:t?decodeURIComponent(t):null})}});var A=e.History=function(){this.handlers=[],i.bindAll(this,"checkUrl"),"undefined"!=typeof window&&(this.location=window.location,this.history=window.history)},I=/^[#\/]|\s+$/g,N=/^\/+|\/+$/g,R=/msie [\w.]+/,O=/\/$/,P=/#.*$/;A.started=!1,i.extend(A.prototype,o,{interval:50,atRoot:function(){return this.location.pathname.replace(/[^\/]$/,"$&/")===this.root},getHash:function(t){var e=(t||this).location.href.match(/#(.*)$/);return e?e[1]:""},getFragment:function(t,e){if(null==t)if(this._hasPushState||!this._wantsHashChange||e){t=decodeURI(this.location.pathname+this.location.search);var i=this.root.replace(O,"");t.indexOf(i)||(t=t.slice(i.length))}else t=this.getHash();return t.replace(I,"")},start:function(t){if(A.started)throw new Error("Backbone.history has already been started");A.started=!0,this.options=i.extend({root:"/"},this.options,t),this.root=this.options.root,this._wantsHashChange=this.options.hashChange!==!1,this._wantsPushState=!!this.options.pushState,this._hasPushState=!!(this.options.pushState&&this.history&&this.history.pushState);var n=this.getFragment(),s=document.documentMode,r=R.exec(navigator.userAgent.toLowerCase())&&(!s||s<=7);if(this.root=("/"+this.root+"/").replace(N,"/"),r&&this._wantsHashChange){var a=e.$('<iframe src="javascript:0" tabindex="-1">');this.iframe=a.hide().appendTo("body")[0].contentWindow,this.navigate(n)}this._hasPushState?e.$(window).on("popstate",this.checkUrl):this._wantsHashChange&&"onhashchange"in window&&!r?e.$(window).on("hashchange",this.checkUrl):this._wantsHashChange&&(this._checkUrlInterval=setInterval(this.checkUrl,this.interval)),this.fragment=n;var o=this.location;if(this._wantsHashChange&&this._wantsPushState){if(!this._hasPushState&&!this.atRoot())return this.fragment=this.getFragment(null,!0),this.location.replace(this.root+"#"+this.fragment),!0;this._hasPushState&&this.atRoot()&&o.hash&&(this.fragment=this.getHash().replace(I,""),this.history.replaceState({},document.title,this.root+this.fragment))}if(!this.options.silent)return this.loadUrl()},stop:function(){e.$(window).off("popstate",this.checkUrl).off("hashchange",this.checkUrl),this._checkUrlInterval&&clearInterval(this._checkUrlInterval),A.started=!1},route:function(t,e){this.handlers.unshift({route:t,callback:e})},checkUrl:function(t){var e=this.getFragment();return e===this.fragment&&this.iframe&&(e=this.getFragment(this.getHash(this.iframe))),e!==this.fragment&&(this.iframe&&this.navigate(e),void this.loadUrl())},loadUrl:function(t){return t=this.fragment=this.getFragment(t),i.any(this.handlers,function(e){if(e.route.test(t))return e.callback(t),!0})},navigate:function(t,e){if(!A.started)return!1;e&&e!==!0||(e={trigger:!!e});var i=this.root+(t=this.getFragment(t||""));if(t=t.replace(P,""),this.fragment!==t){if(this.fragment=t,""===t&&"/"!==i&&(i=i.slice(0,-1)),this._hasPushState)this.history[e.replace?"replaceState":"pushState"]({},document.title,i);else{if(!this._wantsHashChange)return this.location.assign(i);this._updateHash(this.location,t,e.replace),this.iframe&&t!==this.getFragment(this.getHash(this.iframe))&&(e.replace||this.iframe.document.open().close(),this._updateHash(this.iframe.location,t,e.replace))}return e.trigger?this.loadUrl(t):void 0}},_updateHash:function(t,e,i){if(i){var n=t.href.replace(/(javascript:|#).*$/,"");t.replace(n+"#"+e)}else t.hash="#"+e}}),e.history=new A;var C=function(t,e){var n,s=this;n=t&&i.has(t,"constructor")?t.constructor:function(){return s.apply(this,arguments)},i.extend(n,s,e);var r=function(){this.constructor=n};return r.prototype=s.prototype,n.prototype=new r,t&&i.extend(n.prototype,t),n.__super__=s.prototype,n};d.extend=p.extend=k.extend=_.extend=A.extend=C;var j=function(){throw new Error('A "url" property or function must be specified')},U=function(t,e){var i=e.error;e.error=function(n){i&&i(t,n,e),t.trigger("error",t,n,e)}};return e}),Backbone.View=function(t){return t.extend({constructor:function(e){this.options=e||{},t.apply(this,arguments)}})}(Backbone.View);
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/es5-shim.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/es5-shim.js
new file mode 100644 (file)
index 0000000..4c0fcab
--- /dev/null
@@ -0,0 +1 @@
+!function(t,e){"use strict";"function"==typeof define&&define.amd?define(e):"object"==typeof exports?module.exports=e():t.returnExports=e()}(this,function(){var t,e,r=Array,n=r.prototype,o=Object,i=o.prototype,a=Function,u=a.prototype,f=String,s=f.prototype,l=Number,c=l.prototype,h=n.slice,p=n.splice,y=n.push,d=n.unshift,g=n.concat,v=n.join,b=u.call,w=u.apply,T=Math.max,m=Math.min,D=i.toString,x="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag,S=Function.prototype.toString,O=/^\s*class /,j=function(t){try{var e=S.call(t),r=e.replace(/\/\/.*\n/g,""),n=r.replace(/\/\*[.\s\S]*\*\//g,""),o=n.replace(/\n/gm," ").replace(/ {2}/g," ");return O.test(o)}catch(i){return!1}},E=function(t){try{return!j(t)&&(S.call(t),!0)}catch(e){return!1}},M="[object Function]",I="[object GeneratorFunction]",t=function(t){if(!t)return!1;if("function"!=typeof t&&"object"!=typeof t)return!1;if(x)return E(t);if(j(t))return!1;var e=D.call(t);return e===M||e===I},U=RegExp.prototype.exec,F=function(t){try{return U.call(t),!0}catch(e){return!1}},N="[object RegExp]";e=function(t){return"object"==typeof t&&(x?F(t):D.call(t)===N)};var k,C=String.prototype.valueOf,R=function(t){try{return C.call(t),!0}catch(e){return!1}},A="[object String]";k=function(t){return"string"==typeof t||"object"==typeof t&&(x?R(t):D.call(t)===A)};var $=o.defineProperty&&function(){try{var t={};o.defineProperty(t,"x",{enumerable:!1,value:t});for(var e in t)return!1;return t.x===t}catch(r){return!1}}(),P=function(t){var e;return e=$?function(t,e,r,n){!n&&e in t||o.defineProperty(t,e,{configurable:!0,enumerable:!1,writable:!0,value:r})}:function(t,e,r,n){!n&&e in t||(t[e]=r)},function(r,n,o){for(var i in n)t.call(n,i)&&e(r,i,n[i],o)}}(i.hasOwnProperty),J=function(t){var e=typeof t;return null===t||"object"!==e&&"function"!==e},Z=l.isNaN||function(t){return t!==t},z={ToInteger:function(t){var e=+t;return Z(e)?e=0:0!==e&&e!==1/0&&e!==-(1/0)&&(e=(e>0||-1)*Math.floor(Math.abs(e))),e},ToPrimitive:function(e){var r,n,o;if(J(e))return e;if(n=e.valueOf,t(n)&&(r=n.call(e),J(r)))return r;if(o=e.toString,t(o)&&(r=o.call(e),J(r)))return r;throw new TypeError},ToObject:function(t){if(null==t)throw new TypeError("can't convert "+t+" to object");return o(t)},ToUint32:function(t){return t>>>0}},G=function(){};P(u,{bind:function(e){var r=this;if(!t(r))throw new TypeError("Function.prototype.bind called on incompatible "+r);for(var n,i=h.call(arguments,1),u=function(){if(this instanceof n){var t=w.call(r,this,g.call(i,h.call(arguments)));return o(t)===t?t:this}return w.call(r,e,g.call(i,h.call(arguments)))},f=T(0,r.length-i.length),s=[],l=0;l<f;l++)y.call(s,"$"+l);return n=a("binder","return function ("+v.call(s,",")+"){ return binder.apply(this, arguments); }")(u),r.prototype&&(G.prototype=r.prototype,n.prototype=new G,G.prototype=null),n}});var Y=b.bind(i.hasOwnProperty),B=b.bind(i.toString),H=b.bind(h),W=w.bind(h),L=b.bind(s.slice),X=b.bind(s.split),q=b.bind(s.indexOf),K=b.bind(y),Q=b.bind(i.propertyIsEnumerable),V=b.bind(n.sort),_=r.isArray||function(t){return"[object Array]"===B(t)},tt=1!==[].unshift(0);P(n,{unshift:function(){return d.apply(this,arguments),this.length}},tt),P(r,{isArray:_});var et=o("a"),rt="a"!==et[0]||!(0 in et),nt=function(t){var e=!0,r=!0,n=!1;if(t)try{t.call("foo",function(t,r,n){"object"!=typeof n&&(e=!1)}),t.call([1],function(){"use strict";r="string"==typeof this},"x")}catch(o){n=!0}return!!t&&!n&&e&&r};P(n,{forEach:function(e){var r,n=z.ToObject(this),o=rt&&k(this)?X(this,""):n,i=-1,a=z.ToUint32(o.length);if(arguments.length>1&&(r=arguments[1]),!t(e))throw new TypeError("Array.prototype.forEach callback must be a function");for(;++i<a;)i in o&&("undefined"==typeof r?e(o[i],i,n):e.call(r,o[i],i,n))}},!nt(n.forEach)),P(n,{map:function(e){var n,o=z.ToObject(this),i=rt&&k(this)?X(this,""):o,a=z.ToUint32(i.length),u=r(a);if(arguments.length>1&&(n=arguments[1]),!t(e))throw new TypeError("Array.prototype.map callback must be a function");for(var f=0;f<a;f++)f in i&&("undefined"==typeof n?u[f]=e(i[f],f,o):u[f]=e.call(n,i[f],f,o));return u}},!nt(n.map)),P(n,{filter:function(e){var r,n,o=z.ToObject(this),i=rt&&k(this)?X(this,""):o,a=z.ToUint32(i.length),u=[];if(arguments.length>1&&(n=arguments[1]),!t(e))throw new TypeError("Array.prototype.filter callback must be a function");for(var f=0;f<a;f++)f in i&&(r=i[f],("undefined"==typeof n?e(r,f,o):e.call(n,r,f,o))&&K(u,r));return u}},!nt(n.filter)),P(n,{every:function(e){var r,n=z.ToObject(this),o=rt&&k(this)?X(this,""):n,i=z.ToUint32(o.length);if(arguments.length>1&&(r=arguments[1]),!t(e))throw new TypeError("Array.prototype.every callback must be a function");for(var a=0;a<i;a++)if(a in o&&!("undefined"==typeof r?e(o[a],a,n):e.call(r,o[a],a,n)))return!1;return!0}},!nt(n.every)),P(n,{some:function(e){var r,n=z.ToObject(this),o=rt&&k(this)?X(this,""):n,i=z.ToUint32(o.length);if(arguments.length>1&&(r=arguments[1]),!t(e))throw new TypeError("Array.prototype.some callback must be a function");for(var a=0;a<i;a++)if(a in o&&("undefined"==typeof r?e(o[a],a,n):e.call(r,o[a],a,n)))return!0;return!1}},!nt(n.some));var ot=!1;n.reduce&&(ot="object"==typeof n.reduce.call("es5",function(t,e,r,n){return n})),P(n,{reduce:function(e){var r=z.ToObject(this),n=rt&&k(this)?X(this,""):r,o=z.ToUint32(n.length);if(!t(e))throw new TypeError("Array.prototype.reduce callback must be a function");if(0===o&&1===arguments.length)throw new TypeError("reduce of empty array with no initial value");var i,a=0;if(arguments.length>=2)i=arguments[1];else for(;;){if(a in n){i=n[a++];break}if(++a>=o)throw new TypeError("reduce of empty array with no initial value")}for(;a<o;a++)a in n&&(i=e(i,n[a],a,r));return i}},!ot);var it=!1;n.reduceRight&&(it="object"==typeof n.reduceRight.call("es5",function(t,e,r,n){return n})),P(n,{reduceRight:function(e){var r=z.ToObject(this),n=rt&&k(this)?X(this,""):r,o=z.ToUint32(n.length);if(!t(e))throw new TypeError("Array.prototype.reduceRight callback must be a function");if(0===o&&1===arguments.length)throw new TypeError("reduceRight of empty array with no initial value");var i,a=o-1;if(arguments.length>=2)i=arguments[1];else for(;;){if(a in n){i=n[a--];break}if(--a<0)throw new TypeError("reduceRight of empty array with no initial value")}if(a<0)return i;do a in n&&(i=e(i,n[a],a,r));while(a--);return i}},!it);var at=n.indexOf&&[0,1].indexOf(1,2)!==-1;P(n,{indexOf:function(t){var e=rt&&k(this)?X(this,""):z.ToObject(this),r=z.ToUint32(e.length);if(0===r)return-1;var n=0;for(arguments.length>1&&(n=z.ToInteger(arguments[1])),n=n>=0?n:T(0,r+n);n<r;n++)if(n in e&&e[n]===t)return n;return-1}},at);var ut=n.lastIndexOf&&[0,1].lastIndexOf(0,-3)!==-1;P(n,{lastIndexOf:function(t){var e=rt&&k(this)?X(this,""):z.ToObject(this),r=z.ToUint32(e.length);if(0===r)return-1;var n=r-1;for(arguments.length>1&&(n=m(n,z.ToInteger(arguments[1]))),n=n>=0?n:r-Math.abs(n);n>=0;n--)if(n in e&&t===e[n])return n;return-1}},ut);var ft=function(){var t=[1,2],e=t.splice();return 2===t.length&&_(e)&&0===e.length}();P(n,{splice:function(t,e){return 0===arguments.length?[]:p.apply(this,arguments)}},!ft);var st=function(){var t={};return n.splice.call(t,0,0,1),1===t.length}();P(n,{splice:function(t,e){if(0===arguments.length)return[];var r=arguments;return this.length=T(z.ToInteger(this.length),0),arguments.length>0&&"number"!=typeof e&&(r=H(arguments),r.length<2?K(r,this.length-t):r[1]=z.ToInteger(e)),p.apply(this,r)}},!st);var lt=function(){var t=new r(1e5);return t[8]="x",t.splice(1,1),7===t.indexOf("x")}(),ct=function(){var t=256,e=[];return e[t]="a",e.splice(t+1,0,"b"),"a"===e[t]}();P(n,{splice:function(t,e){for(var r,n=z.ToObject(this),o=[],i=z.ToUint32(n.length),a=z.ToInteger(t),u=a<0?T(i+a,0):m(a,i),s=m(T(z.ToInteger(e),0),i-u),l=0;l<s;)r=f(u+l),Y(n,r)&&(o[l]=n[r]),l+=1;var c,h=H(arguments,2),p=h.length;if(p<s){l=u;for(var y=i-s;l<y;)r=f(l+s),c=f(l+p),Y(n,r)?n[c]=n[r]:delete n[c],l+=1;l=i;for(var d=i-s+p;l>d;)delete n[l-1],l-=1}else if(p>s)for(l=i-s;l>u;)r=f(l+s-1),c=f(l+p-1),Y(n,r)?n[c]=n[r]:delete n[c],l-=1;l=u;for(var g=0;g<h.length;++g)n[l]=h[g],l+=1;return n.length=i-s+p,o}},!lt||!ct);var ht,pt=n.join;try{ht="1,2,3"!==Array.prototype.join.call("123",",")}catch(yt){ht=!0}ht&&P(n,{join:function(t){var e="undefined"==typeof t?",":t;return pt.call(k(this)?X(this,""):this,e)}},ht);var dt="1,2"!==[1,2].join(void 0);dt&&P(n,{join:function(t){var e="undefined"==typeof t?",":t;return pt.call(this,e)}},dt);var gt=function(t){for(var e=z.ToObject(this),r=z.ToUint32(e.length),n=0;n<arguments.length;)e[r+n]=arguments[n],n+=1;return e.length=r+n,r+n},vt=function(){var t={},e=Array.prototype.push.call(t,void 0);return 1!==e||1!==t.length||"undefined"!=typeof t[0]||!Y(t,0)}();P(n,{push:function(t){return _(this)?y.apply(this,arguments):gt.apply(this,arguments)}},vt);var bt=function(){var t=[],e=t.push(void 0);return 1!==e||1!==t.length||"undefined"!=typeof t[0]||!Y(t,0)}();P(n,{push:gt},bt),P(n,{slice:function(t,e){var r=k(this)?X(this,""):this;return W(r,arguments)}},rt);var wt=function(){try{return[1,2].sort(null),[1,2].sort({}),!0}catch(t){}return!1}(),Tt=function(){try{return[1,2].sort(/a/),!1}catch(t){}return!0}(),mt=function(){try{return[1,2].sort(void 0),!0}catch(t){}return!1}();P(n,{sort:function(e){if("undefined"==typeof e)return V(this);if(!t(e))throw new TypeError("Array.prototype.sort callback must be a function");return V(this,e)}},wt||!mt||!Tt);var Dt=!Q({toString:null},"toString"),xt=Q(function(){},"prototype"),St=!Y("x","0"),Ot=function(t){var e=t.constructor;return e&&e.prototype===t},jt={$window:!0,$console:!0,$parent:!0,$self:!0,$frame:!0,$frames:!0,$frameElement:!0,$webkitIndexedDB:!0,$webkitStorageInfo:!0,$external:!0},Et=function(){if("undefined"==typeof window)return!1;for(var t in window)try{!jt["$"+t]&&Y(window,t)&&null!==window[t]&&"object"==typeof window[t]&&Ot(window[t])}catch(e){return!0}return!1}(),Mt=function(t){if("undefined"==typeof window||!Et)return Ot(t);try{return Ot(t)}catch(e){return!1}},It=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],Ut=It.length,Ft=function(t){return"[object Arguments]"===B(t)},Nt=function(e){return null!==e&&"object"==typeof e&&"number"==typeof e.length&&e.length>=0&&!_(e)&&t(e.callee)},kt=Ft(arguments)?Ft:Nt;P(o,{keys:function(e){var r=t(e),n=kt(e),o=null!==e&&"object"==typeof e,i=o&&k(e);if(!o&&!r&&!n)throw new TypeError("Object.keys called on a non-object");var a=[],u=xt&&r;if(i&&St||n)for(var s=0;s<e.length;++s)K(a,f(s));if(!n)for(var l in e)u&&"prototype"===l||!Y(e,l)||K(a,f(l));if(Dt)for(var c=Mt(e),h=0;h<Ut;h++){var p=It[h];c&&"constructor"===p||!Y(e,p)||K(a,p)}return a}});var Ct=o.keys&&function(){return 2===o.keys(arguments).length}(1,2),Rt=o.keys&&function(){var t=o.keys(arguments);return 1!==arguments.length||1!==t.length||1!==t[0]}(1),At=o.keys;P(o,{keys:function(t){return At(kt(t)?H(t):t)}},!Ct||Rt);var $t,Pt,Jt=0!==new Date((-0xc782b5b342b24)).getUTCMonth(),Zt=new Date((-0x55d318d56a724)),zt=new Date(14496624e5),Gt="Mon, 01 Jan -45875 11:59:59 GMT"!==Zt.toUTCString(),Yt=Zt.getTimezoneOffset();Yt<-720?($t="Tue Jan 02 -45875"!==Zt.toDateString(),Pt=!/^Thu Dec 10 2015 \d\d:\d\d:\d\d GMT[-\+]\d\d\d\d(?: |$)/.test(zt.toString())):($t="Mon Jan 01 -45875"!==Zt.toDateString(),Pt=!/^Wed Dec 09 2015 \d\d:\d\d:\d\d GMT[-\+]\d\d\d\d(?: |$)/.test(zt.toString()));var Bt=b.bind(Date.prototype.getFullYear),Ht=b.bind(Date.prototype.getMonth),Wt=b.bind(Date.prototype.getDate),Lt=b.bind(Date.prototype.getUTCFullYear),Xt=b.bind(Date.prototype.getUTCMonth),qt=b.bind(Date.prototype.getUTCDate),Kt=b.bind(Date.prototype.getUTCDay),Qt=b.bind(Date.prototype.getUTCHours),Vt=b.bind(Date.prototype.getUTCMinutes),_t=b.bind(Date.prototype.getUTCSeconds),te=b.bind(Date.prototype.getUTCMilliseconds),ee=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],re=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],ne=function(t,e){return Wt(new Date(e,t,0))};P(Date.prototype,{getFullYear:function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var t=Bt(this);return t<0&&Ht(this)>11?t+1:t},getMonth:function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var t=Bt(this),e=Ht(this);return t<0&&e>11?0:e},getDate:function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var t=Bt(this),e=Ht(this),r=Wt(this);if(t<0&&e>11){if(12===e)return r;var n=ne(0,t+1);return n-r+1}return r},getUTCFullYear:function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var t=Lt(this);return t<0&&Xt(this)>11?t+1:t},getUTCMonth:function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var t=Lt(this),e=Xt(this);return t<0&&e>11?0:e},getUTCDate:function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var t=Lt(this),e=Xt(this),r=qt(this);if(t<0&&e>11){if(12===e)return r;var n=ne(0,t+1);return n-r+1}return r}},Jt),P(Date.prototype,{toUTCString:function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var t=Kt(this),e=qt(this),r=Xt(this),n=Lt(this),o=Qt(this),i=Vt(this),a=_t(this);return ee[t]+", "+(e<10?"0"+e:e)+" "+re[r]+" "+n+" "+(o<10?"0"+o:o)+":"+(i<10?"0"+i:i)+":"+(a<10?"0"+a:a)+" GMT"}},Jt||Gt),P(Date.prototype,{toDateString:function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var t=this.getDay(),e=this.getDate(),r=this.getMonth(),n=this.getFullYear();return ee[t]+" "+re[r]+" "+(e<10?"0"+e:e)+" "+n}},Jt||$t),(Jt||Pt)&&(Date.prototype.toString=function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var t=this.getDay(),e=this.getDate(),r=this.getMonth(),n=this.getFullYear(),o=this.getHours(),i=this.getMinutes(),a=this.getSeconds(),u=this.getTimezoneOffset(),f=Math.floor(Math.abs(u)/60),s=Math.floor(Math.abs(u)%60);return ee[t]+" "+re[r]+" "+(e<10?"0"+e:e)+" "+n+" "+(o<10?"0"+o:o)+":"+(i<10?"0"+i:i)+":"+(a<10?"0"+a:a)+" GMT"+(u>0?"-":"+")+(f<10?"0"+f:f)+(s<10?"0"+s:s)},$&&o.defineProperty(Date.prototype,"toString",{configurable:!0,enumerable:!1,writable:!0}));var oe=-621987552e5,ie="-000001",ae=Date.prototype.toISOString&&new Date(oe).toISOString().indexOf(ie)===-1,ue=Date.prototype.toISOString&&"1969-12-31T23:59:59.999Z"!==new Date((-1)).toISOString(),fe=b.bind(Date.prototype.getTime);P(Date.prototype,{toISOString:function(){if(!isFinite(this)||!isFinite(fe(this)))throw new RangeError("Date.prototype.toISOString called on non-finite value.");var t=Lt(this),e=Xt(this);t+=Math.floor(e/12),e=(e%12+12)%12;var r=[e+1,qt(this),Qt(this),Vt(this),_t(this)];t=(t<0?"-":t>9999?"+":"")+L("00000"+Math.abs(t),0<=t&&t<=9999?-4:-6);for(var n=0;n<r.length;++n)r[n]=L("00"+r[n],-2);return t+"-"+H(r,0,2).join("-")+"T"+H(r,2).join(":")+"."+L("000"+te(this),-3)+"Z"}},ae||ue);var se=function(){try{return Date.prototype.toJSON&&null===new Date(NaN).toJSON()&&new Date(oe).toJSON().indexOf(ie)!==-1&&Date.prototype.toJSON.call({toISOString:function(){return!0}})}catch(t){return!1}}();se||(Date.prototype.toJSON=function(e){var r=o(this),n=z.ToPrimitive(r);if("number"==typeof n&&!isFinite(n))return null;var i=r.toISOString;if(!t(i))throw new TypeError("toISOString property is not callable");return i.call(r)});var le=1e15===Date.parse("+033658-09-27T01:46:40.000Z"),ce=!isNaN(Date.parse("2012-04-04T24:00:00.500Z"))||!isNaN(Date.parse("2012-11-31T23:59:59.000Z"))||!isNaN(Date.parse("2012-12-31T23:59:60.000Z")),he=isNaN(Date.parse("2000-01-01T00:00:00.000Z"));if(he||ce||!le){var pe=Math.pow(2,31)-1,ye=Z(new Date(1970,0,1,0,0,0,pe+1).getTime());Date=function(t){var e=function(r,n,o,i,a,u,s){var l,c=arguments.length;if(this instanceof t){var h=u,p=s;if(ye&&c>=7&&s>pe){var y=Math.floor(s/pe)*pe,d=Math.floor(y/1e3);h+=d,p-=1e3*d}l=1===c&&f(r)===r?new t(e.parse(r)):c>=7?new t(r,n,o,i,a,h,p):c>=6?new t(r,n,o,i,a,h):c>=5?new t(r,n,o,i,a):c>=4?new t(r,n,o,i):c>=3?new t(r,n,o):c>=2?new t(r,n):c>=1?new t(r instanceof t?+r:r):new t}else l=t.apply(this,arguments);return J(l)||P(l,{constructor:e},!0),l},r=new RegExp("^(\\d{4}|[+-]\\d{6})(?:-(\\d{2})(?:-(\\d{2})(?:T(\\d{2}):(\\d{2})(?::(\\d{2})(?:(\\.\\d{1,}))?)?(Z|(?:([-+])(\\d{2}):(\\d{2})))?)?)?)?$"),n=[0,31,59,90,120,151,181,212,243,273,304,334,365],o=function(t,e){var r=e>1?1:0;return n[e]+Math.floor((t-1969+r)/4)-Math.floor((t-1901+r)/100)+Math.floor((t-1601+r)/400)+365*(t-1970)},i=function(e){var r=0,n=e;if(ye&&n>pe){var o=Math.floor(n/pe)*pe,i=Math.floor(o/1e3);r+=i,n-=1e3*i}return l(new t(1970,0,1,0,0,r,n))};for(var a in t)Y(t,a)&&(e[a]=t[a]);P(e,{now:t.now,UTC:t.UTC},!0),e.prototype=t.prototype,P(e.prototype,{constructor:e},!0);var u=function(e){var n=r.exec(e);if(n){var a,u=l(n[1]),f=l(n[2]||1)-1,s=l(n[3]||1)-1,c=l(n[4]||0),h=l(n[5]||0),p=l(n[6]||0),y=Math.floor(1e3*l(n[7]||0)),d=Boolean(n[4]&&!n[8]),g="-"===n[9]?1:-1,v=l(n[10]||0),b=l(n[11]||0),w=h>0||p>0||y>0;return c<(w?24:25)&&h<60&&p<60&&y<1e3&&f>-1&&f<12&&v<24&&b<60&&s>-1&&s<o(u,f+1)-o(u,f)&&(a=60*(24*(o(u,f)+s)+c+v*g),a=1e3*(60*(a+h+b*g)+p)+y,d&&(a=i(a)),-864e13<=a&&a<=864e13)?a:NaN}return t.parse.apply(this,arguments)};return P(e,{parse:u}),e}(Date)}Date.now||(Date.now=function(){return(new Date).getTime()});var de=c.toFixed&&("0.000"!==8e-5.toFixed(3)||"1"!==.9.toFixed(0)||"1.25"!==1.255.toFixed(2)||"1000000000000000128"!==(0xde0b6b3a7640080).toFixed(0)),ge={base:1e7,size:6,data:[0,0,0,0,0,0],multiply:function(t,e){for(var r=-1,n=e;++r<ge.size;)n+=t*ge.data[r],ge.data[r]=n%ge.base,n=Math.floor(n/ge.base)},divide:function(t){for(var e=ge.size,r=0;--e>=0;)r+=ge.data[e],ge.data[e]=Math.floor(r/t),r=r%t*ge.base},numToString:function(){for(var t=ge.size,e="";--t>=0;)if(""!==e||0===t||0!==ge.data[t]){var r=f(ge.data[t]);""===e?e=r:e+=L("0000000",0,7-r.length)+r}return e},pow:function Ae(t,e,r){return 0===e?r:e%2===1?Ae(t,e-1,r*t):Ae(t*t,e/2,r)},log:function(t){for(var e=0,r=t;r>=4096;)e+=12,r/=4096;for(;r>=2;)e+=1,r/=2;return e}},ve=function(t){var e,r,n,o,i,a,u,s;if(e=l(t),e=Z(e)?0:Math.floor(e),e<0||e>20)throw new RangeError("Number.toFixed called with invalid number of decimals");if(r=l(this),Z(r))return"NaN";if(r<=-1e21||r>=1e21)return f(r);if(n="",r<0&&(n="-",r=-r),o="0",r>1e-21)if(i=ge.log(r*ge.pow(2,69,1))-69,a=i<0?r*ge.pow(2,-i,1):r/ge.pow(2,i,1),a*=4503599627370496,i=52-i,i>0){for(ge.multiply(0,a),u=e;u>=7;)ge.multiply(1e7,0),u-=7;for(ge.multiply(ge.pow(10,u,1),0),u=i-1;u>=23;)ge.divide(1<<23),u-=23;ge.divide(1<<u),ge.multiply(1,1),ge.divide(2),o=ge.numToString()}else ge.multiply(0,a),ge.multiply(1<<-i,0),o=ge.numToString()+L("0.00000000000000000000",2,2+e);return e>0?(s=o.length,o=s<=e?n+L("0.0000000000000000000",0,e-s+2)+o:n+L(o,0,s-e)+"."+L(o,s-e)):o=n+o,o};P(c,{toFixed:ve},de);var be=function(){try{return"1"===1..toPrecision(void 0)}catch(t){return!0}}(),we=c.toPrecision;P(c,{toPrecision:function(t){return"undefined"==typeof t?we.call(this):we.call(this,t)}},be),2!=="ab".split(/(?:ab)*/).length||4!==".".split(/(.?)(.?)/).length||"t"==="tesst".split(/(s)*/)[1]||4!=="test".split(/(?:)/,-1).length||"".split(/.?/).length||".".split(/()()/).length>1?!function(){var t="undefined"==typeof/()??/.exec("")[1],r=Math.pow(2,32)-1;s.split=function(n,o){var i=String(this);if("undefined"==typeof n&&0===o)return[];if(!e(n))return X(this,n,o);var a,u,f,s,l=[],c=(n.ignoreCase?"i":"")+(n.multiline?"m":"")+(n.unicode?"u":"")+(n.sticky?"y":""),h=0,p=new RegExp(n.source,c+"g");t||(a=new RegExp("^"+p.source+"$(?!\\s)",c));var d="undefined"==typeof o?r:z.ToUint32(o);for(u=p.exec(i);u&&(f=u.index+u[0].length,!(f>h&&(K(l,L(i,h,u.index)),!t&&u.length>1&&u[0].replace(a,function(){for(var t=1;t<arguments.length-2;t++)"undefined"==typeof arguments[t]&&(u[t]=void 0)}),u.length>1&&u.index<i.length&&y.apply(l,H(u,1)),s=u[0].length,h=f,l.length>=d)));)p.lastIndex===u.index&&p.lastIndex++,u=p.exec(i);return h===i.length?!s&&p.test("")||K(l,""):K(l,L(i,h)),l.length>d?H(l,0,d):l}}():"0".split(void 0,0).length&&(s.split=function(t,e){return"undefined"==typeof t&&0===e?[]:X(this,t,e)});var Te=s.replace,me=function(){var t=[];return"x".replace(/x(.)?/g,function(e,r){K(t,r)}),1===t.length&&"undefined"==typeof t[0]}();me||(s.replace=function(r,n){var o=t(n),i=e(r)&&/\)[*?]/.test(r.source);if(o&&i){var a=function(t){var e=arguments.length,o=r.lastIndex;r.lastIndex=0;var i=r.exec(t)||[];return r.lastIndex=o,K(i,arguments[e-2],arguments[e-1]),n.apply(this,i)};return Te.call(this,r,a)}return Te.call(this,r,n)});var De=s.substr,xe="".substr&&"b"!=="0b".substr(-1);P(s,{substr:function(t,e){var r=t;return t<0&&(r=T(this.length+t,0)),De.call(this,r,e)}},xe);var Se="\t\n\x0B\f\r   ᠎              \u2028\u2029\ufeff",Oe="​",je="["+Se+"]",Ee=new RegExp("^"+je+je+"*"),Me=new RegExp(je+je+"*$"),Ie=s.trim&&(Se.trim()||!Oe.trim());P(s,{trim:function(){if("undefined"==typeof this||null===this)throw new TypeError("can't convert "+this+" to object");return f(this).replace(Ee,"").replace(Me,"")}},Ie);var Ue=b.bind(String.prototype.trim),Fe=s.lastIndexOf&&"abcあい".lastIndexOf("あい",2)!==-1;P(s,{lastIndexOf:function(t){if("undefined"==typeof this||null===this)throw new TypeError("can't convert "+this+" to object");for(var e=f(this),r=f(t),n=arguments.length>1?l(arguments[1]):NaN,o=Z(n)?1/0:z.ToInteger(n),i=m(T(o,0),e.length),a=r.length,u=i+a;u>0;){u=T(0,u-a);var s=q(L(e,u,i+a),r);if(s!==-1)return u+s}return-1}},Fe);var Ne=s.lastIndexOf;if(P(s,{lastIndexOf:function(t){return Ne.apply(this,arguments)}},1!==s.lastIndexOf.length),8===parseInt(Se+"08")&&22===parseInt(Se+"0x16")||(parseInt=function(t){var e=/^[\-+]?0[xX]/;return function(r,n){var o=Ue(String(r)),i=l(n)||(e.test(o)?16:10);return t(o,i)}}(parseInt)),1/parseFloat("-0")!==-(1/0)&&(parseFloat=function(t){return function(e){var r=Ue(String(e)),n=t(r);return 0===n&&"-"===L(r,0,1)?-0:n}}(parseFloat)),"RangeError: test"!==String(new RangeError("test"))){var ke=function(){if("undefined"==typeof this||null===this)throw new TypeError("can't convert "+this+" to object");var t=this.name;"undefined"==typeof t?t="Error":"string"!=typeof t&&(t=f(t));var e=this.message;return"undefined"==typeof e?e="":"string"!=typeof e&&(e=f(e)),t?e?t+": "+e:t:e};Error.prototype.toString=ke}if($){var Ce=function(t,e){if(Q(t,e)){var r=Object.getOwnPropertyDescriptor(t,e);r.configurable&&(r.enumerable=!1,Object.defineProperty(t,e,r))}};Ce(Error.prototype,"message"),""!==Error.prototype.message&&(Error.prototype.message=""),Ce(Error.prototype,"name")}if("/a/gim"!==String(/a/gim)){var Re=function(){var t="/"+this.source+"/";return this.global&&(t+="g"),this.ignoreCase&&(t+="i"),this.multiline&&(t+="m"),t};RegExp.prototype.toString=Re}});
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/handlebars-4.0.5.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/handlebars-4.0.5.js
new file mode 100644 (file)
index 0000000..57025bc
--- /dev/null
@@ -0,0 +1,3 @@
+!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Handlebars=e():t.Handlebars=e()}(this,function(){return function(t){function e(s){if(r[s])return r[s].exports;var i=r[s]={exports:{},id:s,loaded:!1};return t[s].call(i.exports,i,i.exports,e),i.loaded=!0,i.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){"use strict";function s(){var t=v();return t.compile=function(e,r){return l.compile(e,r,t)},t.precompile=function(e,r){return l.precompile(e,r,t)},t.AST=c["default"],t.Compiler=l.Compiler,t.JavaScriptCompiler=u["default"],t.Parser=h.parser,t.parse=h.parse,t}var i=r(1)["default"];e.__esModule=!0;var a=r(2),n=i(a),o=r(21),c=i(o),h=r(22),l=r(27),p=r(28),u=i(p),f=r(25),d=i(f),m=r(20),g=i(m),v=n["default"].create,y=s();y.create=s,g["default"](y),y.Visitor=d["default"],y["default"]=y,e["default"]=y,t.exports=e["default"]},function(t,e){"use strict";e["default"]=function(t){return t&&t.__esModule?t:{"default":t}},e.__esModule=!0},function(t,e,r){"use strict";function s(){var t=new o.HandlebarsEnvironment;return f.extend(t,o),t.SafeString=h["default"],t.Exception=p["default"],t.Utils=f,t.escapeExpression=f.escapeExpression,t.VM=m,t.template=function(e){return m.template(e,t)},t}var i=r(3)["default"],a=r(1)["default"];e.__esModule=!0;var n=r(4),o=i(n),c=r(18),h=a(c),l=r(6),p=a(l),u=r(5),f=i(u),d=r(19),m=i(d),g=r(20),v=a(g),y=s();y.create=s,v["default"](y),y["default"]=y,e["default"]=y,t.exports=e["default"]},function(t,e){"use strict";e["default"]=function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e["default"]=t,e},e.__esModule=!0},function(t,e,r){"use strict";function s(t,e,r){this.helpers=t||{},this.partials=e||{},this.decorators=r||{},c.registerDefaultHelpers(this),h.registerDefaultDecorators(this)}var i=r(1)["default"];e.__esModule=!0,e.HandlebarsEnvironment=s;var a=r(5),n=r(6),o=i(n),c=r(7),h=r(15),l=r(17),p=i(l),u="4.0.5";e.VERSION=u;var f=7;e.COMPILER_REVISION=f;var d={1:"<= 1.0.rc.2",2:"== 1.0.0-rc.3",3:"== 1.0.0-rc.4",4:"== 1.x.x",5:"== 2.0.0-alpha.x",6:">= 2.0.0-beta.1",7:">= 4.0.0"};e.REVISION_CHANGES=d;var m="[object Object]";s.prototype={constructor:s,logger:p["default"],log:p["default"].log,registerHelper:function(t,e){if(a.toString.call(t)===m){if(e)throw new o["default"]("Arg not supported with multiple helpers");a.extend(this.helpers,t)}else this.helpers[t]=e},unregisterHelper:function(t){delete this.helpers[t]},registerPartial:function(t,e){if(a.toString.call(t)===m)a.extend(this.partials,t);else{if("undefined"==typeof e)throw new o["default"]('Attempting to register a partial called "'+t+'" as undefined');this.partials[t]=e}},unregisterPartial:function(t){delete this.partials[t]},registerDecorator:function(t,e){if(a.toString.call(t)===m){if(e)throw new o["default"]("Arg not supported with multiple decorators");a.extend(this.decorators,t)}else this.decorators[t]=e},unregisterDecorator:function(t){delete this.decorators[t]}};var g=p["default"].log;e.log=g,e.createFrame=a.createFrame,e.logger=p["default"]},function(t,e){"use strict";function r(t){return l[t]}function s(t){for(var e=1;e<arguments.length;e++)for(var r in arguments[e])Object.prototype.hasOwnProperty.call(arguments[e],r)&&(t[r]=arguments[e][r]);return t}function i(t,e){for(var r=0,s=t.length;r<s;r++)if(t[r]===e)return r;return-1}function a(t){if("string"!=typeof t){if(t&&t.toHTML)return t.toHTML();if(null==t)return"";if(!t)return t+"";t=""+t}return u.test(t)?t.replace(p,r):t}function n(t){return!t&&0!==t||!(!m(t)||0!==t.length)}function o(t){var e=s({},t);return e._parent=t,e}function c(t,e){return t.path=e,t}function h(t,e){return(t?t+".":"")+e}e.__esModule=!0,e.extend=s,e.indexOf=i,e.escapeExpression=a,e.isEmpty=n,e.createFrame=o,e.blockParams=c,e.appendContextPath=h;var l={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","`":"&#x60;","=":"&#x3D;"},p=/[&<>"'`=]/g,u=/[&<>"'`=]/,f=Object.prototype.toString;e.toString=f;var d=function(t){return"function"==typeof t};d(/x/)&&(e.isFunction=d=function(t){return"function"==typeof t&&"[object Function]"===f.call(t)}),e.isFunction=d;var m=Array.isArray||function(t){return!(!t||"object"!=typeof t)&&"[object Array]"===f.call(t)};e.isArray=m},function(t,e){"use strict";function r(t,e){var i=e&&e.loc,a=void 0,n=void 0;i&&(a=i.start.line,n=i.start.column,t+=" - "+a+":"+n);for(var o=Error.prototype.constructor.call(this,t),c=0;c<s.length;c++)this[s[c]]=o[s[c]];Error.captureStackTrace&&Error.captureStackTrace(this,r),i&&(this.lineNumber=a,this.column=n)}e.__esModule=!0;var s=["description","fileName","lineNumber","message","name","number","stack"];r.prototype=new Error,e["default"]=r,t.exports=e["default"]},function(t,e,r){"use strict";function s(t){n["default"](t),c["default"](t),l["default"](t),u["default"](t),d["default"](t),g["default"](t),y["default"](t)}var i=r(1)["default"];e.__esModule=!0,e.registerDefaultHelpers=s;var a=r(8),n=i(a),o=r(9),c=i(o),h=r(10),l=i(h),p=r(11),u=i(p),f=r(12),d=i(f),m=r(13),g=i(m),v=r(14),y=i(v)},function(t,e,r){"use strict";e.__esModule=!0;var s=r(5);e["default"]=function(t){t.registerHelper("blockHelperMissing",function(e,r){var i=r.inverse,a=r.fn;if(e===!0)return a(this);if(e===!1||null==e)return i(this);if(s.isArray(e))return e.length>0?(r.ids&&(r.ids=[r.name]),t.helpers.each(e,r)):i(this);if(r.data&&r.ids){var n=s.createFrame(r.data);n.contextPath=s.appendContextPath(r.data.contextPath,r.name),r={data:n}}return a(e,r)})},t.exports=e["default"]},function(t,e,r){"use strict";var s=r(1)["default"];e.__esModule=!0;var i=r(5),a=r(6),n=s(a);e["default"]=function(t){t.registerHelper("each",function(t,e){function r(e,r,a){h&&(h.key=e,h.index=r,h.first=0===r,h.last=!!a,l&&(h.contextPath=l+e)),c+=s(t[e],{data:h,blockParams:i.blockParams([t[e],e],[l+e,null])})}if(!e)throw new n["default"]("Must pass iterator to #each");var s=e.fn,a=e.inverse,o=0,c="",h=void 0,l=void 0;if(e.data&&e.ids&&(l=i.appendContextPath(e.data.contextPath,e.ids[0])+"."),i.isFunction(t)&&(t=t.call(this)),e.data&&(h=i.createFrame(e.data)),t&&"object"==typeof t)if(i.isArray(t))for(var p=t.length;o<p;o++)o in t&&r(o,o,o===t.length-1);else{var u=void 0;for(var f in t)t.hasOwnProperty(f)&&(void 0!==u&&r(u,o-1),u=f,o++);void 0!==u&&r(u,o-1,!0)}return 0===o&&(c=a(this)),c})},t.exports=e["default"]},function(t,e,r){"use strict";var s=r(1)["default"];e.__esModule=!0;var i=r(6),a=s(i);e["default"]=function(t){t.registerHelper("helperMissing",function(){if(1!==arguments.length)throw new a["default"]('Missing helper: "'+arguments[arguments.length-1].name+'"')})},t.exports=e["default"]},function(t,e,r){"use strict";e.__esModule=!0;var s=r(5);e["default"]=function(t){t.registerHelper("if",function(t,e){return s.isFunction(t)&&(t=t.call(this)),!e.hash.includeZero&&!t||s.isEmpty(t)?e.inverse(this):e.fn(this)}),t.registerHelper("unless",function(e,r){return t.helpers["if"].call(this,e,{fn:r.inverse,inverse:r.fn,hash:r.hash})})},t.exports=e["default"]},function(t,e){"use strict";e.__esModule=!0,e["default"]=function(t){t.registerHelper("log",function(){for(var e=[void 0],r=arguments[arguments.length-1],s=0;s<arguments.length-1;s++)e.push(arguments[s]);var i=1;null!=r.hash.level?i=r.hash.level:r.data&&null!=r.data.level&&(i=r.data.level),e[0]=i,t.log.apply(t,e)})},t.exports=e["default"]},function(t,e){"use strict";e.__esModule=!0,e["default"]=function(t){t.registerHelper("lookup",function(t,e){return t&&t[e]})},t.exports=e["default"]},function(t,e,r){"use strict";e.__esModule=!0;var s=r(5);e["default"]=function(t){t.registerHelper("with",function(t,e){s.isFunction(t)&&(t=t.call(this));var r=e.fn;if(s.isEmpty(t))return e.inverse(this);var i=e.data;return e.data&&e.ids&&(i=s.createFrame(e.data),i.contextPath=s.appendContextPath(e.data.contextPath,e.ids[0])),r(t,{data:i,blockParams:s.blockParams([t],[i&&i.contextPath])})})},t.exports=e["default"]},function(t,e,r){"use strict";function s(t){n["default"](t)}var i=r(1)["default"];e.__esModule=!0,e.registerDefaultDecorators=s;var a=r(16),n=i(a)},function(t,e,r){"use strict";e.__esModule=!0;var s=r(5);e["default"]=function(t){t.registerDecorator("inline",function(t,e,r,i){var a=t;return e.partials||(e.partials={},a=function(i,a){var n=r.partials;r.partials=s.extend({},n,e.partials);var o=t(i,a);return r.partials=n,o}),e.partials[i.args[0]]=i.fn,a})},t.exports=e["default"]},function(t,e,r){"use strict";e.__esModule=!0;var s=r(5),i={methodMap:["debug","info","warn","error"],level:"info",lookupLevel:function(t){if("string"==typeof t){var e=s.indexOf(i.methodMap,t.toLowerCase());t=e>=0?e:parseInt(t,10)}return t},log:function(t){if(t=i.lookupLevel(t),"undefined"!=typeof console&&i.lookupLevel(i.level)<=t){var e=i.methodMap[t];console[e]||(e="log");for(var r=arguments.length,s=Array(r>1?r-1:0),a=1;a<r;a++)s[a-1]=arguments[a];console[e].apply(console,s)}}};e["default"]=i,t.exports=e["default"]},function(t,e){"use strict";function r(t){this.string=t}e.__esModule=!0,r.prototype.toString=r.prototype.toHTML=function(){return""+this.string},e["default"]=r,t.exports=e["default"]},function(t,e,r){"use strict";function s(t){var e=t&&t[0]||1,r=v.COMPILER_REVISION;if(e!==r){if(e<r){var s=v.REVISION_CHANGES[r],i=v.REVISION_CHANGES[e];throw new g["default"]("Template was precompiled with an older version of Handlebars than the current runtime. Please update your precompiler to a newer version ("+s+") or downgrade your runtime to an older version ("+i+").")}throw new g["default"]("Template was precompiled with a newer version of Handlebars than the current runtime. Please update your runtime to a newer version ("+t[1]+").")}}function i(t,e){function r(r,s,i){i.hash&&(s=d.extend({},s,i.hash),i.ids&&(i.ids[0]=!0)),r=e.VM.resolvePartial.call(this,r,s,i);var a=e.VM.invokePartial.call(this,r,s,i);if(null==a&&e.compile&&(i.partials[i.name]=e.compile(r,t.compilerOptions,e),a=i.partials[i.name](s,i)),null!=a){if(i.indent){for(var n=a.split("\n"),o=0,c=n.length;o<c&&(n[o]||o+1!==c);o++)n[o]=i.indent+n[o];a=n.join("\n")}return a}throw new g["default"]("The partial "+i.name+" could not be compiled when running in runtime-only mode")}function s(e){function r(e){return""+t.main(i,e,i.helpers,i.partials,n,c,o)}var a=arguments.length<=1||void 0===arguments[1]?{}:arguments[1],n=a.data;s._setup(a),!a.partial&&t.useData&&(n=h(e,n));var o=void 0,c=t.useBlockParams?[]:void 0;return t.useDepths&&(o=a.depths?e!==a.depths[0]?[e].concat(a.depths):a.depths:[e]),(r=l(t.main,r,i,a.depths||[],n,c))(e,a)}if(!e)throw new g["default"]("No environment passed to template");if(!t||!t.main)throw new g["default"]("Unknown template object: "+typeof t);t.main.decorator=t.main_d,e.VM.checkRevision(t.compiler);var i={strict:function(t,e){if(!(e in t))throw new g["default"]('"'+e+'" not defined in '+t);return t[e]},lookup:function(t,e){for(var r=t.length,s=0;s<r;s++)if(t[s]&&null!=t[s][e])return t[s][e]},lambda:function(t,e){return"function"==typeof t?t.call(e):t},escapeExpression:d.escapeExpression,invokePartial:r,fn:function(e){var r=t[e];return r.decorator=t[e+"_d"],r},programs:[],program:function(t,e,r,s,i){var n=this.programs[t],o=this.fn(t);return e||i||s||r?n=a(this,t,o,e,r,s,i):n||(n=this.programs[t]=a(this,t,o)),n},data:function(t,e){for(;t&&e--;)t=t._parent;return t},merge:function(t,e){var r=t||e;return t&&e&&t!==e&&(r=d.extend({},e,t)),r},noop:e.VM.noop,compilerInfo:t.compiler};return s.isTop=!0,s._setup=function(r){r.partial?(i.helpers=r.helpers,i.partials=r.partials,i.decorators=r.decorators):(i.helpers=i.merge(r.helpers,e.helpers),t.usePartial&&(i.partials=i.merge(r.partials,e.partials)),(t.usePartial||t.useDecorators)&&(i.decorators=i.merge(r.decorators,e.decorators)))},s._child=function(e,r,s,n){if(t.useBlockParams&&!s)throw new g["default"]("must pass block params");if(t.useDepths&&!n)throw new g["default"]("must pass parent depths");return a(i,e,t[e],r,0,s,n)},s}function a(t,e,r,s,i,a,n){function o(e){var i=arguments.length<=1||void 0===arguments[1]?{}:arguments[1],o=n;return n&&e!==n[0]&&(o=[e].concat(n)),r(t,e,t.helpers,t.partials,i.data||s,a&&[i.blockParams].concat(a),o)}return o=l(r,o,t,n,s,a),o.program=e,o.depth=n?n.length:0,o.blockParams=i||0,o}function n(t,e,r){return t?t.call||r.name||(r.name=t,t=r.partials[t]):t="@partial-block"===r.name?r.data["partial-block"]:r.partials[r.name],t}function o(t,e,r){r.partial=!0,r.ids&&(r.data.contextPath=r.ids[0]||r.data.contextPath);var s=void 0;if(r.fn&&r.fn!==c&&(r.data=v.createFrame(r.data),s=r.data["partial-block"]=r.fn,s.partials&&(r.partials=d.extend({},r.partials,s.partials))),void 0===t&&s&&(t=s),void 0===t)throw new g["default"]("The partial "+r.name+" could not be found");if(t instanceof Function)return t(e,r)}function c(){return""}function h(t,e){return e&&"root"in e||(e=e?v.createFrame(e):{},e.root=t),e}function l(t,e,r,s,i,a){if(t.decorator){var n={};e=t.decorator(e,n,r,s&&s[0],i,a,s),d.extend(e,n)}return e}var p=r(3)["default"],u=r(1)["default"];e.__esModule=!0,e.checkRevision=s,e.template=i,e.wrapProgram=a,e.resolvePartial=n,e.invokePartial=o,e.noop=c;var f=r(5),d=p(f),m=r(6),g=u(m),v=r(4)},function(t,e){(function(r){"use strict";e.__esModule=!0,e["default"]=function(t){var e="undefined"!=typeof r?r:window,s=e.Handlebars;t.noConflict=function(){return e.Handlebars===t&&(e.Handlebars=s),t}},t.exports=e["default"]}).call(e,function(){return this}())},function(t,e){"use strict";e.__esModule=!0;var r={helpers:{helperExpression:function(t){return"SubExpression"===t.type||("MustacheStatement"===t.type||"BlockStatement"===t.type)&&!!(t.params&&t.params.length||t.hash)},scopedId:function(t){return/^\.|this\b/.test(t.original)},simpleId:function(t){return 1===t.parts.length&&!r.helpers.scopedId(t)&&!t.depth}}};e["default"]=r,t.exports=e["default"]},function(t,e,r){"use strict";function s(t,e){if("Program"===t.type)return t;o["default"].yy=f,f.locInfo=function(t){return new f.SourceLocation(e&&e.srcName,t)};var r=new h["default"](e);return r.accept(o["default"].parse(t))}var i=r(1)["default"],a=r(3)["default"];e.__esModule=!0,e.parse=s;var n=r(23),o=i(n),c=r(24),h=i(c),l=r(26),p=a(l),u=r(5);e.parser=o["default"];var f={};u.extend(f,p)},function(t,e){"use strict";var r=function(){function t(){this.yy={}}var e={trace:function(){},yy:{},symbols_:{error:2,root:3,program:4,EOF:5,program_repetition0:6,statement:7,mustache:8,block:9,rawBlock:10,partial:11,partialBlock:12,content:13,COMMENT:14,CONTENT:15,openRawBlock:16,rawBlock_repetition_plus0:17,END_RAW_BLOCK:18,OPEN_RAW_BLOCK:19,helperName:20,openRawBlock_repetition0:21,openRawBlock_option0:22,CLOSE_RAW_BLOCK:23,openBlock:24,block_option0:25,closeBlock:26,openInverse:27,block_option1:28,OPEN_BLOCK:29,openBlock_repetition0:30,openBlock_option0:31,openBlock_option1:32,CLOSE:33,OPEN_INVERSE:34,openInverse_repetition0:35,openInverse_option0:36,openInverse_option1:37,openInverseChain:38,OPEN_INVERSE_CHAIN:39,openInverseChain_repetition0:40,openInverseChain_option0:41,openInverseChain_option1:42,inverseAndProgram:43,INVERSE:44,inverseChain:45,inverseChain_option0:46,OPEN_ENDBLOCK:47,OPEN:48,mustache_repetition0:49,mustache_option0:50,OPEN_UNESCAPED:51,mustache_repetition1:52,mustache_option1:53,CLOSE_UNESCAPED:54,OPEN_PARTIAL:55,partialName:56,partial_repetition0:57,partial_option0:58,openPartialBlock:59,OPEN_PARTIAL_BLOCK:60,openPartialBlock_repetition0:61,openPartialBlock_option0:62,param:63,sexpr:64,OPEN_SEXPR:65,sexpr_repetition0:66,sexpr_option0:67,CLOSE_SEXPR:68,hash:69,hash_repetition_plus0:70,hashSegment:71,ID:72,EQUALS:73,blockParams:74,OPEN_BLOCK_PARAMS:75,blockParams_repetition_plus0:76,CLOSE_BLOCK_PARAMS:77,path:78,dataName:79,STRING:80,NUMBER:81,BOOLEAN:82,UNDEFINED:83,NULL:84,DATA:85,pathSegments:86,SEP:87,$accept:0,$end:1},terminals_:{2:"error",5:"EOF",14:"COMMENT",15:"CONTENT",18:"END_RAW_BLOCK",19:"OPEN_RAW_BLOCK",23:"CLOSE_RAW_BLOCK",29:"OPEN_BLOCK",33:"CLOSE",34:"OPEN_INVERSE",39:"OPEN_INVERSE_CHAIN",44:"INVERSE",47:"OPEN_ENDBLOCK",48:"OPEN",51:"OPEN_UNESCAPED",54:"CLOSE_UNESCAPED",55:"OPEN_PARTIAL",60:"OPEN_PARTIAL_BLOCK",65:"OPEN_SEXPR",68:"CLOSE_SEXPR",72:"ID",73:"EQUALS",75:"OPEN_BLOCK_PARAMS",77:"CLOSE_BLOCK_PARAMS",80:"STRING",81:"NUMBER",82:"BOOLEAN",83:"UNDEFINED",84:"NULL",85:"DATA",87:"SEP"},productions_:[0,[3,2],[4,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[13,1],[10,3],[16,5],[9,4],[9,4],[24,6],[27,6],[38,6],[43,2],[45,3],[45,1],[26,3],[8,5],[8,5],[11,5],[12,3],[59,5],[63,1],[63,1],[64,5],[69,1],[71,3],[74,3],[20,1],[20,1],[20,1],[20,1],[20,1],[20,1],[20,1],[56,1],[56,1],[79,2],[78,1],[86,3],[86,1],[6,0],[6,2],[17,1],[17,2],[21,0],[21,2],[22,0],[22,1],[25,0],[25,1],[28,0],[28,1],[30,0],[30,2],[31,0],[31,1],[32,0],[32,1],[35,0],[35,2],[36,0],[36,1],[37,0],[37,1],[40,0],[40,2],[41,0],[41,1],[42,0],[42,1],[46,0],[46,1],[49,0],[49,2],[50,0],[50,1],[52,0],[52,2],[53,0],[53,1],[57,0],[57,2],[58,0],[58,1],[61,0],[61,2],[62,0],[62,1],[66,0],[66,2],[67,0],[67,1],[70,1],[70,2],[76,1],[76,2]],performAction:function(t,e,r,s,i,a,n){var o=a.length-1;switch(i){case 1:return a[o-1];case 2:this.$=s.prepareProgram(a[o]);break;case 3:this.$=a[o];break;case 4:this.$=a[o];break;case 5:this.$=a[o];break;case 6:this.$=a[o];break;case 7:this.$=a[o];break;case 8:this.$=a[o];break;case 9:this.$={type:"CommentStatement",value:s.stripComment(a[o]),strip:s.stripFlags(a[o],a[o]),loc:s.locInfo(this._$)};break;case 10:this.$={type:"ContentStatement",original:a[o],value:a[o],loc:s.locInfo(this._$)};break;case 11:this.$=s.prepareRawBlock(a[o-2],a[o-1],a[o],this._$);break;case 12:this.$={path:a[o-3],params:a[o-2],hash:a[o-1]};break;case 13:this.$=s.prepareBlock(a[o-3],a[o-2],a[o-1],a[o],!1,this._$);break;case 14:this.$=s.prepareBlock(a[o-3],a[o-2],a[o-1],a[o],!0,this._$);break;case 15:this.$={open:a[o-5],path:a[o-4],params:a[o-3],hash:a[o-2],blockParams:a[o-1],strip:s.stripFlags(a[o-5],a[o])};break;case 16:this.$={path:a[o-4],params:a[o-3],hash:a[o-2],blockParams:a[o-1],strip:s.stripFlags(a[o-5],a[o])};break;case 17:this.$={path:a[o-4],params:a[o-3],hash:a[o-2],blockParams:a[o-1],strip:s.stripFlags(a[o-5],a[o])};break;case 18:this.$={strip:s.stripFlags(a[o-1],a[o-1]),program:a[o]};break;case 19:var c=s.prepareBlock(a[o-2],a[o-1],a[o],a[o],!1,this._$),h=s.prepareProgram([c],a[o-1].loc);h.chained=!0,this.$={strip:a[o-2].strip,program:h,chain:!0};break;case 20:this.$=a[o];break;case 21:this.$={path:a[o-1],strip:s.stripFlags(a[o-2],a[o])};break;case 22:this.$=s.prepareMustache(a[o-3],a[o-2],a[o-1],a[o-4],s.stripFlags(a[o-4],a[o]),this._$);break;case 23:this.$=s.prepareMustache(a[o-3],a[o-2],a[o-1],a[o-4],s.stripFlags(a[o-4],a[o]),this._$);break;case 24:this.$={type:"PartialStatement",name:a[o-3],params:a[o-2],hash:a[o-1],indent:"",strip:s.stripFlags(a[o-4],a[o]),loc:s.locInfo(this._$)};break;case 25:this.$=s.preparePartialBlock(a[o-2],a[o-1],a[o],this._$);break;case 26:this.$={path:a[o-3],params:a[o-2],hash:a[o-1],strip:s.stripFlags(a[o-4],a[o])};break;case 27:this.$=a[o];break;case 28:this.$=a[o];break;case 29:this.$={type:"SubExpression",path:a[o-3],params:a[o-2],hash:a[o-1],loc:s.locInfo(this._$)};break;case 30:this.$={type:"Hash",pairs:a[o],loc:s.locInfo(this._$)};break;case 31:this.$={type:"HashPair",key:s.id(a[o-2]),value:a[o],loc:s.locInfo(this._$)};break;case 32:this.$=s.id(a[o-1]);break;case 33:this.$=a[o];break;case 34:this.$=a[o];break;case 35:this.$={type:"StringLiteral",value:a[o],original:a[o],loc:s.locInfo(this._$)};break;case 36:this.$={type:"NumberLiteral",value:Number(a[o]),original:Number(a[o]),loc:s.locInfo(this._$)};break;case 37:this.$={type:"BooleanLiteral",value:"true"===a[o],original:"true"===a[o],loc:s.locInfo(this._$)};break;case 38:this.$={type:"UndefinedLiteral",original:void 0,value:void 0,loc:s.locInfo(this._$)};break;case 39:this.$={type:"NullLiteral",original:null,value:null,loc:s.locInfo(this._$)};break;case 40:this.$=a[o];break;case 41:this.$=a[o];break;case 42:this.$=s.preparePath(!0,a[o],this._$);break;case 43:this.$=s.preparePath(!1,a[o],this._$);break;case 44:a[o-2].push({part:s.id(a[o]),original:a[o],separator:a[o-1]}),this.$=a[o-2];break;case 45:this.$=[{part:s.id(a[o]),original:a[o]}];break;case 46:this.$=[];break;case 47:a[o-1].push(a[o]);break;case 48:this.$=[a[o]];break;case 49:a[o-1].push(a[o]);break;case 50:this.$=[];break;case 51:a[o-1].push(a[o]);break;case 58:this.$=[];break;case 59:a[o-1].push(a[o]);break;case 64:this.$=[];break;case 65:a[o-1].push(a[o]);break;case 70:this.$=[];break;case 71:a[o-1].push(a[o]);break;case 78:this.$=[];break;case 79:a[o-1].push(a[o]);break;case 82:this.$=[];break;case 83:a[o-1].push(a[o]);break;case 86:this.$=[];break;case 87:a[o-1].push(a[o]);break;case 90:this.$=[];break;case 91:a[o-1].push(a[o]);break;case 94:this.$=[];break;case 95:a[o-1].push(a[o]);break;case 98:this.$=[a[o]];break;case 99:a[o-1].push(a[o]);break;case 100:this.$=[a[o]];break;case 101:a[o-1].push(a[o])}},table:[{3:1,4:2,5:[2,46],6:3,14:[2,46],15:[2,46],19:[2,46],29:[2,46],34:[2,46],48:[2,46],51:[2,46],55:[2,46],60:[2,46]},{1:[3]},{5:[1,4]},{5:[2,2],7:5,8:6,9:7,10:8,11:9,12:10,13:11,14:[1,12],15:[1,20],16:17,19:[1,23],24:15,27:16,29:[1,21],34:[1,22],39:[2,2],44:[2,2],47:[2,2],48:[1,13],51:[1,14],55:[1,18],59:19,60:[1,24]},{1:[2,1]},{5:[2,47],14:[2,47],15:[2,47],19:[2,47],29:[2,47],34:[2,47],39:[2,47],44:[2,47],47:[2,47],48:[2,47],51:[2,47],55:[2,47],60:[2,47]},{5:[2,3],14:[2,3],15:[2,3],19:[2,3],29:[2,3],34:[2,3],39:[2,3],44:[2,3],47:[2,3],48:[2,3],51:[2,3],55:[2,3],60:[2,3]},{5:[2,4],14:[2,4],15:[2,4],19:[2,4],29:[2,4],34:[2,4],39:[2,4],44:[2,4],47:[2,4],48:[2,4],51:[2,4],55:[2,4],60:[2,4]},{5:[2,5],14:[2,5],15:[2,5],19:[2,5],29:[2,5],34:[2,5],39:[2,5],44:[2,5],47:[2,5],48:[2,5],51:[2,5],55:[2,5],60:[2,5]},{5:[2,6],14:[2,6],15:[2,6],19:[2,6],29:[2,6],34:[2,6],39:[2,6],44:[2,6],47:[2,6],48:[2,6],51:[2,6],55:[2,6],60:[2,6]},{5:[2,7],14:[2,7],15:[2,7],19:[2,7],29:[2,7],34:[2,7],39:[2,7],44:[2,7],47:[2,7],48:[2,7],51:[2,7],55:[2,7],60:[2,7]},{5:[2,8],14:[2,8],15:[2,8],19:[2,8],29:[2,8],34:[2,8],39:[2,8],44:[2,8],47:[2,8],48:[2,8],51:[2,8],55:[2,8],60:[2,8]},{5:[2,9],14:[2,9],15:[2,9],19:[2,9],29:[2,9],34:[2,9],39:[2,9],44:[2,9],47:[2,9],48:[2,9],51:[2,9],55:[2,9],60:[2,9]},{20:25,72:[1,35],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{20:36,72:[1,35],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{4:37,6:3,14:[2,46],15:[2,46],19:[2,46],29:[2,46],34:[2,46],39:[2,46],44:[2,46],47:[2,46],48:[2,46],51:[2,46],55:[2,46],60:[2,46]},{4:38,6:3,14:[2,46],15:[2,46],19:[2,46],29:[2,46],34:[2,46],44:[2,46],47:[2,46],48:[2,46],51:[2,46],55:[2,46],60:[2,46]},{13:40,15:[1,20],17:39},{20:42,56:41,64:43,65:[1,44],72:[1,35],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{4:45,6:3,14:[2,46],15:[2,46],19:[2,46],29:[2,46],34:[2,46],47:[2,46],48:[2,46],51:[2,46],55:[2,46],60:[2,46]},{5:[2,10],14:[2,10],15:[2,10],18:[2,10],19:[2,10],29:[2,10],34:[2,10],39:[2,10],44:[2,10],47:[2,10],48:[2,10],51:[2,10],55:[2,10],60:[2,10]},{20:46,72:[1,35],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{20:47,72:[1,35],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{20:48,72:[1,35],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{20:42,56:49,64:43,65:[1,44],72:[1,35],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{33:[2,78],49:50,65:[2,78],72:[2,78],80:[2,78],81:[2,78],82:[2,78],83:[2,78],84:[2,78],85:[2,78]},{23:[2,33],33:[2,33],54:[2,33],65:[2,33],68:[2,33],72:[2,33],75:[2,33],80:[2,33],81:[2,33],82:[2,33],83:[2,33],84:[2,33],85:[2,33]},{23:[2,34],33:[2,34],54:[2,34],65:[2,34],68:[2,34],72:[2,34],75:[2,34],80:[2,34],81:[2,34],82:[2,34],83:[2,34],84:[2,34],85:[2,34]},{23:[2,35],33:[2,35],54:[2,35],65:[2,35],68:[2,35],72:[2,35],75:[2,35],80:[2,35],81:[2,35],82:[2,35],83:[2,35],84:[2,35],85:[2,35]},{23:[2,36],33:[2,36],54:[2,36],65:[2,36],68:[2,36],72:[2,36],75:[2,36],80:[2,36],81:[2,36],82:[2,36],83:[2,36],84:[2,36],85:[2,36]},{23:[2,37],33:[2,37],54:[2,37],65:[2,37],68:[2,37],72:[2,37],75:[2,37],80:[2,37],81:[2,37],82:[2,37],83:[2,37],84:[2,37],85:[2,37]},{23:[2,38],33:[2,38],54:[2,38],65:[2,38],68:[2,38],72:[2,38],75:[2,38],80:[2,38],81:[2,38],82:[2,38],83:[2,38],84:[2,38],85:[2,38]},{23:[2,39],33:[2,39],54:[2,39],65:[2,39],68:[2,39],72:[2,39],75:[2,39],80:[2,39],81:[2,39],82:[2,39],83:[2,39],84:[2,39],85:[2,39]},{23:[2,43],33:[2,43],54:[2,43],65:[2,43],68:[2,43],72:[2,43],75:[2,43],80:[2,43],81:[2,43],82:[2,43],83:[2,43],84:[2,43],85:[2,43],87:[1,51]},{72:[1,35],86:52},{23:[2,45],33:[2,45],54:[2,45],65:[2,45],68:[2,45],72:[2,45],75:[2,45],80:[2,45],81:[2,45],82:[2,45],83:[2,45],84:[2,45],85:[2,45],87:[2,45]},{52:53,54:[2,82],65:[2,82],72:[2,82],80:[2,82],81:[2,82],82:[2,82],83:[2,82],84:[2,82],85:[2,82]},{25:54,38:56,39:[1,58],43:57,44:[1,59],45:55,47:[2,54]},{28:60,43:61,44:[1,59],47:[2,56]},{13:63,15:[1,20],18:[1,62]},{15:[2,48],18:[2,48]},{33:[2,86],57:64,65:[2,86],72:[2,86],80:[2,86],81:[2,86],82:[2,86],83:[2,86],84:[2,86],85:[2,86]},{33:[2,40],65:[2,40],72:[2,40],80:[2,40],81:[2,40],82:[2,40],83:[2,40],84:[2,40],85:[2,40]},{33:[2,41],65:[2,41],72:[2,41],80:[2,41],81:[2,41],82:[2,41],83:[2,41],84:[2,41],85:[2,41]},{20:65,72:[1,35],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{26:66,47:[1,67]},{30:68,33:[2,58],65:[2,58],72:[2,58],75:[2,58],80:[2,58],81:[2,58],82:[2,58],83:[2,58],84:[2,58],85:[2,58]},{33:[2,64],35:69,65:[2,64],72:[2,64],75:[2,64],80:[2,64],81:[2,64],82:[2,64],83:[2,64],84:[2,64],85:[2,64]},{21:70,23:[2,50],65:[2,50],72:[2,50],80:[2,50],81:[2,50],82:[2,50],83:[2,50],84:[2,50],85:[2,50]},{33:[2,90],61:71,65:[2,90],72:[2,90],80:[2,90],81:[2,90],82:[2,90],83:[2,90],84:[2,90],85:[2,90]},{20:75,33:[2,80],50:72,63:73,64:76,65:[1,44],69:74,70:77,71:78,72:[1,79],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{72:[1,80]},{23:[2,42],33:[2,42],54:[2,42],65:[2,42],68:[2,42],72:[2,42],75:[2,42],80:[2,42],81:[2,42],82:[2,42],83:[2,42],84:[2,42],85:[2,42],87:[1,51]},{20:75,53:81,54:[2,84],63:82,64:76,65:[1,44],69:83,70:77,71:78,72:[1,79],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{26:84,47:[1,67]},{47:[2,55]},{4:85,6:3,14:[2,46],15:[2,46],19:[2,46],29:[2,46],34:[2,46],39:[2,46],44:[2,46],47:[2,46],48:[2,46],51:[2,46],55:[2,46],60:[2,46]},{47:[2,20]},{20:86,72:[1,35],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{4:87,6:3,14:[2,46],15:[2,46],19:[2,46],29:[2,46],34:[2,46],47:[2,46],48:[2,46],51:[2,46],55:[2,46],60:[2,46]},{26:88,47:[1,67]},{47:[2,57]},{5:[2,11],14:[2,11],15:[2,11],19:[2,11],29:[2,11],34:[2,11],39:[2,11],44:[2,11],47:[2,11],48:[2,11],51:[2,11],55:[2,11],60:[2,11]},{15:[2,49],18:[2,49]},{20:75,33:[2,88],58:89,63:90,64:76,65:[1,44],69:91,70:77,71:78,72:[1,79],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{65:[2,94],66:92,68:[2,94],72:[2,94],80:[2,94],81:[2,94],82:[2,94],83:[2,94],84:[2,94],85:[2,94]},{5:[2,25],14:[2,25],15:[2,25],19:[2,25],29:[2,25],34:[2,25],39:[2,25],44:[2,25],47:[2,25],48:[2,25],51:[2,25],55:[2,25],60:[2,25]},{20:93,72:[1,35],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{20:75,31:94,33:[2,60],63:95,64:76,65:[1,44],69:96,70:77,71:78,72:[1,79],75:[2,60],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{20:75,33:[2,66],36:97,63:98,64:76,65:[1,44],69:99,70:77,71:78,72:[1,79],75:[2,66],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{20:75,22:100,23:[2,52],63:101,64:76,65:[1,44],69:102,70:77,71:78,72:[1,79],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{20:75,33:[2,92],62:103,63:104,64:76,65:[1,44],69:105,70:77,71:78,72:[1,79],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{33:[1,106]},{33:[2,79],65:[2,79],72:[2,79],80:[2,79],81:[2,79],82:[2,79],83:[2,79],84:[2,79],85:[2,79]},{33:[2,81]},{23:[2,27],33:[2,27],54:[2,27],65:[2,27],68:[2,27],72:[2,27],75:[2,27],80:[2,27],81:[2,27],82:[2,27],83:[2,27],84:[2,27],85:[2,27]},{23:[2,28],33:[2,28],54:[2,28],65:[2,28],68:[2,28],72:[2,28],75:[2,28],80:[2,28],81:[2,28],82:[2,28],83:[2,28],84:[2,28],85:[2,28]},{23:[2,30],33:[2,30],54:[2,30],68:[2,30],71:107,72:[1,108],75:[2,30]},{23:[2,98],33:[2,98],54:[2,98],68:[2,98],72:[2,98],75:[2,98]},{23:[2,45],33:[2,45],54:[2,45],65:[2,45],68:[2,45],72:[2,45],73:[1,109],75:[2,45],80:[2,45],81:[2,45],82:[2,45],83:[2,45],84:[2,45],85:[2,45],87:[2,45]},{23:[2,44],33:[2,44],54:[2,44],65:[2,44],68:[2,44],72:[2,44],75:[2,44],80:[2,44],81:[2,44],82:[2,44],83:[2,44],84:[2,44],85:[2,44],87:[2,44]},{54:[1,110]},{54:[2,83],65:[2,83],72:[2,83],80:[2,83],81:[2,83],82:[2,83],83:[2,83],84:[2,83],85:[2,83]},{54:[2,85]},{5:[2,13],14:[2,13],15:[2,13],19:[2,13],29:[2,13],34:[2,13],39:[2,13],44:[2,13],47:[2,13],48:[2,13],51:[2,13],55:[2,13],60:[2,13]},{38:56,39:[1,58],43:57,44:[1,59],45:112,46:111,47:[2,76]},{33:[2,70],40:113,65:[2,70],72:[2,70],75:[2,70],80:[2,70],81:[2,70],82:[2,70],83:[2,70],84:[2,70],85:[2,70]},{47:[2,18]},{5:[2,14],14:[2,14],15:[2,14],19:[2,14],29:[2,14],34:[2,14],39:[2,14],44:[2,14],47:[2,14],48:[2,14],51:[2,14],55:[2,14],60:[2,14]},{33:[1,114]},{33:[2,87],65:[2,87],72:[2,87],80:[2,87],81:[2,87],82:[2,87],83:[2,87],84:[2,87],85:[2,87]},{33:[2,89]},{20:75,63:116,64:76,65:[1,44],67:115,68:[2,96],69:117,70:77,71:78,72:[1,79],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{33:[1,118]},{32:119,33:[2,62],74:120,75:[1,121]},{33:[2,59],65:[2,59],72:[2,59],75:[2,59],80:[2,59],81:[2,59],82:[2,59],83:[2,59],84:[2,59],85:[2,59]},{33:[2,61],75:[2,61]},{33:[2,68],37:122,74:123,75:[1,121]},{33:[2,65],65:[2,65],72:[2,65],75:[2,65],80:[2,65],81:[2,65],82:[2,65],83:[2,65],84:[2,65],85:[2,65]},{33:[2,67],75:[2,67]},{23:[1,124]},{23:[2,51],65:[2,51],72:[2,51],80:[2,51],81:[2,51],82:[2,51],83:[2,51],84:[2,51],85:[2,51]},{23:[2,53]},{33:[1,125]},{33:[2,91],65:[2,91],72:[2,91],80:[2,91],81:[2,91],82:[2,91],83:[2,91],84:[2,91],85:[2,91]},{33:[2,93]},{5:[2,22],14:[2,22],15:[2,22],19:[2,22],29:[2,22],34:[2,22],39:[2,22],44:[2,22],47:[2,22],48:[2,22],51:[2,22],55:[2,22],60:[2,22]},{23:[2,99],33:[2,99],54:[2,99],68:[2,99],72:[2,99],75:[2,99]},{73:[1,109]},{20:75,63:126,64:76,65:[1,44],72:[1,35],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{5:[2,23],14:[2,23],15:[2,23],19:[2,23],29:[2,23],34:[2,23],39:[2,23],44:[2,23],47:[2,23],48:[2,23],51:[2,23],55:[2,23],60:[2,23]},{47:[2,19]},{47:[2,77]},{20:75,33:[2,72],41:127,63:128,64:76,65:[1,44],69:129,70:77,71:78,72:[1,79],75:[2,72],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{5:[2,24],14:[2,24],15:[2,24],19:[2,24],29:[2,24],34:[2,24],39:[2,24],44:[2,24],47:[2,24],48:[2,24],51:[2,24],55:[2,24],60:[2,24]},{68:[1,130]},{65:[2,95],68:[2,95],72:[2,95],80:[2,95],81:[2,95],82:[2,95],83:[2,95],84:[2,95],85:[2,95]},{68:[2,97]},{5:[2,21],14:[2,21],15:[2,21],19:[2,21],29:[2,21],34:[2,21],39:[2,21],44:[2,21],47:[2,21],48:[2,21],51:[2,21],55:[2,21],60:[2,21]},{33:[1,131]},{33:[2,63]},{72:[1,133],76:132},{33:[1,134]},{33:[2,69]},{15:[2,12]},{14:[2,26],15:[2,26],19:[2,26],29:[2,26],34:[2,26],47:[2,26],48:[2,26],51:[2,26],55:[2,26],60:[2,26]},{23:[2,31],33:[2,31],54:[2,31],68:[2,31],72:[2,31],75:[2,31]},{33:[2,74],42:135,74:136,75:[1,121]},{33:[2,71],65:[2,71],72:[2,71],75:[2,71],80:[2,71],81:[2,71],82:[2,71],83:[2,71],84:[2,71],85:[2,71]},{33:[2,73],75:[2,73]},{23:[2,29],33:[2,29],54:[2,29],65:[2,29],68:[2,29],72:[2,29],75:[2,29],80:[2,29],81:[2,29],82:[2,29],83:[2,29],84:[2,29],85:[2,29]},{14:[2,15],15:[2,15],19:[2,15],29:[2,15],34:[2,15],39:[2,15],44:[2,15],47:[2,15],48:[2,15],51:[2,15],55:[2,15],60:[2,15]},{72:[1,138],77:[1,137]},{72:[2,100],77:[2,100]},{14:[2,16],15:[2,16],19:[2,16],29:[2,16],34:[2,16],44:[2,16],47:[2,16],
+48:[2,16],51:[2,16],55:[2,16],60:[2,16]},{33:[1,139]},{33:[2,75]},{33:[2,32]},{72:[2,101],77:[2,101]},{14:[2,17],15:[2,17],19:[2,17],29:[2,17],34:[2,17],39:[2,17],44:[2,17],47:[2,17],48:[2,17],51:[2,17],55:[2,17],60:[2,17]}],defaultActions:{4:[2,1],55:[2,55],57:[2,20],61:[2,57],74:[2,81],83:[2,85],87:[2,18],91:[2,89],102:[2,53],105:[2,93],111:[2,19],112:[2,77],117:[2,97],120:[2,63],123:[2,69],124:[2,12],136:[2,75],137:[2,32]},parseError:function(t,e){throw new Error(t)},parse:function(t){function e(){var t;return t=r.lexer.lex()||1,"number"!=typeof t&&(t=r.symbols_[t]||t),t}var r=this,s=[0],i=[null],a=[],n=this.table,o="",c=0,h=0,l=0;this.lexer.setInput(t),this.lexer.yy=this.yy,this.yy.lexer=this.lexer,this.yy.parser=this,"undefined"==typeof this.lexer.yylloc&&(this.lexer.yylloc={});var p=this.lexer.yylloc;a.push(p);var u=this.lexer.options&&this.lexer.options.ranges;"function"==typeof this.yy.parseError&&(this.parseError=this.yy.parseError);for(var f,d,m,g,v,y,k,S,b,_={};;){if(m=s[s.length-1],this.defaultActions[m]?g=this.defaultActions[m]:(null!==f&&"undefined"!=typeof f||(f=e()),g=n[m]&&n[m][f]),"undefined"==typeof g||!g.length||!g[0]){var P="";if(!l){b=[];for(y in n[m])this.terminals_[y]&&y>2&&b.push("'"+this.terminals_[y]+"'");P=this.lexer.showPosition?"Parse error on line "+(c+1)+":\n"+this.lexer.showPosition()+"\nExpecting "+b.join(", ")+", got '"+(this.terminals_[f]||f)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==f?"end of input":"'"+(this.terminals_[f]||f)+"'"),this.parseError(P,{text:this.lexer.match,token:this.terminals_[f]||f,line:this.lexer.yylineno,loc:p,expected:b})}}if(g[0]instanceof Array&&g.length>1)throw new Error("Parse Error: multiple actions possible at state: "+m+", token: "+f);switch(g[0]){case 1:s.push(f),i.push(this.lexer.yytext),a.push(this.lexer.yylloc),s.push(g[1]),f=null,d?(f=d,d=null):(h=this.lexer.yyleng,o=this.lexer.yytext,c=this.lexer.yylineno,p=this.lexer.yylloc,l>0&&l--);break;case 2:if(k=this.productions_[g[1]][1],_.$=i[i.length-k],_._$={first_line:a[a.length-(k||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(k||1)].first_column,last_column:a[a.length-1].last_column},u&&(_._$.range=[a[a.length-(k||1)].range[0],a[a.length-1].range[1]]),v=this.performAction.call(_,o,h,c,this.yy,g[1],i,a),"undefined"!=typeof v)return v;k&&(s=s.slice(0,-1*k*2),i=i.slice(0,-1*k),a=a.slice(0,-1*k)),s.push(this.productions_[g[1]][0]),i.push(_.$),a.push(_._$),S=n[s[s.length-2]][s[s.length-1]],s.push(S);break;case 3:return!0}}return!0}},r=function(){var t={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t){return this._input=t,this._more=this._less=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t;var e=t.match(/(?:\r\n?|\n).*/g);return e?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,r=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e-1),this.offset-=e;var s=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),r.length-1&&(this.yylineno-=r.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:r?(r.length===s.length?this.yylloc.first_column:0)+s[s.length-r.length].length-r[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this},more:function(){return this._more=!0,this},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var t,e,r,s,i;this._more||(this.yytext="",this.match="");for(var a=this._currentRules(),n=0;n<a.length&&(r=this._input.match(this.rules[a[n]]),!r||e&&!(r[0].length>e[0].length)||(e=r,s=n,this.options.flex));n++);return e?(i=e[0].match(/(?:\r\n?|\n).*/g),i&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+e[0].length},this.yytext+=e[0],this.match+=e[0],this.matches=e,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._input=this._input.slice(e[0].length),this.matched+=e[0],t=this.performAction.call(this,this.yy,this,a[s],this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),t?t:void 0):""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return"undefined"!=typeof t?t:this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.pop()},_currentRules:function(){return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules},topState:function(){return this.conditionStack[this.conditionStack.length-2]},pushState:function(t){this.begin(t)}};return t.options={},t.performAction=function(t,e,r,s){function i(t,r){return e.yytext=e.yytext.substr(t,e.yyleng-r)}switch(r){case 0:if("\\\\"===e.yytext.slice(-2)?(i(0,1),this.begin("mu")):"\\"===e.yytext.slice(-1)?(i(0,1),this.begin("emu")):this.begin("mu"),e.yytext)return 15;break;case 1:return 15;case 2:return this.popState(),15;case 3:return this.begin("raw"),15;case 4:return this.popState(),"raw"===this.conditionStack[this.conditionStack.length-1]?15:(e.yytext=e.yytext.substr(5,e.yyleng-9),"END_RAW_BLOCK");case 5:return 15;case 6:return this.popState(),14;case 7:return 65;case 8:return 68;case 9:return 19;case 10:return this.popState(),this.begin("raw"),23;case 11:return 55;case 12:return 60;case 13:return 29;case 14:return 47;case 15:return this.popState(),44;case 16:return this.popState(),44;case 17:return 34;case 18:return 39;case 19:return 51;case 20:return 48;case 21:this.unput(e.yytext),this.popState(),this.begin("com");break;case 22:return this.popState(),14;case 23:return 48;case 24:return 73;case 25:return 72;case 26:return 72;case 27:return 87;case 28:break;case 29:return this.popState(),54;case 30:return this.popState(),33;case 31:return e.yytext=i(1,2).replace(/\\"/g,'"'),80;case 32:return e.yytext=i(1,2).replace(/\\'/g,"'"),80;case 33:return 85;case 34:return 82;case 35:return 82;case 36:return 83;case 37:return 84;case 38:return 81;case 39:return 75;case 40:return 77;case 41:return 72;case 42:return e.yytext=e.yytext.replace(/\\([\\\]])/g,"$1"),72;case 43:return"INVALID";case 44:return 5}},t.rules=[/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/,/^(?:\{\{\{\{(?=[^\/]))/,/^(?:\{\{\{\{\/[^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=[=}\s\/.])\}\}\}\})/,/^(?:[^\x00]*?(?=(\{\{\{\{)))/,/^(?:[\s\S]*?--(~)?\}\})/,/^(?:\()/,/^(?:\))/,/^(?:\{\{\{\{)/,/^(?:\}\}\}\})/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#>)/,/^(?:\{\{(~)?#\*?)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^\s*(~)?\}\})/,/^(?:\{\{(~)?\s*else\s*(~)?\}\})/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{(~)?!--)/,/^(?:\{\{(~)?![\s\S]*?\}\})/,/^(?:\{\{(~)?\*?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.)|])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s)])))/,/^(?:false(?=([~}\s)])))/,/^(?:undefined(?=([~}\s)])))/,/^(?:null(?=([~}\s)])))/,/^(?:-?[0-9]+(?:\.[0-9]+)?(?=([~}\s)])))/,/^(?:as\s+\|)/,/^(?:\|)/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)|]))))/,/^(?:\[(\\\]|[^\]])*\])/,/^(?:.)/,/^(?:$)/],t.conditions={mu:{rules:[7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44],inclusive:!1},emu:{rules:[2],inclusive:!1},com:{rules:[6],inclusive:!1},raw:{rules:[3,4,5],inclusive:!1},INITIAL:{rules:[0,1,44],inclusive:!0}},t}();return e.lexer=r,t.prototype=e,e.Parser=t,new t}();e.__esModule=!0,e["default"]=r},function(t,e,r){"use strict";function s(){var t=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];this.options=t}function i(t,e,r){void 0===e&&(e=t.length);var s=t[e-1],i=t[e-2];return s?"ContentStatement"===s.type?(i||!r?/\r?\n\s*?$/:/(^|\r?\n)\s*?$/).test(s.original):void 0:r}function a(t,e,r){void 0===e&&(e=-1);var s=t[e+1],i=t[e+2];return s?"ContentStatement"===s.type?(i||!r?/^\s*?\r?\n/:/^\s*?(\r?\n|$)/).test(s.original):void 0:r}function n(t,e,r){var s=t[null==e?0:e+1];if(s&&"ContentStatement"===s.type&&(r||!s.rightStripped)){var i=s.value;s.value=s.value.replace(r?/^\s+/:/^[ \t]*\r?\n?/,""),s.rightStripped=s.value!==i}}function o(t,e,r){var s=t[null==e?t.length-1:e-1];if(s&&"ContentStatement"===s.type&&(r||!s.leftStripped)){var i=s.value;return s.value=s.value.replace(r?/\s+$/:/[ \t]+$/,""),s.leftStripped=s.value!==i,s.leftStripped}}var c=r(1)["default"];e.__esModule=!0;var h=r(25),l=c(h);s.prototype=new l["default"],s.prototype.Program=function(t){var e=!this.options.ignoreStandalone,r=!this.isRootSeen;this.isRootSeen=!0;for(var s=t.body,c=0,h=s.length;c<h;c++){var l=s[c],p=this.accept(l);if(p){var u=i(s,c,r),f=a(s,c,r),d=p.openStandalone&&u,m=p.closeStandalone&&f,g=p.inlineStandalone&&u&&f;p.close&&n(s,c,!0),p.open&&o(s,c,!0),e&&g&&(n(s,c),o(s,c)&&"PartialStatement"===l.type&&(l.indent=/([ \t]+$)/.exec(s[c-1].original)[1])),e&&d&&(n((l.program||l.inverse).body),o(s,c)),e&&m&&(n(s,c),o((l.inverse||l.program).body))}}return t},s.prototype.BlockStatement=s.prototype.DecoratorBlock=s.prototype.PartialBlockStatement=function(t){this.accept(t.program),this.accept(t.inverse);var e=t.program||t.inverse,r=t.program&&t.inverse,s=r,c=r;if(r&&r.chained)for(s=r.body[0].program;c.chained;)c=c.body[c.body.length-1].program;var h={open:t.openStrip.open,close:t.closeStrip.close,openStandalone:a(e.body),closeStandalone:i((s||e).body)};if(t.openStrip.close&&n(e.body,null,!0),r){var l=t.inverseStrip;l.open&&o(e.body,null,!0),l.close&&n(s.body,null,!0),t.closeStrip.open&&o(c.body,null,!0),!this.options.ignoreStandalone&&i(e.body)&&a(s.body)&&(o(e.body),n(s.body))}else t.closeStrip.open&&o(e.body,null,!0);return h},s.prototype.Decorator=s.prototype.MustacheStatement=function(t){return t.strip},s.prototype.PartialStatement=s.prototype.CommentStatement=function(t){var e=t.strip||{};return{inlineStandalone:!0,open:e.open,close:e.close}},e["default"]=s,t.exports=e["default"]},function(t,e,r){"use strict";function s(){this.parents=[]}function i(t){this.acceptRequired(t,"path"),this.acceptArray(t.params),this.acceptKey(t,"hash")}function a(t){i.call(this,t),this.acceptKey(t,"program"),this.acceptKey(t,"inverse")}function n(t){this.acceptRequired(t,"name"),this.acceptArray(t.params),this.acceptKey(t,"hash")}var o=r(1)["default"];e.__esModule=!0;var c=r(6),h=o(c);s.prototype={constructor:s,mutating:!1,acceptKey:function(t,e){var r=this.accept(t[e]);if(this.mutating){if(r&&!s.prototype[r.type])throw new h["default"]('Unexpected node type "'+r.type+'" found when accepting '+e+" on "+t.type);t[e]=r}},acceptRequired:function(t,e){if(this.acceptKey(t,e),!t[e])throw new h["default"](t.type+" requires "+e)},acceptArray:function(t){for(var e=0,r=t.length;e<r;e++)this.acceptKey(t,e),t[e]||(t.splice(e,1),e--,r--)},accept:function(t){if(t){if(!this[t.type])throw new h["default"]("Unknown type: "+t.type,t);this.current&&this.parents.unshift(this.current),this.current=t;var e=this[t.type](t);return this.current=this.parents.shift(),!this.mutating||e?e:e!==!1?t:void 0}},Program:function(t){this.acceptArray(t.body)},MustacheStatement:i,Decorator:i,BlockStatement:a,DecoratorBlock:a,PartialStatement:n,PartialBlockStatement:function(t){n.call(this,t),this.acceptKey(t,"program")},ContentStatement:function(){},CommentStatement:function(){},SubExpression:i,PathExpression:function(){},StringLiteral:function(){},NumberLiteral:function(){},BooleanLiteral:function(){},UndefinedLiteral:function(){},NullLiteral:function(){},Hash:function(t){this.acceptArray(t.pairs)},HashPair:function(t){this.acceptRequired(t,"value")}},e["default"]=s,t.exports=e["default"]},function(t,e,r){"use strict";function s(t,e){if(e=e.path?e.path.original:e,t.path.original!==e){var r={loc:t.path.loc};throw new g["default"](t.path.original+" doesn't match "+e,r)}}function i(t,e){this.source=t,this.start={line:e.first_line,column:e.first_column},this.end={line:e.last_line,column:e.last_column}}function a(t){return/^\[.*\]$/.test(t)?t.substr(1,t.length-2):t}function n(t,e){return{open:"~"===t.charAt(2),close:"~"===e.charAt(e.length-3)}}function o(t){return t.replace(/^\{\{~?\!-?-?/,"").replace(/-?-?~?\}\}$/,"")}function c(t,e,r){r=this.locInfo(r);for(var s=t?"@":"",i=[],a=0,n="",o=0,c=e.length;o<c;o++){var h=e[o].part,l=e[o].original!==h;if(s+=(e[o].separator||"")+h,l||".."!==h&&"."!==h&&"this"!==h)i.push(h);else{if(i.length>0)throw new g["default"]("Invalid path: "+s,{loc:r});".."===h&&(a++,n+="../")}}return{type:"PathExpression",data:t,depth:a,parts:i,original:s,loc:r}}function h(t,e,r,s,i,a){var n=s.charAt(3)||s.charAt(2),o="{"!==n&&"&"!==n,c=/\*/.test(s);return{type:c?"Decorator":"MustacheStatement",path:t,params:e,hash:r,escaped:o,strip:i,loc:this.locInfo(a)}}function l(t,e,r,i){s(t,r),i=this.locInfo(i);var a={type:"Program",body:e,strip:{},loc:i};return{type:"BlockStatement",path:t.path,params:t.params,hash:t.hash,program:a,openStrip:{},inverseStrip:{},closeStrip:{},loc:i}}function p(t,e,r,i,a,n){i&&i.path&&s(t,i);var o=/\*/.test(t.open);e.blockParams=t.blockParams;var c=void 0,h=void 0;if(r){if(o)throw new g["default"]("Unexpected inverse block on decorator",r);r.chain&&(r.program.body[0].closeStrip=i.strip),h=r.strip,c=r.program}return a&&(a=c,c=e,e=a),{type:o?"DecoratorBlock":"BlockStatement",path:t.path,params:t.params,hash:t.hash,program:e,inverse:c,openStrip:t.strip,inverseStrip:h,closeStrip:i&&i.strip,loc:this.locInfo(n)}}function u(t,e){if(!e&&t.length){var r=t[0].loc,s=t[t.length-1].loc;r&&s&&(e={source:r.source,start:{line:r.start.line,column:r.start.column},end:{line:s.end.line,column:s.end.column}})}return{type:"Program",body:t,strip:{},loc:e}}function f(t,e,r,i){return s(t,r),{type:"PartialBlockStatement",name:t.path,params:t.params,hash:t.hash,program:e,openStrip:t.strip,closeStrip:r&&r.strip,loc:this.locInfo(i)}}var d=r(1)["default"];e.__esModule=!0,e.SourceLocation=i,e.id=a,e.stripFlags=n,e.stripComment=o,e.preparePath=c,e.prepareMustache=h,e.prepareRawBlock=l,e.prepareBlock=p,e.prepareProgram=u,e.preparePartialBlock=f;var m=r(6),g=d(m)},function(t,e,r){"use strict";function s(){}function i(t,e,r){if(null==t||"string"!=typeof t&&"Program"!==t.type)throw new l["default"]("You must pass a string or Handlebars AST to Handlebars.precompile. You passed "+t);e=e||{},"data"in e||(e.data=!0),e.compat&&(e.useDepths=!0);var s=r.parse(t,e),i=(new r.Compiler).compile(s,e);return(new r.JavaScriptCompiler).compile(i,e)}function a(t,e,r){function s(){var s=r.parse(t,e),i=(new r.Compiler).compile(s,e),a=(new r.JavaScriptCompiler).compile(i,e,void 0,!0);return r.template(a)}function i(t,e){return a||(a=s()),a.call(this,t,e)}if(void 0===e&&(e={}),null==t||"string"!=typeof t&&"Program"!==t.type)throw new l["default"]("You must pass a string or Handlebars AST to Handlebars.compile. You passed "+t);"data"in e||(e.data=!0),e.compat&&(e.useDepths=!0);var a=void 0;return i._setup=function(t){return a||(a=s()),a._setup(t)},i._child=function(t,e,r,i){return a||(a=s()),a._child(t,e,r,i)},i}function n(t,e){if(t===e)return!0;if(p.isArray(t)&&p.isArray(e)&&t.length===e.length){for(var r=0;r<t.length;r++)if(!n(t[r],e[r]))return!1;return!0}}function o(t){if(!t.path.parts){var e=t.path;t.path={type:"PathExpression",data:!1,depth:0,parts:[e.original+""],original:e.original+"",loc:e.loc}}}var c=r(1)["default"];e.__esModule=!0,e.Compiler=s,e.precompile=i,e.compile=a;var h=r(6),l=c(h),p=r(5),u=r(21),f=c(u),d=[].slice;s.prototype={compiler:s,equals:function(t){var e=this.opcodes.length;if(t.opcodes.length!==e)return!1;for(var r=0;r<e;r++){var s=this.opcodes[r],i=t.opcodes[r];if(s.opcode!==i.opcode||!n(s.args,i.args))return!1}e=this.children.length;for(var r=0;r<e;r++)if(!this.children[r].equals(t.children[r]))return!1;return!0},guid:0,compile:function(t,e){this.sourceNode=[],this.opcodes=[],this.children=[],this.options=e,this.stringParams=e.stringParams,this.trackIds=e.trackIds,e.blockParams=e.blockParams||[];var r=e.knownHelpers;if(e.knownHelpers={helperMissing:!0,blockHelperMissing:!0,each:!0,"if":!0,unless:!0,"with":!0,log:!0,lookup:!0},r)for(var s in r)s in r&&(e.knownHelpers[s]=r[s]);return this.accept(t)},compileProgram:function(t){var e=new this.compiler,r=e.compile(t,this.options),s=this.guid++;return this.usePartial=this.usePartial||r.usePartial,this.children[s]=r,this.useDepths=this.useDepths||r.useDepths,s},accept:function(t){if(!this[t.type])throw new l["default"]("Unknown type: "+t.type,t);this.sourceNode.unshift(t);var e=this[t.type](t);return this.sourceNode.shift(),e},Program:function(t){this.options.blockParams.unshift(t.blockParams);for(var e=t.body,r=e.length,s=0;s<r;s++)this.accept(e[s]);return this.options.blockParams.shift(),this.isSimple=1===r,this.blockParams=t.blockParams?t.blockParams.length:0,this},BlockStatement:function(t){o(t);var e=t.program,r=t.inverse;e=e&&this.compileProgram(e),r=r&&this.compileProgram(r);var s=this.classifySexpr(t);"helper"===s?this.helperSexpr(t,e,r):"simple"===s?(this.simpleSexpr(t),this.opcode("pushProgram",e),this.opcode("pushProgram",r),this.opcode("emptyHash"),this.opcode("blockValue",t.path.original)):(this.ambiguousSexpr(t,e,r),this.opcode("pushProgram",e),this.opcode("pushProgram",r),this.opcode("emptyHash"),this.opcode("ambiguousBlockValue")),this.opcode("append")},DecoratorBlock:function(t){var e=t.program&&this.compileProgram(t.program),r=this.setupFullMustacheParams(t,e,void 0),s=t.path;this.useDecorators=!0,this.opcode("registerDecorator",r.length,s.original)},PartialStatement:function(t){this.usePartial=!0;var e=t.program;e&&(e=this.compileProgram(t.program));var r=t.params;if(r.length>1)throw new l["default"]("Unsupported number of partial arguments: "+r.length,t);r.length||(this.options.explicitPartialContext?this.opcode("pushLiteral","undefined"):r.push({type:"PathExpression",parts:[],depth:0}));var s=t.name.original,i="SubExpression"===t.name.type;i&&this.accept(t.name),this.setupFullMustacheParams(t,e,void 0,!0);var a=t.indent||"";this.options.preventIndent&&a&&(this.opcode("appendContent",a),a=""),this.opcode("invokePartial",i,s,a),this.opcode("append")},PartialBlockStatement:function(t){this.PartialStatement(t)},MustacheStatement:function(t){this.SubExpression(t),t.escaped&&!this.options.noEscape?this.opcode("appendEscaped"):this.opcode("append")},Decorator:function(t){this.DecoratorBlock(t)},ContentStatement:function(t){t.value&&this.opcode("appendContent",t.value)},CommentStatement:function(){},SubExpression:function(t){o(t);var e=this.classifySexpr(t);"simple"===e?this.simpleSexpr(t):"helper"===e?this.helperSexpr(t):this.ambiguousSexpr(t)},ambiguousSexpr:function(t,e,r){var s=t.path,i=s.parts[0],a=null!=e||null!=r;this.opcode("getContext",s.depth),this.opcode("pushProgram",e),this.opcode("pushProgram",r),s.strict=!0,this.accept(s),this.opcode("invokeAmbiguous",i,a)},simpleSexpr:function(t){var e=t.path;e.strict=!0,this.accept(e),this.opcode("resolvePossibleLambda")},helperSexpr:function(t,e,r){var s=this.setupFullMustacheParams(t,e,r),i=t.path,a=i.parts[0];if(this.options.knownHelpers[a])this.opcode("invokeKnownHelper",s.length,a);else{if(this.options.knownHelpersOnly)throw new l["default"]("You specified knownHelpersOnly, but used the unknown helper "+a,t);i.strict=!0,i.falsy=!0,this.accept(i),this.opcode("invokeHelper",s.length,i.original,f["default"].helpers.simpleId(i))}},PathExpression:function(t){this.addDepth(t.depth),this.opcode("getContext",t.depth);var e=t.parts[0],r=f["default"].helpers.scopedId(t),s=!t.depth&&!r&&this.blockParamIndex(e);s?this.opcode("lookupBlockParam",s,t.parts):e?t.data?(this.options.data=!0,this.opcode("lookupData",t.depth,t.parts,t.strict)):this.opcode("lookupOnContext",t.parts,t.falsy,t.strict,r):this.opcode("pushContext")},StringLiteral:function(t){this.opcode("pushString",t.value)},NumberLiteral:function(t){this.opcode("pushLiteral",t.value)},BooleanLiteral:function(t){this.opcode("pushLiteral",t.value)},UndefinedLiteral:function(){this.opcode("pushLiteral","undefined")},NullLiteral:function(){this.opcode("pushLiteral","null")},Hash:function(t){var e=t.pairs,r=0,s=e.length;for(this.opcode("pushHash");r<s;r++)this.pushParam(e[r].value);for(;r--;)this.opcode("assignToHash",e[r].key);this.opcode("popHash")},opcode:function(t){this.opcodes.push({opcode:t,args:d.call(arguments,1),loc:this.sourceNode[0].loc})},addDepth:function(t){t&&(this.useDepths=!0)},classifySexpr:function(t){var e=f["default"].helpers.simpleId(t.path),r=e&&!!this.blockParamIndex(t.path.parts[0]),s=!r&&f["default"].helpers.helperExpression(t),i=!r&&(s||e);if(i&&!s){var a=t.path.parts[0],n=this.options;n.knownHelpers[a]?s=!0:n.knownHelpersOnly&&(i=!1)}return s?"helper":i?"ambiguous":"simple"},pushParams:function(t){for(var e=0,r=t.length;e<r;e++)this.pushParam(t[e])},pushParam:function(t){var e=null!=t.value?t.value:t.original||"";if(this.stringParams)e.replace&&(e=e.replace(/^(\.?\.\/)*/g,"").replace(/\//g,".")),t.depth&&this.addDepth(t.depth),this.opcode("getContext",t.depth||0),this.opcode("pushStringParam",e,t.type),"SubExpression"===t.type&&this.accept(t);else{if(this.trackIds){var r=void 0;if(!t.parts||f["default"].helpers.scopedId(t)||t.depth||(r=this.blockParamIndex(t.parts[0])),r){var s=t.parts.slice(1).join(".");this.opcode("pushId","BlockParam",r,s)}else e=t.original||e,e.replace&&(e=e.replace(/^this(?:\.|$)/,"").replace(/^\.\//,"").replace(/^\.$/,"")),this.opcode("pushId",t.type,e)}this.accept(t)}},setupFullMustacheParams:function(t,e,r,s){var i=t.params;return this.pushParams(i),this.opcode("pushProgram",e),this.opcode("pushProgram",r),t.hash?this.accept(t.hash):this.opcode("emptyHash",s),i},blockParamIndex:function(t){for(var e=0,r=this.options.blockParams.length;e<r;e++){var s=this.options.blockParams[e],i=s&&p.indexOf(s,t);if(s&&i>=0)return[e,i]}}}},function(t,e,r){"use strict";function s(t){this.value=t}function i(){}function a(t,e,r,s){var i=e.popStack(),a=0,n=r.length;for(t&&n--;a<n;a++)i=e.nameLookup(i,r[a],s);return t?[e.aliasable("container.strict"),"(",i,", ",e.quotedString(r[a]),")"]:i}var n=r(1)["default"];e.__esModule=!0;var o=r(4),c=r(6),h=n(c),l=r(5),p=r(29),u=n(p);i.prototype={nameLookup:function(t,e){return i.isValidJavaScriptVariableName(e)?[t,".",e]:[t,"[",JSON.stringify(e),"]"]},depthedLookup:function(t){return[this.aliasable("container.lookup"),'(depths, "',t,'")']},compilerInfo:function(){var t=o.COMPILER_REVISION,e=o.REVISION_CHANGES[t];return[t,e]},appendToBuffer:function(t,e,r){return l.isArray(t)||(t=[t]),t=this.source.wrap(t,e),this.environment.isSimple?["return ",t,";"]:r?["buffer += ",t,";"]:(t.appendToBuffer=!0,t)},initializeBuffer:function(){return this.quotedString("")},compile:function(t,e,r,s){this.environment=t,this.options=e,this.stringParams=this.options.stringParams,this.trackIds=this.options.trackIds,this.precompile=!s,this.name=this.environment.name,this.isChild=!!r,this.context=r||{decorators:[],programs:[],environments:[]},this.preamble(),this.stackSlot=0,this.stackVars=[],this.aliases={},this.registers={list:[]},this.hashes=[],this.compileStack=[],this.inlineStack=[],this.blockParams=[],this.compileChildren(t,e),this.useDepths=this.useDepths||t.useDepths||t.useDecorators||this.options.compat,this.useBlockParams=this.useBlockParams||t.useBlockParams;var i=t.opcodes,a=void 0,n=void 0,o=void 0,c=void 0;for(o=0,c=i.length;o<c;o++)a=i[o],this.source.currentLocation=a.loc,n=n||a.loc,this[a.opcode].apply(this,a.args);if(this.source.currentLocation=n,this.pushSource(""),this.stackSlot||this.inlineStack.length||this.compileStack.length)throw new h["default"]("Compile completed with content left on stack");this.decorators.isEmpty()?this.decorators=void 0:(this.useDecorators=!0,this.decorators.prepend("var decorators = container.decorators;\n"),this.decorators.push("return fn;"),s?this.decorators=Function.apply(this,["fn","props","container","depth0","data","blockParams","depths",this.decorators.merge()]):(this.decorators.prepend("function(fn, props, container, depth0, data, blockParams, depths) {\n"),this.decorators.push("}\n"),this.decorators=this.decorators.merge()));var l=this.createFunctionContext(s);if(this.isChild)return l;var p={compiler:this.compilerInfo(),main:l};this.decorators&&(p.main_d=this.decorators,p.useDecorators=!0);var u=this.context,f=u.programs,d=u.decorators;for(o=0,c=f.length;o<c;o++)f[o]&&(p[o]=f[o],d[o]&&(p[o+"_d"]=d[o],p.useDecorators=!0));return this.environment.usePartial&&(p.usePartial=!0),this.options.data&&(p.useData=!0),this.useDepths&&(p.useDepths=!0),this.useBlockParams&&(p.useBlockParams=!0),this.options.compat&&(p.compat=!0),s?p.compilerOptions=this.options:(p.compiler=JSON.stringify(p.compiler),this.source.currentLocation={start:{line:1,column:0}},p=this.objectLiteral(p),e.srcName?(p=p.toStringWithSourceMap({file:e.destName}),p.map=p.map&&p.map.toString()):p=p.toString()),p},preamble:function(){this.lastContext=0,this.source=new u["default"](this.options.srcName),this.decorators=new u["default"](this.options.srcName)},createFunctionContext:function(t){var e="",r=this.stackVars.concat(this.registers.list);r.length>0&&(e+=", "+r.join(", "));var s=0;for(var i in this.aliases){var a=this.aliases[i];this.aliases.hasOwnProperty(i)&&a.children&&a.referenceCount>1&&(e+=", alias"+ ++s+"="+i,a.children[0]="alias"+s)}var n=["container","depth0","helpers","partials","data"];(this.useBlockParams||this.useDepths)&&n.push("blockParams"),this.useDepths&&n.push("depths");var o=this.mergeSource(e);return t?(n.push(o),Function.apply(this,n)):this.source.wrap(["function(",n.join(","),") {\n  ",o,"}"])},mergeSource:function(t){var e=this.environment.isSimple,r=!this.forceBuffer,s=void 0,i=void 0,a=void 0,n=void 0;return this.source.each(function(t){t.appendToBuffer?(a?t.prepend("  + "):a=t,n=t):(a&&(i?a.prepend("buffer += "):s=!0,n.add(";"),a=n=void 0),i=!0,e||(r=!1))}),r?a?(a.prepend("return "),n.add(";")):i||this.source.push('return "";'):(t+=", buffer = "+(s?"":this.initializeBuffer()),a?(a.prepend("return buffer + "),n.add(";")):this.source.push("return buffer;")),t&&this.source.prepend("var "+t.substring(2)+(s?"":";\n")),this.source.merge()},blockValue:function(t){var e=this.aliasable("helpers.blockHelperMissing"),r=[this.contextName(0)];this.setupHelperArgs(t,0,r);var s=this.popStack();r.splice(1,0,s),this.push(this.source.functionCall(e,"call",r))},ambiguousBlockValue:function(){var t=this.aliasable("helpers.blockHelperMissing"),e=[this.contextName(0)];this.setupHelperArgs("",0,e,!0),this.flushInline();var r=this.topStack();e.splice(1,0,r),this.pushSource(["if (!",this.lastHelper,") { ",r," = ",this.source.functionCall(t,"call",e),"}"])},appendContent:function(t){this.pendingContent?t=this.pendingContent+t:this.pendingLocation=this.source.currentLocation,this.pendingContent=t},append:function(){if(this.isInline())this.replaceStack(function(t){return[" != null ? ",t,' : ""']}),this.pushSource(this.appendToBuffer(this.popStack()));else{var t=this.popStack();this.pushSource(["if (",t," != null) { ",this.appendToBuffer(t,void 0,!0)," }"]),this.environment.isSimple&&this.pushSource(["else { ",this.appendToBuffer("''",void 0,!0)," }"])}},appendEscaped:function(){this.pushSource(this.appendToBuffer([this.aliasable("container.escapeExpression"),"(",this.popStack(),")"]))},getContext:function(t){this.lastContext=t},pushContext:function(){this.pushStackLiteral(this.contextName(this.lastContext))},lookupOnContext:function(t,e,r,s){var i=0;s||!this.options.compat||this.lastContext?this.pushContext():this.push(this.depthedLookup(t[i++])),this.resolvePath("context",t,i,e,r)},lookupBlockParam:function(t,e){this.useBlockParams=!0,this.push(["blockParams[",t[0],"][",t[1],"]"]),this.resolvePath("context",e,1)},lookupData:function(t,e,r){t?this.pushStackLiteral("container.data(data, "+t+")"):this.pushStackLiteral("data"),this.resolvePath("data",e,0,!0,r)},resolvePath:function(t,e,r,s,i){var n=this;if(this.options.strict||this.options.assumeObjects)return void this.push(a(this.options.strict&&i,this,e,t));for(var o=e.length;r<o;r++)this.replaceStack(function(i){var a=n.nameLookup(i,e[r],t);return s?[" && ",a]:[" != null ? ",a," : ",i]})},resolvePossibleLambda:function(){this.push([this.aliasable("container.lambda"),"(",this.popStack(),", ",this.contextName(0),")"])},pushStringParam:function(t,e){this.pushContext(),this.pushString(e),"SubExpression"!==e&&("string"==typeof t?this.pushString(t):this.pushStackLiteral(t))},emptyHash:function(t){this.trackIds&&this.push("{}"),this.stringParams&&(this.push("{}"),this.push("{}")),this.pushStackLiteral(t?"undefined":"{}")},pushHash:function(){this.hash&&this.hashes.push(this.hash),this.hash={values:[],types:[],contexts:[],ids:[]}},popHash:function(){var t=this.hash;this.hash=this.hashes.pop(),this.trackIds&&this.push(this.objectLiteral(t.ids)),this.stringParams&&(this.push(this.objectLiteral(t.contexts)),this.push(this.objectLiteral(t.types))),this.push(this.objectLiteral(t.values))},pushString:function(t){this.pushStackLiteral(this.quotedString(t))},pushLiteral:function(t){this.pushStackLiteral(t)},pushProgram:function(t){null!=t?this.pushStackLiteral(this.programExpression(t)):this.pushStackLiteral(null)},registerDecorator:function(t,e){var r=this.nameLookup("decorators",e,"decorator"),s=this.setupHelperArgs(e,t);this.decorators.push(["fn = ",this.decorators.functionCall(r,"",["fn","props","container",s])," || fn;"])},invokeHelper:function(t,e,r){var s=this.popStack(),i=this.setupHelper(t,e),a=r?[i.name," || "]:"",n=["("].concat(a,s);this.options.strict||n.push(" || ",this.aliasable("helpers.helperMissing")),n.push(")"),this.push(this.source.functionCall(n,"call",i.callParams))},invokeKnownHelper:function(t,e){var r=this.setupHelper(t,e);this.push(this.source.functionCall(r.name,"call",r.callParams))},invokeAmbiguous:function(t,e){this.useRegister("helper");var r=this.popStack();this.emptyHash();var s=this.setupHelper(0,t,e),i=this.lastHelper=this.nameLookup("helpers",t,"helper"),a=["(","(helper = ",i," || ",r,")"];this.options.strict||(a[0]="(helper = ",a.push(" != null ? helper : ",this.aliasable("helpers.helperMissing"))),this.push(["(",a,s.paramsInit?["),(",s.paramsInit]:[],"),","(typeof helper === ",this.aliasable('"function"')," ? ",this.source.functionCall("helper","call",s.callParams)," : helper))"])},invokePartial:function(t,e,r){var s=[],i=this.setupParams(e,1,s);t&&(e=this.popStack(),delete i.name),r&&(i.indent=JSON.stringify(r)),i.helpers="helpers",i.partials="partials",i.decorators="container.decorators",t?s.unshift(e):s.unshift(this.nameLookup("partials",e,"partial")),this.options.compat&&(i.depths="depths"),i=this.objectLiteral(i),
+s.push(i),this.push(this.source.functionCall("container.invokePartial","",s))},assignToHash:function(t){var e=this.popStack(),r=void 0,s=void 0,i=void 0;this.trackIds&&(i=this.popStack()),this.stringParams&&(s=this.popStack(),r=this.popStack());var a=this.hash;r&&(a.contexts[t]=r),s&&(a.types[t]=s),i&&(a.ids[t]=i),a.values[t]=e},pushId:function(t,e,r){"BlockParam"===t?this.pushStackLiteral("blockParams["+e[0]+"].path["+e[1]+"]"+(r?" + "+JSON.stringify("."+r):"")):"PathExpression"===t?this.pushString(e):"SubExpression"===t?this.pushStackLiteral("true"):this.pushStackLiteral("null")},compiler:i,compileChildren:function(t,e){for(var r=t.children,s=void 0,i=void 0,a=0,n=r.length;a<n;a++){s=r[a],i=new this.compiler;var o=this.matchExistingProgram(s);null==o?(this.context.programs.push(""),o=this.context.programs.length,s.index=o,s.name="program"+o,this.context.programs[o]=i.compile(s,e,this.context,!this.precompile),this.context.decorators[o]=i.decorators,this.context.environments[o]=s,this.useDepths=this.useDepths||i.useDepths,this.useBlockParams=this.useBlockParams||i.useBlockParams):(s.index=o,s.name="program"+o,this.useDepths=this.useDepths||s.useDepths,this.useBlockParams=this.useBlockParams||s.useBlockParams)}},matchExistingProgram:function(t){for(var e=0,r=this.context.environments.length;e<r;e++){var s=this.context.environments[e];if(s&&s.equals(t))return e}},programExpression:function(t){var e=this.environment.children[t],r=[e.index,"data",e.blockParams];return(this.useBlockParams||this.useDepths)&&r.push("blockParams"),this.useDepths&&r.push("depths"),"container.program("+r.join(", ")+")"},useRegister:function(t){this.registers[t]||(this.registers[t]=!0,this.registers.list.push(t))},push:function(t){return t instanceof s||(t=this.source.wrap(t)),this.inlineStack.push(t),t},pushStackLiteral:function(t){this.push(new s(t))},pushSource:function(t){this.pendingContent&&(this.source.push(this.appendToBuffer(this.source.quotedString(this.pendingContent),this.pendingLocation)),this.pendingContent=void 0),t&&this.source.push(t)},replaceStack:function(t){var e=["("],r=void 0,i=void 0,a=void 0;if(!this.isInline())throw new h["default"]("replaceStack on non-inline");var n=this.popStack(!0);if(n instanceof s)r=[n.value],e=["(",r],a=!0;else{i=!0;var o=this.incrStack();e=["((",this.push(o)," = ",n,")"],r=this.topStack()}var c=t.call(this,r);a||this.popStack(),i&&this.stackSlot--,this.push(e.concat(c,")"))},incrStack:function(){return this.stackSlot++,this.stackSlot>this.stackVars.length&&this.stackVars.push("stack"+this.stackSlot),this.topStackName()},topStackName:function(){return"stack"+this.stackSlot},flushInline:function(){var t=this.inlineStack;this.inlineStack=[];for(var e=0,r=t.length;e<r;e++){var i=t[e];if(i instanceof s)this.compileStack.push(i);else{var a=this.incrStack();this.pushSource([a," = ",i,";"]),this.compileStack.push(a)}}},isInline:function(){return this.inlineStack.length},popStack:function(t){var e=this.isInline(),r=(e?this.inlineStack:this.compileStack).pop();if(!t&&r instanceof s)return r.value;if(!e){if(!this.stackSlot)throw new h["default"]("Invalid stack pop");this.stackSlot--}return r},topStack:function(){var t=this.isInline()?this.inlineStack:this.compileStack,e=t[t.length-1];return e instanceof s?e.value:e},contextName:function(t){return this.useDepths&&t?"depths["+t+"]":"depth"+t},quotedString:function(t){return this.source.quotedString(t)},objectLiteral:function(t){return this.source.objectLiteral(t)},aliasable:function(t){var e=this.aliases[t];return e?(e.referenceCount++,e):(e=this.aliases[t]=this.source.wrap(t),e.aliasable=!0,e.referenceCount=1,e)},setupHelper:function(t,e,r){var s=[],i=this.setupHelperArgs(e,t,s,r),a=this.nameLookup("helpers",e,"helper"),n=this.aliasable(this.contextName(0)+" != null ? "+this.contextName(0)+" : {}");return{params:s,paramsInit:i,name:a,callParams:[n].concat(s)}},setupParams:function(t,e,r){var s={},i=[],a=[],n=[],o=!r,c=void 0;o&&(r=[]),s.name=this.quotedString(t),s.hash=this.popStack(),this.trackIds&&(s.hashIds=this.popStack()),this.stringParams&&(s.hashTypes=this.popStack(),s.hashContexts=this.popStack());var h=this.popStack(),l=this.popStack();(l||h)&&(s.fn=l||"container.noop",s.inverse=h||"container.noop");for(var p=e;p--;)c=this.popStack(),r[p]=c,this.trackIds&&(n[p]=this.popStack()),this.stringParams&&(a[p]=this.popStack(),i[p]=this.popStack());return o&&(s.args=this.source.generateArray(r)),this.trackIds&&(s.ids=this.source.generateArray(n)),this.stringParams&&(s.types=this.source.generateArray(a),s.contexts=this.source.generateArray(i)),this.options.data&&(s.data="data"),this.useBlockParams&&(s.blockParams="blockParams"),s},setupHelperArgs:function(t,e,r,s){var i=this.setupParams(t,e,r);return i=this.objectLiteral(i),s?(this.useRegister("options"),r.push("options"),["options=",i]):r?(r.push(i),""):i}},function(){for(var t="break else new var case finally return void catch for switch while continue function this with default if throw delete in try do instanceof typeof abstract enum int short boolean export interface static byte extends long super char final native synchronized class float package throws const goto private transient debugger implements protected volatile double import public let yield await null true false".split(" "),e=i.RESERVED_WORDS={},r=0,s=t.length;r<s;r++)e[t[r]]=!0}(),i.isValidJavaScriptVariableName=function(t){return!i.RESERVED_WORDS[t]&&/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(t)},e["default"]=i,t.exports=e["default"]},function(t,e,r){"use strict";function s(t,e,r){if(a.isArray(t)){for(var s=[],i=0,n=t.length;i<n;i++)s.push(e.wrap(t[i],r));return s}return"boolean"==typeof t||"number"==typeof t?t+"":t}function i(t){this.srcFile=t,this.source=[]}e.__esModule=!0;var a=r(5),n=void 0;try{}catch(o){}n||(n=function(t,e,r,s){this.src="",s&&this.add(s)},n.prototype={add:function(t){a.isArray(t)&&(t=t.join("")),this.src+=t},prepend:function(t){a.isArray(t)&&(t=t.join("")),this.src=t+this.src},toStringWithSourceMap:function(){return{code:this.toString()}},toString:function(){return this.src}}),i.prototype={isEmpty:function(){return!this.source.length},prepend:function(t,e){this.source.unshift(this.wrap(t,e))},push:function(t,e){this.source.push(this.wrap(t,e))},merge:function(){var t=this.empty();return this.each(function(e){t.add(["  ",e,"\n"])}),t},each:function(t){for(var e=0,r=this.source.length;e<r;e++)t(this.source[e])},empty:function(){var t=this.currentLocation||{start:{}};return new n(t.start.line,t.start.column,this.srcFile)},wrap:function(t){var e=arguments.length<=1||void 0===arguments[1]?this.currentLocation||{start:{}}:arguments[1];return t instanceof n?t:(t=s(t,this,e),new n(e.start.line,e.start.column,this.srcFile,t))},functionCall:function(t,e,r){return r=this.generateList(r),this.wrap([t,e?"."+e+"(":"(",r,")"])},quotedString:function(t){return'"'+(t+"").replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029")+'"'},objectLiteral:function(t){var e=[];for(var r in t)if(t.hasOwnProperty(r)){var i=s(t[r],this);"undefined"!==i&&e.push([this.quotedString(r),":",i])}var a=this.generateList(e);return a.prepend("{"),a.add("}"),a},generateList:function(t){for(var e=this.empty(),r=0,i=t.length;r<i;r++)r&&e.add(","),e.add(s(t[r],this));return e},generateArray:function(t){var e=this.generateList(t);return e.prepend("["),e.add("]"),e}},e["default"]=i,t.exports=e["default"]}])});
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/highlight.9.1.0.pack.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/highlight.9.1.0.pack.js
new file mode 100644 (file)
index 0000000..7b00c68
--- /dev/null
@@ -0,0 +1 @@
+!function(e){"undefined"!=typeof exports?e(exports):(self.hljs=e({}),"function"==typeof define&&define.amd&&define("hljs",[],function(){return self.hljs}))}(function(e){function r(e){return e.replace(/&/gm,"&amp;").replace(/</gm,"&lt;").replace(/>/gm,"&gt;")}function t(e){return e.nodeName.toLowerCase()}function n(e,r){var t=e&&e.exec(r);return t&&0==t.index}function a(e){return/^(no-?highlight|plain|text)$/i.test(e)}function c(e){var r,t,n,c=e.className+" ";if(c+=e.parentNode?e.parentNode.className:"",t=/\blang(?:uage)?-([\w-]+)\b/i.exec(c))return E(t[1])?t[1]:"no-highlight";for(c=c.split(/\s+/),r=0,n=c.length;n>r;r++)if(E(c[r])||a(c[r]))return c[r]}function i(e,r){var t,n={};for(t in e)n[t]=e[t];if(r)for(t in r)n[t]=r[t];return n}function o(e){var r=[];return function n(e,a){for(var c=e.firstChild;c;c=c.nextSibling)3==c.nodeType?a+=c.nodeValue.length:1==c.nodeType&&(r.push({event:"start",offset:a,node:c}),a=n(c,a),t(c).match(/br|hr|img|input/)||r.push({event:"stop",offset:a,node:c}));return a}(e,0),r}function s(e,n,a){function c(){return e.length&&n.length?e[0].offset!=n[0].offset?e[0].offset<n[0].offset?e:n:"start"==n[0].event?e:n:e.length?e:n}function i(e){function n(e){return" "+e.nodeName+'="'+r(e.value)+'"'}l+="<"+t(e)+Array.prototype.map.call(e.attributes,n).join("")+">"}function o(e){l+="</"+t(e)+">"}function s(e){("start"==e.event?i:o)(e.node)}for(var u=0,l="",f=[];e.length||n.length;){var b=c();if(l+=r(a.substr(u,b[0].offset-u)),u=b[0].offset,b==e){f.reverse().forEach(o);do s(b.splice(0,1)[0]),b=c();while(b==e&&b.length&&b[0].offset==u);f.reverse().forEach(i)}else"start"==b[0].event?f.push(b[0].node):f.pop(),s(b.splice(0,1)[0])}return l+r(a.substr(u))}function u(e){function r(e){return e&&e.source||e}function t(t,n){return new RegExp(r(t),"m"+(e.cI?"i":"")+(n?"g":""))}function n(a,c){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var o={},s=function(r,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");o[t[0]]=[r,t[1]?Number(t[1]):1]})};"string"==typeof a.k?s("keyword",a.k):Object.keys(a.k).forEach(function(e){s(e,a.k[e])}),a.k=o}a.lR=t(a.l||/\b\w+\b/,!0),c&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=r(a.e)||"",a.eW&&c.tE&&(a.tE+=(a.e?"|":"")+c.tE)),a.i&&(a.iR=t(a.i)),void 0===a.r&&(a.r=1),a.c||(a.c=[]);var u=[];a.c.forEach(function(e){e.v?e.v.forEach(function(r){u.push(i(e,r))}):u.push("self"==e?a:e)}),a.c=u,a.c.forEach(function(e){n(e,a)}),a.starts&&n(a.starts,c);var l=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(r).filter(Boolean);a.t=l.length?t(l.join("|"),!0):{exec:function(){return null}}}}n(e)}function l(e,t,a,c){function i(e,r){for(var t=0;t<r.c.length;t++)if(n(r.c[t].bR,e))return r.c[t]}function o(e,r){if(n(e.eR,r)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?o(e.parent,r):void 0}function s(e,r){return!a&&n(r.iR,e)}function b(e,r){var t=N.cI?r[0].toLowerCase():r[0];return e.k.hasOwnProperty(t)&&e.k[t]}function g(e,r,t,n){var a=n?"":w.classPrefix,c='<span class="'+a,i=t?"":"</span>";return c+=e+'">',c+r+i}function p(){if(!M.k)return r(B);var e="",t=0;M.lR.lastIndex=0;for(var n=M.lR.exec(B);n;){e+=r(B.substr(t,n.index-t));var a=b(M,n);a?(L+=a[1],e+=g(a[0],r(n[0]))):e+=r(n[0]),t=M.lR.lastIndex,n=M.lR.exec(B)}return e+r(B.substr(t))}function h(){var e="string"==typeof M.sL;if(e&&!y[M.sL])return r(B);var t=e?l(M.sL,B,!0,R[M.sL]):f(B,M.sL.length?M.sL:void 0);return M.r>0&&(L+=t.r),e&&(R[M.sL]=t.top),g(t.language,t.value,!1,!0)}function d(){return void 0!==M.sL?h():p()}function m(e,t){var n=e.cN?g(e.cN,"",!0):"";e.rB?(x+=n,B=""):e.eB?(x+=r(t)+n,B=""):(x+=n,B=t),M=Object.create(e,{parent:{value:M}})}function v(e,t){if(B+=e,void 0===t)return x+=d(),0;var n=i(t,M);if(n)return x+=d(),m(n,t),n.rB?0:t.length;var a=o(M,t);if(a){var c=M;c.rE||c.eE||(B+=t),x+=d();do M.cN&&(x+="</span>"),L+=M.r,M=M.parent;while(M!=a.parent);return c.eE&&(x+=r(t)),B="",a.starts&&m(a.starts,""),c.rE?0:t.length}if(s(t,M))throw new Error('Illegal lexeme "'+t+'" for mode "'+(M.cN||"<unnamed>")+'"');return B+=t,t.length||1}var N=E(e);if(!N)throw new Error('Unknown language: "'+e+'"');u(N);var C,M=c||N,R={},x="";for(C=M;C!=N;C=C.parent)C.cN&&(x=g(C.cN,"",!0)+x);var B="",L=0;try{for(var S,A,k=0;M.t.lastIndex=k,S=M.t.exec(t),S;)A=v(t.substr(k,S.index-k),S[0]),k=S.index+A;for(v(t.substr(k)),C=M;C.parent;C=C.parent)C.cN&&(x+="</span>");return{r:L,value:x,language:e,top:M}}catch(I){if(-1!=I.message.indexOf("Illegal"))return{r:0,value:r(t)};throw I}}function f(e,t){t=t||w.languages||Object.keys(y);var n={r:0,value:r(e)},a=n;return t.forEach(function(r){if(E(r)){var t=l(r,e,!1);t.language=r,t.r>a.r&&(a=t),t.r>n.r&&(a=n,n=t)}}),a.language&&(n.second_best=a),n}function b(e){return w.tabReplace&&(e=e.replace(/^((<[^>]+>|\t)+)/gm,function(e,r){return r.replace(/\t/g,w.tabReplace)})),w.useBR&&(e=e.replace(/\n/g,"<br>")),e}function g(e,r,t){var n=r?C[r]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(n)&&a.push(n),a.join(" ").trim()}function p(e){var r=c(e);if(!a(r)){var t;w.useBR?(t=document.createElementNS("http://www.w3.org/1999/xhtml","div"),t.innerHTML=e.innerHTML.replace(/\n/g,"").replace(/<br[ \/]*>/g,"\n")):t=e;var n=t.textContent,i=r?l(r,n,!0):f(n),u=o(t);if(u.length){var p=document.createElementNS("http://www.w3.org/1999/xhtml","div");p.innerHTML=i.value,i.value=s(u,o(p),n)}i.value=b(i.value),e.innerHTML=i.value,e.className=g(e.className,r,i.language),e.result={language:i.language,re:i.r},i.second_best&&(e.second_best={language:i.second_best.language,re:i.second_best.r})}}function h(e){w=i(w,e)}function d(){if(!d.called){d.called=!0;var e=document.querySelectorAll("pre code");Array.prototype.forEach.call(e,p)}}function m(){addEventListener("DOMContentLoaded",d,!1),addEventListener("load",d,!1)}function v(r,t){var n=y[r]=t(e);n.aliases&&n.aliases.forEach(function(e){C[e]=r})}function N(){return Object.keys(y)}function E(e){return e=(e||"").toLowerCase(),y[e]||y[C[e]]}var w={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0},y={},C={};return e.highlight=l,e.highlightAuto=f,e.fixMarkup=b,e.highlightBlock=p,e.configure=h,e.initHighlighting=d,e.initHighlightingOnLoad=m,e.registerLanguage=v,e.listLanguages=N,e.getLanguage=E,e.inherit=i,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|like)\b/},e.C=function(r,t,n){var a=e.inherit({cN:"comment",b:r,e:t,c:[]},n||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e}),hljs.registerLanguage("json",function(e){var r={literal:"true false null"},t=[e.QSM,e.CNM],n={e:",",eW:!0,eE:!0,c:t,k:r},a={b:"{",e:"}",c:[{cN:"attr",b:'\\s*"',e:'"\\s*:\\s*',eB:!0,eE:!0,c:[e.BE],i:"\\n",starts:n}],i:"\\S"},c={b:"\\[",e:"\\]",c:[e.inherit(n)],i:"\\S"};return t.splice(t.length,0,a,c),{c:t,k:r,i:"\\S"}}),hljs.registerLanguage("xml",function(e){var r="[A-Za-z0-9\\._:-]+",t={b:/<\?(php)?(?!\w)/,e:/\?>/,sL:"php"},n={eW:!0,i:/</,r:0,c:[t,{cN:"attr",b:r,r:0},{b:"=",r:0,c:[{cN:"string",c:[t],v:[{b:/"/,e:/"/},{b:/'/,e:/'/},{b:/[^\s\/>]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xsl","plist"],cI:!0,c:[{cN:"meta",b:"<!DOCTYPE",e:">",r:10,c:[{b:"\\[",e:"\\]"}]},e.C("<!--","-->",{r:10}),{b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"<style(?=\\s|>|$)",e:">",k:{name:"style"},c:[n],starts:{e:"</style>",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"<script(?=\\s|>|$)",e:">",k:{name:"script"},c:[n],starts:{e:"</script>",rE:!0,sL:["actionscript","javascript","handlebars","xml"]}},t,{cN:"meta",b:/<\?\w+/,e:/\?>/,r:10},{cN:"tag",b:"</?",e:"/?>",c:[{cN:"name",b:/[^\/><\s]+/,r:0},n]}]}}),hljs.registerLanguage("javascript",function(e){return{aliases:["js"],k:{keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await import from as",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},c:[{cN:"meta",r:10,b:/^\s*['"]use (strict|asm)['"]/},{cN:"meta",b:/^#!/,e:/$/},e.ASM,e.QSM,{cN:"string",b:"`",e:"`",c:[e.BE,{cN:"subst",b:"\\$\\{",e:"\\}"}]},e.CLCM,e.CBCM,{cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{b:/</,e:/>\s*[);\]]/,r:0,sL:"xml"}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:[e.CLCM,e.CBCM]}],i:/\[|%/},{b:/\$[(.]/},{b:"\\."+e.IR,r:0},{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]},{bK:"constructor",e:/\{/,eE:!0}],i:/#(?!!)/}}),hljs.registerLanguage("css",function(e){var r="[a-zA-Z-][a-zA-Z0-9_-]*",t={b:/[A-Z\_\.\-]+\s*:/,rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:/\S/,e:":",eE:!0,starts:{eW:!0,eE:!0,c:[{b:/[\w-]+\s*\(/,rB:!0,c:[{cN:"built_in",b:/[\w-]+/}]},e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"number",b:"#[0-9A-Fa-f]+"},{cN:"meta",b:"!important"}]}}]};return{cI:!0,i:/[=\/|'\$]/,c:[e.CBCM,{cN:"selector-id",b:/#[A-Za-z0-9_-]+/},{cN:"selector-class",b:/\.[A-Za-z0-9_-]+/},{cN:"selector-attr",b:/\[/,e:/\]/,i:"$"},{cN:"selector-pseudo",b:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{b:"@",e:"[{;]",c:[{cN:"keyword",b:/\S+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[e.ASM,e.QSM,e.CSSNM]}]},{cN:"selector-tag",b:r,r:0},{b:"{",e:"}",i:/\S/,c:[e.CBCM,t]}]}});
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/highlight.9.1.0.pack_extended.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/highlight.9.1.0.pack_extended.js
new file mode 100644 (file)
index 0000000..162a224
--- /dev/null
@@ -0,0 +1 @@
+"use strict";!function(){var h,l;h=hljs.configure,hljs.configure=function(l){var i=l.highlightSizeThreshold;hljs.highlightSizeThreshold=i===+i?i:null,h.call(this,l)},l=hljs.highlightBlock,hljs.highlightBlock=function(h){var i=h.innerHTML,g=hljs.highlightSizeThreshold;(null==g||g>i.length)&&l.call(hljs,h)}}();
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/jquery-1.8.0.min.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/jquery-1.8.0.min.js
new file mode 100644 (file)
index 0000000..e2e2b7f
--- /dev/null
@@ -0,0 +1,3 @@
+!function(e,t){function n(e){var t=he[e]={};return K.each(e.split(te),function(e,n){t[n]=!0}),t}function r(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(me,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r||"false"!==r&&("null"===r?null:+r+""===r?+r:ge.test(r)?K.parseJSON(r):r)}catch(o){}K.data(e,n,r)}else r=t}return r}function i(e){var t;for(t in e)if(("data"!==t||!K.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}function o(){return!1}function a(){return!0}function s(e){return!e||!e.parentNode||11===e.parentNode.nodeType}function l(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}function u(e,t,n){if(t=t||0,K.isFunction(t))return K.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return K.grep(e,function(e,r){return e===t===n});if("string"==typeof t){var r=K.grep(e,function(e){return 1===e.nodeType});if(_e.test(t))return K.filter(t,r,!n);t=K.filter(t,r)}return K.grep(e,function(e,r){return K.inArray(e,t)>=0===n})}function c(e){var t=We.split("|"),n=e.createDocumentFragment();if(n.createElement)for(;t.length;)n.createElement(t.pop());return n}function f(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function p(e,t){if(1===t.nodeType&&K.hasData(e)){var n,r,i,o=K._data(e),a=K._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;r<i;r++)K.event.add(t,n,s[n][r])}a.data&&(a.data=K.extend({},a.data))}}function d(e,t){var n;1===t.nodeType&&(t.clearAttributes&&t.clearAttributes(),t.mergeAttributes&&t.mergeAttributes(e),n=t.nodeName.toLowerCase(),"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),K.support.html5Clone&&e.innerHTML&&!K.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Ve.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.selected=e.defaultSelected:"input"===n||"textarea"===n?t.defaultValue=e.defaultValue:"script"===n&&t.text!==e.text&&(t.text=e.text),t.removeAttribute(K.expando))}function h(e){return"undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName("*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll("*"):[]}function g(e){Ve.test(e.type)&&(e.defaultChecked=e.checked)}function m(e,t){if(t in e)return t;for(var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=mt.length;i--;)if(t=mt[i]+n,t in e)return t;return r}function y(e,t){return e=t||e,"none"===K.css(e,"display")||!K.contains(e.ownerDocument,e)}function v(e,t){for(var n,r,i=[],o=0,a=e.length;o<a;o++)n=e[o],n.style&&(i[o]=K._data(n,"olddisplay"),t?(!i[o]&&"none"===n.style.display&&(n.style.display=""),""===n.style.display&&y(n)&&(i[o]=K._data(n,"olddisplay",T(n.nodeName)))):(r=nt(n,"display"),!i[o]&&"none"!==r&&K._data(n,"olddisplay",r)));for(o=0;o<a;o++)n=e[o],n.style&&(t&&"none"!==n.style.display&&""!==n.style.display||(n.style.display=t?i[o]||"":"none"));return e}function b(e,t,n){var r=ut.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function x(e,t,n,r){for(var i=n===(r?"border":"content")?4:"width"===t?1:0,o=0;i<4;i+=2)"margin"===n&&(o+=K.css(e,n+gt[i],!0)),r?("content"===n&&(o-=parseFloat(nt(e,"padding"+gt[i]))||0),"margin"!==n&&(o-=parseFloat(nt(e,"border"+gt[i]+"Width"))||0)):(o+=parseFloat(nt(e,"padding"+gt[i]))||0,"padding"!==n&&(o+=parseFloat(nt(e,"border"+gt[i]+"Width"))||0));return o}function w(e,t,n){var r="width"===t?e.offsetWidth:e.offsetHeight,i=!0,o=K.support.boxSizing&&"border-box"===K.css(e,"boxSizing");if(r<=0){if(r=nt(e,t),(r<0||null==r)&&(r=e.style[t]),ct.test(r))return r;i=o&&(K.support.boxSizingReliable||r===e.style[t]),r=parseFloat(r)||0}return r+x(e,t,n||(o?"border":"content"),i)+"px"}function T(e){if(pt[e])return pt[e];var t=K("<"+e+">").appendTo(R.body),n=t.css("display");return t.remove(),"none"!==n&&""!==n||(rt=R.body.appendChild(rt||K.extend(R.createElement("iframe"),{frameBorder:0,width:0,height:0})),it&&rt.createElement||(it=(rt.contentWindow||rt.contentDocument).document,it.write("<!doctype html><html><body>"),it.close()),t=it.body.appendChild(it.createElement(e)),n=nt(t,"display"),R.body.removeChild(rt)),pt[e]=n,n}function N(e,t,n,r){var i;if(K.isArray(t))K.each(t,function(t,i){n||bt.test(e)?r(e,i):N(e+"["+("object"==typeof i?t:"")+"]",i,n,r)});else if(n||"object"!==K.type(t))r(e,t);else for(i in t)N(e+"["+i+"]",t[i],n,r)}function C(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i,o,a=t.toLowerCase().split(te),s=0,l=a.length;if(K.isFunction(n))for(;s<l;s++)r=a[s],o=/^\+/.test(r),o&&(r=r.substr(1)||"*"),i=e[r]=e[r]||[],i[o?"unshift":"push"](n)}}function E(e,n,r,i,o,a){o=o||n.dataTypes[0],a=a||{},a[o]=!0;for(var s,l=e[o],u=0,c=l?l.length:0,f=e===Ot;u<c&&(f||!s);u++)s=l[u](n,r,i),"string"==typeof s&&(!f||a[s]?s=t:(n.dataTypes.unshift(s),s=E(e,n,r,i,s,a)));return(f||!s)&&!a["*"]&&(s=E(e,n,r,i,"*",a)),s}function k(e,n){var r,i,o=K.ajaxSettings.flatOptions||{};for(r in n)n[r]!==t&&((o[r]?e:i||(i={}))[r]=n[r]);i&&K.extend(!0,e,i)}function S(e,n,r){var i,o,a,s,l=e.contents,u=e.dataTypes,c=e.responseFields;for(o in c)o in r&&(n[c[o]]=r[o]);for(;"*"===u[0];)u.shift(),i===t&&(i=e.mimeType||n.getResponseHeader("content-type"));if(i)for(o in l)if(l[o]&&l[o].test(i)){u.unshift(o);break}if(u[0]in r)a=u[0];else{for(o in r){if(!u[0]||e.converters[o+" "+u[0]]){a=o;break}s||(s=o)}a=a||s}if(a)return a!==u[0]&&u.unshift(a),r[a]}function A(e,t){var n,r,i,o,a=e.dataTypes.slice(),s=a[0],l={},u=0;if(e.dataFilter&&(t=e.dataFilter(t,e.dataType)),a[1])for(n in e.converters)l[n.toLowerCase()]=e.converters[n];for(;i=a[++u];)if("*"!==i){if("*"!==s&&s!==i){if(n=l[s+" "+i]||l["* "+i],!n)for(r in l)if(o=r.split(" "),o[1]===i&&(n=l[s+" "+o[0]]||l["* "+o[0]])){n===!0?n=l[r]:l[r]!==!0&&(i=o[0],a.splice(u--,0,i));break}if(n!==!0)if(n&&e["throws"])t=n(t);else try{t=n(t)}catch(c){return{state:"parsererror",error:n?c:"No conversion from "+s+" to "+i}}}s=i}return{state:"success",data:t}}function j(){try{return new e.XMLHttpRequest}catch(t){}}function D(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}function L(){return setTimeout(function(){Ut=t},0),Ut=K.now()}function H(e,t){K.each(t,function(t,n){for(var r=(Kt[t]||[]).concat(Kt["*"]),i=0,o=r.length;i<o;i++)if(r[i].call(e,t,n))return})}function F(e,t,n){var r,i=0,o=Qt.length,a=K.Deferred().always(function(){delete s.elem}),s=function(){for(var t=Ut||L(),n=Math.max(0,l.startTime+l.duration-t),r=1-(n/l.duration||0),i=0,o=l.tweens.length;i<o;i++)l.tweens[i].run(r);return a.notifyWith(e,[l,r,n]),r<1&&o?n:(a.resolveWith(e,[l]),!1)},l=a.promise({elem:e,props:K.extend({},t),opts:K.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:Ut||L(),duration:n.duration,tweens:[],createTween:function(t,n,r){var i=K.Tween(e,l.opts,t,n,l.opts.specialEasing[t]||l.opts.easing);return l.tweens.push(i),i},stop:function(t){for(var n=0,r=t?l.tweens.length:0;n<r;n++)l.tweens[n].run(1);return t?a.resolveWith(e,[l,t]):a.rejectWith(e,[l,t]),this}}),u=l.props;for(M(u,l.opts.specialEasing);i<o;i++)if(r=Qt[i].call(l,e,u,l.opts))return r;return H(l,u),K.isFunction(l.opts.start)&&l.opts.start.call(e,l),K.fx.timer(K.extend(s,{anim:l,queue:l.opts.queue,elem:e})),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always)}function M(e,t){var n,r,i,o,a;for(n in e)if(r=K.camelCase(n),i=t[r],o=e[n],K.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),a=K.cssHooks[r],a&&"expand"in a){o=a.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}function O(e,t,n){var r,i,o,a,s,l,u,c,f=this,p=e.style,d={},h=[],g=e.nodeType&&y(e);n.queue||(u=K._queueHooks(e,"fx"),null==u.unqueued&&(u.unqueued=0,c=u.empty.fire,u.empty.fire=function(){u.unqueued||c()}),u.unqueued++,f.always(function(){f.always(function(){u.unqueued--,K.queue(e,"fx").length||u.empty.fire()})})),1===e.nodeType&&("height"in t||"width"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],"inline"===K.css(e,"display")&&"none"===K.css(e,"float")&&(K.support.inlineBlockNeedsLayout&&"inline"!==T(e.nodeName)?p.zoom=1:p.display="inline-block")),n.overflow&&(p.overflow="hidden",K.support.shrinkWrapBlocks||f.done(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t)if(o=t[r],Jt.exec(o)){if(delete t[r],o===(g?"hide":"show"))continue;h.push(r)}if(a=h.length)for(s=K._data(e,"fxshow")||K._data(e,"fxshow",{}),g?K(e).show():f.done(function(){K(e).hide()}),f.done(function(){var t;K.removeData(e,"fxshow",!0);for(t in d)K.style(e,t,d[t])}),r=0;r<a;r++)i=h[r],l=f.createTween(i,g?s[i]:0),d[i]=s[i]||K.style(e,i),i in s||(s[i]=l.start,g&&(l.end=l.start,l.start="width"===i||"height"===i?1:0))}function _(e,t,n,r,i){return new _.prototype.init(e,t,n,r,i)}function q(e,t){for(var n,r={height:e},i=0;i<4;i+=2-t)n=gt[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}function B(e){return K.isWindow(e)?e:9===e.nodeType&&(e.defaultView||e.parentWindow)}var W,P,R=e.document,$=e.location,I=e.navigator,z=e.jQuery,X=e.$,U=Array.prototype.push,Y=Array.prototype.slice,J=Array.prototype.indexOf,V=Object.prototype.toString,G=Object.prototype.hasOwnProperty,Q=String.prototype.trim,K=function(e,t){return new K.fn.init(e,t,W)},Z=/[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source,ee=/\S/,te=/\s+/,ne=ee.test(" ")?/^[\s\xA0]+|[\s\xA0]+$/g:/^\s+|\s+$/g,re=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,ie=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,oe=/^[\],:{}\s]*$/,ae=/(?:^|:|,)(?:\s*\[)+/g,se=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,le=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,ue=/^-ms-/,ce=/-([\da-z])/gi,fe=function(e,t){return(t+"").toUpperCase()},pe=function(){R.addEventListener?(R.removeEventListener("DOMContentLoaded",pe,!1),K.ready()):"complete"===R.readyState&&(R.detachEvent("onreadystatechange",pe),K.ready())},de={};K.fn=K.prototype={constructor:K,init:function(e,n,r){var i,o,a;if(!e)return this;if(e.nodeType)return this.context=this[0]=e,this.length=1,this;if("string"==typeof e){if(i="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:re.exec(e),i&&(i[1]||!n)){if(i[1])return n=n instanceof K?n[0]:n,a=n&&n.nodeType?n.ownerDocument||n:R,e=K.parseHTML(i[1],a,!0),ie.test(i[1])&&K.isPlainObject(n)&&this.attr.call(e,n,!0),K.merge(this,e);if(o=R.getElementById(i[2]),o&&o.parentNode){if(o.id!==i[2])return r.find(e);this.length=1,this[0]=o}return this.context=R,this.selector=e,this}return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e)}return K.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),K.makeArray(e,this))},selector:"",jquery:"1.8.0",length:0,size:function(){return this.length},toArray:function(){return Y.call(this)},get:function(e){return null==e?this.toArray():e<0?this[this.length+e]:this[e]},pushStack:function(e,t,n){var r=K.merge(this.constructor(),e);return r.prevObject=this,r.context=this.context,"find"===t?r.selector=this.selector+(this.selector?" ":"")+n:t&&(r.selector=this.selector+"."+t+"("+n+")"),r},each:function(e,t){return K.each(this,e,t)},ready:function(e){return K.ready.promise().done(e),this},eq:function(e){return e=+e,e===-1?this.slice(e):this.slice(e,e+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(Y.apply(this,arguments),"slice",Y.call(arguments).join(","))},map:function(e){return this.pushStack(K.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:U,sort:[].sort,splice:[].splice},K.fn.init.prototype=K.fn,K.extend=K.fn.extend=function(){var e,n,r,i,o,a,s=arguments[0]||{},l=1,u=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[1]||{},l=2),"object"!=typeof s&&!K.isFunction(s)&&(s={}),u===l&&(s=this,--l);l<u;l++)if(null!=(e=arguments[l]))for(n in e)r=s[n],i=e[n],s!==i&&(c&&i&&(K.isPlainObject(i)||(o=K.isArray(i)))?(o?(o=!1,a=r&&K.isArray(r)?r:[]):a=r&&K.isPlainObject(r)?r:{},s[n]=K.extend(c,a,i)):i!==t&&(s[n]=i));return s},K.extend({noConflict:function(t){return e.$===K&&(e.$=X),t&&e.jQuery===K&&(e.jQuery=z),K},isReady:!1,readyWait:1,holdReady:function(e){e?K.readyWait++:K.ready(!0)},ready:function(e){if(e===!0?!--K.readyWait:!K.isReady){if(!R.body)return setTimeout(K.ready,1);K.isReady=!0,e!==!0&&--K.readyWait>0||(P.resolveWith(R,[K]),K.fn.trigger&&K(R).trigger("ready").off("ready"))}},isFunction:function(e){return"function"===K.type(e)},isArray:Array.isArray||function(e){return"array"===K.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?String(e):de[V.call(e)]||"object"},isPlainObject:function(e){if(!e||"object"!==K.type(e)||e.nodeType||K.isWindow(e))return!1;try{if(e.constructor&&!G.call(e,"constructor")&&!G.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||G.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw new Error(e)},parseHTML:function(e,t,n){var r;return e&&"string"==typeof e?("boolean"==typeof t&&(n=t,t=0),t=t||R,(r=ie.exec(e))?[t.createElement(r[1])]:(r=K.buildFragment([e],t,n?null:[]),K.merge([],(r.cacheable?K.clone(r.fragment):r.fragment).childNodes))):null},parseJSON:function(t){return t&&"string"==typeof t?(t=K.trim(t),e.JSON&&e.JSON.parse?e.JSON.parse(t):oe.test(t.replace(se,"@").replace(le,"]").replace(ae,""))?new Function("return "+t)():void K.error("Invalid JSON: "+t)):null},parseXML:function(n){var r,i;if(!n||"string"!=typeof n)return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(o){r=t}return(!r||!r.documentElement||r.getElementsByTagName("parsererror").length)&&K.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&ee.test(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(ue,"ms-").replace(ce,fe)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toUpperCase()===t.toUpperCase()},each:function(e,n,r){var i,o=0,a=e.length,s=a===t||K.isFunction(e);if(r)if(s){for(i in e)if(n.apply(e[i],r)===!1)break}else for(;o<a&&n.apply(e[o++],r)!==!1;);else if(s){for(i in e)if(n.call(e[i],i,e[i])===!1)break}else for(;o<a&&n.call(e[o],o,e[o++])!==!1;);return e},trim:Q?function(e){return null==e?"":Q.call(e)}:function(e){return null==e?"":e.toString().replace(ne,"")},makeArray:function(e,t){var n,r=t||[];return null!=e&&(n=K.type(e),null==e.length||"string"===n||"function"===n||"regexp"===n||K.isWindow(e)?U.call(r,e):K.merge(r,e)),r},inArray:function(e,t,n){var r;if(t){if(J)return J.call(t,e,n);for(r=t.length,n=n?n<0?Math.max(0,r+n):n:0;n<r;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,o=0;if("number"==typeof r)for(;o<r;o++)e[i++]=n[o];else for(;n[o]!==t;)e[i++]=n[o++];return e.length=i,e},grep:function(e,t,n){var r,i=[],o=0,a=e.length;for(n=!!n;o<a;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,n,r){var i,o,a=[],s=0,l=e.length,u=e instanceof K||l!==t&&"number"==typeof l&&(l>0&&e[0]&&e[l-1]||0===l||K.isArray(e));if(u)for(;s<l;s++)i=n(e[s],s,r),null!=i&&(a[a.length]=i);else for(o in e)i=n(e[o],o,r),null!=i&&(a[a.length]=i);return a.concat.apply([],a)},guid:1,proxy:function(e,n){var r,i,o;return"string"==typeof n&&(r=e[n],n=e,e=r),K.isFunction(e)?(i=Y.call(arguments,2),o=function(){return e.apply(n,i.concat(Y.call(arguments)))},o.guid=e.guid=e.guid||o.guid||K.guid++,o):t},access:function(e,n,r,i,o,a,s){var l,u=null==r,c=0,f=e.length;if(r&&"object"==typeof r){for(c in r)K.access(e,n,c,r[c],1,a,i);o=1}else if(i!==t){if(l=s===t&&K.isFunction(i),u&&(l?(l=n,n=function(e,t,n){return l.call(K(e),n)}):(n.call(e,i),n=null)),n)for(;c<f;c++)n(e[c],r,l?i.call(e[c],c,n(e[c],r)):i,s);o=1}return o?e:u?n.call(e):f?n(e[0],r):a},now:function(){return(new Date).getTime()}}),K.ready.promise=function(t){if(!P)if(P=K.Deferred(),"complete"===R.readyState||"loading"!==R.readyState&&R.addEventListener)setTimeout(K.ready,1);else if(R.addEventListener)R.addEventListener("DOMContentLoaded",pe,!1),e.addEventListener("load",K.ready,!1);else{R.attachEvent("onreadystatechange",pe),e.attachEvent("onload",K.ready);var n=!1;try{n=null==e.frameElement&&R.documentElement}catch(r){}n&&n.doScroll&&function i(){if(!K.isReady){try{n.doScroll("left")}catch(e){return setTimeout(i,50)}K.ready()}}()}return P.promise(t)},K.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(e,t){de["[object "+t+"]"]=t.toLowerCase()}),W=K(R);var he={};K.Callbacks=function(e){e="string"==typeof e?he[e]||n(e):K.extend({},e);var r,i,o,a,s,l,u=[],c=!e.once&&[],f=function(t){for(r=e.memory&&t,i=!0,l=a||0,a=0,s=u.length,o=!0;u&&l<s;l++)if(u[l].apply(t[0],t[1])===!1&&e.stopOnFalse){r=!1;break}o=!1,u&&(c?c.length&&f(c.shift()):r?u=[]:p.disable())},p={add:function(){if(u){var t=u.length;!function n(t){K.each(t,function(t,r){!K.isFunction(r)||e.unique&&p.has(r)?r&&r.length&&n(r):u.push(r)})}(arguments),o?s=u.length:r&&(a=t,f(r))}return this},remove:function(){return u&&K.each(arguments,function(e,t){for(var n;(n=K.inArray(t,u,n))>-1;)u.splice(n,1),o&&(n<=s&&s--,n<=l&&l--)}),this},has:function(e){return K.inArray(e,u)>-1},empty:function(){return u=[],this},disable:function(){return u=c=r=t,this},disabled:function(){return!u},lock:function(){return c=t,r||p.disable(),this},locked:function(){return!c},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],u&&(!i||c)&&(o?c.push(t):f(t)),this},fire:function(){return p.fireWith(this,arguments),this},fired:function(){return!!i}};return p},K.extend({Deferred:function(e){var t=[["resolve","done",K.Callbacks("once memory"),"resolved"],["reject","fail",K.Callbacks("once memory"),"rejected"],["notify","progress",K.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return K.Deferred(function(n){K.each(t,function(t,r){var o=r[0],a=e[t];i[r[1]](K.isFunction(a)?function(){var e=a.apply(this,arguments);e&&K.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[o+"With"](this===i?n:this,[e])}:n[o])}),e=null}).promise()},promise:function(e){return"object"==typeof e?K.extend(e,r):r}},i={};return r.pipe=r.then,K.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=a.fire,i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t,n,r,i=0,o=Y.call(arguments),a=o.length,s=1!==a||e&&K.isFunction(e.promise)?a:0,l=1===s?e:K.Deferred(),u=function(e,n,r){return function(i){n[e]=this,r[e]=arguments.length>1?Y.call(arguments):i,r===t?l.notifyWith(n,r):--s||l.resolveWith(n,r)}};if(a>1)for(t=new Array(a),n=new Array(a),r=new Array(a);i<a;i++)o[i]&&K.isFunction(o[i].promise)?o[i].promise().done(u(i,r,o)).fail(l.reject).progress(u(i,n,t)):--s;return s||l.resolveWith(r,o),l.promise()}}),K.support=function(){var t,n,r,i,o,a,s,l,u,c,f,p=R.createElement("div");if(p.setAttribute("className","t"),p.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",n=p.getElementsByTagName("*"),r=p.getElementsByTagName("a")[0],r.style.cssText="top:1px;float:left;opacity:.5",!n||!n.length||!r)return{};i=R.createElement("select"),o=i.appendChild(R.createElement("option")),a=p.getElementsByTagName("input")[0],t={leadingWhitespace:3===p.firstChild.nodeType,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:"/a"===r.getAttribute("href"),opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:"on"===a.value,optSelected:o.selected,getSetAttribute:"t"!==p.className,enctype:!!R.createElement("form").enctype,html5Clone:"<:nav></:nav>"!==R.createElement("nav").cloneNode(!0).outerHTML,boxModel:"CSS1Compat"===R.compatMode,submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},a.checked=!0,t.noCloneChecked=a.cloneNode(!0).checked,i.disabled=!0,t.optDisabled=!o.disabled;try{delete p.test}catch(d){t.deleteExpando=!1}if(!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",f=function(){t.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick"),p.detachEvent("onclick",f)),a=R.createElement("input"),a.value="t",a.setAttribute("type","radio"),t.radioValue="t"===a.value,a.setAttribute("checked","checked"),a.setAttribute("name","t"),p.appendChild(a),s=R.createDocumentFragment(),s.appendChild(p.lastChild),t.checkClone=s.cloneNode(!0).cloneNode(!0).lastChild.checked,t.appendChecked=a.checked,s.removeChild(a),s.appendChild(p),p.attachEvent)for(u in{submit:!0,change:!0,focusin:!0})l="on"+u,c=l in p,c||(p.setAttribute(l,"return;"),c="function"==typeof p[l]),t[u+"Bubbles"]=c;return K(function(){var n,r,i,o,a="padding:0;margin:0;border:0;display:block;overflow:hidden;",s=R.getElementsByTagName("body")[0];s&&(n=R.createElement("div"),n.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",s.insertBefore(n,s.firstChild),r=R.createElement("div"),n.appendChild(r),r.innerHTML="<table><tr><td></td><td>t</td></tr></table>",i=r.getElementsByTagName("td"),i[0].style.cssText="padding:0;margin:0;border:0;display:none",c=0===i[0].offsetHeight,i[0].style.display="",i[1].style.display="none",t.reliableHiddenOffsets=c&&0===i[0].offsetHeight,r.innerHTML="",r.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=4===r.offsetWidth,t.doesNotIncludeMarginInBodyOffset=1!==s.offsetTop,e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(r,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(r,null)||{width:"4px"}).width,o=R.createElement("div"),o.style.cssText=r.style.cssText=a,o.style.marginRight=o.style.width="0",r.style.width="1px",r.appendChild(o),t.reliableMarginRight=!parseFloat((e.getComputedStyle(o,null)||{}).marginRight)),"undefined"!=typeof r.style.zoom&&(r.innerHTML="",r.style.cssText=a+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=3===r.offsetWidth,r.style.display="block",r.style.overflow="visible",r.innerHTML="<div></div>",r.firstChild.style.width="5px",t.shrinkWrapBlocks=3!==r.offsetWidth,n.style.zoom=1),s.removeChild(n),n=r=i=o=null)}),s.removeChild(p),n=r=i=o=a=s=p=null,t}();var ge=/^(?:\{.*\}|\[.*\])$/,me=/([A-Z])/g;K.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(K.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?K.cache[e[K.expando]]:e[K.expando],!!e&&!i(e)},data:function(e,n,r,i){if(K.acceptData(e)){var o,a,s=K.expando,l="string"==typeof n,u=e.nodeType,c=u?K.cache:e,f=u?e[s]:e[s]&&s;if(f&&c[f]&&(i||c[f].data)||!l||r!==t)return f||(u?e[s]=f=K.deletedIds.pop()||++K.uuid:f=s),c[f]||(c[f]={},u||(c[f].toJSON=K.noop)),"object"!=typeof n&&"function"!=typeof n||(i?c[f]=K.extend(c[f],n):c[f].data=K.extend(c[f].data,n)),o=c[f],i||(o.data||(o.data={}),o=o.data),r!==t&&(o[K.camelCase(n)]=r),l?(a=o[n],null==a&&(a=o[K.camelCase(n)])):a=o,a}},removeData:function(e,t,n){if(K.acceptData(e)){var r,o,a,s=e.nodeType,l=s?K.cache:e,u=s?e[K.expando]:K.expando;if(l[u]){if(t&&(r=n?l[u]:l[u].data)){K.isArray(t)||(t in r?t=[t]:(t=K.camelCase(t),t=t in r?[t]:t.split(" ")));for(o=0,a=t.length;o<a;o++)delete r[t[o]];if(!(n?i:K.isEmptyObject)(r))return}(n||(delete l[u].data,i(l[u])))&&(s?K.cleanData([e],!0):K.support.deleteExpando||l!=l.window?delete l[u]:l[u]=null)}}},_data:function(e,t,n){return K.data(e,t,n,!0)},acceptData:function(e){var t=e.nodeName&&K.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),K.fn.extend({data:function(e,n){var i,o,a,s,l,u=this[0],c=0,f=null;if(e===t){if(this.length&&(f=K.data(u),1===u.nodeType&&!K._data(u,"parsedAttrs"))){for(a=u.attributes,l=a.length;c<l;c++)s=a[c].name,0===s.indexOf("data-")&&(s=K.camelCase(s.substring(5)),r(u,s,f[s]));K._data(u,"parsedAttrs",!0)}return f}return"object"==typeof e?this.each(function(){K.data(this,e)}):(i=e.split(".",2),i[1]=i[1]?"."+i[1]:"",o=i[1]+"!",K.access(this,function(n){return n===t?(f=this.triggerHandler("getData"+o,[i[0]]),f===t&&u&&(f=K.data(u,e),f=r(u,e,f)),f===t&&i[1]?this.data(i[0]):f):(i[1]=n,void this.each(function(){var t=K(this);t.triggerHandler("setData"+o,i),K.data(this,e,n),t.triggerHandler("changeData"+o,i)}))},null,n,arguments.length>1,null,!1))},removeData:function(e){return this.each(function(){K.removeData(this,e)})}}),K.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=K._data(e,t),n&&(!r||K.isArray(n)?r=K._data(e,t,K.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=K.queue(e,t),r=n.shift(),i=K._queueHooks(e,t),o=function(){K.dequeue(e,t)};"inprogress"===r&&(r=n.shift()),r&&("fx"===t&&n.unshift("inprogress"),delete i.stop,r.call(e,o,i)),!n.length&&i&&i.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return K._data(e,n)||K._data(e,n,{empty:K.Callbacks("once memory").add(function(){K.removeData(e,t+"queue",!0),K.removeData(e,n,!0)})})}}),K.fn.extend({queue:function(e,n){var r=2;return"string"!=typeof e&&(n=e,e="fx",r--),arguments.length<r?K.queue(this[0],e):n===t?this:this.each(function(){var t=K.queue(this,e,n);K._queueHooks(this,e),"fx"===e&&"inprogress"!==t[0]&&K.dequeue(this,e)})},dequeue:function(e){return this.each(function(){K.dequeue(this,e)})},delay:function(e,t){return e=K.fx?K.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,o=K.Deferred(),a=this,s=this.length,l=function(){--i||o.resolveWith(a,[a])};for("string"!=typeof e&&(n=e,e=t),e=e||"fx";s--;)(r=K._data(a[s],e+"queueHooks"))&&r.empty&&(i++,r.empty.add(l));return l(),o.promise(n)}});var ye,ve,be,xe=/[\t\r\n]/g,we=/\r/g,Te=/^(?:button|input)$/i,Ne=/^(?:button|input|object|select|textarea)$/i,Ce=/^a(?:rea|)$/i,Ee=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,ke=K.support.getSetAttribute;K.fn.extend({attr:function(e,t){return K.access(this,K.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){K.removeAttr(this,e)})},prop:function(e,t){return K.access(this,K.prop,e,t,arguments.length>1)},removeProp:function(e){return e=K.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,o,a,s;if(K.isFunction(e))return this.each(function(t){K(this).addClass(e.call(this,t,this.className))});if(e&&"string"==typeof e)for(t=e.split(te),n=0,r=this.length;n<r;n++)if(i=this[n],1===i.nodeType)if(i.className||1!==t.length){for(o=" "+i.className+" ",a=0,s=t.length;a<s;a++)~o.indexOf(" "+t[a]+" ")||(o+=t[a]+" ");i.className=K.trim(o)}else i.className=e;return this},removeClass:function(e){var n,r,i,o,a,s,l;if(K.isFunction(e))return this.each(function(t){K(this).removeClass(e.call(this,t,this.className))});if(e&&"string"==typeof e||e===t)for(n=(e||"").split(te),s=0,l=this.length;s<l;s++)if(i=this[s],1===i.nodeType&&i.className){for(r=(" "+i.className+" ").replace(xe," "),o=0,a=n.length;o<a;o++)for(;r.indexOf(" "+n[o]+" ")>-1;)r=r.replace(" "+n[o]+" "," ");i.className=e?K.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e,r="boolean"==typeof t;return K.isFunction(e)?this.each(function(n){K(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n)for(var i,o=0,a=K(this),s=t,l=e.split(te);i=l[o++];)s=r?s:!a.hasClass(i),a[s?"addClass":"removeClass"](i);else"undefined"!==n&&"boolean"!==n||(this.className&&K._data(this,"__className__",this.className),this.className=this.className||e===!1?"":K._data(this,"__className__")||"")})},hasClass:function(e){for(var t=" "+e+" ",n=0,r=this.length;n<r;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(xe," ").indexOf(t)>-1)return!0;return!1},val:function(e){var n,r,i,o=this[0];{if(arguments.length)return i=K.isFunction(e),this.each(function(r){var o,a=K(this);1===this.nodeType&&(o=i?e.call(this,r,a.val()):e,null==o?o="":"number"==typeof o?o+="":K.isArray(o)&&(o=K.map(o,function(e){return null==e?"":e+""})),n=K.valHooks[this.type]||K.valHooks[this.nodeName.toLowerCase()],n&&"set"in n&&n.set(this,o,"value")!==t||(this.value=o))});if(o)return n=K.valHooks[o.type]||K.valHooks[o.nodeName.toLowerCase()],n&&"get"in n&&(r=n.get(o,"value"))!==t?r:(r=o.value,"string"==typeof r?r.replace(we,""):null==r?"":r)}}}),K.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r,i,o=e.selectedIndex,a=[],s=e.options,l="select-one"===e.type;if(o<0)return null;for(n=l?o:0,r=l?o+1:s.length;n<r;n++)if(i=s[n],i.selected&&(K.support.optDisabled?!i.disabled:null===i.getAttribute("disabled"))&&(!i.parentNode.disabled||!K.nodeName(i.parentNode,"optgroup"))){if(t=K(i).val(),l)return t;a.push(t)}return l&&!a.length&&s.length?K(s[o]).val():a},set:function(e,t){var n=K.makeArray(t);return K(e).find("option").each(function(){this.selected=K.inArray(K(this).val(),n)>=0}),n.length||(e.selectedIndex=-1),n}}},attrFn:{},attr:function(e,n,r,i){var o,a,s,l=e.nodeType;if(e&&3!==l&&8!==l&&2!==l)return i&&K.isFunction(K.fn[n])?K(e)[n](r):"undefined"==typeof e.getAttribute?K.prop(e,n,r):(s=1!==l||!K.isXMLDoc(e),s&&(n=n.toLowerCase(),a=K.attrHooks[n]||(Ee.test(n)?ve:ye)),r!==t?null===r?void K.removeAttr(e,n):a&&"set"in a&&s&&(o=a.set(e,r,n))!==t?o:(e.setAttribute(n,""+r),r):a&&"get"in a&&s&&null!==(o=a.get(e,n))?o:(o=e.getAttribute(n),null===o?t:o))},removeAttr:function(e,t){var n,r,i,o,a=0;if(t&&1===e.nodeType)for(r=t.split(te);a<r.length;a++)i=r[a],i&&(n=K.propFix[i]||i,o=Ee.test(i),o||K.attr(e,i,""),e.removeAttribute(ke?i:n),o&&n in e&&(e[n]=!1))},attrHooks:{type:{set:function(e,t){if(Te.test(e.nodeName)&&e.parentNode)K.error("type property can't be changed");else if(!K.support.radioValue&&"radio"===t&&K.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}},value:{get:function(e,t){return ye&&K.nodeName(e,"button")?ye.get(e,t):t in e?e.value:null},set:function(e,t,n){return ye&&K.nodeName(e,"button")?ye.set(e,t,n):void(e.value=t)}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(e,n,r){var i,o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return a=1!==s||!K.isXMLDoc(e),a&&(n=K.propFix[n]||n,o=K.propHooks[n]),r!==t?o&&"set"in o&&(i=o.set(e,r,n))!==t?i:e[n]=r:o&&"get"in o&&null!==(i=o.get(e,n))?i:e[n]},propHooks:{tabIndex:{get:function(e){var n=e.getAttributeNode("tabindex");return n&&n.specified?parseInt(n.value,10):Ne.test(e.nodeName)||Ce.test(e.nodeName)&&e.href?0:t}}}}),ve={get:function(e,n){var r,i=K.prop(e,n);return i===!0||"boolean"!=typeof i&&(r=e.getAttributeNode(n))&&r.nodeValue!==!1?n.toLowerCase():t},set:function(e,t,n){var r;return t===!1?K.removeAttr(e,n):(r=K.propFix[n]||n,r in e&&(e[r]=!0),e.setAttribute(n,n.toLowerCase())),n}},ke||(be={name:!0,id:!0,coords:!0},ye=K.valHooks.button={get:function(e,n){var r;return r=e.getAttributeNode(n),r&&(be[n]?""!==r.value:r.specified)?r.value:t},set:function(e,t,n){var r=e.getAttributeNode(n);return r||(r=R.createAttribute(n),e.setAttributeNode(r)),r.value=t+""}},K.each(["width","height"],function(e,t){K.attrHooks[t]=K.extend(K.attrHooks[t],{set:function(e,n){if(""===n)return e.setAttribute(t,"auto"),
+n}})}),K.attrHooks.contenteditable={get:ye.get,set:function(e,t,n){""===t&&(t="false"),ye.set(e,t,n)}}),K.support.hrefNormalized||K.each(["href","src","width","height"],function(e,n){K.attrHooks[n]=K.extend(K.attrHooks[n],{get:function(e){var r=e.getAttribute(n,2);return null===r?t:r}})}),K.support.style||(K.attrHooks.style={get:function(e){return e.style.cssText.toLowerCase()||t},set:function(e,t){return e.style.cssText=""+t}}),K.support.optSelected||(K.propHooks.selected=K.extend(K.propHooks.selected,{get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}})),K.support.enctype||(K.propFix.enctype="encoding"),K.support.checkOn||K.each(["radio","checkbox"],function(){K.valHooks[this]={get:function(e){return null===e.getAttribute("value")?"on":e.value}}}),K.each(["radio","checkbox"],function(){K.valHooks[this]=K.extend(K.valHooks[this],{set:function(e,t){if(K.isArray(t))return e.checked=K.inArray(K(e).val(),t)>=0}})});var Se=/^(?:textarea|input|select)$/i,Ae=/^([^\.]*|)(?:\.(.+)|)$/,je=/(?:^|\s)hover(\.\S+|)\b/,De=/^key/,Le=/^(?:mouse|contextmenu)|click/,He=/^(?:focusinfocus|focusoutblur)$/,Fe=function(e){return K.event.special.hover?e:e.replace(je,"mouseenter$1 mouseleave$1")};K.event={add:function(e,n,r,i,o){var a,s,l,u,c,f,p,d,h,g,m;if(3!==e.nodeType&&8!==e.nodeType&&n&&r&&(a=K._data(e))){for(r.handler&&(h=r,r=h.handler,o=h.selector),r.guid||(r.guid=K.guid++),l=a.events,l||(a.events=l={}),s=a.handle,s||(a.handle=s=function(e){return"undefined"==typeof K||e&&K.event.triggered===e.type?t:K.event.dispatch.apply(s.elem,arguments)},s.elem=e),n=K.trim(Fe(n)).split(" "),u=0;u<n.length;u++)c=Ae.exec(n[u])||[],f=c[1],p=(c[2]||"").split(".").sort(),m=K.event.special[f]||{},f=(o?m.delegateType:m.bindType)||f,m=K.event.special[f]||{},d=K.extend({type:f,origType:c[1],data:i,handler:r,guid:r.guid,selector:o,namespace:p.join(".")},h),g=l[f],g||(g=l[f]=[],g.delegateCount=0,m.setup&&m.setup.call(e,i,p,s)!==!1||(e.addEventListener?e.addEventListener(f,s,!1):e.attachEvent&&e.attachEvent("on"+f,s))),m.add&&(m.add.call(e,d),d.handler.guid||(d.handler.guid=r.guid)),o?g.splice(g.delegateCount++,0,d):g.push(d),K.event.global[f]=!0;e=null}},global:{},remove:function(e,t,n,r,i){var o,a,s,l,u,c,f,p,d,h,g,m=K.hasData(e)&&K._data(e);if(m&&(p=m.events)){for(t=K.trim(Fe(t||"")).split(" "),o=0;o<t.length;o++)if(a=Ae.exec(t[o])||[],s=l=a[1],u=a[2],s){for(d=K.event.special[s]||{},s=(r?d.delegateType:d.bindType)||s,h=p[s]||[],c=h.length,u=u?new RegExp("(^|\\.)"+u.split(".").sort().join("\\.(?:.*\\.|)")+"(\\.|$)"):null,f=0;f<h.length;f++)g=h[f],(i||l===g.origType)&&(!n||n.guid===g.guid)&&(!u||u.test(g.namespace))&&(!r||r===g.selector||"**"===r&&g.selector)&&(h.splice(f--,1),g.selector&&h.delegateCount--,d.remove&&d.remove.call(e,g));0===h.length&&c!==h.length&&((!d.teardown||d.teardown.call(e,u,m.handle)===!1)&&K.removeEvent(e,s,m.handle),delete p[s])}else for(s in p)K.event.remove(e,s+t[o],n,r,!0);K.isEmptyObject(p)&&(delete m.handle,K.removeData(e,"events",!0))}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(n,r,i,o){if(!i||3!==i.nodeType&&8!==i.nodeType){var a,s,l,u,c,f,p,d,h,g,m=n.type||n,y=[];if(He.test(m+K.event.triggered))return;if(m.indexOf("!")>=0&&(m=m.slice(0,-1),s=!0),m.indexOf(".")>=0&&(y=m.split("."),m=y.shift(),y.sort()),(!i||K.event.customEvent[m])&&!K.event.global[m])return;if(n="object"==typeof n?n[K.expando]?n:new K.Event(m,n):new K.Event(m),n.type=m,n.isTrigger=!0,n.exclusive=s,n.namespace=y.join("."),n.namespace_re=n.namespace?new RegExp("(^|\\.)"+y.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,f=m.indexOf(":")<0?"on"+m:"",!i){a=K.cache;for(l in a)a[l].events&&a[l].events[m]&&K.event.trigger(n,r,a[l].handle.elem,!0);return}if(n.result=t,n.target||(n.target=i),r=null!=r?K.makeArray(r):[],r.unshift(n),p=K.event.special[m]||{},p.trigger&&p.trigger.apply(i,r)===!1)return;if(h=[[i,p.bindType||m]],!o&&!p.noBubble&&!K.isWindow(i)){for(g=p.delegateType||m,u=He.test(g+m)?i:i.parentNode,c=i;u;u=u.parentNode)h.push([u,g]),c=u;c===(i.ownerDocument||R)&&h.push([c.defaultView||c.parentWindow||e,g])}for(l=0;l<h.length&&!n.isPropagationStopped();l++)u=h[l][0],n.type=h[l][1],d=(K._data(u,"events")||{})[n.type]&&K._data(u,"handle"),d&&d.apply(u,r),d=f&&u[f],d&&K.acceptData(u)&&d.apply(u,r)===!1&&n.preventDefault();return n.type=m,!o&&!n.isDefaultPrevented()&&(!p._default||p._default.apply(i.ownerDocument,r)===!1)&&("click"!==m||!K.nodeName(i,"a"))&&K.acceptData(i)&&f&&i[m]&&("focus"!==m&&"blur"!==m||0!==n.target.offsetWidth)&&!K.isWindow(i)&&(c=i[f],c&&(i[f]=null),K.event.triggered=m,i[m](),K.event.triggered=t,c&&(i[f]=c)),n.result}},dispatch:function(n){n=K.event.fix(n||e.event);var r,i,o,a,s,l,u,c,f,p,d=(K._data(this,"events")||{})[n.type]||[],h=d.delegateCount,g=[].slice.call(arguments),m=!n.exclusive&&!n.namespace,y=K.event.special[n.type]||{},v=[];if(g[0]=n,n.delegateTarget=this,!y.preDispatch||y.preDispatch.call(this,n)!==!1){if(h&&(!n.button||"click"!==n.type))for(a=K(this),a.context=this,o=n.target;o!=this;o=o.parentNode||this)if(o.disabled!==!0||"click"!==n.type){for(l={},c=[],a[0]=o,r=0;r<h;r++)f=d[r],p=f.selector,l[p]===t&&(l[p]=a.is(p)),l[p]&&c.push(f);c.length&&v.push({elem:o,matches:c})}for(d.length>h&&v.push({elem:this,matches:d.slice(h)}),r=0;r<v.length&&!n.isPropagationStopped();r++)for(u=v[r],n.currentTarget=u.elem,i=0;i<u.matches.length&&!n.isImmediatePropagationStopped();i++)f=u.matches[i],(m||!n.namespace&&!f.namespace||n.namespace_re&&n.namespace_re.test(f.namespace))&&(n.data=f.data,n.handleObj=f,s=((K.event.special[f.origType]||{}).handle||f.handler).apply(u.elem,g),s!==t&&(n.result=s,s===!1&&(n.preventDefault(),n.stopPropagation())));return y.postDispatch&&y.postDispatch.call(this,n),n.result}},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,i,o,a=n.button,s=n.fromElement;return null==e.pageX&&null!=n.clientX&&(r=e.target.ownerDocument||R,i=r.documentElement,o=r.body,e.pageX=n.clientX+(i&&i.scrollLeft||o&&o.scrollLeft||0)-(i&&i.clientLeft||o&&o.clientLeft||0),e.pageY=n.clientY+(i&&i.scrollTop||o&&o.scrollTop||0)-(i&&i.clientTop||o&&o.clientTop||0)),!e.relatedTarget&&s&&(e.relatedTarget=s===e.target?n.toElement:s),!e.which&&a!==t&&(e.which=1&a?1:2&a?3:4&a?2:0),e}},fix:function(e){if(e[K.expando])return e;var t,n,r=e,i=K.event.fixHooks[e.type]||{},o=i.props?this.props.concat(i.props):this.props;for(e=K.Event(r),t=o.length;t;)n=o[--t],e[n]=r[n];return e.target||(e.target=r.srcElement||R),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,i.filter?i.filter(e,r):e},special:{ready:{setup:K.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(e,t,n){K.isWindow(this)&&(this.onbeforeunload=n)},teardown:function(e,t){this.onbeforeunload===t&&(this.onbeforeunload=null)}}},simulate:function(e,t,n,r){var i=K.extend(new K.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?K.event.trigger(i,null,t):K.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},K.event.handle=K.event.dispatch,K.removeEvent=R.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&("undefined"==typeof e[r]&&(e[r]=null),e.detachEvent(r,n))},K.Event=function(e,t){return this instanceof K.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?a:o):this.type=e,t&&K.extend(this,t),this.timeStamp=e&&e.timeStamp||K.now(),this[K.expando]=!0,void 0):new K.Event(e,t)},K.Event.prototype={preventDefault:function(){this.isDefaultPrevented=a;var e=this.originalEvent;e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=a;var e=this.originalEvent;e&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=a,this.stopPropagation()},isDefaultPrevented:o,isPropagationStopped:o,isImmediatePropagationStopped:o},K.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){K.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;o.selector;return i&&(i===r||K.contains(r,i))||(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),K.support.submitBubbles||(K.event.special.submit={setup:function(){return!K.nodeName(this,"form")&&void K.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=K.nodeName(n,"input")||K.nodeName(n,"button")?n.form:t;r&&!K._data(r,"_submit_attached")&&(K.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),K._data(r,"_submit_attached",!0))})},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&K.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){return!K.nodeName(this,"form")&&void K.event.remove(this,"._submit")}}),K.support.changeBubbles||(K.event.special.change={setup:function(){return Se.test(this.nodeName)?("checkbox"!==this.type&&"radio"!==this.type||(K.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._just_changed=!0)}),K.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),K.event.simulate("change",this,e,!0)})),!1):void K.event.add(this,"beforeactivate._change",function(e){var t=e.target;Se.test(t.nodeName)&&!K._data(t,"_change_attached")&&(K.event.add(t,"change._change",function(e){this.parentNode&&!e.isSimulated&&!e.isTrigger&&K.event.simulate("change",this.parentNode,e,!0)}),K._data(t,"_change_attached",!0))})},handle:function(e){var t=e.target;if(this!==t||e.isSimulated||e.isTrigger||"radio"!==t.type&&"checkbox"!==t.type)return e.handleObj.handler.apply(this,arguments)},teardown:function(){return K.event.remove(this,"._change"),Se.test(this.nodeName)}}),K.support.focusinBubbles||K.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){K.event.simulate(t,e.target,K.event.fix(e),!0)};K.event.special[t]={setup:function(){0===n++&&R.addEventListener(e,r,!0)},teardown:function(){0===--n&&R.removeEventListener(e,r,!0)}}}),K.fn.extend({on:function(e,n,r,i,a){var s,l;if("object"==typeof e){"string"!=typeof n&&(r=r||n,n=t);for(l in e)this.on(l,n,r,e[l],a);return this}if(null==r&&null==i?(i=n,r=n=t):null==i&&("string"==typeof n?(i=r,r=t):(i=r,r=n,n=t)),i===!1)i=o;else if(!i)return this;return 1===a&&(s=i,i=function(e){return K().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=K.guid++)),this.each(function(){K.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,a;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,K(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if("object"==typeof e){for(a in e)this.off(a,n,e[a]);return this}return n!==!1&&"function"!=typeof n||(r=n,n=t),r===!1&&(r=o),this.each(function(){K.event.remove(this,e,r,n)})},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},live:function(e,t,n){return K(this.context).on(e,this.selector,t,n),this},die:function(e,t){return K(this.context).off(e,this.selector||"**",t),this},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1==arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},trigger:function(e,t){return this.each(function(){K.event.trigger(e,t,this)})},triggerHandler:function(e,t){if(this[0])return K.event.trigger(e,t,this[0],!0)},toggle:function(e){var t=arguments,n=e.guid||K.guid++,r=0,i=function(n){var i=(K._data(this,"lastToggle"+e.guid)||0)%r;return K._data(this,"lastToggle"+e.guid,i+1),n.preventDefault(),t[i].apply(this,arguments)||!1};for(i.guid=n;r<t.length;)t[r++].guid=n;return this.click(i)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),K.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(e,t){K.fn[t]=function(e,n){return null==n&&(n=e,e=null),arguments.length>0?this.on(t,null,e,n):this.trigger(t)},De.test(t)&&(K.event.fixHooks[t]=K.event.keyHooks),Le.test(t)&&(K.event.fixHooks[t]=K.event.mouseHooks)}),function(e,t){function n(e,t,n,r){for(var i=0,o=t.length;i<o;i++)oe(e,t[i],n,r)}function r(e,t,r,i,o,a){var s,l=ae.setFilters[t.toLowerCase()];return l||oe.error(t),(e||!(s=o))&&n(e||"*",i,s=[],o),s.length>0?l(s,r,a):[]}function i(e,i,o,a,s){for(var l,u,c,f,p,d,h,g,m=0,y=s.length,v=z.POS,b=new RegExp("^"+v.source+"(?!"+C+")","i"),x=function(){for(var e=1,n=arguments.length-2;e<n;e++)arguments[e]===t&&(l[e]=t)};m<y;m++){for(v.exec(""),e=s[m],f=[],c=0,p=a;l=v.exec(e);)g=v.lastIndex=l.index+l[0].length,g>c&&(h=e.slice(c,l.index),c=g,d=[i],M.test(h)&&(p&&(d=p),p=a),(u=P.test(h))&&(h=h.slice(0,-5).replace(M,"$&*")),l.length>1&&l[0].replace(b,x),p=r(h,l[1],l[2],d,p,u));p?(f=f.concat(p),(h=e.slice(c))&&")"!==h?M.test(h)?n(h,f,o,a):oe(h,i,o,a?a.concat(p):p):T.apply(o,f)):oe(e,i,o,a)}return 1===y?o:oe.uniqueSort(o)}function o(e,t,n){for(var r,i,o,a=[],s=0,l=_.exec(e),u=!l.pop()&&!l.pop(),c=u&&e.match(O)||[""],f=ae.preFilter,p=ae.filter,d=!n&&t!==g;null!=(i=c[s])&&u;s++)for(a.push(r=[]),d&&(i=" "+i);i;){u=!1,(l=M.exec(i))&&(i=i.slice(l[0].length),u=r.push({part:l.pop().replace(F," "),captures:l}));for(o in p)(l=z[o].exec(i))&&(!f[o]||(l=f[o](l,t,n)))&&(i=i.slice(l.shift().length),u=r.push({part:o,captures:l}));if(!u)break}return u||oe.error(e),a}function a(e,t,n){var r=t.dir,i=x++;return e||(e=function(e){return e===n}),t.first?function(t,n){for(;t=t[r];)if(1===t.nodeType)return e(t,n)&&t}:function(t,n){for(var o,a=i+"."+f,s=a+"."+c;t=t[r];)if(1===t.nodeType){if((o=t[N])===s)return t.sizset;if("string"==typeof o&&0===o.indexOf(a)){if(t.sizset)return t}else{if(t[N]=s,e(t,n))return t.sizset=!0,t;t.sizset=!1}}}}function s(e,t){return e?function(n,r){var i=t(n,r);return i&&e(i===!0?n:i,r)}:t}function l(e,t,n){for(var r,i,o=0;r=e[o];o++)ae.relative[r.part]?i=a(i,ae.relative[r.part],t):(r.captures.push(t,n),i=s(i,ae.filter[r.part].apply(null,r.captures)));return i}function u(e){return function(t,n){for(var r,i=0;r=e[i];i++)if(r(t,n))return!0;return!1}}var c,f,p,d,h,g=e.document,m=g.documentElement,y="undefined",v=!1,b=!0,x=0,w=[].slice,T=[].push,N=("sizcache"+Math.random()).replace(".",""),C="[\\x20\\t\\r\\n\\f]",E="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",k=E.replace("w","w#"),S="([*^$|!~]?=)",A="\\["+C+"*("+E+")"+C+"*(?:"+S+C+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+k+")|)|)"+C+"*\\]",j=":("+E+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|((?:[^,]|\\\\,|(?:,(?=[^\\[]*\\]))|(?:,(?=[^\\(]*\\))))*))\\)|)",D=":(nth|eq|gt|lt|first|last|even|odd)(?:\\((\\d*)\\)|)(?=[^-]|$)",L=C+"*([\\x20\\t\\r\\n\\f>+~])"+C+"*",H="(?=[^\\x20\\t\\r\\n\\f])(?:\\\\.|"+A+"|"+j.replace(2,7)+"|[^\\\\(),])+",F=new RegExp("^"+C+"+|((?:^|[^\\\\])(?:\\\\.)*)"+C+"+$","g"),M=new RegExp("^"+L),O=new RegExp(H+"?(?="+C+"*,|$)","g"),_=new RegExp("^(?:(?!,)(?:(?:^|,)"+C+"*"+H+")*?|"+C+"*(.*?))(\\)|$)"),q=new RegExp(H.slice(19,-6)+"\\x20\\t\\r\\n\\f>+~])+|"+L,"g"),B=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,W=/[\x20\t\r\n\f]*[+~]/,P=/:not\($/,R=/h\d/i,$=/input|select|textarea|button/i,I=/\\(?!\\)/g,z={ID:new RegExp("^#("+E+")"),CLASS:new RegExp("^\\.("+E+")"),NAME:new RegExp("^\\[name=['\"]?("+E+")['\"]?\\]"),TAG:new RegExp("^("+E.replace("[-","[-\\*")+")"),ATTR:new RegExp("^"+A),PSEUDO:new RegExp("^"+j),CHILD:new RegExp("^:(only|nth|last|first)-child(?:\\("+C+"*(even|odd|(([+-]|)(\\d*)n|)"+C+"*(?:([+-]|)"+C+"*(\\d+)|))"+C+"*\\)|)","i"),POS:new RegExp(D,"ig"),needsContext:new RegExp("^"+C+"*[>+~]|"+D,"i")},X={},U=[],Y={},J=[],V=function(e){return e.sizzleFilter=!0,e},G=function(e){return function(t){return"input"===t.nodeName.toLowerCase()&&t.type===e}},Q=function(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}},Z=function(e){var t=!1,n=g.createElement("div");try{t=e(n)}catch(r){}return n=null,t},ee=Z(function(e){e.innerHTML="<select></select>";var t=typeof e.lastChild.getAttribute("multiple");return"boolean"!==t&&"string"!==t}),te=Z(function(e){e.id=N+0,e.innerHTML="<a name='"+N+"'></a><div name='"+N+"'></div>",m.insertBefore(e,m.firstChild);var t=g.getElementsByName&&g.getElementsByName(N).length===2+g.getElementsByName(N+0).length;return h=!g.getElementById(N),m.removeChild(e),t}),ne=Z(function(e){return e.appendChild(g.createComment("")),0===e.getElementsByTagName("*").length}),re=Z(function(e){return e.innerHTML="<a href='#'></a>",e.firstChild&&typeof e.firstChild.getAttribute!==y&&"#"===e.firstChild.getAttribute("href")}),ie=Z(function(e){return e.innerHTML="<div class='hidden e'></div><div class='hidden'></div>",!(!e.getElementsByClassName||0===e.getElementsByClassName("e").length)&&(e.lastChild.className="e",1!==e.getElementsByClassName("e").length)}),oe=function(e,t,n,r){n=n||[],t=t||g;var i,o,a,s,l=t.nodeType;if(1!==l&&9!==l)return[];if(!e||"string"!=typeof e)return n;if(a=le(t),!a&&!r&&(i=B.exec(e)))if(s=i[1]){if(9===l){if(o=t.getElementById(s),!o||!o.parentNode)return n;if(o.id===s)return n.push(o),n}else if(t.ownerDocument&&(o=t.ownerDocument.getElementById(s))&&ue(t,o)&&o.id===s)return n.push(o),n}else{if(i[2])return T.apply(n,w.call(t.getElementsByTagName(e),0)),n;if((s=i[3])&&ie&&t.getElementsByClassName)return T.apply(n,w.call(t.getElementsByClassName(s),0)),n}return pe(e,t,n,r,a)},ae=oe.selectors={cacheLength:50,match:z,order:["ID","TAG"],attrHandle:{},createPseudo:V,find:{ID:h?function(e,t,n){if(typeof t.getElementById!==y&&!n){var r=t.getElementById(e);return r&&r.parentNode?[r]:[]}}:function(e,n,r){if(typeof n.getElementById!==y&&!r){var i=n.getElementById(e);return i?i.id===e||typeof i.getAttributeNode!==y&&i.getAttributeNode("id").value===e?[i]:t:[]}},TAG:ne?function(e,t){if(typeof t.getElementsByTagName!==y)return t.getElementsByTagName(e)}:function(e,t){var n=t.getElementsByTagName(e);if("*"===e){for(var r,i=[],o=0;r=n[o];o++)1===r.nodeType&&i.push(r);return i}return n}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(I,""),e[3]=(e[4]||e[5]||"").replace(I,""),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1]?(e[2]||oe.error(e[0]),e[3]=+(e[3]?e[4]+(e[5]||1):2*("even"===e[2]||"odd"===e[2])),e[4]=+(e[6]+e[7]||"odd"===e[2])):e[2]&&oe.error(e[0]),e},PSEUDO:function(e){var t,n=e[4];return z.CHILD.test(e[0])?null:(n&&(t=_.exec(n))&&t.pop()&&(e[0]=e[0].slice(0,t[0].length-n.length-1),n=t[0].slice(0,-1)),e.splice(2,3,n||e[3]),e)}},filter:{ID:h?function(e){return e=e.replace(I,""),function(t){return t.getAttribute("id")===e}}:function(e){return e=e.replace(I,""),function(t){var n=typeof t.getAttributeNode!==y&&t.getAttributeNode("id");return n&&n.value===e}},TAG:function(e){return"*"===e?function(){return!0}:(e=e.replace(I,"").toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=X[e];return t||(t=X[e]=new RegExp("(^|"+C+")"+e+"("+C+"|$)"),U.push(e),U.length>ae.cacheLength&&delete X[U.shift()]),function(e){return t.test(e.className||typeof e.getAttribute!==y&&e.getAttribute("class")||"")}},ATTR:function(e,t,n){return t?function(r){var i=oe.attr(r,e),o=i+"";if(null==i)return"!="===t;switch(t){case"=":return o===n;case"!=":return o!==n;case"^=":return n&&0===o.indexOf(n);case"*=":return n&&o.indexOf(n)>-1;case"$=":return n&&o.substr(o.length-n.length)===n;case"~=":return(" "+o+" ").indexOf(n)>-1;case"|=":return o===n||o.substr(0,n.length+1)===n+"-"}}:function(t){return null!=oe.attr(t,e)}},CHILD:function(e,t,n,r){if("nth"===e){var i=x++;return function(e){var t,o,a=0,s=e;if(1===n&&0===r)return!0;if(t=e.parentNode,t&&(t[N]!==i||!e.sizset)){for(s=t.firstChild;s&&(1!==s.nodeType||(s.sizset=++a,s!==e));s=s.nextSibling);t[N]=i}return o=e.sizset-r,0===n?0===o:o%n===0&&o/n>=0}}return function(t){var n=t;switch(e){case"only":case"first":for(;n=n.previousSibling;)if(1===n.nodeType)return!1;if("first"===e)return!0;n=t;case"last":for(;n=n.nextSibling;)if(1===n.nodeType)return!1;return!0}}},PSEUDO:function(e,t,n,r){var i=ae.pseudos[e]||ae.pseudos[e.toLowerCase()];return i||oe.error("unsupported pseudo: "+e),i.sizzleFilter?i(t,n,r):i}},pseudos:{not:V(function(e,t,n){var r=fe(e.replace(F,"$1"),t,n);return function(e){return!r(e)}}),enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},parent:function(e){return!ae.pseudos.empty(e)},empty:function(e){var t;for(e=e.firstChild;e;){if(e.nodeName>"@"||3===(t=e.nodeType)||4===t)return!1;e=e.nextSibling}return!0},contains:V(function(e){return function(t){return(t.textContent||t.innerText||ce(t)).indexOf(e)>-1}}),has:V(function(e){return function(t){return oe(e,t).length>0}}),header:function(e){return R.test(e.nodeName)},text:function(e){var t,n;return"input"===e.nodeName.toLowerCase()&&"text"===(t=e.type)&&(null==(n=e.getAttribute("type"))||n.toLowerCase()===t)},radio:G("radio"),checkbox:G("checkbox"),file:G("file"),password:G("password"),image:G("image"),submit:Q("submit"),reset:Q("reset"),button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},input:function(e){return $.test(e.nodeName)},focus:function(e){var t=e.ownerDocument;return e===t.activeElement&&(!t.hasFocus||t.hasFocus())&&(!!e.type||!!e.href)},active:function(e){return e===e.ownerDocument.activeElement}},setFilters:{first:function(e,t,n){return n?e.slice(1):[e[0]]},last:function(e,t,n){var r=e.pop();return n?e:[r]},even:function(e,t,n){for(var r=[],i=n?1:0,o=e.length;i<o;i+=2)r.push(e[i]);return r},odd:function(e,t,n){for(var r=[],i=n?0:1,o=e.length;i<o;i+=2)r.push(e[i]);return r},lt:function(e,t,n){return n?e.slice(+t):e.slice(0,+t)},gt:function(e,t,n){return n?e.slice(0,+t+1):e.slice(+t+1)},eq:function(e,t,n){var r=e.splice(+t,1);return n?e:r}}};ae.setFilters.nth=ae.setFilters.eq,ae.filters=ae.pseudos,re||(ae.attrHandle={href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}}),te&&(ae.order.push("NAME"),ae.find.NAME=function(e,t){if(typeof t.getElementsByName!==y)return t.getElementsByName(e)}),ie&&(ae.order.splice(1,0,"CLASS"),ae.find.CLASS=function(e,t,n){if(typeof t.getElementsByClassName!==y&&!n)return t.getElementsByClassName(e)});try{w.call(m.childNodes,0)[0].nodeType}catch(se){w=function(e){for(var t,n=[];t=this[e];e++)n.push(t);return n}}var le=oe.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},ue=oe.contains=m.compareDocumentPosition?function(e,t){return!!(16&e.compareDocumentPosition(t))}:m.contains?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t.parentNode;return e===r||!!(r&&1===r.nodeType&&n.contains&&n.contains(r))}:function(e,t){for(;t=t.parentNode;)if(t===e)return!0;return!1},ce=oe.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=ce(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=ce(t);return n};oe.attr=function(e,t){var n,r=le(e);return r||(t=t.toLowerCase()),ae.attrHandle[t]?ae.attrHandle[t](e):ee||r?e.getAttribute(t):(n=e.getAttributeNode(t),n?"boolean"==typeof e[t]?e[t]?t:null:n.specified?n.value:null:null)},oe.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},[0,0].sort(function(){return b=0}),m.compareDocumentPosition?p=function(e,t){return e===t?(v=!0,0):(e.compareDocumentPosition&&t.compareDocumentPosition?4&e.compareDocumentPosition(t):e.compareDocumentPosition)?-1:1}:(p=function(e,t){if(e===t)return v=!0,0;if(e.sourceIndex&&t.sourceIndex)return e.sourceIndex-t.sourceIndex;var n,r,i=[],o=[],a=e.parentNode,s=t.parentNode,l=a;if(a===s)return d(e,t);if(!a)return-1;if(!s)return 1;for(;l;)i.unshift(l),l=l.parentNode;for(l=s;l;)o.unshift(l),l=l.parentNode;n=i.length,r=o.length;for(var u=0;u<n&&u<r;u++)if(i[u]!==o[u])return d(i[u],o[u]);return u===n?d(e,o[u],-1):d(i[u],t,1)},d=function(e,t,n){if(e===t)return n;for(var r=e.nextSibling;r;){if(r===t)return-1;r=r.nextSibling}return 1}),oe.uniqueSort=function(e){var t,n=1;if(p&&(v=b,e.sort(p),v))for(;t=e[n];n++)t===e[n-1]&&e.splice(n--,1);return e};var fe=oe.compile=function(e,t,n){var r,i,a,s=Y[e];if(s&&s.context===t)return s;for(i=o(e,t,n),a=0;r=i[a];a++)i[a]=l(r,t,n);return s=Y[e]=u(i),s.context=t,s.runs=s.dirruns=0,J.push(e),J.length>ae.cacheLength&&delete Y[J.shift()],s};oe.matches=function(e,t){return oe(e,null,null,t)},oe.matchesSelector=function(e,t){return oe(t,null,null,[e]).length>0};var pe=function(e,t,n,r,o){e=e.replace(F,"$1");var a,s,l,u,p,d,h,g,m,y=e.match(O),v=e.match(q),b=t.nodeType;if(z.POS.test(e))return i(e,t,n,r,y);if(r)a=w.call(r,0);else if(y&&1===y.length){if(v.length>1&&9===b&&!o&&(y=z.ID.exec(v[0]))){if(t=ae.find.ID(y[1],t,o)[0],!t)return n;e=e.slice(v.shift().length)}for(g=(y=W.exec(v[0]))&&!y.index&&t.parentNode||t,m=v.pop(),d=m.split(":not")[0],l=0,u=ae.order.length;l<u;l++)if(h=ae.order[l],y=z[h].exec(d)){if(a=ae.find[h]((y[1]||"").replace(I,""),g,o),null==a)continue;d===m&&(e=e.slice(0,e.length-m.length)+d.replace(z[h],""),e||T.apply(n,w.call(a,0)));break}}if(e)for(s=fe(e,t,o),f=s.dirruns++,null==a&&(a=ae.find.TAG("*",W.test(e)&&t.parentNode||t)),l=0;p=a[l];l++)c=s.runs++,s(p,t)&&n.push(p);return n};g.querySelectorAll&&function(){var e,t=pe,n=/'|\\/g,r=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,i=[],o=[":active"],a=m.matchesSelector||m.mozMatchesSelector||m.webkitMatchesSelector||m.oMatchesSelector||m.msMatchesSelector;Z(function(e){e.innerHTML="<select><option selected></option></select>",e.querySelectorAll("[selected]").length||i.push("\\["+C+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||i.push(":checked")}),Z(function(e){e.innerHTML="<p test=''></p>",e.querySelectorAll("[test^='']").length&&i.push("[*^$]="+C+"*(?:\"\"|'')"),e.innerHTML="<input type='hidden'>",e.querySelectorAll(":enabled").length||i.push(":enabled",":disabled")}),i=i.length&&new RegExp(i.join("|")),pe=function(e,r,o,a,s){if(!(a||s||i&&i.test(e)))if(9===r.nodeType)try{return T.apply(o,w.call(r.querySelectorAll(e),0)),o}catch(l){}else if(1===r.nodeType&&"object"!==r.nodeName.toLowerCase()){var u=r.getAttribute("id"),c=u||N,f=W.test(e)&&r.parentNode||r;u?c=c.replace(n,"\\$&"):r.setAttribute("id",c);try{return T.apply(o,w.call(f.querySelectorAll(e.replace(O,"[id='"+c+"'] $&")),0)),o}catch(l){}finally{u||r.removeAttribute("id")}}return t(e,r,o,a,s)},a&&(Z(function(t){e=a.call(t,"div");try{a.call(t,"[test!='']:sizzle"),o.push(ae.match.PSEUDO)}catch(n){}}),o=new RegExp(o.join("|")),oe.matchesSelector=function(t,n){if(n=n.replace(r,"='$1']"),!(le(t)||o.test(n)||i&&i.test(n)))try{var s=a.call(t,n);if(s||e||t.document&&11!==t.document.nodeType)return s}catch(l){}return oe(n,null,null,[t]).length>0})}(),oe.attr=K.attr,K.find=oe,K.expr=oe.selectors,K.expr[":"]=K.expr.pseudos,K.unique=oe.uniqueSort,K.text=oe.getText,K.isXMLDoc=oe.isXML,K.contains=oe.contains}(e);var Me=/Until$/,Oe=/^(?:parents|prev(?:Until|All))/,_e=/^.[^:#\[\.,]*$/,qe=K.expr.match.needsContext,Be={children:!0,contents:!0,next:!0,prev:!0};K.fn.extend({find:function(e){var t,n,r,i,o,a,s=this;if("string"!=typeof e)return K(e).filter(function(){for(t=0,n=s.length;t<n;t++)if(K.contains(s[t],this))return!0});for(a=this.pushStack("","find",e),t=0,n=this.length;t<n;t++)if(r=a.length,K.find(e,this[t],a),t>0)for(i=r;i<a.length;i++)for(o=0;o<r;o++)if(a[o]===a[i]){a.splice(i--,1);break}return a},has:function(e){var t,n=K(e,this),r=n.length;return this.filter(function(){for(t=0;t<r;t++)if(K.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(u(this,e,!1),"not",e)},filter:function(e){return this.pushStack(u(this,e,!0),"filter",e)},is:function(e){return!!e&&("string"==typeof e?qe.test(e)?K(e,this.context).index(this[0])>=0:K.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){for(var n,r=0,i=this.length,o=[],a=qe.test(e)||"string"!=typeof e?K(e,t||this.context):0;r<i;r++)for(n=this[r];n&&n.ownerDocument&&n!==t&&11!==n.nodeType;){if(a?a.index(n)>-1:K.find.matchesSelector(n,e)){o.push(n);break}n=n.parentNode}return o=o.length>1?K.unique(o):o,this.pushStack(o,"closest",e)},index:function(e){return e?"string"==typeof e?K.inArray(this[0],K(e)):K.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(e,t){var n="string"==typeof e?K(e,t):K.makeArray(e&&e.nodeType?[e]:e),r=K.merge(this.get(),n);return this.pushStack(s(n[0])||s(r[0])?r:K.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),K.fn.andSelf=K.fn.addBack,K.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return K.dir(e,"parentNode")},parentsUntil:function(e,t,n){return K.dir(e,"parentNode",n)},next:function(e){return l(e,"nextSibling")},prev:function(e){return l(e,"previousSibling")},nextAll:function(e){return K.dir(e,"nextSibling")},prevAll:function(e){return K.dir(e,"previousSibling")},nextUntil:function(e,t,n){return K.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return K.dir(e,"previousSibling",n)},siblings:function(e){return K.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return K.sibling(e.firstChild)},contents:function(e){return K.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:K.merge([],e.childNodes)}},function(e,t){K.fn[e]=function(n,r){var i=K.map(this,t,n);return Me.test(e)||(r=n),r&&"string"==typeof r&&(i=K.filter(r,i)),i=this.length>1&&!Be[e]?K.unique(i):i,this.length>1&&Oe.test(e)&&(i=i.reverse()),this.pushStack(i,e,Y.call(arguments).join(","))}}),K.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),1===t.length?K.find.matchesSelector(t[0],e)?[t[0]]:[]:K.find.matches(e,t)},dir:function(e,n,r){for(var i=[],o=e[n];o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!K(o).is(r));)1===o.nodeType&&i.push(o),o=o[n];return i},sibling:function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});var We="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",Pe=/ jQuery\d+="(?:null|\d+)"/g,Re=/^\s+/,$e=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,Ie=/<([\w:]+)/,ze=/<tbody/i,Xe=/<|&#?\w+;/,Ue=/<(?:script|style|link)/i,Ye=/<(?:script|object|embed|option|style)/i,Je=new RegExp("<(?:"+We+")[\\s/>]","i"),Ve=/^(?:checkbox|radio)$/,Ge=/checked\s*(?:[^=]|=\s*.checked.)/i,Qe=/\/(java|ecma)script/i,Ke=/^\s*<!(?:\[CDATA\[|\-\-)|[\]\-]{2}>\s*$/g,Ze={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},et=c(R),tt=et.appendChild(R.createElement("div"));
+Ze.optgroup=Ze.option,Ze.tbody=Ze.tfoot=Ze.colgroup=Ze.caption=Ze.thead,Ze.th=Ze.td,K.support.htmlSerialize||(Ze._default=[1,"X<div>","</div>"]),K.fn.extend({text:function(e){return K.access(this,function(e){return e===t?K.text(this):this.empty().append((this[0]&&this[0].ownerDocument||R).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(K.isFunction(e))return this.each(function(t){K(this).wrapAll(e.call(this,t))});if(this[0]){var t=K(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){for(var e=this;e.firstChild&&1===e.firstChild.nodeType;)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return K.isFunction(e)?this.each(function(t){K(this).wrapInner(e.call(this,t))}):this.each(function(){var t=K(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=K.isFunction(e);return this.each(function(n){K(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){K.nodeName(this,"body")||K(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(1===this.nodeType||11===this.nodeType)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(1===this.nodeType||11===this.nodeType)&&this.insertBefore(e,this.firstChild)})},before:function(){if(!s(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this)});if(arguments.length){var e=K.clean(arguments);return this.pushStack(K.merge(e,this),"before",this.selector)}},after:function(){if(!s(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this.nextSibling)});if(arguments.length){var e=K.clean(arguments);return this.pushStack(K.merge(this,e),"after",this.selector)}},remove:function(e,t){for(var n,r=0;null!=(n=this[r]);r++)e&&!K.filter(e,[n]).length||(!t&&1===n.nodeType&&(K.cleanData(n.getElementsByTagName("*")),K.cleanData([n])),n.parentNode&&n.parentNode.removeChild(n));return this},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)for(1===e.nodeType&&K.cleanData(e.getElementsByTagName("*"));e.firstChild;)e.removeChild(e.firstChild);return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return K.clone(this,e,t)})},html:function(e){return K.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return 1===n.nodeType?n.innerHTML.replace(Pe,""):t;if("string"==typeof e&&!Ue.test(e)&&(K.support.htmlSerialize||!Je.test(e))&&(K.support.leadingWhitespace||!Re.test(e))&&!Ze[(Ie.exec(e)||["",""])[1].toLowerCase()]){e=e.replace($e,"<$1></$2>");try{for(;r<i;r++)n=this[r]||{},1===n.nodeType&&(K.cleanData(n.getElementsByTagName("*")),n.innerHTML=e);n=0}catch(o){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(e){return s(this[0])?this.length?this.pushStack(K(K.isFunction(e)?e():e),"replaceWith",e):this:K.isFunction(e)?this.each(function(t){var n=K(this),r=n.html();n.replaceWith(e.call(this,t,r))}):("string"!=typeof e&&(e=K(e).detach()),this.each(function(){var t=this.nextSibling,n=this.parentNode;K(this).remove(),t?K(t).before(e):K(n).append(e)}))},detach:function(e){return this.remove(e,!0)},domManip:function(e,n,r){e=[].concat.apply([],e);var i,o,a,s,l=0,u=e[0],c=[],p=this.length;if(!K.support.checkClone&&p>1&&"string"==typeof u&&Ge.test(u))return this.each(function(){K(this).domManip(e,n,r)});if(K.isFunction(u))return this.each(function(i){var o=K(this);e[0]=u.call(this,i,n?o.html():t),o.domManip(e,n,r)});if(this[0]){if(i=K.buildFragment(e,this,c),a=i.fragment,o=a.firstChild,1===a.childNodes.length&&(a=o),o)for(n=n&&K.nodeName(o,"tr"),s=i.cacheable||p-1;l<p;l++)r.call(n&&K.nodeName(this[l],"table")?f(this[l],"tbody"):this[l],l===s?a:K.clone(a,!0,!0));a=o=null,c.length&&K.each(c,function(e,t){t.src?K.ajax?K.ajax({url:t.src,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0}):K.error("no ajax"):K.globalEval((t.text||t.textContent||t.innerHTML||"").replace(Ke,"")),t.parentNode&&t.parentNode.removeChild(t)})}return this}}),K.buildFragment=function(e,n,r){var i,o,a,s=e[0];return n=n||R,n=(n[0]||n).ownerDocument||n[0]||n,"undefined"==typeof n.createDocumentFragment&&(n=R),1===e.length&&"string"==typeof s&&s.length<512&&n===R&&"<"===s.charAt(0)&&!Ye.test(s)&&(K.support.checkClone||!Ge.test(s))&&(K.support.html5Clone||!Je.test(s))&&(o=!0,i=K.fragments[s],a=i!==t),i||(i=n.createDocumentFragment(),K.clean(e,n,i,r),o&&(K.fragments[s]=a&&i)),{fragment:i,cacheable:o}},K.fragments={},K.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){K.fn[e]=function(n){var r,i=0,o=[],a=K(n),s=a.length,l=1===this.length&&this[0].parentNode;if((null==l||l&&11===l.nodeType&&1===l.childNodes.length)&&1===s)return a[t](this[0]),this;for(;i<s;i++)r=(i>0?this.clone(!0):this).get(),K(a[i])[t](r),o=o.concat(r);return this.pushStack(o,e,a.selector)}}),K.extend({clone:function(e,t,n){var r,i,o,a;if(K.support.html5Clone||K.isXMLDoc(e)||!Je.test("<"+e.nodeName+">")?a=e.cloneNode(!0):(tt.innerHTML=e.outerHTML,tt.removeChild(a=tt.firstChild)),!(K.support.noCloneEvent&&K.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||K.isXMLDoc(e)))for(d(e,a),r=h(e),i=h(a),o=0;r[o];++o)i[o]&&d(r[o],i[o]);if(t&&(p(e,a),n))for(r=h(e),i=h(a),o=0;r[o];++o)p(r[o],i[o]);return r=i=null,a},clean:function(e,t,n,r){var i,o,a,s,l,u,f,p,d,h,m,y=0,v=[];for(t&&"undefined"!=typeof t.createDocumentFragment||(t=R),o=t===R&&et;null!=(a=e[y]);y++)if("number"==typeof a&&(a+=""),a){if("string"==typeof a)if(Xe.test(a)){for(o=o||c(t),f=f||o.appendChild(t.createElement("div")),a=a.replace($e,"<$1></$2>"),s=(Ie.exec(a)||["",""])[1].toLowerCase(),l=Ze[s]||Ze._default,u=l[0],f.innerHTML=l[1]+a+l[2];u--;)f=f.lastChild;if(!K.support.tbody)for(p=ze.test(a),d="table"!==s||p?"<table>"!==l[1]||p?[]:f.childNodes:f.firstChild&&f.firstChild.childNodes,i=d.length-1;i>=0;--i)K.nodeName(d[i],"tbody")&&!d[i].childNodes.length&&d[i].parentNode.removeChild(d[i]);!K.support.leadingWhitespace&&Re.test(a)&&f.insertBefore(t.createTextNode(Re.exec(a)[0]),f.firstChild),a=f.childNodes,f=o.lastChild}else a=t.createTextNode(a);a.nodeType?v.push(a):v=K.merge(v,a)}if(f&&(o.removeChild(f),a=f=o=null),!K.support.appendChecked)for(y=0;null!=(a=v[y]);y++)K.nodeName(a,"input")?g(a):"undefined"!=typeof a.getElementsByTagName&&K.grep(a.getElementsByTagName("input"),g);if(n)for(h=function(e){if(!e.type||Qe.test(e.type))return r?r.push(e.parentNode?e.parentNode.removeChild(e):e):n.appendChild(e)},y=0;null!=(a=v[y]);y++)K.nodeName(a,"script")&&h(a)||(n.appendChild(a),"undefined"!=typeof a.getElementsByTagName&&(m=K.grep(K.merge([],a.getElementsByTagName("script")),h),v.splice.apply(v,[y+1,0].concat(m)),y+=m.length));return v},cleanData:function(e,t){for(var n,r,i,o,a=0,s=K.expando,l=K.cache,u=K.support.deleteExpando,c=K.event.special;null!=(i=e[a]);a++)if((t||K.acceptData(i))&&(r=i[s],n=r&&l[r])){if(n.events)for(o in n.events)c[o]?K.event.remove(i,o):K.removeEvent(i,o,n.handle);l[r]&&(delete l[r],u?delete i[s]:i.removeAttribute?i.removeAttribute(s):i[s]=null,K.deletedIds.push(r))}}}),function(){var e,t;K.uaMatch=function(e){e=e.toLowerCase();var t=/(chrome)[ \/]([\w.]+)/.exec(e)||/(webkit)[ \/]([\w.]+)/.exec(e)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(e)||/(msie) ([\w.]+)/.exec(e)||e.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(e)||[];return{browser:t[1]||"",version:t[2]||"0"}},e=K.uaMatch(I.userAgent),t={},e.browser&&(t[e.browser]=!0,t.version=e.version),t.webkit&&(t.safari=!0),K.browser=t,K.sub=function(){function e(t,n){return new e.fn.init(t,n)}K.extend(!0,e,this),e.superclass=this,e.fn=e.prototype=this(),e.fn.constructor=e,e.sub=this.sub,e.fn.init=function n(n,r){return r&&r instanceof K&&!(r instanceof e)&&(r=e(r)),K.fn.init.call(this,n,r,t)},e.fn.init.prototype=e.fn;var t=e(R);return e}}();var nt,rt,it,ot=/alpha\([^)]*\)/i,at=/opacity=([^)]*)/,st=/^(top|right|bottom|left)$/,lt=/^margin/,ut=new RegExp("^("+Z+")(.*)$","i"),ct=new RegExp("^("+Z+")(?!px)[a-z%]+$","i"),ft=new RegExp("^([-+])=("+Z+")","i"),pt={},dt={position:"absolute",visibility:"hidden",display:"block"},ht={letterSpacing:0,fontWeight:400,lineHeight:1},gt=["Top","Right","Bottom","Left"],mt=["Webkit","O","Moz","ms"],yt=K.fn.toggle;K.fn.extend({css:function(e,n){return K.access(this,function(e,n,r){return r!==t?K.style(e,n,r):K.css(e,n)},e,n,arguments.length>1)},show:function(){return v(this,!0)},hide:function(){return v(this)},toggle:function(e,t){var n="boolean"==typeof e;return K.isFunction(e)&&K.isFunction(t)?yt.apply(this,arguments):this.each(function(){(n?e:y(this))?K(this).show():K(this).hide()})}}),K.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=nt(e,"opacity");return""===n?"1":n}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":K.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,a,s,l=K.camelCase(n),u=e.style;if(n=K.cssProps[l]||(K.cssProps[l]=m(u,l)),s=K.cssHooks[n]||K.cssHooks[l],r===t)return s&&"get"in s&&(o=s.get(e,!1,i))!==t?o:u[n];if(a=typeof r,"string"===a&&(o=ft.exec(r))&&(r=(o[1]+1)*o[2]+parseFloat(K.css(e,n)),a="number"),!(null==r||"number"===a&&isNaN(r)||("number"===a&&!K.cssNumber[l]&&(r+="px"),s&&"set"in s&&(r=s.set(e,r,i))===t)))try{u[n]=r}catch(c){}}},css:function(e,n,r,i){var o,a,s,l=K.camelCase(n);return n=K.cssProps[l]||(K.cssProps[l]=m(e.style,l)),s=K.cssHooks[n]||K.cssHooks[l],s&&"get"in s&&(o=s.get(e,!0,i)),o===t&&(o=nt(e,n)),"normal"===o&&n in ht&&(o=ht[n]),r||i!==t?(a=parseFloat(o),r||K.isNumeric(a)?a||0:o):o},swap:function(e,t,n){var r,i,o={};for(i in t)o[i]=e.style[i],e.style[i]=t[i];r=n.call(e);for(i in t)e.style[i]=o[i];return r}}),e.getComputedStyle?nt=function(e,t){var n,r,i,o,a=getComputedStyle(e,null),s=e.style;return a&&(n=a[t],""===n&&!K.contains(e.ownerDocument.documentElement,e)&&(n=K.style(e,t)),ct.test(n)&&lt.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=n,n=a.width,s.width=r,s.minWidth=i,s.maxWidth=o)),n}:R.documentElement.currentStyle&&(nt=function(e,t){var n,r,i=e.currentStyle&&e.currentStyle[t],o=e.style;return null==i&&o&&o[t]&&(i=o[t]),ct.test(i)&&!st.test(t)&&(n=o.left,r=e.runtimeStyle&&e.runtimeStyle.left,r&&(e.runtimeStyle.left=e.currentStyle.left),o.left="fontSize"===t?"1em":i,i=o.pixelLeft+"px",o.left=n,r&&(e.runtimeStyle.left=r)),""===i?"auto":i}),K.each(["height","width"],function(e,t){K.cssHooks[t]={get:function(e,n,r){if(n)return 0!==e.offsetWidth||"none"!==nt(e,"display")?w(e,t,r):K.swap(e,dt,function(){return w(e,t,r)})},set:function(e,n,r){return b(e,n,r?x(e,t,r,K.support.boxSizing&&"border-box"===K.css(e,"boxSizing")):0)}}}),K.support.opacity||(K.cssHooks.opacity={get:function(e,t){return at.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=K.isNumeric(t)?"alpha(opacity="+100*t+")":"",o=r&&r.filter||n.filter||"";n.zoom=1,t>=1&&""===K.trim(o.replace(ot,""))&&n.removeAttribute&&(n.removeAttribute("filter"),r&&!r.filter)||(n.filter=ot.test(o)?o.replace(ot,i):o+" "+i)}}),K(function(){K.support.reliableMarginRight||(K.cssHooks.marginRight={get:function(e,t){return K.swap(e,{display:"inline-block"},function(){if(t)return nt(e,"marginRight")})}}),!K.support.pixelPosition&&K.fn.position&&K.each(["top","left"],function(e,t){K.cssHooks[t]={get:function(e,n){if(n){var r=nt(e,t);return ct.test(r)?K(e).position()[t]+"px":r}}}})}),K.expr&&K.expr.filters&&(K.expr.filters.hidden=function(e){return 0===e.offsetWidth&&0===e.offsetHeight||!K.support.reliableHiddenOffsets&&"none"===(e.style&&e.style.display||nt(e,"display"))},K.expr.filters.visible=function(e){return!K.expr.filters.hidden(e)}),K.each({margin:"",padding:"",border:"Width"},function(e,t){K.cssHooks[e+t]={expand:function(n){var r,i="string"==typeof n?n.split(" "):[n],o={};for(r=0;r<4;r++)o[e+gt[r]+t]=i[r]||i[r-2]||i[0];return o}},lt.test(e)||(K.cssHooks[e+t].set=b)});var vt=/%20/g,bt=/\[\]$/,xt=/\r?\n/g,wt=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,Tt=/^(?:select|textarea)/i;K.fn.extend({serialize:function(){return K.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?K.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||Tt.test(this.nodeName)||wt.test(this.type))}).map(function(e,t){var n=K(this).val();return null==n?null:K.isArray(n)?K.map(n,function(e,n){return{name:t.name,value:e.replace(xt,"\r\n")}}):{name:t.name,value:n.replace(xt,"\r\n")}}).get()}}),K.param=function(e,n){var r,i=[],o=function(e,t){t=K.isFunction(t)?t():null==t?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(n===t&&(n=K.ajaxSettings&&K.ajaxSettings.traditional),K.isArray(e)||e.jquery&&!K.isPlainObject(e))K.each(e,function(){o(this.name,this.value)});else for(r in e)N(r,e[r],n,o);return i.join("&").replace(vt,"+")};var Nt,Ct,Et=/#.*$/,kt=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,St=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,At=/^(?:GET|HEAD)$/,jt=/^\/\//,Dt=/\?/,Lt=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,Ht=/([?&])_=[^&]*/,Ft=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,Mt=K.fn.load,Ot={},_t={},qt=["*/"]+["*"];try{Nt=$.href}catch(Bt){Nt=R.createElement("a"),Nt.href="",Nt=Nt.href}Ct=Ft.exec(Nt.toLowerCase())||[],K.fn.load=function(e,n,r){if("string"!=typeof e&&Mt)return Mt.apply(this,arguments);if(!this.length)return this;var i,o,a,s=this,l=e.indexOf(" ");return l>=0&&(i=e.slice(l,e.length),e=e.slice(0,l)),K.isFunction(n)?(r=n,n=t):"object"==typeof n&&(o="POST"),K.ajax({url:e,type:o,dataType:"html",data:n,complete:function(e,t){r&&s.each(r,a||[e.responseText,t,e])}}).done(function(e){a=arguments,s.html(i?K("<div>").append(e.replace(Lt,"")).find(i):e)}),this},K.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,t){K.fn[t]=function(e){return this.on(t,e)}}),K.each(["get","post"],function(e,n){K[n]=function(e,r,i,o){return K.isFunction(r)&&(o=o||i,i=r,r=t),K.ajax({type:n,url:e,data:r,success:i,dataType:o})}}),K.extend({getScript:function(e,n){return K.get(e,t,n,"script")},getJSON:function(e,t,n){return K.get(e,t,n,"json")},ajaxSetup:function(e,t){return t?k(e,K.ajaxSettings):(t=e,e=K.ajaxSettings),k(e,t),e},ajaxSettings:{url:Nt,isLocal:St.test(Ct[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":qt},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":K.parseJSON,"text xml":K.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:C(Ot),ajaxTransport:C(_t),ajax:function(e,n){function r(e,n,r,a){var u,f,v,b,w,N=n;2!==x&&(x=2,l&&clearTimeout(l),s=t,o=a||"",T.readyState=e>0?4:0,r&&(b=S(p,T,r)),e>=200&&e<300||304===e?(p.ifModified&&(w=T.getResponseHeader("Last-Modified"),w&&(K.lastModified[i]=w),w=T.getResponseHeader("Etag"),w&&(K.etag[i]=w)),304===e?(N="notmodified",u=!0):(u=A(p,b),N=u.state,f=u.data,v=u.error,u=!v)):(v=N,N&&!e||(N="error",e<0&&(e=0))),T.status=e,T.statusText=""+(n||N),u?g.resolveWith(d,[f,N,T]):g.rejectWith(d,[T,N,v]),T.statusCode(y),y=t,c&&h.trigger("ajax"+(u?"Success":"Error"),[T,p,u?f:v]),m.fireWith(d,[T,N]),c&&(h.trigger("ajaxComplete",[T,p]),--K.active||K.event.trigger("ajaxStop")))}"object"==typeof e&&(n=e,e=t),n=n||{};var i,o,a,s,l,u,c,f,p=K.ajaxSetup({},n),d=p.context||p,h=d!==p&&(d.nodeType||d instanceof K)?K(d):K.event,g=K.Deferred(),m=K.Callbacks("once memory"),y=p.statusCode||{},v={},b={},x=0,w="canceled",T={readyState:0,setRequestHeader:function(e,t){if(!x){var n=e.toLowerCase();e=b[n]=b[n]||e,v[e]=t}return this},getAllResponseHeaders:function(){return 2===x?o:null},getResponseHeader:function(e){var n;if(2===x){if(!a)for(a={};n=kt.exec(o);)a[n[1].toLowerCase()]=n[2];n=a[e.toLowerCase()]}return n===t?null:n},overrideMimeType:function(e){return x||(p.mimeType=e),this},abort:function(e){return e=e||w,s&&s.abort(e),r(0,e),this}};if(g.promise(T),T.success=T.done,T.error=T.fail,T.complete=m.add,T.statusCode=function(e){if(e){var t;if(x<2)for(t in e)y[t]=[y[t],e[t]];else t=e[T.status],T.always(t)}return this},p.url=((e||p.url)+"").replace(Et,"").replace(jt,Ct[1]+"//"),p.dataTypes=K.trim(p.dataType||"*").toLowerCase().split(te),null==p.crossDomain&&(u=Ft.exec(p.url.toLowerCase()),p.crossDomain=!(!u||u[1]==Ct[1]&&u[2]==Ct[2]&&(u[3]||("http:"===u[1]?80:443))==(Ct[3]||("http:"===Ct[1]?80:443)))),p.data&&p.processData&&"string"!=typeof p.data&&(p.data=K.param(p.data,p.traditional)),E(Ot,p,n,T),2===x)return T;if(c=p.global,p.type=p.type.toUpperCase(),p.hasContent=!At.test(p.type),c&&0===K.active++&&K.event.trigger("ajaxStart"),!p.hasContent&&(p.data&&(p.url+=(Dt.test(p.url)?"&":"?")+p.data,delete p.data),i=p.url,p.cache===!1)){var N=K.now(),C=p.url.replace(Ht,"$1_="+N);p.url=C+(C===p.url?(Dt.test(p.url)?"&":"?")+"_="+N:"")}(p.data&&p.hasContent&&p.contentType!==!1||n.contentType)&&T.setRequestHeader("Content-Type",p.contentType),p.ifModified&&(i=i||p.url,K.lastModified[i]&&T.setRequestHeader("If-Modified-Since",K.lastModified[i]),K.etag[i]&&T.setRequestHeader("If-None-Match",K.etag[i])),T.setRequestHeader("Accept",p.dataTypes[0]&&p.accepts[p.dataTypes[0]]?p.accepts[p.dataTypes[0]]+("*"!==p.dataTypes[0]?", "+qt+"; q=0.01":""):p.accepts["*"]);for(f in p.headers)T.setRequestHeader(f,p.headers[f]);if(!p.beforeSend||p.beforeSend.call(d,T,p)!==!1&&2!==x){w="abort";for(f in{success:1,error:1,complete:1})T[f](p[f]);if(s=E(_t,p,n,T)){T.readyState=1,c&&h.trigger("ajaxSend",[T,p]),p.async&&p.timeout>0&&(l=setTimeout(function(){T.abort("timeout")},p.timeout));try{x=1,s.send(v,r)}catch(k){if(!(x<2))throw k;r(-1,k)}}else r(-1,"No Transport");return T}return T.abort()},active:0,lastModified:{},etag:{}});var Wt=[],Pt=/\?/,Rt=/(=)\?(?=&|$)|\?\?/,$t=K.now();K.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Wt.pop()||K.expando+"_"+$t++;return this[e]=!0,e}}),K.ajaxPrefilter("json jsonp",function(n,r,i){var o,a,s,l=n.data,u=n.url,c=n.jsonp!==!1,f=c&&Rt.test(u),p=c&&!f&&"string"==typeof l&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Rt.test(l);if("jsonp"===n.dataTypes[0]||f||p)return o=n.jsonpCallback=K.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,a=e[o],f?n.url=u.replace(Rt,"$1"+o):p?n.data=l.replace(Rt,"$1"+o):c&&(n.url+=(Pt.test(u)?"&":"?")+n.jsonp+"="+o),n.converters["script json"]=function(){return s||K.error(o+" was not called"),s[0]},n.dataTypes[0]="json",e[o]=function(){s=arguments},i.always(function(){e[o]=a,n[o]&&(n.jsonpCallback=r.jsonpCallback,Wt.push(o)),s&&K.isFunction(a)&&a(s[0]),s=a=t}),"script"}),K.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(e){return K.globalEval(e),e}}}),K.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),K.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=R.head||R.getElementsByTagName("head")[0]||R.documentElement;return{send:function(i,o){n=R.createElement("script"),n.async="async",e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,i){(i||!n.readyState||/loaded|complete/.test(n.readyState))&&(n.onload=n.onreadystatechange=null,r&&n.parentNode&&r.removeChild(n),n=t,i||o(200,"success"))},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(0,1)}}}});var It,zt=!!e.ActiveXObject&&function(){for(var e in It)It[e](0,1)},Xt=0;K.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&j()||D()}:j,function(e){K.extend(K.support,{ajax:!!e,cors:!!e&&"withCredentials"in e})}(K.ajaxSettings.xhr()),K.support.ajax&&K.ajaxTransport(function(n){if(!n.crossDomain||K.support.cors){var r;return{send:function(i,o){var a,s,l=n.xhr();if(n.username?l.open(n.type,n.url,n.async,n.username,n.password):l.open(n.type,n.url,n.async),n.xhrFields)for(s in n.xhrFields)l[s]=n.xhrFields[s];n.mimeType&&l.overrideMimeType&&l.overrideMimeType(n.mimeType),!n.crossDomain&&!i["X-Requested-With"]&&(i["X-Requested-With"]="XMLHttpRequest");try{for(s in i)l.setRequestHeader(s,i[s])}catch(u){}l.send(n.hasContent&&n.data||null),r=function(e,i){var s,u,c,f,p;try{if(r&&(i||4===l.readyState))if(r=t,a&&(l.onreadystatechange=K.noop,zt&&delete It[a]),i)4!==l.readyState&&l.abort();else{s=l.status,c=l.getAllResponseHeaders(),f={},p=l.responseXML,p&&p.documentElement&&(f.xml=p);try{f.text=l.responseText}catch(e){}try{u=l.statusText}catch(d){u=""}s||!n.isLocal||n.crossDomain?1223===s&&(s=204):s=f.text?200:404}}catch(h){i||o(-1,h)}f&&o(s,u,f,c)},n.async?4===l.readyState?setTimeout(r,0):(a=++Xt,zt&&(It||(It={},K(e).unload(zt)),It[a]=r),l.onreadystatechange=r):r()},abort:function(){r&&r(0,1)}}}});var Ut,Yt,Jt=/^(?:toggle|show|hide)$/,Vt=new RegExp("^(?:([-+])=|)("+Z+")([a-z%]*)$","i"),Gt=/queueHooks$/,Qt=[O],Kt={"*":[function(e,t){var n,r,i,o=this.createTween(e,t),a=Vt.exec(t),s=o.cur(),l=+s||0,u=1;if(a){if(n=+a[2],r=a[3]||(K.cssNumber[e]?"":"px"),"px"!==r&&l){l=K.css(o.elem,e,!0)||n||1;do i=u=u||".5",l/=u,K.style(o.elem,e,l+r),u=o.cur()/s;while(1!==u&&u!==i)}o.unit=r,o.start=l,o.end=a[1]?l+(a[1]+1)*n:n}return o}]};K.Animation=K.extend(F,{tweener:function(e,t){K.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");for(var n,r=0,i=e.length;r<i;r++)n=e[r],Kt[n]=Kt[n]||[],Kt[n].unshift(t)},prefilter:function(e,t){t?Qt.unshift(e):Qt.push(e)}}),K.Tween=_,_.prototype={constructor:_,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(K.cssNumber[n]?"":"px")},cur:function(){var e=_.propHooks[this.prop];return e&&e.get?e.get(this):_.propHooks._default.get(this)},run:function(e){var t,n=_.propHooks[this.prop];return this.pos=t=K.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration),this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):_.propHooks._default.set(this),this}},_.prototype.init.prototype=_.prototype,_.propHooks={_default:{get:function(e){var t;return null==e.elem[e.prop]||e.elem.style&&null!=e.elem.style[e.prop]?(t=K.css(e.elem,e.prop,!1,""),t&&"auto"!==t?t:0):e.elem[e.prop]},set:function(e){K.fx.step[e.prop]?K.fx.step[e.prop](e):e.elem.style&&(null!=e.elem.style[K.cssProps[e.prop]]||K.cssHooks[e.prop])?K.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},_.propHooks.scrollTop=_.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},K.each(["toggle","show","hide"],function(e,t){var n=K.fn[t];K.fn[t]=function(r,i,o){return null==r||"boolean"==typeof r||!e&&K.isFunction(r)&&K.isFunction(i)?n.apply(this,arguments):this.animate(q(t,!0),r,i,o)}}),K.fn.extend({fadeTo:function(e,t,n,r){return this.filter(y).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=K.isEmptyObject(e),o=K.speed(t,n,r),a=function(){var t=F(this,K.extend({},e),o);i&&t.stop(!0)};return i||o.queue===!1?this.each(a):this.queue(o.queue,a)},stop:function(e,n,r){var i=function(e){var t=e.stop;delete e.stop,t(r)};return"string"!=typeof e&&(r=n,n=e,e=t),n&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,n=null!=e&&e+"queueHooks",o=K.timers,a=K._data(this);if(n)a[n]&&a[n].stop&&i(a[n]);else for(n in a)a[n]&&a[n].stop&&Gt.test(n)&&i(a[n]);for(n=o.length;n--;)o[n].elem===this&&(null==e||o[n].queue===e)&&(o[n].anim.stop(r),t=!1,o.splice(n,1));(t||!r)&&K.dequeue(this,e)})}}),K.each({slideDown:q("show"),slideUp:q("hide"),slideToggle:q("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){K.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),K.speed=function(e,t,n){var r=e&&"object"==typeof e?K.extend({},e):{complete:n||!n&&t||K.isFunction(e)&&e,duration:e,easing:n&&t||t&&!K.isFunction(t)&&t};return r.duration=K.fx.off?0:"number"==typeof r.duration?r.duration:r.duration in K.fx.speeds?K.fx.speeds[r.duration]:K.fx.speeds._default,null!=r.queue&&r.queue!==!0||(r.queue="fx"),r.old=r.complete,r.complete=function(){K.isFunction(r.old)&&r.old.call(this),r.queue&&K.dequeue(this,r.queue)},r},K.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},K.timers=[],K.fx=_.prototype.init,K.fx.tick=function(){for(var e,t=K.timers,n=0;n<t.length;n++)e=t[n],!e()&&t[n]===e&&t.splice(n--,1);t.length||K.fx.stop()},K.fx.timer=function(e){e()&&K.timers.push(e)&&!Yt&&(Yt=setInterval(K.fx.tick,K.fx.interval))},K.fx.interval=13,K.fx.stop=function(){clearInterval(Yt),Yt=null},K.fx.speeds={slow:600,fast:200,_default:400},K.fx.step={},K.expr&&K.expr.filters&&(K.expr.filters.animated=function(e){return K.grep(K.timers,function(t){return e===t.elem}).length});var Zt=/^(?:body|html)$/i;K.fn.offset=function(e){if(arguments.length)return e===t?this:this.each(function(t){K.offset.setOffset(this,e,t)});var n,r,i,o,a,s,l,u,c,f,p=this[0],d=p&&p.ownerDocument;if(d)return(i=d.body)===p?K.offset.bodyOffset(p):(r=d.documentElement,K.contains(r,p)?(n=p.getBoundingClientRect(),o=B(d),a=r.clientTop||i.clientTop||0,s=r.clientLeft||i.clientLeft||0,l=o.pageYOffset||r.scrollTop,u=o.pageXOffset||r.scrollLeft,c=n.top+l-a,f=n.left+u-s,{top:c,left:f}):{top:0,left:0})},K.offset={bodyOffset:function(e){var t=e.offsetTop,n=e.offsetLeft;return K.support.doesNotIncludeMarginInBodyOffset&&(t+=parseFloat(K.css(e,"marginTop"))||0,n+=parseFloat(K.css(e,"marginLeft"))||0),{top:t,left:n}},setOffset:function(e,t,n){var r=K.css(e,"position");"static"===r&&(e.style.position="relative");var i,o,a=K(e),s=a.offset(),l=K.css(e,"top"),u=K.css(e,"left"),c=("absolute"===r||"fixed"===r)&&K.inArray("auto",[l,u])>-1,f={},p={};c?(p=a.position(),i=p.top,o=p.left):(i=parseFloat(l)||0,o=parseFloat(u)||0),K.isFunction(t)&&(t=t.call(e,n,s)),null!=t.top&&(f.top=t.top-s.top+i),null!=t.left&&(f.left=t.left-s.left+o),"using"in t?t.using.call(e,f):a.css(f)}},K.fn.extend({position:function(){if(this[0]){var e=this[0],t=this.offsetParent(),n=this.offset(),r=Zt.test(t[0].nodeName)?{top:0,left:0}:t.offset();return n.top-=parseFloat(K.css(e,"marginTop"))||0,n.left-=parseFloat(K.css(e,"marginLeft"))||0,r.top+=parseFloat(K.css(t[0],"borderTopWidth"))||0,r.left+=parseFloat(K.css(t[0],"borderLeftWidth"))||0,{top:n.top-r.top,left:n.left-r.left}}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent||R.body;e&&!Zt.test(e.nodeName)&&"static"===K.css(e,"position");)e=e.offsetParent;return e||R.body})}}),K.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);K.fn[e]=function(i){return K.access(this,function(e,i,o){var a=B(e);return o===t?a?n in a?a[n]:a.document.documentElement[i]:e[i]:void(a?a.scrollTo(r?K(a).scrollLeft():o,r?o:K(a).scrollTop()):e[i]=o)},e,i,arguments.length,null)}}),K.each({Height:"height",Width:"width"},function(e,n){K.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){K.fn[i]=function(i,o){var a=arguments.length&&(r||"boolean"!=typeof i),s=r||(i===!0||o===!0?"margin":"border");return K.access(this,function(n,r,i){var o;return K.isWindow(n)?n.document.documentElement["client"+e]:9===n.nodeType?(o=n.documentElement,Math.max(n.body["scroll"+e],o["scroll"+e],n.body["offset"+e],o["offset"+e],o["client"+e])):i===t?K.css(n,r,i,s):K.style(n,r,i,s)},n,a?i:t,a)}})}),e.jQuery=e.$=K,"function"==typeof define&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return K})}(window);
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/jquery.ba-bbq.min.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/jquery.ba-bbq.min.js
new file mode 100644 (file)
index 0000000..78d1ff5
--- /dev/null
@@ -0,0 +1 @@
+!function(e,t){function n(e){return"string"==typeof e}function r(e){var t=g.call(arguments,1);return function(){return e.apply(this,t.concat(g.call(arguments)))}}function o(e){return e.replace(/^[^#]*#?(.*)$/,"$1")}function a(e){return e.replace(/(?:^[^?#]*\?([^#]*).*$)?.*/,"$1")}function i(r,o,a,i,c){var u,s,p,h,d;return i!==f?(p=a.match(r?/^([^#]*)\#?(.*)$/:/^([^#?]*)\??([^#]*)(#?.*)/),d=p[3]||"",2===c&&n(i)?s=i.replace(r?R:E,""):(h=l(p[2]),i=n(i)?l[r?A:w](i):i,s=2===c?i:1===c?e.extend({},i,h):e.extend({},h,i),s=b(s),r&&(s=s.replace(m,y))),u=p[1]+(r?"#":s||!p[1]?"?":"")+s+d):u=o(a!==f?a:t[S][q]),u}function c(e,t,r){return t===f||"boolean"==typeof t?(r=t,t=b[e?A:w]()):t=n(t)?t.replace(e?R:E,""):t,l(t,r)}function u(t,r,o,a){return n(o)||"object"==typeof o||(a=o,o=r,r=f),this.each(function(){var n=e(this),i=r||v()[(this.nodeName||"").toLowerCase()]||"",c=i&&n.attr(i)||"";n.attr(i,b[t](c,o,a))})}var f,s,l,p,h,d,v,m,g=Array.prototype.slice,y=decodeURIComponent,b=e.param,$=e.bbq=e.bbq||{},x=e.event.special,j="hashchange",w="querystring",A="fragment",N="elemUrlAttr",S="location",q="href",C="src",E=/^.*\?|#.*$/g,R=/^.*\#/,U={};b[w]=r(i,0,a),b[A]=s=r(i,1,o),s.noEscape=function(t){t=t||"";var n=e.map(t.split(""),encodeURIComponent);m=new RegExp(n.join("|"),"g")},s.noEscape(",/"),e.deparam=l=function(t,n){var r={},o={"true":!0,"false":!1,"null":null};return e.each(t.replace(/\+/g," ").split("&"),function(t,a){var i,c=a.split("="),u=y(c[0]),s=r,l=0,p=u.split("]["),h=p.length-1;if(/\[/.test(p[0])&&/\]$/.test(p[h])?(p[h]=p[h].replace(/\]$/,""),p=p.shift().split("[").concat(p),h=p.length-1):h=0,2===c.length)if(i=y(c[1]),n&&(i=i&&!isNaN(i)?+i:"undefined"===i?f:o[i]!==f?o[i]:i),h)for(;l<=h;l++)u=""===p[l]?s.length:p[l],s=s[u]=l<h?s[u]||(p[l+1]&&isNaN(p[l+1])?{}:[]):i;else e.isArray(r[u])?r[u].push(i):r[u]!==f?r[u]=[r[u],i]:r[u]=i;else u&&(r[u]=n?f:"")}),r},l[w]=r(c,0),l[A]=p=r(c,1),e[N]||(e[N]=function(t){return e.extend(U,t)})({a:q,base:q,iframe:C,img:C,input:C,form:"action",link:q,script:C}),v=e[N],e.fn[w]=r(u,w),e.fn[A]=r(u,A),$.pushState=h=function(e,r){n(e)&&/^#/.test(e)&&r===f&&(r=2);var o=e!==f,a=s(t[S][q],o?e:{},o?r:2);t[S][q]=a+(/#/.test(a)?"":"#")},$.getState=d=function(e,t){return e===f||"boolean"==typeof e?p(e):p(t)[e]},$.removeState=function(t){var n={};t!==f&&(n=d(),e.each(e.isArray(t)?t:arguments,function(e,t){delete n[t]})),h(n,2)},x[j]=e.extend(x[j],{add:function(t){function n(e){var t=e[A]=s();e.getState=function(e,n){return e===f||"boolean"==typeof e?l(t,e):l(t,n)[e]},r.apply(this,arguments)}var r;return e.isFunction(t)?(r=t,n):(r=t.handler,void(t.handler=n))}})}(jQuery,this),function(e,t,n){function r(e){return e=e||t[i][u],e.replace(/^[^#]*#?(.*)$/,"$1")}var o,a=e.event.special,i="location",c="hashchange",u="href",f=e.browser,s=document.documentMode,l=f.msie&&(s===n||s<8),p="on"+c in t&&!l;e[c+"Delay"]=100,a[c]=e.extend(a[c],{setup:function(){return!p&&void e(o.start)},teardown:function(){return!p&&void e(o.stop)}}),o=function(){function n(){f=s=function(e){return e},l&&(a=e('<iframe src="javascript:0"/>').hide().insertAfter("body")[0].contentWindow,s=function(){return r(a.document[i][u])},(f=function(e,t){if(e!==t){var n=a.document;n.open().close(),n[i].hash="#"+e}})(r()))}var o,a,f,s,p={};return p.start=function(){if(!o){var a=r();f||n(),function l(){var n=r(),p=s(a);n!==a?(f(a=n,p),e(t).trigger(c)):p!==a&&(t[i][u]=t[i][u].replace(/#.*/,"")+"#"+p),o=setTimeout(l,e[c+"Delay"])}()}},p.stop=function(){a||(o&&clearTimeout(o),o=0)},p}()}(jQuery,this);
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/jquery.slideto.min.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/jquery.slideto.min.js
new file mode 100644 (file)
index 0000000..b15997b
--- /dev/null
@@ -0,0 +1 @@
+!function(i){i.fn.slideto=function(o){return o=i.extend({slide_duration:"slow",highlight_duration:3e3,highlight:!0,highlight_color:"#FFFF99"},o),this.each(function(){obj=i(this),i("body").animate({scrollTop:obj.offset().top},o.slide_duration,function(){o.highlight&&i.ui.version&&obj.effect("highlight",{color:o.highlight_color},o.highlight_duration)})})}}(jQuery);
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/jquery.wiggle.min.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/jquery.wiggle.min.js
new file mode 100644 (file)
index 0000000..6b4e261
--- /dev/null
@@ -0,0 +1 @@
+jQuery.fn.wiggle=function(e){var a={speed:50,wiggles:3,travel:5,callback:null},e=jQuery.extend(a,e);return this.each(function(){var a=this,l=(jQuery(this).wrap('<div class="wiggle-wrap"></div>').css("position","relative"),0);for(i=1;i<=e.wiggles;i++)jQuery(this).animate({left:"-="+e.travel},e.speed).animate({left:"+="+2*e.travel},2*e.speed).animate({left:"-="+e.travel},e.speed,function(){l++,jQuery(a).parent().hasClass("wiggle-wrap")&&jQuery(a).parent().replaceWith(a),l==e.wiggles&&jQuery.isFunction(e.callback)&&e.callback()})})};
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/js-yaml.min.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/js-yaml.min.js
new file mode 100644 (file)
index 0000000..2514a41
--- /dev/null
@@ -0,0 +1,2 @@
+!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.jsyaml=t()}}(function(){var t;return function e(t,n,i){function r(a,s){if(!n[a]){if(!t[a]){var c="function"==typeof require&&require;if(!s&&c)return c(a,!0);if(o)return o(a,!0);var u=new Error("Cannot find module '"+a+"'");throw u.code="MODULE_NOT_FOUND",u}var l=n[a]={exports:{}};t[a][0].call(l.exports,function(e){var n=t[a][1][e];return r(n?n:e)},l,l.exports,e,t,n,i)}return n[a].exports}for(var o="function"==typeof require&&require,a=0;a<i.length;a++)r(i[a]);return r}({1:[function(t,e,n){"use strict";function i(t){return function(){throw new Error("Function "+t+" is deprecated and cannot be used.")}}var r=t("./js-yaml/loader"),o=t("./js-yaml/dumper");e.exports.Type=t("./js-yaml/type"),e.exports.Schema=t("./js-yaml/schema"),e.exports.FAILSAFE_SCHEMA=t("./js-yaml/schema/failsafe"),e.exports.JSON_SCHEMA=t("./js-yaml/schema/json"),e.exports.CORE_SCHEMA=t("./js-yaml/schema/core"),e.exports.DEFAULT_SAFE_SCHEMA=t("./js-yaml/schema/default_safe"),e.exports.DEFAULT_FULL_SCHEMA=t("./js-yaml/schema/default_full"),e.exports.load=r.load,e.exports.loadAll=r.loadAll,e.exports.safeLoad=r.safeLoad,e.exports.safeLoadAll=r.safeLoadAll,e.exports.dump=o.dump,e.exports.safeDump=o.safeDump,e.exports.YAMLException=t("./js-yaml/exception"),e.exports.MINIMAL_SCHEMA=t("./js-yaml/schema/failsafe"),e.exports.SAFE_SCHEMA=t("./js-yaml/schema/default_safe"),e.exports.DEFAULT_SCHEMA=t("./js-yaml/schema/default_full"),e.exports.scan=i("scan"),e.exports.parse=i("parse"),e.exports.compose=i("compose"),e.exports.addConstructor=i("addConstructor")},{"./js-yaml/dumper":3,"./js-yaml/exception":4,"./js-yaml/loader":5,"./js-yaml/schema":7,"./js-yaml/schema/core":8,"./js-yaml/schema/default_full":9,"./js-yaml/schema/default_safe":10,"./js-yaml/schema/failsafe":11,"./js-yaml/schema/json":12,"./js-yaml/type":13}],2:[function(t,e,n){"use strict";function i(t){return"undefined"==typeof t||null===t}function r(t){return"object"==typeof t&&null!==t}function o(t){return Array.isArray(t)?t:i(t)?[]:[t]}function a(t,e){var n,i,r,o;if(e)for(o=Object.keys(e),n=0,i=o.length;i>n;n+=1)r=o[n],t[r]=e[r];return t}function s(t,e){var n,i="";for(n=0;e>n;n+=1)i+=t;return i}function c(t){return 0===t&&Number.NEGATIVE_INFINITY===1/t}e.exports.isNothing=i,e.exports.isObject=r,e.exports.toArray=o,e.exports.repeat=s,e.exports.isNegativeZero=c,e.exports.extend=a},{}],3:[function(t,e,n){"use strict";function i(t,e){var n,i,r,o,a,s,c;if(null===e)return{};for(n={},i=Object.keys(e),r=0,o=i.length;o>r;r+=1)a=i[r],s=String(e[a]),"!!"===a.slice(0,2)&&(a="tag:yaml.org,2002:"+a.slice(2)),c=t.compiledTypeMap[a],c&&E.call(c.styleAliases,s)&&(s=c.styleAliases[s]),n[a]=s;return n}function r(t){var e,n,i;if(e=t.toString(16).toUpperCase(),255>=t)n="x",i=2;else if(65535>=t)n="u",i=4;else{if(!(4294967295>=t))throw new O("code point within a string may not be greater than 0xFFFFFFFF");n="U",i=8}return"\\"+n+j.repeat("0",i-e.length)+e}function o(t){this.schema=t.schema||S,this.indent=Math.max(1,t.indent||2),this.skipInvalid=t.skipInvalid||!1,this.flowLevel=j.isNothing(t.flowLevel)?-1:t.flowLevel,this.styleMap=i(this.schema,t.styles||null),this.sortKeys=t.sortKeys||!1,this.lineWidth=t.lineWidth||80,this.implicitTypes=this.schema.compiledImplicit,this.explicitTypes=this.schema.compiledExplicit,this.tag=null,this.result="",this.duplicates=[],this.usedDuplicates=null}function a(t,e){for(var n,i=j.repeat(" ",e),r=0,o=-1,a="",s=t.length;s>r;)o=t.indexOf("\n",r),-1===o?(n=t.slice(r),r=s):(n=t.slice(r,o+1),r=o+1),n.length&&"\n"!==n&&(a+=i),a+=n;return a}function s(t,e){return"\n"+j.repeat(" ",t.indent*e)}function c(t,e){var n,i,r;for(n=0,i=t.implicitTypes.length;i>n;n+=1)if(r=t.implicitTypes[n],r.resolve(e))return!0;return!1}function u(t){this.source=t,this.result="",this.checkpoint=0}function l(t,e,n,i){var r,o,s,l,f,m,y,g,v,x,A,b,w,k,C,j,O,S,_,I,E;if(0===e.length)return void(t.dump="''");if(-1!==et.indexOf(e))return void(t.dump="'"+e+"'");for(r=!0,o=e.length?e.charCodeAt(0):0,s=M===o||M===e.charCodeAt(e.length-1),(K===o||W===o||G===o||z===o)&&(r=!1),s?(r=!1,l=!1,f=!1):(l=!i,f=!i),m=!0,y=new u(e),g=!1,v=0,x=0,A=t.indent*n,b=t.lineWidth,-1===b&&(b=9007199254740991),40>A?b-=A:b=40,k=0;k<e.length;k++){if(w=e.charCodeAt(k),r){if(h(w))continue;r=!1}m&&w===P&&(m=!1),C=tt[w],j=d(w),(C||j)&&(w!==N&&w!==D&&w!==P?(l=!1,f=!1):w===N&&(g=!0,m=!1,k>0&&(O=e.charCodeAt(k-1),O===M&&(f=!1,l=!1)),l&&(S=k-v,v=k,S>x&&(x=S))),w!==D&&(m=!1),y.takeUpTo(k),y.escapeChar())}if(r&&c(t,e)&&(r=!1),_="",(l||f)&&(I=0,e.charCodeAt(e.length-1)===N&&(I+=1,e.charCodeAt(e.length-2)===N&&(I+=1)),0===I?_="-":2===I&&(_="+")),f&&b>x&&(l=!1),g||(f=!1),r)t.dump=e;else if(m)t.dump="'"+e+"'";else if(l)E=p(e,b),t.dump=">"+_+"\n"+a(E,A);else if(f)_||(e=e.replace(/\n$/,"")),t.dump="|"+_+"\n"+a(e,A);else{if(!y)throw new Error("Failed to dump scalar value");y.finish(),t.dump='"'+y.result+'"'}}function p(t,e){var n,i="",r=0,o=t.length,a=/\n+$/.exec(t);for(a&&(o=a.index+1);o>r;)n=t.indexOf("\n",r),n>o||-1===n?(i&&(i+="\n\n"),i+=f(t.slice(r,o),e),r=o):(i&&(i+="\n\n"),i+=f(t.slice(r,n),e),r=n+1);return a&&"\n"!==a[0]&&(i+=a[0]),i}function f(t,e){if(""===t)return t;for(var n,i,r,o=/[^\s] [^\s]/g,a="",s=0,c=0,u=o.exec(t);u;)n=u.index,n-c>e&&(i=s!==c?s:n,a&&(a+="\n"),r=t.slice(c,i),a+=r,c=i+1),s=n+1,u=o.exec(t);return a&&(a+="\n"),a+=c!==s&&t.length-c>e?t.slice(c,s)+"\n"+t.slice(s+1):t.slice(c)}function h(t){return F!==t&&N!==t&&T!==t&&$!==t&&V!==t&&Z!==t&&J!==t&&X!==t&&U!==t&&Y!==t&&B!==t&&L!==t&&Q!==t&&R!==t&&P!==t&&D!==t&&q!==t&&H!==t&&!tt[t]&&!d(t)}function d(t){return!(t>=32&&126>=t||133===t||t>=160&&55295>=t||t>=57344&&65533>=t||t>=65536&&1114111>=t)}function m(t,e,n){var i,r,o="",a=t.tag;for(i=0,r=n.length;r>i;i+=1)A(t,e,n[i],!1,!1)&&(0!==i&&(o+=", "),o+=t.dump);t.tag=a,t.dump="["+o+"]"}function y(t,e,n,i){var r,o,a="",c=t.tag;for(r=0,o=n.length;o>r;r+=1)A(t,e+1,n[r],!0,!0)&&(i&&0===r||(a+=s(t,e)),a+="- "+t.dump);t.tag=c,t.dump=a||"[]"}function g(t,e,n){var i,r,o,a,s,c="",u=t.tag,l=Object.keys(n);for(i=0,r=l.length;r>i;i+=1)s="",0!==i&&(s+=", "),o=l[i],a=n[o],A(t,e,o,!1,!1)&&(t.dump.length>1024&&(s+="? "),s+=t.dump+": ",A(t,e,a,!1,!1)&&(s+=t.dump,c+=s));t.tag=u,t.dump="{"+c+"}"}function v(t,e,n,i){var r,o,a,c,u,l,p="",f=t.tag,h=Object.keys(n);if(t.sortKeys===!0)h.sort();else if("function"==typeof t.sortKeys)h.sort(t.sortKeys);else if(t.sortKeys)throw new O("sortKeys must be a boolean or a function");for(r=0,o=h.length;o>r;r+=1)l="",i&&0===r||(l+=s(t,e)),a=h[r],c=n[a],A(t,e+1,a,!0,!0,!0)&&(u=null!==t.tag&&"?"!==t.tag||t.dump&&t.dump.length>1024,u&&(l+=t.dump&&N===t.dump.charCodeAt(0)?"?":"? "),l+=t.dump,u&&(l+=s(t,e)),A(t,e+1,c,!0,u)&&(l+=t.dump&&N===t.dump.charCodeAt(0)?":":": ",l+=t.dump,p+=l));t.tag=f,t.dump=p||"{}"}function x(t,e,n){var i,r,o,a,s,c;for(r=n?t.explicitTypes:t.implicitTypes,o=0,a=r.length;a>o;o+=1)if(s=r[o],(s.instanceOf||s.predicate)&&(!s.instanceOf||"object"==typeof e&&e instanceof s.instanceOf)&&(!s.predicate||s.predicate(e))){if(t.tag=n?s.tag:"?",s.represent){if(c=t.styleMap[s.tag]||s.defaultStyle,"[object Function]"===I.call(s.represent))i=s.represent(e,c);else{if(!E.call(s.represent,c))throw new O("!<"+s.tag+'> tag resolver accepts not "'+c+'" style');i=s.represent[c](e,c)}t.dump=i}return!0}return!1}function A(t,e,n,i,r,o){t.tag=null,t.dump=n,x(t,n,!1)||x(t,n,!0);var a=I.call(t.dump);i&&(i=0>t.flowLevel||t.flowLevel>e);var s,c,u="[object Object]"===a||"[object Array]"===a;if(u&&(s=t.duplicates.indexOf(n),c=-1!==s),(null!==t.tag&&"?"!==t.tag||c||2!==t.indent&&e>0)&&(r=!1),c&&t.usedDuplicates[s])t.dump="*ref_"+s;else{if(u&&c&&!t.usedDuplicates[s]&&(t.usedDuplicates[s]=!0),"[object Object]"===a)i&&0!==Object.keys(t.dump).length?(v(t,e,t.dump,r),c&&(t.dump="&ref_"+s+t.dump)):(g(t,e,t.dump),c&&(t.dump="&ref_"+s+" "+t.dump));else if("[object Array]"===a)i&&0!==t.dump.length?(y(t,e,t.dump,r),c&&(t.dump="&ref_"+s+t.dump)):(m(t,e,t.dump),c&&(t.dump="&ref_"+s+" "+t.dump));else{if("[object String]"!==a){if(t.skipInvalid)return!1;throw new O("unacceptable kind of an object to dump "+a)}"?"!==t.tag&&l(t,t.dump,e,o)}null!==t.tag&&"?"!==t.tag&&(t.dump="!<"+t.tag+"> "+t.dump)}return!0}function b(t,e){var n,i,r=[],o=[];for(w(t,r,o),n=0,i=o.length;i>n;n+=1)e.duplicates.push(r[o[n]]);e.usedDuplicates=new Array(i)}function w(t,e,n){var i,r,o;if(null!==t&&"object"==typeof t)if(r=e.indexOf(t),-1!==r)-1===n.indexOf(r)&&n.push(r);else if(e.push(t),Array.isArray(t))for(r=0,o=t.length;o>r;r+=1)w(t[r],e,n);else for(i=Object.keys(t),r=0,o=i.length;o>r;r+=1)w(t[i[r]],e,n)}function k(t,e){e=e||{};var n=new o(e);return b(t,n),A(n,0,t,!0,!0)?n.dump+"\n":""}function C(t,e){return k(t,j.extend({schema:_},e))}var j=t("./common"),O=t("./exception"),S=t("./schema/default_full"),_=t("./schema/default_safe"),I=Object.prototype.toString,E=Object.prototype.hasOwnProperty,F=9,N=10,T=13,M=32,L=33,D=34,U=35,q=37,Y=38,P=39,B=42,$=44,K=45,H=58,R=62,W=63,G=64,V=91,Z=93,z=96,J=123,Q=124,X=125,tt={};tt[0]="\\0",tt[7]="\\a",tt[8]="\\b",tt[9]="\\t",tt[10]="\\n",tt[11]="\\v",tt[12]="\\f",tt[13]="\\r",tt[27]="\\e",tt[34]='\\"',tt[92]="\\\\",tt[133]="\\N",tt[160]="\\_",tt[8232]="\\L",tt[8233]="\\P";var et=["y","Y","yes","Yes","YES","on","On","ON","n","N","no","No","NO","off","Off","OFF"];u.prototype.takeUpTo=function(t){var e;if(t<this.checkpoint)throw e=new Error("position should be > checkpoint"),e.position=t,e.checkpoint=this.checkpoint,e;return this.result+=this.source.slice(this.checkpoint,t),this.checkpoint=t,this},u.prototype.escapeChar=function(){var t,e;return t=this.source.charCodeAt(this.checkpoint),e=tt[t]||r(t),this.result+=e,this.checkpoint+=1,this},u.prototype.finish=function(){this.source.length>this.checkpoint&&this.takeUpTo(this.source.length)},e.exports.dump=k,e.exports.safeDump=C},{"./common":2,"./exception":4,"./schema/default_full":9,"./schema/default_safe":10}],4:[function(t,e,n){"use strict";function i(t,e){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack||"",this.name="YAMLException",this.reason=t,this.mark=e,this.message=(this.reason||"(unknown reason)")+(this.mark?" "+this.mark.toString():"")}var r=t("inherit");r(i,Error),i.prototype.toString=function(t){var e=this.name+": ";return e+=this.reason||"(unknown reason)",!t&&this.mark&&(e+=" "+this.mark.toString()),e},e.exports=i},{inherit:31}],5:[function(t,e,n){"use strict";function i(t){return 10===t||13===t}function r(t){return 9===t||32===t}function o(t){return 9===t||32===t||10===t||13===t}function a(t){return 44===t||91===t||93===t||123===t||125===t}function s(t){var e;return t>=48&&57>=t?t-48:(e=32|t,e>=97&&102>=e?e-97+10:-1)}function c(t){return 120===t?2:117===t?4:85===t?8:0}function u(t){return t>=48&&57>=t?t-48:-1}function l(t){return 48===t?"\0":97===t?"\a":98===t?"\b":116===t?"\t":9===t?"\t":110===t?"\n":118===t?"\x0B":102===t?"\f":114===t?"\r":101===t?"\e":32===t?" ":34===t?'"':47===t?"/":92===t?"\\":78===t?"\85":95===t?" ":76===t?"\u2028":80===t?"\u2029":""}function p(t){return 65535>=t?String.fromCharCode(t):String.fromCharCode((t-65536>>10)+55296,(t-65536&1023)+56320)}function f(t,e){this.input=t,this.filename=e.filename||null,this.schema=e.schema||H,this.onWarning=e.onWarning||null,this.legacy=e.legacy||!1,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=t.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.documents=[]}function h(t,e){return new B(e,new $(t.filename,t.input,t.position,t.line,t.position-t.lineStart))}function d(t,e){throw h(t,e)}function m(t,e){t.onWarning&&t.onWarning.call(null,h(t,e))}function y(t,e,n,i){var r,o,a,s;if(n>e){if(s=t.input.slice(e,n),i)for(r=0,o=s.length;o>r;r+=1)a=s.charCodeAt(r),9===a||a>=32&&1114111>=a||d(t,"expected valid JSON character");else X.test(s)&&d(t,"the stream contains non-printable characters");t.result+=s}}function g(t,e,n){var i,r,o,a;for(P.isObject(n)||d(t,"cannot merge mappings; the provided source object is unacceptable"),i=Object.keys(n),o=0,a=i.length;a>o;o+=1)r=i[o],R.call(e,r)||(e[r]=n[r])}function v(t,e,n,i,r){var o,a;if(i=String(i),null===e&&(e={}),"tag:yaml.org,2002:merge"===n)if(Array.isArray(r))for(o=0,a=r.length;a>o;o+=1)g(t,e,r[o]);else g(t,e,r);else e[i]=r;return e}function x(t){var e;e=t.input.charCodeAt(t.position),10===e?t.position++:13===e?(t.position++,10===t.input.charCodeAt(t.position)&&t.position++):d(t,"a line break is expected"),t.line+=1,t.lineStart=t.position}function A(t,e,n){for(var o=0,a=t.input.charCodeAt(t.position);0!==a;){for(;r(a);)a=t.input.charCodeAt(++t.position);if(e&&35===a)do a=t.input.charCodeAt(++t.position);while(10!==a&&13!==a&&0!==a);if(!i(a))break;for(x(t),a=t.input.charCodeAt(t.position),o++,t.lineIndent=0;32===a;)t.lineIndent++,a=t.input.charCodeAt(++t.position)}return-1!==n&&0!==o&&t.lineIndent<n&&m(t,"deficient indentation"),o}function b(t){var e,n=t.position;return e=t.input.charCodeAt(n),!(45!==e&&46!==e||t.input.charCodeAt(n+1)!==e||t.input.charCodeAt(n+2)!==e||(n+=3,e=t.input.charCodeAt(n),0!==e&&!o(e)))}function w(t,e){1===e?t.result+=" ":e>1&&(t.result+=P.repeat("\n",e-1))}function k(t,e,n){var s,c,u,l,p,f,h,d,m,g=t.kind,v=t.result;if(m=t.input.charCodeAt(t.position),o(m)||a(m)||35===m||38===m||42===m||33===m||124===m||62===m||39===m||34===m||37===m||64===m||96===m)return!1;if((63===m||45===m)&&(c=t.input.charCodeAt(t.position+1),o(c)||n&&a(c)))return!1;for(t.kind="scalar",t.result="",u=l=t.position,p=!1;0!==m;){if(58===m){if(c=t.input.charCodeAt(t.position+1),o(c)||n&&a(c))break}else if(35===m){if(s=t.input.charCodeAt(t.position-1),o(s))break}else{if(t.position===t.lineStart&&b(t)||n&&a(m))break;if(i(m)){if(f=t.line,h=t.lineStart,d=t.lineIndent,A(t,!1,-1),t.lineIndent>=e){p=!0,m=t.input.charCodeAt(t.position);continue}t.position=l,t.line=f,t.lineStart=h,t.lineIndent=d;break}}p&&(y(t,u,l,!1),w(t,t.line-f),u=l=t.position,p=!1),r(m)||(l=t.position+1),m=t.input.charCodeAt(++t.position)}return y(t,u,l,!1),!!t.result||(t.kind=g,t.result=v,!1)}function C(t,e){var n,r,o;if(n=t.input.charCodeAt(t.position),39!==n)return!1;for(t.kind="scalar",t.result="",t.position++,r=o=t.position;0!==(n=t.input.charCodeAt(t.position));)if(39===n){if(y(t,r,t.position,!0),n=t.input.charCodeAt(++t.position),39!==n)return!0;r=o=t.position,t.position++}else i(n)?(y(t,r,o,!0),w(t,A(t,!1,e)),r=o=t.position):t.position===t.lineStart&&b(t)?d(t,"unexpected end of the document within a single quoted scalar"):(t.position++,o=t.position);d(t,"unexpected end of the stream within a single quoted scalar")}function j(t,e){var n,r,o,a,u,l;if(l=t.input.charCodeAt(t.position),34!==l)return!1;for(t.kind="scalar",t.result="",t.position++,n=r=t.position;0!==(l=t.input.charCodeAt(t.position));){if(34===l)return y(t,n,t.position,!0),t.position++,!0;if(92===l){if(y(t,n,t.position,!0),l=t.input.charCodeAt(++t.position),i(l))A(t,!1,e);else if(256>l&&rt[l])t.result+=ot[l],t.position++;else if((u=c(l))>0){for(o=u,a=0;o>0;o--)l=t.input.charCodeAt(++t.position),(u=s(l))>=0?a=(a<<4)+u:d(t,"expected hexadecimal character");t.result+=p(a),t.position++}else d(t,"unknown escape sequence");n=r=t.position}else i(l)?(y(t,n,r,!0),w(t,A(t,!1,e)),n=r=t.position):t.position===t.lineStart&&b(t)?d(t,"unexpected end of the document within a double quoted scalar"):(t.position++,r=t.position)}d(t,"unexpected end of the stream within a double quoted scalar")}function O(t,e){var n,i,r,a,s,c,u,l,p,f,h,m=!0,y=t.tag,g=t.anchor;if(h=t.input.charCodeAt(t.position),91===h)a=93,u=!1,i=[];else{if(123!==h)return!1;a=125,u=!0,i={}}for(null!==t.anchor&&(t.anchorMap[t.anchor]=i),h=t.input.charCodeAt(++t.position);0!==h;){if(A(t,!0,e),h=t.input.charCodeAt(t.position),h===a)return t.position++,t.tag=y,t.anchor=g,t.kind=u?"mapping":"sequence",t.result=i,!0;m||d(t,"missed comma between flow collection entries"),p=l=f=null,s=c=!1,63===h&&(r=t.input.charCodeAt(t.position+1),o(r)&&(s=c=!0,t.position++,A(t,!0,e))),n=t.line,T(t,e,W,!1,!0),p=t.tag,l=t.result,A(t,!0,e),h=t.input.charCodeAt(t.position),!c&&t.line!==n||58!==h||(s=!0,h=t.input.charCodeAt(++t.position),A(t,!0,e),T(t,e,W,!1,!0),f=t.result),u?v(t,i,p,l,f):i.push(s?v(t,null,p,l,f):l),A(t,!0,e),h=t.input.charCodeAt(t.position),44===h?(m=!0,h=t.input.charCodeAt(++t.position)):m=!1}d(t,"unexpected end of the stream within a flow collection")}function S(t,e){var n,o,a,s,c=z,l=!1,p=e,f=0,h=!1;if(s=t.input.charCodeAt(t.position),124===s)o=!1;else{if(62!==s)return!1;o=!0}for(t.kind="scalar",t.result="";0!==s;)if(s=t.input.charCodeAt(++t.position),43===s||45===s)z===c?c=43===s?Q:J:d(t,"repeat of a chomping mode identifier");else{if(!((a=u(s))>=0))break;0===a?d(t,"bad explicit indentation width of a block scalar; it cannot be less than one"):l?d(t,"repeat of an indentation width identifier"):(p=e+a-1,l=!0)}if(r(s)){do s=t.input.charCodeAt(++t.position);while(r(s));if(35===s)do s=t.input.charCodeAt(++t.position);while(!i(s)&&0!==s)}for(;0!==s;){for(x(t),t.lineIndent=0,s=t.input.charCodeAt(t.position);(!l||t.lineIndent<p)&&32===s;)t.lineIndent++,s=t.input.charCodeAt(++t.position);if(!l&&t.lineIndent>p&&(p=t.lineIndent),i(s))f++;else{if(t.lineIndent<p){c===Q?t.result+=P.repeat("\n",f):c===z&&l&&(t.result+="\n");break}for(o?r(s)?(h=!0,t.result+=P.repeat("\n",f+1)):h?(h=!1,t.result+=P.repeat("\n",f+1)):0===f?l&&(t.result+=" "):t.result+=P.repeat("\n",f):l?t.result+=P.repeat("\n",f+1):t.result+=P.repeat("\n",f),l=!0,f=0,n=t.position;!i(s)&&0!==s;)s=t.input.charCodeAt(++t.position);y(t,n,t.position,!1)}}return!0}function _(t,e){var n,i,r,a=t.tag,s=t.anchor,c=[],u=!1;for(null!==t.anchor&&(t.anchorMap[t.anchor]=c),r=t.input.charCodeAt(t.position);0!==r&&45===r&&(i=t.input.charCodeAt(t.position+1),o(i));)if(u=!0,t.position++,A(t,!0,-1)&&t.lineIndent<=e)c.push(null),r=t.input.charCodeAt(t.position);else if(n=t.line,T(t,e,V,!1,!0),c.push(t.result),A(t,!0,-1),r=t.input.charCodeAt(t.position),(t.line===n||t.lineIndent>e)&&0!==r)d(t,"bad indentation of a sequence entry");else if(t.lineIndent<e)break;return!!u&&(t.tag=a,t.anchor=s,t.kind="sequence",t.result=c,!0)}function I(t,e,n){var i,a,s,c,u=t.tag,l=t.anchor,p={},f=null,h=null,m=null,y=!1,g=!1;for(null!==t.anchor&&(t.anchorMap[t.anchor]=p),c=t.input.charCodeAt(t.position);0!==c;){if(i=t.input.charCodeAt(t.position+1),s=t.line,63!==c&&58!==c||!o(i)){if(!T(t,n,G,!1,!0))break;if(t.line===s){for(c=t.input.charCodeAt(t.position);r(c);)c=t.input.charCodeAt(++t.position);if(58===c)c=t.input.charCodeAt(++t.position),o(c)||d(t,"a whitespace character is expected after the key-value separator within a block mapping"),y&&(v(t,p,f,h,null),f=h=m=null),g=!0,y=!1,a=!1,f=t.tag,h=t.result;else{if(!g)return t.tag=u,t.anchor=l,!0;d(t,"can not read an implicit mapping pair; a colon is missed")}}else{if(!g)return t.tag=u,t.anchor=l,!0;d(t,"can not read a block mapping entry; a multiline key may not be an implicit key")}}else 63===c?(y&&(v(t,p,f,h,null),f=h=m=null),g=!0,y=!0,a=!0):y?(y=!1,a=!0):d(t,"incomplete explicit mapping pair; a key node is missed"),t.position+=1,c=i;if((t.line===s||t.lineIndent>e)&&(T(t,e,Z,!0,a)&&(y?h=t.result:m=t.result),y||(v(t,p,f,h,m),f=h=m=null),A(t,!0,-1),c=t.input.charCodeAt(t.position)),t.lineIndent>e&&0!==c)d(t,"bad indentation of a mapping entry");else if(t.lineIndent<e)break}return y&&v(t,p,f,h,null),g&&(t.tag=u,t.anchor=l,t.kind="mapping",t.result=p),g}function E(t){var e,n,i,r,a=!1,s=!1;if(r=t.input.charCodeAt(t.position),33!==r)return!1;if(null!==t.tag&&d(t,"duplication of a tag property"),r=t.input.charCodeAt(++t.position),60===r?(a=!0,r=t.input.charCodeAt(++t.position)):33===r?(s=!0,n="!!",r=t.input.charCodeAt(++t.position)):n="!",e=t.position,a){do r=t.input.charCodeAt(++t.position);while(0!==r&&62!==r);t.position<t.length?(i=t.input.slice(e,t.position),r=t.input.charCodeAt(++t.position)):d(t,"unexpected end of the stream within a verbatim tag")}else{for(;0!==r&&!o(r);)33===r&&(s?d(t,"tag suffix cannot contain exclamation marks"):(n=t.input.slice(e-1,t.position+1),nt.test(n)||d(t,"named tag handle cannot contain such characters"),s=!0,e=t.position+1)),r=t.input.charCodeAt(++t.position);i=t.input.slice(e,t.position),et.test(i)&&d(t,"tag suffix cannot contain flow indicator characters")}return i&&!it.test(i)&&d(t,"tag name cannot contain such characters: "+i),a?t.tag=i:R.call(t.tagMap,n)?t.tag=t.tagMap[n]+i:"!"===n?t.tag="!"+i:"!!"===n?t.tag="tag:yaml.org,2002:"+i:d(t,'undeclared tag handle "'+n+'"'),!0}function F(t){var e,n;if(n=t.input.charCodeAt(t.position),38!==n)return!1;for(null!==t.anchor&&d(t,"duplication of an anchor property"),n=t.input.charCodeAt(++t.position),e=t.position;0!==n&&!o(n)&&!a(n);)n=t.input.charCodeAt(++t.position);return t.position===e&&d(t,"name of an anchor node must contain at least one character"),t.anchor=t.input.slice(e,t.position),!0}function N(t){var e,n,i;if(i=t.input.charCodeAt(t.position),42!==i)return!1;for(i=t.input.charCodeAt(++t.position),e=t.position;0!==i&&!o(i)&&!a(i);)i=t.input.charCodeAt(++t.position);return t.position===e&&d(t,"name of an alias node must contain at least one character"),n=t.input.slice(e,t.position),t.anchorMap.hasOwnProperty(n)||d(t,'unidentified alias "'+n+'"'),t.result=t.anchorMap[n],A(t,!0,-1),!0}function T(t,e,n,i,r){var o,a,s,c,u,l,p,f,h=1,m=!1,y=!1;if(t.tag=null,t.anchor=null,t.kind=null,t.result=null,o=a=s=Z===n||V===n,i&&A(t,!0,-1)&&(m=!0,t.lineIndent>e?h=1:t.lineIndent===e?h=0:t.lineIndent<e&&(h=-1)),1===h)for(;E(t)||F(t);)A(t,!0,-1)?(m=!0,s=o,t.lineIndent>e?h=1:t.lineIndent===e?h=0:t.lineIndent<e&&(h=-1)):s=!1;if(s&&(s=m||r),(1===h||Z===n)&&(p=W===n||G===n?e:e+1,f=t.position-t.lineStart,1===h?s&&(_(t,f)||I(t,f,p))||O(t,p)?y=!0:(a&&S(t,p)||C(t,p)||j(t,p)?y=!0:N(t)?(y=!0,(null!==t.tag||null!==t.anchor)&&d(t,"alias node should not have any properties")):k(t,p,W===n)&&(y=!0,null===t.tag&&(t.tag="?")),null!==t.anchor&&(t.anchorMap[t.anchor]=t.result)):0===h&&(y=s&&_(t,f))),null!==t.tag&&"!"!==t.tag)if("?"===t.tag){for(c=0,u=t.implicitTypes.length;u>c;c+=1)if(l=t.implicitTypes[c],l.resolve(t.result)){t.result=l.construct(t.result),t.tag=l.tag,null!==t.anchor&&(t.anchorMap[t.anchor]=t.result);break}}else R.call(t.typeMap,t.tag)?(l=t.typeMap[t.tag],null!==t.result&&l.kind!==t.kind&&d(t,"unacceptable node kind for !<"+t.tag+'> tag; it should be "'+l.kind+'", not "'+t.kind+'"'),l.resolve(t.result)?(t.result=l.construct(t.result),null!==t.anchor&&(t.anchorMap[t.anchor]=t.result)):d(t,"cannot resolve a node with !<"+t.tag+"> explicit tag")):d(t,"unknown tag !<"+t.tag+">");return null!==t.tag||null!==t.anchor||y}function M(t){var e,n,a,s,c=t.position,u=!1;for(t.version=null,t.checkLineBreaks=t.legacy,t.tagMap={},t.anchorMap={};0!==(s=t.input.charCodeAt(t.position))&&(A(t,!0,-1),s=t.input.charCodeAt(t.position),!(t.lineIndent>0||37!==s));){for(u=!0,s=t.input.charCodeAt(++t.position),e=t.position;0!==s&&!o(s);)s=t.input.charCodeAt(++t.position);for(n=t.input.slice(e,t.position),a=[],n.length<1&&d(t,"directive name must not be less than one character in length");0!==s;){for(;r(s);)s=t.input.charCodeAt(++t.position);if(35===s){do s=t.input.charCodeAt(++t.position);while(0!==s&&!i(s));break}if(i(s))break;for(e=t.position;0!==s&&!o(s);)s=t.input.charCodeAt(++t.position);a.push(t.input.slice(e,t.position))}0!==s&&x(t),R.call(st,n)?st[n](t,n,a):m(t,'unknown document directive "'+n+'"')}return A(t,!0,-1),0===t.lineIndent&&45===t.input.charCodeAt(t.position)&&45===t.input.charCodeAt(t.position+1)&&45===t.input.charCodeAt(t.position+2)?(t.position+=3,A(t,!0,-1)):u&&d(t,"directives end mark is expected"),T(t,t.lineIndent-1,Z,!1,!0),A(t,!0,-1),t.checkLineBreaks&&tt.test(t.input.slice(c,t.position))&&m(t,"non-ASCII line breaks are interpreted as content"),t.documents.push(t.result),t.position===t.lineStart&&b(t)?void(46===t.input.charCodeAt(t.position)&&(t.position+=3,A(t,!0,-1))):void(t.position<t.length-1&&d(t,"end of the stream or a document separator is expected"))}function L(t,e){t=String(t),e=e||{},0!==t.length&&(10!==t.charCodeAt(t.length-1)&&13!==t.charCodeAt(t.length-1)&&(t+="\n"),65279===t.charCodeAt(0)&&(t=t.slice(1)));var n=new f(t,e);for(n.input+="\0";32===n.input.charCodeAt(n.position);)n.lineIndent+=1,n.position+=1;for(;n.position<n.length-1;)M(n);return n.documents}function D(t,e,n){var i,r,o=L(t,n);for(i=0,r=o.length;r>i;i+=1)e(o[i])}function U(t,e){var n=L(t,e);if(0!==n.length){if(1===n.length)return n[0];throw new B("expected a single document in the stream, but found more")}}function q(t,e,n){D(t,e,P.extend({schema:K},n))}function Y(t,e){return U(t,P.extend({schema:K},e))}for(var P=t("./common"),B=t("./exception"),$=t("./mark"),K=t("./schema/default_safe"),H=t("./schema/default_full"),R=Object.prototype.hasOwnProperty,W=1,G=2,V=3,Z=4,z=1,J=2,Q=3,X=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,tt=/[\x85\u2028\u2029]/,et=/[,\[\]\{\}]/,nt=/^(?:!|!!|![a-z\-]+!)$/i,it=/^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i,rt=new Array(256),ot=new Array(256),at=0;256>at;at++)rt[at]=l(at)?1:0,ot[at]=l(at);var st={YAML:function(t,e,n){var i,r,o;null!==t.version&&d(t,"duplication of %YAML directive"),1!==n.length&&d(t,"YAML directive accepts exactly one argument"),i=/^([0-9]+)\.([0-9]+)$/.exec(n[0]),null===i&&d(t,"ill-formed argument of the YAML directive"),r=parseInt(i[1],10),o=parseInt(i[2],10),1!==r&&d(t,"unacceptable YAML version of the document"),t.version=n[0],t.checkLineBreaks=2>o,1!==o&&2!==o&&m(t,"unsupported YAML version of the document")},TAG:function(t,e,n){var i,r;2!==n.length&&d(t,"TAG directive accepts exactly two arguments"),i=n[0],r=n[1],nt.test(i)||d(t,"ill-formed tag handle (first argument) of the TAG directive"),R.call(t.tagMap,i)&&d(t,'there is a previously declared suffix for "'+i+'" tag handle'),it.test(r)||d(t,"ill-formed tag prefix (second argument) of the TAG directive"),t.tagMap[i]=r}};e.exports.loadAll=D,e.exports.load=U,e.exports.safeLoadAll=q,e.exports.safeLoad=Y},{"./common":2,"./exception":4,"./mark":6,"./schema/default_full":9,"./schema/default_safe":10}],6:[function(t,e,n){"use strict";function i(t,e,n,i,r){this.name=t,this.buffer=e,this.position=n,this.line=i,this.column=r}var r=t("./common");i.prototype.getSnippet=function(t,e){var n,i,o,a,s;if(!this.buffer)return null;for(t=t||4,e=e||75,n="",i=this.position;i>0&&-1==="\0\r\n\85\u2028\u2029".indexOf(this.buffer.charAt(i-1));)if(i-=1,this.position-i>e/2-1){n=" ... ",i+=5;break}for(o="",a=this.position;a<this.buffer.length&&-1==="\0\r\n\85\u2028\u2029".indexOf(this.buffer.charAt(a));)if(a+=1,a-this.position>e/2-1){o=" ... ",a-=5;break}return s=this.buffer.slice(i,a),r.repeat(" ",t)+n+s+o+"\n"+r.repeat(" ",t+this.position-i+n.length)+"^"},i.prototype.toString=function(t){var e,n="";return this.name&&(n+='in "'+this.name+'" '),n+="at line "+(this.line+1)+", column "+(this.column+1),t||(e=this.getSnippet(),e&&(n+=":\n"+e)),n},e.exports=i},{"./common":2}],7:[function(t,e,n){"use strict";function i(t,e,n){var r=[];return t.include.forEach(function(t){n=i(t,e,n)}),t[e].forEach(function(t){n.forEach(function(e,n){e.tag===t.tag&&r.push(n)}),n.push(t)}),n.filter(function(t,e){return-1===r.indexOf(e)})}function r(){function t(t){i[t.tag]=t}var e,n,i={};for(e=0,n=arguments.length;n>e;e+=1)arguments[e].forEach(t);return i}function o(t){this.include=t.include||[],this.implicit=t.implicit||[],this.explicit=t.explicit||[],this.implicit.forEach(function(t){if(t.loadKind&&"scalar"!==t.loadKind)throw new s("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.")}),this.compiledImplicit=i(this,"implicit",[]),this.compiledExplicit=i(this,"explicit",[]),this.compiledTypeMap=r(this.compiledImplicit,this.compiledExplicit)}var a=t("./common"),s=t("./exception"),c=t("./type");o.DEFAULT=null,o.create=function(){var t,e;switch(arguments.length){case 1:t=o.DEFAULT,e=arguments[0];break;case 2:t=arguments[0],e=arguments[1];break;default:throw new s("Wrong number of arguments for Schema.create function")}if(t=a.toArray(t),e=a.toArray(e),!t.every(function(t){return t instanceof o}))throw new s("Specified list of super schemas (or a single Schema object) contains a non-Schema object.");if(!e.every(function(t){return t instanceof c}))throw new s("Specified list of YAML types (or a single Type object) contains a non-Type object.");return new o({include:t,explicit:e})},e.exports=o},{"./common":2,"./exception":4,"./type":13}],8:[function(t,e,n){"use strict";var i=t("../schema");e.exports=new i({include:[t("./json")]})},{"../schema":7,"./json":12}],9:[function(t,e,n){"use strict";var i=t("../schema");e.exports=i.DEFAULT=new i({include:[t("./default_safe")],explicit:[t("../type/js/undefined"),t("../type/js/regexp"),t("../type/js/function")]})},{"../schema":7,"../type/js/function":18,"../type/js/regexp":19,"../type/js/undefined":20,"./default_safe":10}],10:[function(t,e,n){"use strict";var i=t("../schema");e.exports=new i({include:[t("./core")],implicit:[t("../type/timestamp"),t("../type/merge")],explicit:[t("../type/binary"),t("../type/omap"),t("../type/pairs"),t("../type/set")]})},{"../schema":7,"../type/binary":14,"../type/merge":22,"../type/omap":24,"../type/pairs":25,"../type/set":27,"../type/timestamp":29,"./core":8}],11:[function(t,e,n){"use strict";var i=t("../schema");e.exports=new i({explicit:[t("../type/str"),t("../type/seq"),t("../type/map")]})},{"../schema":7,"../type/map":21,"../type/seq":26,"../type/str":28}],12:[function(t,e,n){"use strict";var i=t("../schema");e.exports=new i({include:[t("./failsafe")],implicit:[t("../type/null"),t("../type/bool"),t("../type/int"),t("../type/float")]})},{"../schema":7,"../type/bool":15,"../type/float":16,"../type/int":17,"../type/null":23,"./failsafe":11}],13:[function(t,e,n){"use strict";function i(t){var e={};return null!==t&&Object.keys(t).forEach(function(n){t[n].forEach(function(t){e[String(t)]=n})}),e}function r(t,e){if(e=e||{},Object.keys(e).forEach(function(e){if(-1===a.indexOf(e))throw new o('Unknown option "'+e+'" is met in definition of "'+t+'" YAML type.')}),this.tag=t,this.kind=e.kind||null,this.resolve=e.resolve||function(){return!0},this.construct=e.construct||function(t){return t},this.instanceOf=e.instanceOf||null,this.predicate=e.predicate||null,this.represent=e.represent||null,this.defaultStyle=e.defaultStyle||null,this.styleAliases=i(e.styleAliases||null),-1===s.indexOf(this.kind))throw new o('Unknown kind "'+this.kind+'" is specified for "'+t+'" YAML type.')}var o=t("./exception"),a=["kind","resolve","construct","instanceOf","predicate","represent","defaultStyle","styleAliases"],s=["scalar","sequence","mapping"];e.exports=r},{"./exception":4}],14:[function(t,e,n){"use strict";function i(t){if(null===t)return!1;var e,n,i=0,r=t.length,o=u;for(n=0;r>n;n++)if(e=o.indexOf(t.charAt(n)),!(e>64)){if(0>e)return!1;i+=6}return i%8===0}function r(t){var e,n,i=t.replace(/[\r\n=]/g,""),r=i.length,o=u,a=0,c=[];for(e=0;r>e;e++)e%4===0&&e&&(c.push(a>>16&255),c.push(a>>8&255),c.push(255&a)),a=a<<6|o.indexOf(i.charAt(e));return n=r%4*6,0===n?(c.push(a>>16&255),c.push(a>>8&255),c.push(255&a)):18===n?(c.push(a>>10&255),c.push(a>>2&255)):12===n&&c.push(a>>4&255),s?new s(c):c}function o(t){var e,n,i="",r=0,o=t.length,a=u;for(e=0;o>e;e++)e%3===0&&e&&(i+=a[r>>18&63],i+=a[r>>12&63],i+=a[r>>6&63],i+=a[63&r]),r=(r<<8)+t[e];return n=o%3,0===n?(i+=a[r>>18&63],i+=a[r>>12&63],i+=a[r>>6&63],i+=a[63&r]):2===n?(i+=a[r>>10&63],i+=a[r>>4&63],i+=a[r<<2&63],i+=a[64]):1===n&&(i+=a[r>>2&63],i+=a[r<<4&63],i+=a[64],i+=a[64]),i}function a(t){return s&&s.isBuffer(t)}var s=t("buffer").Buffer,c=t("../type"),u="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r";e.exports=new c("tag:yaml.org,2002:binary",{kind:"scalar",resolve:i,construct:r,
+predicate:a,represent:o})},{"../type":13,buffer:30}],15:[function(t,e,n){"use strict";function i(t){if(null===t)return!1;var e=t.length;return 4===e&&("true"===t||"True"===t||"TRUE"===t)||5===e&&("false"===t||"False"===t||"FALSE"===t)}function r(t){return"true"===t||"True"===t||"TRUE"===t}function o(t){return"[object Boolean]"===Object.prototype.toString.call(t)}var a=t("../type");e.exports=new a("tag:yaml.org,2002:bool",{kind:"scalar",resolve:i,construct:r,predicate:o,represent:{lowercase:function(t){return t?"true":"false"},uppercase:function(t){return t?"TRUE":"FALSE"},camelcase:function(t){return t?"True":"False"}},defaultStyle:"lowercase"})},{"../type":13}],16:[function(t,e,n){"use strict";function i(t){return null!==t&&!!u.test(t)}function r(t){var e,n,i,r;return e=t.replace(/_/g,"").toLowerCase(),n="-"===e[0]?-1:1,r=[],0<="+-".indexOf(e[0])&&(e=e.slice(1)),".inf"===e?1===n?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:".nan"===e?NaN:0<=e.indexOf(":")?(e.split(":").forEach(function(t){r.unshift(parseFloat(t,10))}),e=0,i=1,r.forEach(function(t){e+=t*i,i*=60}),n*e):n*parseFloat(e,10)}function o(t,e){var n;if(isNaN(t))switch(e){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===t)switch(e){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===t)switch(e){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(s.isNegativeZero(t))return"-0.0";return n=t.toString(10),l.test(n)?n.replace("e",".e"):n}function a(t){return"[object Number]"===Object.prototype.toString.call(t)&&(0!==t%1||s.isNegativeZero(t))}var s=t("../common"),c=t("../type"),u=new RegExp("^(?:[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+][0-9]+)?|\\.[0-9_]+(?:[eE][-+][0-9]+)?|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$"),l=/^[-+]?[0-9]+e/;e.exports=new c("tag:yaml.org,2002:float",{kind:"scalar",resolve:i,construct:r,predicate:a,represent:o,defaultStyle:"lowercase"})},{"../common":2,"../type":13}],17:[function(t,e,n){"use strict";function i(t){return t>=48&&57>=t||t>=65&&70>=t||t>=97&&102>=t}function r(t){return t>=48&&55>=t}function o(t){return t>=48&&57>=t}function a(t){if(null===t)return!1;var e,n=t.length,a=0,s=!1;if(!n)return!1;if(e=t[a],("-"===e||"+"===e)&&(e=t[++a]),"0"===e){if(a+1===n)return!0;if(e=t[++a],"b"===e){for(a++;n>a;a++)if(e=t[a],"_"!==e){if("0"!==e&&"1"!==e)return!1;s=!0}return s}if("x"===e){for(a++;n>a;a++)if(e=t[a],"_"!==e){if(!i(t.charCodeAt(a)))return!1;s=!0}return s}for(;n>a;a++)if(e=t[a],"_"!==e){if(!r(t.charCodeAt(a)))return!1;s=!0}return s}for(;n>a;a++)if(e=t[a],"_"!==e){if(":"===e)break;if(!o(t.charCodeAt(a)))return!1;s=!0}return!!s&&(":"!==e||/^(:[0-5]?[0-9])+$/.test(t.slice(a)))}function s(t){var e,n,i=t,r=1,o=[];return-1!==i.indexOf("_")&&(i=i.replace(/_/g,"")),e=i[0],("-"===e||"+"===e)&&("-"===e&&(r=-1),i=i.slice(1),e=i[0]),"0"===i?0:"0"===e?"b"===i[1]?r*parseInt(i.slice(2),2):"x"===i[1]?r*parseInt(i,16):r*parseInt(i,8):-1!==i.indexOf(":")?(i.split(":").forEach(function(t){o.unshift(parseInt(t,10))}),i=0,n=1,o.forEach(function(t){i+=t*n,n*=60}),r*i):r*parseInt(i,10)}function c(t){return"[object Number]"===Object.prototype.toString.call(t)&&0===t%1&&!u.isNegativeZero(t)}var u=t("../common"),l=t("../type");e.exports=new l("tag:yaml.org,2002:int",{kind:"scalar",resolve:a,construct:s,predicate:c,represent:{binary:function(t){return"0b"+t.toString(2)},octal:function(t){return"0"+t.toString(8)},decimal:function(t){return t.toString(10)},hexadecimal:function(t){return"0x"+t.toString(16).toUpperCase()}},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}})},{"../common":2,"../type":13}],18:[function(t,e,n){"use strict";function i(t){if(null===t)return!1;try{var e="("+t+")",n=s.parse(e,{range:!0});return"Program"===n.type&&1===n.body.length&&"ExpressionStatement"===n.body[0].type&&"FunctionExpression"===n.body[0].expression.type}catch(i){return!1}}function r(t){var e,n="("+t+")",i=s.parse(n,{range:!0}),r=[];if("Program"!==i.type||1!==i.body.length||"ExpressionStatement"!==i.body[0].type||"FunctionExpression"!==i.body[0].expression.type)throw new Error("Failed to resolve function");return i.body[0].expression.params.forEach(function(t){r.push(t.name)}),e=i.body[0].expression.body.range,new Function(r,n.slice(e[0]+1,e[1]-1))}function o(t){return t.toString()}function a(t){return"[object Function]"===Object.prototype.toString.call(t)}var s;try{s=t("esprima")}catch(c){"undefined"!=typeof window&&(s=window.esprima)}var u=t("../../type");e.exports=new u("tag:yaml.org,2002:js/function",{kind:"scalar",resolve:i,construct:r,predicate:a,represent:o})},{"../../type":13,esprima:"esprima"}],19:[function(t,e,n){"use strict";function i(t){if(null===t)return!1;if(0===t.length)return!1;var e=t,n=/\/([gim]*)$/.exec(t),i="";if("/"===e[0]){if(n&&(i=n[1]),i.length>3)return!1;if("/"!==e[e.length-i.length-1])return!1;e=e.slice(1,e.length-i.length-1)}try{return!0}catch(r){return!1}}function r(t){var e=t,n=/\/([gim]*)$/.exec(t),i="";return"/"===e[0]&&(n&&(i=n[1]),e=e.slice(1,e.length-i.length-1)),new RegExp(e,i)}function o(t){var e="/"+t.source+"/";return t.global&&(e+="g"),t.multiline&&(e+="m"),t.ignoreCase&&(e+="i"),e}function a(t){return"[object RegExp]"===Object.prototype.toString.call(t)}var s=t("../../type");e.exports=new s("tag:yaml.org,2002:js/regexp",{kind:"scalar",resolve:i,construct:r,predicate:a,represent:o})},{"../../type":13}],20:[function(t,e,n){"use strict";function i(){return!0}function r(){}function o(){return""}function a(t){return"undefined"==typeof t}var s=t("../../type");e.exports=new s("tag:yaml.org,2002:js/undefined",{kind:"scalar",resolve:i,construct:r,predicate:a,represent:o})},{"../../type":13}],21:[function(t,e,n){"use strict";var i=t("../type");e.exports=new i("tag:yaml.org,2002:map",{kind:"mapping",construct:function(t){return null!==t?t:{}}})},{"../type":13}],22:[function(t,e,n){"use strict";function i(t){return"<<"===t||null===t}var r=t("../type");e.exports=new r("tag:yaml.org,2002:merge",{kind:"scalar",resolve:i})},{"../type":13}],23:[function(t,e,n){"use strict";function i(t){if(null===t)return!0;var e=t.length;return 1===e&&"~"===t||4===e&&("null"===t||"Null"===t||"NULL"===t)}function r(){return null}function o(t){return null===t}var a=t("../type");e.exports=new a("tag:yaml.org,2002:null",{kind:"scalar",resolve:i,construct:r,predicate:o,represent:{canonical:function(){return"~"},lowercase:function(){return"null"},uppercase:function(){return"NULL"},camelcase:function(){return"Null"}},defaultStyle:"lowercase"})},{"../type":13}],24:[function(t,e,n){"use strict";function i(t){if(null===t)return!0;var e,n,i,r,o,c=[],u=t;for(e=0,n=u.length;n>e;e+=1){if(i=u[e],o=!1,"[object Object]"!==s.call(i))return!1;for(r in i)if(a.call(i,r)){if(o)return!1;o=!0}if(!o)return!1;if(-1!==c.indexOf(r))return!1;c.push(r)}return!0}function r(t){return null!==t?t:[]}var o=t("../type"),a=Object.prototype.hasOwnProperty,s=Object.prototype.toString;e.exports=new o("tag:yaml.org,2002:omap",{kind:"sequence",resolve:i,construct:r})},{"../type":13}],25:[function(t,e,n){"use strict";function i(t){if(null===t)return!0;var e,n,i,r,o,s=t;for(o=new Array(s.length),e=0,n=s.length;n>e;e+=1){if(i=s[e],"[object Object]"!==a.call(i))return!1;if(r=Object.keys(i),1!==r.length)return!1;o[e]=[r[0],i[r[0]]]}return!0}function r(t){if(null===t)return[];var e,n,i,r,o,a=t;for(o=new Array(a.length),e=0,n=a.length;n>e;e+=1)i=a[e],r=Object.keys(i),o[e]=[r[0],i[r[0]]];return o}var o=t("../type"),a=Object.prototype.toString;e.exports=new o("tag:yaml.org,2002:pairs",{kind:"sequence",resolve:i,construct:r})},{"../type":13}],26:[function(t,e,n){"use strict";var i=t("../type");e.exports=new i("tag:yaml.org,2002:seq",{kind:"sequence",construct:function(t){return null!==t?t:[]}})},{"../type":13}],27:[function(t,e,n){"use strict";function i(t){if(null===t)return!0;var e,n=t;for(e in n)if(a.call(n,e)&&null!==n[e])return!1;return!0}function r(t){return null!==t?t:{}}var o=t("../type"),a=Object.prototype.hasOwnProperty;e.exports=new o("tag:yaml.org,2002:set",{kind:"mapping",resolve:i,construct:r})},{"../type":13}],28:[function(t,e,n){"use strict";var i=t("../type");e.exports=new i("tag:yaml.org,2002:str",{kind:"scalar",construct:function(t){return null!==t?t:""}})},{"../type":13}],29:[function(t,e,n){"use strict";function i(t){return null!==t&&null!==s.exec(t)}function r(t){var e,n,i,r,o,a,c,u,l,p,f=0,h=null;if(e=s.exec(t),null===e)throw new Error("Date resolve error");if(n=+e[1],i=+e[2]-1,r=+e[3],!e[4])return new Date(Date.UTC(n,i,r));if(o=+e[4],a=+e[5],c=+e[6],e[7]){for(f=e[7].slice(0,3);f.length<3;)f+="0";f=+f}return e[9]&&(u=+e[10],l=+(e[11]||0),h=6e4*(60*u+l),"-"===e[9]&&(h=-h)),p=new Date(Date.UTC(n,i,r,o,a,c,f)),h&&p.setTime(p.getTime()-h),p}function o(t){return t.toISOString()}var a=t("../type"),s=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?)?$");e.exports=new a("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:i,construct:r,instanceOf:Date,represent:o})},{"../type":13}],30:[function(t,e,n){},{}],31:[function(t,e,n){e.exports=t("./lib/inherit")},{"./lib/inherit":32}],32:[function(e,n,i){!function(e){function r(t){var e=f(t);if(v)for(var n,i=0;n=b[i++];)t.hasOwnProperty(n)&&e.push(n);return e}function o(t,e,n){for(var i,o,a=r(n),s=0,u=a.length;u>s;)"__self"!==(i=a[s++])&&(o=n[i],y(o)&&(!c||o.toString().indexOf(".__base")>-1)?e[i]=function(n,i){var r=t[n]?t[n]:"__constructor"===n?e.__self.__parent:g;return function(){var t=this.__base;this.__base=r;var e=i.apply(this,arguments);return this.__base=t,e}}(i,o):e[i]=o)}function a(t,e){for(var n,i=1;n=t[i++];)e?y(n)?s.self(e,n.prototype,n):s.self(e,n):e=y(n)?s(t[0],n.prototype,n):s(t[0],n);return e||t[0]}function s(){var t=arguments,e=m(t[0]),n=e||y(t[0]),i=n?e?a(t[0]):t[0]:u,r=t[n?1:0]||{},s=t[n?2:1],c=r.__constructor||n&&i.prototype.__constructor?function(){return this.__constructor.apply(this,arguments)}:n?function(){return i.apply(this,arguments)}:function(){};if(!n)return c.prototype=r,c.prototype.__self=c.prototype.constructor=c,h(c,s);h(c,i),c.__parent=i;var l=i.prototype,f=c.prototype=p(l);return f.__self=f.constructor=c,r&&o(l,f,r),s&&o(i,c,s),c}var c=function(){}.toString().indexOf("_")>-1,u=function(){},l=Object.prototype.hasOwnProperty,p=Object.create||function(t){var e=function(){};return e.prototype=t,new e},f=Object.keys||function(t){var e=[];for(var n in t)l.call(t,n)&&e.push(n);return e},h=function(t,e){for(var n in e)l.call(e,n)&&(t[n]=e[n]);return t},d=Object.prototype.toString,m=Array.isArray||function(t){return"[object Array]"===d.call(t)},y=function(t){return"[object Function]"===d.call(t)},g=function(){},v=!0,x={toString:""};for(var A in x)x.hasOwnProperty(A)&&(v=!1);var b=v?["toString","valueOf"]:null;s.self=function(){var t=arguments,e=m(t[0]),n=e?a(t[0],t[0][0]):t[0],i=t[1],r=t[2],s=n.prototype;return i&&o(s,s,i),r&&o(n,n,r),n};var w=!0;"object"==typeof i&&(n.exports=s,w=!1),"object"==typeof modules&&(modules.define("inherit",function(t){t(s)}),w=!1),"function"==typeof t&&(t(function(t,e,n){n.exports=s}),w=!1),w&&(e.inherit=s)}(this)},{}],"/":[function(t,e,n){"use strict";var i=t("./lib/js-yaml.js");e.exports=i},{"./lib/js-yaml.js":1}]},{},[])("/")});
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/jsoneditor.min.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/jsoneditor.min.js
new file mode 100644 (file)
index 0000000..21db1ab
--- /dev/null
@@ -0,0 +1,5 @@
+!function(){var t;!function(){var e=!1,i=/xyz/.test(function(){window.postMessage("xyz")})?/\b_super\b/:/.*/;return t=function(){},t.extend=function(t){function s(){!e&&this.init&&this.init.apply(this,arguments)}var r=this.prototype;e=!0;var n=new this;e=!1;for(var o in t)n[o]="function"==typeof t[o]&&"function"==typeof r[o]&&i.test(t[o])?function(t,e){return function(){var i=this._super;this._super=r[t];var s=e.apply(this,arguments);return this._super=i,s}}(o,t[o]):t[o];return s.prototype=n,s.prototype.constructor=s,s.extend=arguments.callee,s},t}(),function(){function t(t,e){e=e||{bubbles:!1,cancelable:!1,detail:void 0};var i=document.createEvent("CustomEvent");return i.initCustomEvent(t,e.bubbles,e.cancelable,e.detail),i}t.prototype=window.Event.prototype,window.CustomEvent=t}(),function(){for(var t=0,e=["ms","moz","webkit","o"],i=0;i<e.length&&!window.requestAnimationFrame;++i)window.requestAnimationFrame=window[e[i]+"RequestAnimationFrame"],window.cancelAnimationFrame=window[e[i]+"CancelAnimationFrame"]||window[e[i]+"CancelRequestAnimationFrame"];window.requestAnimationFrame||(window.requestAnimationFrame=function(e,i){var s=(new Date).getTime(),r=Math.max(0,16-(s-t)),n=window.setTimeout(function(){e(s+r)},r);return t=s+r,n}),window.cancelAnimationFrame||(window.cancelAnimationFrame=function(t){clearTimeout(t)})}(),function(){Array.isArray||(Array.isArray=function(t){return"[object Array]"===Object.prototype.toString.call(t)})}();var e=function(t){return!("object"!=typeof t||t.nodeType||null!==t&&t===t.window)&&!(t.constructor&&!Object.prototype.hasOwnProperty.call(t.constructor.prototype,"isPrototypeOf"))},i=function(t){var s,r,n;for(r=1;r<arguments.length;r++){s=arguments[r];for(n in s)s.hasOwnProperty(n)&&(s[n]&&e(s[n])?(t.hasOwnProperty(n)||(t[n]={}),i(t[n],s[n])):t[n]=s[n])}return t},s=function(t,e){if(t&&"object"==typeof t){var i;if(Array.isArray(t)||"number"==typeof t.length&&t.length>0&&t.length-1 in t){for(i=0;i<t.length;i++)if(e(i,t[i])===!1)return}else if(Object.keys){var s=Object.keys(t);for(i=0;i<s.length;i++)if(e(s[i],t[s[i]])===!1)return}else for(i in t)if(t.hasOwnProperty(i)&&e(i,t[i])===!1)return}},r=function(t,e){var i=document.createEvent("HTMLEvents");i.initEvent(e,!0,!0),t.dispatchEvent(i)},n=function(t,e){if(!(t instanceof Element))throw new Error("element should be an instance of Element");e=i({},n.defaults.options,e||{}),this.element=t,this.options=e,this.init()};n.prototype={constructor:n,init:function(){var t=this;this.ready=!1;var e=n.defaults.themes[this.options.theme||n.defaults.theme];if(!e)throw"Unknown theme "+(this.options.theme||n.defaults.theme);this.schema=this.options.schema,this.theme=new e,this.template=this.options.template,this.refs=this.options.refs||{},this.uuid=0,this.__data={};var i=n.defaults.iconlibs[this.options.iconlib||n.defaults.iconlib];i&&(this.iconlib=new i),this.root_container=this.theme.getContainer(),this.element.appendChild(this.root_container),this.translate=this.options.translate||n.defaults.translate,this._loadExternalRefs(this.schema,function(){t._getDefinitions(t.schema),t.validator=new n.Validator(t);var e=t.getEditorClass(t.schema);t.root=t.createEditor(e,{jsoneditor:t,schema:t.schema,required:!0,container:t.root_container}),t.root.preBuild(),t.root.build(),t.root.postBuild(),t.options.startval&&t.root.setValue(t.options.startval),t.validation_results=t.validator.validate(t.root.getValue()),t.root.showValidationErrors(t.validation_results),t.ready=!0,window.requestAnimationFrame(function(){t.ready&&(t.validation_results=t.validator.validate(t.root.getValue()),t.root.showValidationErrors(t.validation_results),t.trigger("ready"),t.trigger("change"))})})},getValue:function(){if(!this.ready)throw"JSON Editor not ready yet.  Listen for 'ready' event before getting the value";return this.root.getValue()},setValue:function(t){if(!this.ready)throw"JSON Editor not ready yet.  Listen for 'ready' event before setting the value";return this.root.setValue(t),this},validate:function(t){if(!this.ready)throw"JSON Editor not ready yet.  Listen for 'ready' event before validating";return 1===arguments.length?this.validator.validate(t):this.validation_results},destroy:function(){this.destroyed||this.ready&&(this.schema=null,this.options=null,this.root.destroy(),this.root=null,this.root_container=null,this.validator=null,this.validation_results=null,this.theme=null,this.iconlib=null,this.template=null,this.__data=null,this.ready=!1,this.element.innerHTML="",this.destroyed=!0)},on:function(t,e){return this.callbacks=this.callbacks||{},this.callbacks[t]=this.callbacks[t]||[],this.callbacks[t].push(e),this},off:function(t,e){if(t&&e){this.callbacks=this.callbacks||{},this.callbacks[t]=this.callbacks[t]||[];for(var i=[],s=0;s<this.callbacks[t].length;s++)this.callbacks[t][s]!==e&&i.push(this.callbacks[t][s]);this.callbacks[t]=i}else t?(this.callbacks=this.callbacks||{},this.callbacks[t]=[]):this.callbacks={};return this},trigger:function(t){if(this.callbacks&&this.callbacks[t]&&this.callbacks[t].length)for(var e=0;e<this.callbacks[t].length;e++)this.callbacks[t][e]();return this},setOption:function(t,e){if("show_errors"!==t)throw"Option "+t+" must be set during instantiation and cannot be changed later";return this.options.show_errors=e,this.onChange(),this},getEditorClass:function(t){var e;if(t=this.expandSchema(t),s(n.defaults.resolvers,function(i,s){var r=s(t);return r&&n.defaults.editors[r]?(e=r,!1):void 0}),!e)throw"Unknown editor for schema "+JSON.stringify(t);if(!n.defaults.editors[e])throw"Unknown editor "+e;return n.defaults.editors[e]},createEditor:function(t,e){return e=i({},t.options||{},e),new t(e)},onChange:function(){if(this.ready&&!this.firing_change){this.firing_change=!0;var t=this;return window.requestAnimationFrame(function(){t.firing_change=!1,t.ready&&(t.validation_results=t.validator.validate(t.root.getValue()),"never"!==t.options.show_errors?t.root.showValidationErrors(t.validation_results):t.root.showValidationErrors([]),t.trigger("change"))}),this}},compileTemplate:function(t,e){e=e||n.defaults.template;var i;if("string"==typeof e){if(!n.defaults.templates[e])throw"Unknown template engine "+e;if(i=n.defaults.templates[e](),!i)throw"Template engine "+e+" missing required library."}else i=e;if(!i)throw"No template engine set";if(!i.compile)throw"Invalid template engine set";return i.compile(t)},_data:function(t,e,i){if(3!==arguments.length)return t.hasAttribute("data-jsoneditor-"+e)?this.__data[t.getAttribute("data-jsoneditor-"+e)]:null;var s;t.hasAttribute("data-jsoneditor-"+e)?s=t.getAttribute("data-jsoneditor-"+e):(s=this.uuid++,t.setAttribute("data-jsoneditor-"+e,s)),this.__data[s]=i},registerEditor:function(t){return this.editors=this.editors||{},this.editors[t.path]=t,this},unregisterEditor:function(t){return this.editors=this.editors||{},this.editors[t.path]=null,this},getEditor:function(t){return this.editors?this.editors[t]:void 0},watch:function(t,e){return this.watchlist=this.watchlist||{},this.watchlist[t]=this.watchlist[t]||[],this.watchlist[t].push(e),this},unwatch:function(t,e){if(!this.watchlist||!this.watchlist[t])return this;if(!e)return this.watchlist[t]=null,this;for(var i=[],s=0;s<this.watchlist[t].length;s++)this.watchlist[t][s]!==e&&i.push(this.watchlist[t][s]);return this.watchlist[t]=i.length?i:null,this},notifyWatchers:function(t){if(!this.watchlist||!this.watchlist[t])return this;for(var e=0;e<this.watchlist[t].length;e++)this.watchlist[t][e]()},isEnabled:function(){return!this.root||this.root.isEnabled()},enable:function(){this.root.enable()},disable:function(){this.root.disable()},_getDefinitions:function(t,e){if(e=e||"#/definitions/",t.definitions)for(var i in t.definitions)t.definitions.hasOwnProperty(i)&&(this.refs[e+i]=t.definitions[i],t.definitions[i].definitions&&this._getDefinitions(t.definitions[i],e+i+"/definitions/"))},_getExternalRefs:function(t){var e={},i=function(t){for(var i in t)t.hasOwnProperty(i)&&(e[i]=!0)};t.$ref&&"object"!=typeof t.$ref&&"#"!==t.$ref.substr(0,1)&&!this.refs[t.$ref]&&(e[t.$ref]=!0);for(var s in t)if(t.hasOwnProperty(s))if(t[s]&&"object"==typeof t[s]&&Array.isArray(t[s]))for(var r=0;r<t[s].length;r++)"object"==typeof t[s][r]&&i(this._getExternalRefs(t[s][r]));else t[s]&&"object"==typeof t[s]&&i(this._getExternalRefs(t[s]));return e},_loadExternalRefs:function(t,e){var i=this,r=this._getExternalRefs(t),n=0,o=0,a=!1;s(r,function(t){if(!i.refs[t]){if(!i.options.ajax)throw"Must set ajax option to true to load external ref "+t;i.refs[t]="loading",o++;var s=new XMLHttpRequest;s.open("GET",t,!0),s.onreadystatechange=function(){if(4==s.readyState){if(200!==s.status)throw window.console.log(s),"Failed to fetch ref via ajax- "+t;var r;try{r=JSON.parse(s.responseText)}catch(h){throw window.console.log(h),"Failed to parse external ref "+t}if(!r||"object"!=typeof r)throw"External ref does not contain a valid schema - "+t;i.refs[t]=r,i._loadExternalRefs(r,function(){n++,n>=o&&!a&&(a=!0,e())})}},s.send()}}),o||e()},expandRefs:function(t){for(t=i({},t);t.$ref;){var e=t.$ref;delete t.$ref,this.refs[e]||(e=decodeURIComponent(e)),t=this.extendSchemas(t,this.refs[e])}return t},expandSchema:function(t){var e,r=this,n=i({},t);if("object"==typeof t.type&&(Array.isArray(t.type)?s(t.type,function(e,i){"object"==typeof i&&(t.type[e]=r.expandSchema(i))}):t.type=r.expandSchema(t.type)),"object"==typeof t.disallow&&(Array.isArray(t.disallow)?s(t.disallow,function(e,i){"object"==typeof i&&(t.disallow[e]=r.expandSchema(i))}):t.disallow=r.expandSchema(t.disallow)),t.anyOf&&s(t.anyOf,function(e,i){t.anyOf[e]=r.expandSchema(i)}),t.dependencies&&s(t.dependencies,function(e,i){"object"!=typeof i||Array.isArray(i)||(t.dependencies[e]=r.expandSchema(i))}),t.not&&(t.not=this.expandSchema(t.not)),t.allOf){for(e=0;e<t.allOf.length;e++)n=this.extendSchemas(n,this.expandSchema(t.allOf[e]));delete n.allOf}if(t["extends"]){if(Array.isArray(t["extends"]))for(e=0;e<t["extends"].length;e++)n=this.extendSchemas(n,this.expandSchema(t["extends"][e]));else n=this.extendSchemas(n,this.expandSchema(t["extends"]));delete n["extends"]}if(t.oneOf){var o=i({},n);for(delete o.oneOf,e=0;e<t.oneOf.length;e++)n.oneOf[e]=this.extendSchemas(this.expandSchema(t.oneOf[e]),o)}return this.expandRefs(n)},extendSchemas:function(t,e){t=i({},t),e=i({},e);var r=this,n={};return s(t,function(t,i){"undefined"!=typeof e[t]?"required"===t&&"object"==typeof i&&Array.isArray(i)?n.required=i.concat(e[t]).reduce(function(t,e){return t.indexOf(e)<0&&t.push(e),t},[]):"type"!==t||"string"!=typeof i&&!Array.isArray(i)?"object"==typeof i&&Array.isArray(i)?n[t]=i.filter(function(i){return-1!==e[t].indexOf(i)}):"object"==typeof i&&null!==i?n[t]=r.extendSchemas(i,e[t]):n[t]=i:("string"==typeof i&&(i=[i]),"string"==typeof e.type&&(e.type=[e.type]),n.type=i.filter(function(t){return-1!==e.type.indexOf(t)}),1===n.type.length&&"string"==typeof n.type[0]&&(n.type=n.type[0])):n[t]=i}),s(e,function(e,i){"undefined"==typeof t[e]&&(n[e]=i)}),n}},n.defaults={themes:{},templates:{},iconlibs:{},editors:{},languages:{},resolvers:[],custom_validators:[]},n.Validator=t.extend({init:function(t,e){this.jsoneditor=t,this.schema=e||this.jsoneditor.schema,this.options={},this.translate=this.jsoneditor.translate||n.defaults.translate},validate:function(t){return this._validateSchema(this.schema,t)},_validateSchema:function(t,e,r){var o,a,h,l=this,d=[],u=JSON.stringify(e);if(r=r||"root",t=i({},this.jsoneditor.expandRefs(t)),t.required&&t.required===!0){if("undefined"==typeof e)return d.push({path:r,property:"required",message:this.translate("error_notset")}),d}else if("undefined"==typeof e){if(!this.jsoneditor.options.required_by_default)return d;d.push({path:r,property:"required",message:this.translate("error_notset")})}if(t["enum"]){for(o=!1,a=0;a<t["enum"].length;a++)u===JSON.stringify(t["enum"][a])&&(o=!0);o||d.push({path:r,property:"enum",message:this.translate("error_enum")})}if(t["extends"])for(a=0;a<t["extends"].length;a++)d=d.concat(this._validateSchema(t["extends"][a],e,r));if(t.allOf)for(a=0;a<t.allOf.length;a++)d=d.concat(this._validateSchema(t.allOf[a],e,r));if(t.anyOf){for(o=!1,a=0;a<t.anyOf.length;a++)if(!this._validateSchema(t.anyOf[a],e,r).length){o=!0;break}o||d.push({path:r,property:"anyOf",message:this.translate("error_anyOf")})}if(t.oneOf){o=0;var p=[];for(a=0;a<t.oneOf.length;a++){var c=this._validateSchema(t.oneOf[a],e,r);for(c.length||o++,h=0;h<c.length;h++)c[h].path=r+".oneOf["+a+"]"+c[h].path.substr(r.length);p=p.concat(c)}1!==o&&(d.push({path:r,property:"oneOf",message:this.translate("error_oneOf",[o])}),d=d.concat(p))}if(t.not&&(this._validateSchema(t.not,e,r).length||d.push({path:r,property:"not",message:this.translate("error_not")})),t.type)if(Array.isArray(t.type)){for(o=!1,a=0;a<t.type.length;a++)if(this._checkType(t.type[a],e)){o=!0;break}o||d.push({path:r,property:"type",message:this.translate("error_type_union")})}else this._checkType(t.type,e)||d.push({path:r,property:"type",message:this.translate("error_type",[t.type])});if(t.disallow)if(Array.isArray(t.disallow)){for(o=!0,a=0;a<t.disallow.length;a++)if(this._checkType(t.disallow[a],e)){o=!1;break}o||d.push({path:r,property:"disallow",message:this.translate("error_disallow_union")})}else this._checkType(t.disallow,e)&&d.push({path:r,property:"disallow",message:this.translate("error_disallow",[t.disallow])});if("number"==typeof e)(t.multipleOf||t.divisibleBy)&&(o=e/(t.multipleOf||t.divisibleBy),o!==Math.floor(o)&&d.push({path:r,property:t.multipleOf?"multipleOf":"divisibleBy",message:this.translate("error_multipleOf",[t.multipleOf||t.divisibleBy])})),t.hasOwnProperty("maximum")&&(t.exclusiveMaximum&&e>=t.maximum?d.push({path:r,property:"maximum",message:this.translate("error_maximum_excl",[t.maximum])}):!t.exclusiveMaximum&&e>t.maximum&&d.push({path:r,property:"maximum",message:this.translate("error_maximum_incl",[t.maximum])})),t.hasOwnProperty("minimum")&&(t.exclusiveMinimum&&e<=t.minimum?d.push({path:r,property:"minimum",message:this.translate("error_minimum_excl",[t.minimum])}):!t.exclusiveMinimum&&e<t.minimum&&d.push({path:r,property:"minimum",message:this.translate("error_minimum_incl",[t.minimum])}));else if("string"==typeof e)t.maxLength&&(e+"").length>t.maxLength&&d.push({path:r,property:"maxLength",message:this.translate("error_maxLength",[t.maxLength])}),t.minLength&&(e+"").length<t.minLength&&d.push({path:r,property:"minLength",message:this.translate(1===t.minLength?"error_notempty":"error_minLength",[t.minLength])}),t.pattern&&(new RegExp(t.pattern).test(e)||d.push({path:r,property:"pattern",message:this.translate("error_pattern")}));else if("object"==typeof e&&null!==e&&Array.isArray(e)){if(t.items)if(Array.isArray(t.items))for(a=0;a<e.length;a++)if(t.items[a])d=d.concat(this._validateSchema(t.items[a],e[a],r+"."+a));else{if(t.additionalItems===!0)break;if(!t.additionalItems){if(t.additionalItems===!1){d.push({path:r,property:"additionalItems",message:this.translate("error_additionalItems")});break}break}d=d.concat(this._validateSchema(t.additionalItems,e[a],r+"."+a))}else for(a=0;a<e.length;a++)d=d.concat(this._validateSchema(t.items,e[a],r+"."+a));if(t.maxItems&&e.length>t.maxItems&&d.push({path:r,property:"maxItems",message:this.translate("error_maxItems",[t.maxItems])}),t.minItems&&e.length<t.minItems&&d.push({path:r,property:"minItems",message:this.translate("error_minItems",[t.minItems])}),t.uniqueItems){var m={};for(a=0;a<e.length;a++){if(o=JSON.stringify(e[a]),m[o]){d.push({path:r,property:"uniqueItems",message:this.translate("error_uniqueItems")});break}m[o]=!0}}}else if("object"==typeof e&&null!==e){if(t.maxProperties){o=0;for(a in e)e.hasOwnProperty(a)&&o++;o>t.maxProperties&&d.push({path:r,property:"maxProperties",message:this.translate("error_maxProperties",[t.maxProperties])})}if(t.minProperties){o=0;for(a in e)e.hasOwnProperty(a)&&o++;o<t.minProperties&&d.push({path:r,property:"minProperties",message:this.translate("error_minProperties",[t.minProperties])})}if(t.required&&Array.isArray(t.required))for(a=0;a<t.required.length;a++)"undefined"==typeof e[t.required[a]]&&d.push({path:r,property:"required",message:this.translate("error_required",[t.required[a]])});var f={};if(t.properties)for(a in t.properties)t.properties.hasOwnProperty(a)&&(f[a]=!0,d=d.concat(this._validateSchema(t.properties[a],e[a],r+"."+a)));if(t.patternProperties)for(a in t.patternProperties)if(t.patternProperties.hasOwnProperty(a)){var g=new RegExp(a);for(h in e)e.hasOwnProperty(h)&&g.test(h)&&(f[h]=!0,d=d.concat(this._validateSchema(t.patternProperties[a],e[h],r+"."+h)))}if("undefined"!=typeof t.additionalProperties||!this.jsoneditor.options.no_additional_properties||t.oneOf||t.anyOf||(t.additionalProperties=!1),"undefined"!=typeof t.additionalProperties)for(a in e)if(e.hasOwnProperty(a)&&!f[a]){if(!t.additionalProperties){d.push({path:r,property:"additionalProperties",message:this.translate("error_additional_properties",[a])});break}if(t.additionalProperties===!0)break;d=d.concat(this._validateSchema(t.additionalProperties,e[a],r+"."+a))}if(t.dependencies)for(a in t.dependencies)if(t.dependencies.hasOwnProperty(a)&&"undefined"!=typeof e[a])if(Array.isArray(t.dependencies[a]))for(h=0;h<t.dependencies[a].length;h++)"undefined"==typeof e[t.dependencies[a][h]]&&d.push({path:r,property:"dependencies",message:this.translate("error_dependency",[t.dependencies[a][h]])});else d=d.concat(this._validateSchema(t.dependencies[a],e,r))}return s(n.defaults.custom_validators,function(i,s){d=d.concat(s.call(l,t,e,r))}),d},_checkType:function(t,e){return"string"==typeof t?"string"===t?"string"==typeof e:"number"===t?"number"==typeof e:"integer"===t?"number"==typeof e&&e===Math.floor(e):"boolean"===t?"boolean"==typeof e:"array"===t?Array.isArray(e):"object"===t?null!==e&&!Array.isArray(e)&&"object"==typeof e:"null"!==t||null===e:!this._validateSchema(t,e).length}}),n.AbstractEditor=t.extend({onChildEditorChange:function(t){this.onChange(!0)},notify:function(){this.jsoneditor.notifyWatchers(this.path)},change:function(){this.parent?this.parent.onChildEditorChange(this):this.jsoneditor.onChange()},onChange:function(t){this.notify(),this.watch_listener&&this.watch_listener(),t&&this.change()},register:function(){this.jsoneditor.registerEditor(this),this.onChange()},unregister:function(){this.jsoneditor&&this.jsoneditor.unregisterEditor(this)},getNumColumns:function(){return 12},init:function(t){this.jsoneditor=t.jsoneditor,this.theme=this.jsoneditor.theme,this.template_engine=this.jsoneditor.template,this.iconlib=this.jsoneditor.iconlib,this.original_schema=t.schema,this.schema=this.jsoneditor.expandSchema(this.original_schema),this.options=i({},this.options||{},t.schema.options||{},t),t.path||this.schema.id||(this.schema.id="root"),this.path=t.path||"root",this.formname=t.formname||this.path.replace(/\.([^.]+)/g,"[$1]"),this.jsoneditor.options.form_name_root&&(this.formname=this.formname.replace(/^root\[/,this.jsoneditor.options.form_name_root+"[")),this.key=this.path.split(".").pop(),this.parent=t.parent,this.link_watchers=[],t.container&&this.setContainer(t.container)},setContainer:function(t){this.container=t,this.schema.id&&this.container.setAttribute("data-schemaid",this.schema.id),this.schema.type&&"string"==typeof this.schema.type&&this.container.setAttribute("data-schematype",this.schema.type),this.container.setAttribute("data-schemapath",this.path)},preBuild:function(){},build:function(){},postBuild:function(){this.setupWatchListeners(),this.addLinks(),this.setValue(this.getDefault(),!0),this.updateHeaderText(),this.register(),this.onWatchedFieldChange()},setupWatchListeners:function(){var t=this;if(this.watched={},this.schema.vars&&(this.schema.watch=this.schema.vars),this.watched_values={},this.watch_listener=function(){t.refreshWatchedFieldValues()&&t.onWatchedFieldChange()},this.register(),this.schema.hasOwnProperty("watch")){var e,i,s,r,n;for(var o in this.schema.watch)if(this.schema.watch.hasOwnProperty(o)){if(e=this.schema.watch[o],Array.isArray(e)?i=[e[0]].concat(e[1].split(".")):(i=e.split("."),t.theme.closest(t.container,'[data-schemaid="'+i[0]+'"]')||i.unshift("#")),s=i.shift(),"#"===s&&(s=t.jsoneditor.schema.id||"root"),r=t.theme.closest(t.container,'[data-schemaid="'+s+'"]'),!r)throw"Could not find ancestor node with id "+s;n=r.getAttribute("data-schemapath")+"."+i.join("."),t.jsoneditor.watch(n,t.watch_listener),t.watched[o]=n}}this.schema.headerTemplate&&(this.header_template=this.jsoneditor.compileTemplate(this.schema.headerTemplate,this.template_engine))},addLinks:function(){if(!this.no_link_holder&&(this.link_holder=this.theme.getLinksHolder(),this.container.appendChild(this.link_holder),this.schema.links))for(var t=0;t<this.schema.links.length;t++)this.addLink(this.getLink(this.schema.links[t]))},getButton:function(t,e,i){var s="json-editor-btn-"+e;e=this.iconlib?this.iconlib.getIcon(e):null,!e&&i&&(t=i,i=null);var r=this.theme.getButton(t,e,i);return r.className+=" "+s+" ",r},setButtonText:function(t,e,i,s){return i=this.iconlib?this.iconlib.getIcon(i):null,!i&&s&&(e=s,s=null),this.theme.setButtonText(t,e,i,s)},addLink:function(t){this.link_holder&&this.link_holder.appendChild(t)},getLink:function(t){var e,i,s=t.mediaType||"application/javascript",r=s.split("/")[0],n=this.jsoneditor.compileTemplate(t.href,this.template_engine);if("image"===r){e=this.theme.getBlockLinkHolder(),i=document.createElement("a"),i.setAttribute("target","_blank");var o=document.createElement("img");this.theme.createImageLink(e,i,o),this.link_watchers.push(function(e){var s=n(e);i.setAttribute("href",s),i.setAttribute("title",t.rel||s),o.setAttribute("src",s)})}else if(["audio","video"].indexOf(r)>=0){e=this.theme.getBlockLinkHolder(),i=this.theme.getBlockLink(),i.setAttribute("target","_blank");var a=document.createElement(r);a.setAttribute("controls","controls"),this.theme.createMediaLink(e,i,a),this.link_watchers.push(function(e){var s=n(e);i.setAttribute("href",s),i.textContent=t.rel||s,a.setAttribute("src",s)})}else e=this.theme.getBlockLink(),e.setAttribute("target","_blank"),e.textContent=t.rel,this.link_watchers.push(function(i){var s=n(i);e.setAttribute("href",s),e.textContent=t.rel||s});return e},refreshWatchedFieldValues:function(){if(this.watched_values){var t={},e=!1,i=this;if(this.watched){var s,r;for(var n in this.watched)this.watched.hasOwnProperty(n)&&(r=i.jsoneditor.getEditor(this.watched[n]),s=r?r.getValue():null,i.watched_values[n]!==s&&(e=!0),t[n]=s)}return t.self=this.getValue(),this.watched_values.self!==t.self&&(e=!0),this.watched_values=t,e}},getWatchedFieldValues:function(){return this.watched_values},updateHeaderText:function(){if(this.header)if(this.header.children.length){for(var t=0;t<this.header.childNodes.length;t++)if(3===this.header.childNodes[t].nodeType){this.header.childNodes[t].nodeValue=this.getHeaderText();break}}else this.header.textContent=this.getHeaderText()},getHeaderText:function(t){return this.header_text?this.header_text:t?this.schema.title:this.getTitle()},onWatchedFieldChange:function(){var t;if(this.header_template){t=i(this.getWatchedFieldValues(),{key:this.key,i:this.key,i0:1*this.key,i1:1*this.key+1,title:this.getTitle()});var e=this.header_template(t);e!==this.header_text&&(this.header_text=e,this.updateHeaderText(),this.notify())}if(this.link_watchers.length){t=this.getWatchedFieldValues();for(var s=0;s<this.link_watchers.length;s++)this.link_watchers[s](t)}},setValue:function(t){this.value=t},getValue:function(){return this.value},refreshValue:function(){},getChildEditors:function(){return!1},destroy:function(){var t=this;this.unregister(this),s(this.watched,function(e,i){t.jsoneditor.unwatch(i,t.watch_listener)}),this.watched=null,this.watched_values=null,this.watch_listener=null,this.header_text=null,this.header_template=null,this.value=null,this.container&&this.container.parentNode&&this.container.parentNode.removeChild(this.container),this.container=null,this.jsoneditor=null,this.schema=null,this.path=null,this.key=null,this.parent=null},getDefault:function(){if(this.schema["default"])return this.schema["default"];if(this.schema["enum"])return this.schema["enum"][0];var t=this.schema.type||this.schema.oneOf;if(t&&Array.isArray(t)&&(t=t[0]),t&&"object"==typeof t&&(t=t.type),t&&Array.isArray(t)&&(t=t[0]),"string"==typeof t){if("number"===t)return 0;if("boolean"===t)return!1;if("integer"===t)return 0;if("string"===t)return"";if("object"===t)return{};if("array"===t)return[]}return null},getTitle:function(){return this.schema.title||this.key},enable:function(){this.disabled=!1},disable:function(){this.disabled=!0},isEnabled:function(){return!this.disabled},isRequired:function(){return"boolean"==typeof this.schema.required?this.schema.required:this.parent&&this.parent.schema&&Array.isArray(this.parent.schema.required)?this.parent.schema.required.indexOf(this.key)>-1:!!this.jsoneditor.options.required_by_default},getDisplayText:function(t){var e=[],i={};s(t,function(t,e){e.title&&(i[e.title]=i[e.title]||0,i[e.title]++),e.description&&(i[e.description]=i[e.description]||0,i[e.description]++),e.format&&(i[e.format]=i[e.format]||0,i[e.format]++),e.type&&(i[e.type]=i[e.type]||0,i[e.type]++)}),s(t,function(t,s){var r;r="string"==typeof s?s:s.title&&i[s.title]<=1?s.title:s.format&&i[s.format]<=1?s.format:s.type&&i[s.type]<=1?s.type:s.description&&i[s.description]<=1?s.descripton:s.title?s.title:s.format?s.format:s.type?s.type:s.description?s.description:JSON.stringify(s).length<50?JSON.stringify(s):"type",e.push(r)});var r={};return s(e,function(t,s){r[s]=r[s]||0,r[s]++,i[s]>1&&(e[t]=s+" "+r[s])}),e},getOption:function(t){try{throw"getOption is deprecated"}catch(e){window.console.error(e)}return this.options[t]},showValidationErrors:function(t){}}),n.defaults.editors["null"]=n.AbstractEditor.extend({getValue:function(){return null},setValue:function(){this.onChange()},getNumColumns:function(){return 2}}),n.defaults.editors.string=n.AbstractEditor.extend({register:function(){this._super(),this.input&&this.input.setAttribute("name",this.formname)},unregister:function(){this._super(),this.input&&this.input.removeAttribute("name")},setValue:function(t,e,i){if((!this.template||i)&&(null===t||"undefined"==typeof t?t="":"object"==typeof t?t=JSON.stringify(t):"string"!=typeof t&&(t=""+t),t!==this.serialized)){var s=this.sanitize(t);if(this.input.value!==s){this.input.value=s,this.sceditor_instance?this.sceditor_instance.val(s):this.epiceditor?this.epiceditor.importFile(null,s):this.ace_editor&&this.ace_editor.setValue(s);var r=i||this.getValue()!==t;this.refreshValue(),e?this.is_dirty=!1:"change"===this.jsoneditor.options.show_errors&&(this.is_dirty=!0),this.adjust_height&&this.adjust_height(this.input),this.onChange(r)}}},getNumColumns:function(){var t,e=Math.ceil(Math.max(this.getTitle().length,this.schema.maxLength||0,this.schema.minLength||0)/5);return t="textarea"===this.input_type?6:["text","email"].indexOf(this.input_type)>=0?4:2,Math.min(12,Math.max(e,t))},build:function(){var t=this;if(this.options.compact||(this.header=this.label=this.theme.getFormInputLabel(this.getTitle(),this.isRequired())),this.schema.description&&(this.description=this.theme.getFormInputDescription(this.schema.description)),this.format=this.schema.format,!this.format&&this.schema.media&&this.schema.media.type&&(this.format=this.schema.media.type.replace(/(^(application|text)\/(x-)?(script\.)?)|(-source$)/g,"")),!this.format&&this.options.default_format&&(this.format=this.options.default_format),this.options.format&&(this.format=this.options.format),this.format)if("textarea"===this.format)this.input_type="textarea",this.input=this.theme.getTextareaInput();else if("range"===this.format){this.input_type="range";var e=this.schema.minimum||0,i=this.schema.maximum||Math.max(100,e+1),s=1;this.schema.multipleOf&&(e%this.schema.multipleOf&&(e=Math.ceil(e/this.schema.multipleOf)*this.schema.multipleOf),i%this.schema.multipleOf&&(i=Math.floor(i/this.schema.multipleOf)*this.schema.multipleOf),s=this.schema.multipleOf),this.input=this.theme.getRangeInput(e,i,s)}else["actionscript","batchfile","bbcode","c","c++","cpp","coffee","csharp","css","dart","django","ejs","erlang","golang","handlebars","haskell","haxe","html","ini","jade","java","javascript","json","less","lisp","lua","makefile","markdown","matlab","mysql","objectivec","pascal","perl","pgsql","php","python","r","ruby","sass","scala","scss","smarty","sql","stylus","svg","twig","vbscript","xml","yaml"].indexOf(this.format)>=0?(this.input_type=this.format,this.source_code=!0,this.input=this.theme.getTextareaInput()):(this.input_type=this.format,this.input=this.theme.getFormInputField(this.input_type));else this.input_type="text",this.input=this.theme.getFormInputField(this.input_type);"undefined"!=typeof this.schema.maxLength&&this.input.setAttribute("maxlength",this.schema.maxLength),"undefined"!=typeof this.schema.pattern?this.input.setAttribute("pattern",this.schema.pattern):"undefined"!=typeof this.schema.minLength&&this.input.setAttribute("pattern",".{"+this.schema.minLength+",}"),this.options.compact?this.container.className+=" compact":this.options.input_width&&(this.input.style.width=this.options.input_width),(this.schema.readOnly||this.schema.readonly||this.schema.template)&&(this.always_disabled=!0,this.input.disabled=!0),this.input.addEventListener("change",function(e){if(e.preventDefault(),e.stopPropagation(),t.schema.template)return void(this.value=t.value);var i=this.value,s=t.sanitize(i);i!==s&&(this.value=s),t.is_dirty=!0,t.refreshValue(),t.onChange(!0)}),this.options.input_height&&(this.input.style.height=this.options.input_height),this.options.expand_height&&(this.adjust_height=function(t){if(t){var e,i=t.offsetHeight;if(t.offsetHeight<t.scrollHeight)for(e=0;t.offsetHeight<t.scrollHeight+3&&!(e>100);)e++,i++,t.style.height=i+"px";else{for(e=0;t.offsetHeight>=t.scrollHeight+3&&!(e>100);)e++,i--,t.style.height=i+"px";t.style.height=i+1+"px"}}},this.input.addEventListener("keyup",function(e){t.adjust_height(this)}),this.input.addEventListener("change",function(e){t.adjust_height(this)}),this.adjust_height()),this.format&&this.input.setAttribute("data-schemaformat",this.format),this.control=this.theme.getFormControl(this.label,this.input,this.description),this.container.appendChild(this.control),window.requestAnimationFrame(function(){t.input.parentNode&&t.afterInputReady(),t.adjust_height&&t.adjust_height(t.input)}),this.schema.template?(this.template=this.jsoneditor.compileTemplate(this.schema.template,this.template_engine),this.refreshValue()):this.refreshValue()},enable:function(){this.always_disabled||(this.input.disabled=!1),this._super()},disable:function(){this.input.disabled=!0,this._super()},afterInputReady:function(){var t,e=this;if(this.source_code)if(this.options.wysiwyg&&["html","bbcode"].indexOf(this.input_type)>=0&&window.jQuery&&window.jQuery.fn&&window.jQuery.fn.sceditor)t=i({},{plugins:"html"===e.input_type?"xhtml":"bbcode",emoticonsEnabled:!1,width:"100%",height:300},n.plugins.sceditor,e.options.sceditor_options||{}),window.jQuery(e.input).sceditor(t),e.sceditor_instance=window.jQuery(e.input).sceditor("instance"),e.sceditor_instance.blur(function(){var t=window.jQuery("<div>"+e.sceditor_instance.val()+"</div>");window.jQuery("#sceditor-start-marker,#sceditor-end-marker,.sceditor-nlf",t).remove(),e.input.value=t.html(),e.value=e.input.value,e.is_dirty=!0,e.onChange(!0)});else if("markdown"===this.input_type&&window.EpicEditor)this.epiceditor_container=document.createElement("div"),this.input.parentNode.insertBefore(this.epiceditor_container,this.input),this.input.style.display="none",t=i({},n.plugins.epiceditor,{container:this.epiceditor_container,clientSideStorage:!1}),this.epiceditor=new window.EpicEditor(t).load(),this.epiceditor.importFile(null,this.getValue()),this.epiceditor.on("update",function(){var t=e.epiceditor.exportFile();e.input.value=t,e.value=t,e.is_dirty=!0,e.onChange(!0)});else if(window.ace){
+var s=this.input_type;("cpp"===s||"c++"===s||"c"===s)&&(s="c_cpp"),this.ace_container=document.createElement("div"),this.ace_container.style.width="100%",this.ace_container.style.position="relative",this.ace_container.style.height="400px",this.input.parentNode.insertBefore(this.ace_container,this.input),this.input.style.display="none",this.ace_editor=window.ace.edit(this.ace_container),this.ace_editor.setValue(this.getValue()),n.plugins.ace.theme&&this.ace_editor.setTheme("ace/theme/"+n.plugins.ace.theme),s=window.ace.require("ace/mode/"+s),s&&this.ace_editor.getSession().setMode(new s.Mode),this.ace_editor.on("change",function(){var t=e.ace_editor.getValue();e.input.value=t,e.refreshValue(),e.is_dirty=!0,e.onChange(!0)})}e.theme.afterInputReady(e.input)},refreshValue:function(){this.value=this.input.value,"string"!=typeof this.value&&(this.value=""),this.serialized=this.value},destroy:function(){this.sceditor_instance?this.sceditor_instance.destroy():this.epiceditor?this.epiceditor.unload():this.ace_editor&&this.ace_editor.destroy(),this.template=null,this.input&&this.input.parentNode&&this.input.parentNode.removeChild(this.input),this.label&&this.label.parentNode&&this.label.parentNode.removeChild(this.label),this.description&&this.description.parentNode&&this.description.parentNode.removeChild(this.description),this._super()},sanitize:function(t){return t},onWatchedFieldChange:function(){var t;this.template&&(t=this.getWatchedFieldValues(),this.setValue(this.template(t),!1,!0)),this._super()},showValidationErrors:function(t){var e=this;if("always"===this.jsoneditor.options.show_errors);else if(!this.is_dirty&&this.previous_error_setting===this.jsoneditor.options.show_errors)return;this.previous_error_setting=this.jsoneditor.options.show_errors;var i=[];s(t,function(t,s){s.path===e.path&&i.push(s.message)}),i.length?this.theme.addInputError(this.input,i.join(". ")+"."):this.theme.removeInputError(this.input)}}),n.defaults.editors.number=n.defaults.editors.string.extend({sanitize:function(t){return(t+"").replace(/[^0-9\.\-eE]/g,"")},getNumColumns:function(){return 2},getValue:function(){return 1*this.value}}),n.defaults.editors.integer=n.defaults.editors.number.extend({sanitize:function(t){return t+="",t.replace(/[^0-9\-]/g,"")},getNumColumns:function(){return 2}}),n.defaults.editors.object=n.AbstractEditor.extend({getDefault:function(){return i({},this.schema["default"]||{})},getChildEditors:function(){return this.editors},register:function(){if(this._super(),this.editors)for(var t in this.editors)this.editors.hasOwnProperty(t)&&this.editors[t].register()},unregister:function(){if(this._super(),this.editors)for(var t in this.editors)this.editors.hasOwnProperty(t)&&this.editors[t].unregister()},getNumColumns:function(){return Math.max(Math.min(12,this.maxwidth),3)},enable:function(){if(this.editjson_button&&(this.editjson_button.disabled=!1),this.addproperty_button&&(this.addproperty_button.disabled=!1),this._super(),this.editors)for(var t in this.editors)this.editors.hasOwnProperty(t)&&this.editors[t].enable()},disable:function(){if(this.editjson_button&&(this.editjson_button.disabled=!0),this.addproperty_button&&(this.addproperty_button.disabled=!0),this.hideEditJSON(),this._super(),this.editors)for(var t in this.editors)this.editors.hasOwnProperty(t)&&this.editors[t].disable()},layoutEditors:function(){var t,e,i=this;if(this.row_container){this.property_order=Object.keys(this.editors),this.property_order=this.property_order.sort(function(t,e){var s=i.editors[t].schema.propertyOrder,r=i.editors[e].schema.propertyOrder;return"number"!=typeof s&&(s=1e3),"number"!=typeof r&&(r=1e3),s-r});var r;if("grid"===this.format){var n=[];for(s(this.property_order,function(t,e){var s=i.editors[e];if(!s.property_removed){for(var r=!1,o=s.options.hidden?0:s.options.grid_columns||s.getNumColumns(),a=s.options.hidden?0:s.container.offsetHeight,h=0;h<n.length;h++)n[h].width+o<=12&&(!a||.5*n[h].minh<a&&2*n[h].maxh>a)&&(r=h);r===!1&&(n.push({width:0,minh:999999,maxh:0,editors:[]}),r=n.length-1),n[r].editors.push({key:e,width:o,height:a}),n[r].width+=o,n[r].minh=Math.min(n[r].minh,a),n[r].maxh=Math.max(n[r].maxh,a)}}),t=0;t<n.length;t++)if(n[t].width<12){var o=!1,a=0;for(e=0;e<n[t].editors.length;e++)o===!1?o=e:n[t].editors[e].width>n[t].editors[o].width&&(o=e),n[t].editors[e].width*=12/n[t].width,n[t].editors[e].width=Math.floor(n[t].editors[e].width),a+=n[t].editors[e].width;12>a&&(n[t].editors[o].width+=12-a),n[t].width=12}if(this.layout===JSON.stringify(n))return!1;for(this.layout=JSON.stringify(n),r=document.createElement("div"),t=0;t<n.length;t++){var h=this.theme.getGridRow();for(r.appendChild(h),e=0;e<n[t].editors.length;e++){var l=n[t].editors[e].key,d=this.editors[l];d.options.hidden?d.container.style.display="none":this.theme.setGridColumnSize(d.container,n[t].editors[e].width),h.appendChild(d.container)}}}else r=document.createElement("div"),s(this.property_order,function(t,e){var s=i.editors[e];if(!s.property_removed){var n=i.theme.getGridRow();r.appendChild(n),s.options.hidden?s.container.style.display="none":i.theme.setGridColumnSize(s.container,12),n.appendChild(s.container)}});this.row_container.innerHTML="",this.row_container.appendChild(r)}},getPropertySchema:function(t){var e=this.schema.properties[t]||{};e=i({},e);var s=!!this.schema.properties[t];if(this.schema.patternProperties)for(var r in this.schema.patternProperties)if(this.schema.patternProperties.hasOwnProperty(r)){var n=new RegExp(r);n.test(t)&&(e.allOf=e.allOf||[],e.allOf.push(this.schema.patternProperties[r]),s=!0)}return!s&&this.schema.additionalProperties&&"object"==typeof this.schema.additionalProperties&&(e=i({},this.schema.additionalProperties)),e},preBuild:function(){this._super(),this.editors={},this.cached_editors={};var t=this;if(this.format=this.options.layout||this.options.object_layout||this.schema.format||this.jsoneditor.options.object_layout||"normal",this.schema.properties=this.schema.properties||{},this.minwidth=0,this.maxwidth=0,this.options.table_row)s(this.schema.properties,function(e,i){var s=t.jsoneditor.getEditorClass(i);t.editors[e]=t.jsoneditor.createEditor(s,{jsoneditor:t.jsoneditor,schema:i,path:t.path+"."+e,parent:t,compact:!0,required:!0}),t.editors[e].preBuild();var r=t.editors[e].options.hidden?0:t.editors[e].options.grid_columns||t.editors[e].getNumColumns();t.minwidth+=r,t.maxwidth+=r}),this.no_link_holder=!0;else{if(this.options.table)throw"Not supported yet";this.defaultProperties=this.schema.defaultProperties||Object.keys(this.schema.properties),t.maxwidth+=1,s(this.defaultProperties,function(e,i){t.addObjectProperty(i,!0),t.editors[i]&&(t.minwidth=Math.max(t.minwidth,t.editors[i].options.grid_columns||t.editors[i].getNumColumns()),t.maxwidth+=t.editors[i].options.grid_columns||t.editors[i].getNumColumns())})}this.property_order=Object.keys(this.editors),this.property_order=this.property_order.sort(function(e,i){var s=t.editors[e].schema.propertyOrder,r=t.editors[i].schema.propertyOrder;return"number"!=typeof s&&(s=1e3),"number"!=typeof r&&(r=1e3),s-r})},build:function(){var t=this;if(this.options.table_row)this.editor_holder=this.container,s(this.editors,function(e,i){var s=t.theme.getTableCell();t.editor_holder.appendChild(s),i.setContainer(s),i.build(),i.postBuild(),t.editors[e].options.hidden&&(s.style.display="none"),t.editors[e].options.input_width&&(s.style.width=t.editors[e].options.input_width)});else{if(this.options.table)throw"Not supported yet";this.header=document.createElement("span"),this.header.textContent=this.getTitle(),this.title=this.theme.getHeader(this.header),this.container.appendChild(this.title),this.container.style.position="relative",this.editjson_holder=this.theme.getModal(),this.editjson_textarea=this.theme.getTextareaInput(),this.editjson_textarea.style.height="170px",this.editjson_textarea.style.width="300px",this.editjson_textarea.style.display="block",this.editjson_save=this.getButton("Save","save","Save"),this.editjson_save.addEventListener("click",function(e){e.preventDefault(),e.stopPropagation(),t.saveJSON()}),this.editjson_cancel=this.getButton("Cancel","cancel","Cancel"),this.editjson_cancel.addEventListener("click",function(e){e.preventDefault(),e.stopPropagation(),t.hideEditJSON()}),this.editjson_holder.appendChild(this.editjson_textarea),this.editjson_holder.appendChild(this.editjson_save),this.editjson_holder.appendChild(this.editjson_cancel),this.addproperty_holder=this.theme.getModal(),this.addproperty_list=document.createElement("div"),this.addproperty_list.style.width="295px",this.addproperty_list.style.maxHeight="160px",this.addproperty_list.style.padding="5px 0",this.addproperty_list.style.overflowY="auto",this.addproperty_list.style.overflowX="hidden",this.addproperty_list.style.paddingLeft="5px",this.addproperty_list.setAttribute("class","property-selector"),this.addproperty_add=this.getButton("add","add","add"),this.addproperty_input=this.theme.getFormInputField("text"),this.addproperty_input.setAttribute("placeholder","Property name..."),this.addproperty_input.style.width="220px",this.addproperty_input.style.marginBottom="0",this.addproperty_input.style.display="inline-block",this.addproperty_add.addEventListener("click",function(e){if(e.preventDefault(),e.stopPropagation(),t.addproperty_input.value){if(t.editors[t.addproperty_input.value])return void window.alert("there is already a property with that name");t.addObjectProperty(t.addproperty_input.value),t.editors[t.addproperty_input.value]&&t.editors[t.addproperty_input.value].disable(),t.onChange(!0)}}),this.addproperty_holder.appendChild(this.addproperty_list),this.addproperty_holder.appendChild(this.addproperty_input),this.addproperty_holder.appendChild(this.addproperty_add);var e=document.createElement("div");e.style.clear="both",this.addproperty_holder.appendChild(e),this.schema.description&&(this.description=this.theme.getDescription(this.schema.description),this.container.appendChild(this.description)),this.error_holder=document.createElement("div"),this.container.appendChild(this.error_holder),this.editor_holder=this.theme.getIndentedPanel(),this.editor_holder.style.paddingBottom="0",this.container.appendChild(this.editor_holder),this.row_container=this.theme.getGridContainer(),this.editor_holder.appendChild(this.row_container),s(this.editors,function(e,i){var s=t.theme.getGridColumn();t.row_container.appendChild(s),i.setContainer(s),i.build(),i.postBuild()}),this.title_controls=this.theme.getHeaderButtonHolder(),this.editjson_controls=this.theme.getHeaderButtonHolder(),this.addproperty_controls=this.theme.getHeaderButtonHolder(),this.title.appendChild(this.title_controls),this.title.appendChild(this.editjson_controls),this.title.appendChild(this.addproperty_controls),this.collapsed=!1,this.toggle_button=this.getButton("","collapse","Collapse"),this.title_controls.appendChild(this.toggle_button),this.toggle_button.addEventListener("click",function(e){e.preventDefault(),e.stopPropagation(),t.collapsed?(t.editor_holder.style.display="",t.collapsed=!1,t.setButtonText(t.toggle_button,"","collapse","Collapse")):(t.editor_holder.style.display="none",t.collapsed=!0,t.setButtonText(t.toggle_button,"","expand","Expand"))}),this.options.collapsed&&r(this.toggle_button,"click"),this.schema.options&&"undefined"!=typeof this.schema.options.disable_collapse?this.schema.options.disable_collapse&&(this.toggle_button.style.display="none"):this.jsoneditor.options.disable_collapse&&(this.toggle_button.style.display="none"),this.editjson_button=this.getButton("JSON","edit","Edit JSON"),this.editjson_button.addEventListener("click",function(e){e.preventDefault(),e.stopPropagation(),t.toggleEditJSON()}),this.editjson_controls.appendChild(this.editjson_button),this.editjson_controls.appendChild(this.editjson_holder),this.schema.options&&"undefined"!=typeof this.schema.options.disable_edit_json?this.schema.options.disable_edit_json&&(this.editjson_button.style.display="none"):this.jsoneditor.options.disable_edit_json&&(this.editjson_button.style.display="none"),this.addproperty_button=this.getButton("Properties","edit","Object Properties"),this.addproperty_button.addEventListener("click",function(e){e.preventDefault(),e.stopPropagation(),t.toggleAddProperty()}),this.addproperty_controls.appendChild(this.addproperty_button),this.addproperty_controls.appendChild(this.addproperty_holder),this.refreshAddProperties()}this.options.table_row?(this.editor_holder=this.container,s(this.property_order,function(e,i){t.editor_holder.appendChild(t.editors[i].container)})):(this.layoutEditors(),this.layoutEditors())},showEditJSON:function(){this.editjson_holder&&(this.hideAddProperty(),this.editjson_holder.style.left=this.editjson_button.offsetLeft+"px",this.editjson_holder.style.top=this.editjson_button.offsetTop+this.editjson_button.offsetHeight+"px",this.editjson_textarea.value=JSON.stringify(this.getValue(),null,2),this.disable(),this.editjson_holder.style.display="",this.editjson_button.disabled=!1,this.editing_json=!0)},hideEditJSON:function(){this.editjson_holder&&this.editing_json&&(this.editjson_holder.style.display="none",this.enable(),this.editing_json=!1)},saveJSON:function(){if(this.editjson_holder)try{var t=JSON.parse(this.editjson_textarea.value);this.setValue(t),this.hideEditJSON()}catch(e){throw window.alert("invalid JSON"),e}},toggleEditJSON:function(){this.editing_json?this.hideEditJSON():this.showEditJSON()},insertPropertyControlUsingPropertyOrder:function(t,e,i){var s;this.schema.properties[t]&&(s=this.schema.properties[t].propertyOrder),"number"!=typeof s&&(s=1e3),e.propertyOrder=s;for(var r=0;r<i.childNodes.length;r++){var n=i.childNodes[r];if(e.propertyOrder<n.propertyOrder){this.addproperty_list.insertBefore(e,n),e=null;break}}e&&this.addproperty_list.appendChild(e)},addPropertyCheckbox:function(t){var e,i,s,r,n=this;return e=n.theme.getCheckbox(),e.style.width="auto",s=this.schema.properties[t]&&this.schema.properties[t].title?this.schema.properties[t].title:t,i=n.theme.getCheckboxLabel(s),r=n.theme.getFormControl(i,e),r.style.paddingBottom=r.style.marginBottom=r.style.paddingTop=r.style.marginTop=0,r.style.height="auto",this.insertPropertyControlUsingPropertyOrder(t,r,this.addproperty_list),e.checked=t in this.editors,e.addEventListener("change",function(){e.checked?n.addObjectProperty(t):n.removeObjectProperty(t),n.onChange(!0)}),n.addproperty_checkboxes[t]=e,e},showAddProperty:function(){this.addproperty_holder&&(this.hideEditJSON(),this.addproperty_holder.style.left=this.addproperty_button.offsetLeft+"px",this.addproperty_holder.style.top=this.addproperty_button.offsetTop+this.addproperty_button.offsetHeight+"px",this.disable(),this.adding_property=!0,this.addproperty_button.disabled=!1,this.addproperty_holder.style.display="",this.refreshAddProperties())},hideAddProperty:function(){this.addproperty_holder&&this.adding_property&&(this.addproperty_holder.style.display="none",this.enable(),this.adding_property=!1)},toggleAddProperty:function(){this.adding_property?this.hideAddProperty():this.showAddProperty()},removeObjectProperty:function(t){this.editors[t]&&(this.editors[t].unregister(),delete this.editors[t],this.refreshValue(),this.layoutEditors())},addObjectProperty:function(t,e){var i=this;if(!this.editors[t]){if(this.cached_editors[t]){if(this.editors[t]=this.cached_editors[t],e)return;this.editors[t].register()}else{if(!(this.canHaveAdditionalProperties()||this.schema.properties&&this.schema.properties[t]))return;var s=i.getPropertySchema(t),r=i.jsoneditor.getEditorClass(s);if(i.editors[t]=i.jsoneditor.createEditor(r,{jsoneditor:i.jsoneditor,schema:s,path:i.path+"."+t,parent:i}),i.editors[t].preBuild(),!e){var n=i.theme.getChildEditorHolder();i.editor_holder.appendChild(n),i.editors[t].setContainer(n),i.editors[t].build(),i.editors[t].postBuild()}i.cached_editors[t]=i.editors[t]}e||(i.refreshValue(),i.layoutEditors())}},onChildEditorChange:function(t){this.refreshValue(),this._super(t)},canHaveAdditionalProperties:function(){return"boolean"==typeof this.schema.additionalProperties?this.schema.additionalProperties:!this.jsoneditor.options.no_additional_properties},destroy:function(){s(this.cached_editors,function(t,e){e.destroy()}),this.editor_holder&&(this.editor_holder.innerHTML=""),this.title&&this.title.parentNode&&this.title.parentNode.removeChild(this.title),this.error_holder&&this.error_holder.parentNode&&this.error_holder.parentNode.removeChild(this.error_holder),this.editors=null,this.cached_editors=null,this.editor_holder&&this.editor_holder.parentNode&&this.editor_holder.parentNode.removeChild(this.editor_holder),this.editor_holder=null,this._super()},getValue:function(){var t=this._super();if(this.jsoneditor.options.remove_empty_properties||this.options.remove_empty_properties)for(var e in t)t.hasOwnProperty(e)&&(t[e]||delete t[e]);return t},refreshValue:function(){this.value={};for(var t in this.editors)this.editors.hasOwnProperty(t)&&(this.value[t]=this.editors[t].getValue());this.adding_property&&this.refreshAddProperties()},refreshAddProperties:function(){if(this.options.disable_properties||this.options.disable_properties!==!1&&this.jsoneditor.options.disable_properties)return void(this.addproperty_controls.style.display="none");var t,e=!1,i=!1,s=0,r=!1;for(t in this.editors)this.editors.hasOwnProperty(t)&&s++;e=this.canHaveAdditionalProperties()&&!("undefined"!=typeof this.schema.maxProperties&&s>=this.schema.maxProperties),this.addproperty_checkboxes&&(this.addproperty_list.innerHTML=""),this.addproperty_checkboxes={};for(t in this.cached_editors)this.cached_editors.hasOwnProperty(t)&&(this.addPropertyCheckbox(t),this.isRequired(this.cached_editors[t])&&t in this.editors&&(this.addproperty_checkboxes[t].disabled=!0),"undefined"!=typeof this.schema.minProperties&&s<=this.schema.minProperties?(this.addproperty_checkboxes[t].disabled=this.addproperty_checkboxes[t].checked,this.addproperty_checkboxes[t].checked||(r=!0)):t in this.editors?(r=!0,i=!0):e||this.schema.properties.hasOwnProperty(t)?(this.addproperty_checkboxes[t].disabled=!1,r=!0):this.addproperty_checkboxes[t].disabled=!0);this.canHaveAdditionalProperties()&&(r=!0);for(t in this.schema.properties)this.schema.properties.hasOwnProperty(t)&&(this.cached_editors[t]||(r=!0,this.addPropertyCheckbox(t)));r?this.canHaveAdditionalProperties()?e?this.addproperty_add.disabled=!1:this.addproperty_add.disabled=!0:(this.addproperty_add.style.display="none",this.addproperty_input.style.display="none"):(this.hideAddProperty(),this.addproperty_controls.style.display="none")},isRequired:function(t){return"boolean"==typeof t.schema.required?t.schema.required:Array.isArray(this.schema.required)?this.schema.required.indexOf(t.key)>-1:!!this.jsoneditor.options.required_by_default},setValue:function(t,e){var i=this;t=t||{},("object"!=typeof t||Array.isArray(t))&&(t={}),s(this.cached_editors,function(s,r){"undefined"!=typeof t[s]?(i.addObjectProperty(s),r.setValue(t[s],e)):e||i.isRequired(r)?r.setValue(r.getDefault(),e):i.removeObjectProperty(s)}),s(t,function(t,s){i.cached_editors[t]||(i.addObjectProperty(t),i.editors[t]&&i.editors[t].setValue(s,e))}),this.refreshValue(),this.layoutEditors(),this.onChange()},showValidationErrors:function(t){var e=this,i=[],r=[];s(t,function(t,s){s.path===e.path?i.push(s):r.push(s)}),this.error_holder&&(i.length?(this.error_holder.innerHTML="",this.error_holder.style.display="",s(i,function(t,i){e.error_holder.appendChild(e.theme.getErrorMessage(i.message))})):this.error_holder.style.display="none"),this.options.table_row&&(i.length?this.theme.addTableRowError(this.container):this.theme.removeTableRowError(this.container)),s(this.editors,function(t,e){e.showValidationErrors(r)})}}),n.defaults.editors.array=n.AbstractEditor.extend({getDefault:function(){return this.schema["default"]||[]},register:function(){if(this._super(),this.rows)for(var t=0;t<this.rows.length;t++)this.rows[t].register()},unregister:function(){if(this._super(),this.rows)for(var t=0;t<this.rows.length;t++)this.rows[t].unregister()},getNumColumns:function(){var t=this.getItemInfo(0);return this.tabs_holder?Math.max(Math.min(12,t.width+2),4):t.width},enable:function(){if(this.add_row_button&&(this.add_row_button.disabled=!1),this.remove_all_rows_button&&(this.remove_all_rows_button.disabled=!1),this.delete_last_row_button&&(this.delete_last_row_button.disabled=!1),this.rows)for(var t=0;t<this.rows.length;t++)this.rows[t].enable(),this.rows[t].moveup_button&&(this.rows[t].moveup_button.disabled=!1),this.rows[t].movedown_button&&(this.rows[t].movedown_button.disabled=!1),this.rows[t].delete_button&&(this.rows[t].delete_button.disabled=!1);this._super()},disable:function(){if(this.add_row_button&&(this.add_row_button.disabled=!0),this.remove_all_rows_button&&(this.remove_all_rows_button.disabled=!0),this.delete_last_row_button&&(this.delete_last_row_button.disabled=!0),this.rows)for(var t=0;t<this.rows.length;t++)this.rows[t].disable(),this.rows[t].moveup_button&&(this.rows[t].moveup_button.disabled=!0),this.rows[t].movedown_button&&(this.rows[t].movedown_button.disabled=!0),this.rows[t].delete_button&&(this.rows[t].delete_button.disabled=!0);this._super()},preBuild:function(){this._super(),this.rows=[],this.row_cache=[],this.hide_delete_buttons=this.options.disable_array_delete||this.jsoneditor.options.disable_array_delete,this.hide_move_buttons=this.options.disable_array_reorder||this.jsoneditor.options.disable_array_reorder,this.hide_add_button=this.options.disable_array_add||this.jsoneditor.options.disable_array_add},build:function(){this.options.compact?(this.panel=this.theme.getIndentedPanel(),this.container.appendChild(this.panel),this.controls=this.theme.getButtonHolder(),this.panel.appendChild(this.controls),this.row_holder=document.createElement("div"),this.panel.appendChild(this.row_holder)):(this.header=document.createElement("span"),this.header.textContent=this.getTitle(),this.title=this.theme.getHeader(this.header,this.isRequired()),this.container.appendChild(this.title),this.title_controls=this.theme.getHeaderButtonHolder(),this.title.appendChild(this.title_controls),this.schema.description&&(this.description=this.theme.getDescription(this.schema.description),this.container.appendChild(this.description)),this.error_holder=document.createElement("div"),this.container.appendChild(this.error_holder),"tabs"===this.schema.format?(this.controls=this.theme.getHeaderButtonHolder(),this.title.appendChild(this.controls),this.tabs_holder=this.theme.getTabHolder(),this.container.appendChild(this.tabs_holder),this.row_holder=this.theme.getTabContentHolder(this.tabs_holder),this.active_tab=null):(this.panel=this.theme.getIndentedPanel(),this.container.appendChild(this.panel),this.row_holder=document.createElement("div"),this.panel.appendChild(this.row_holder),this.controls=this.theme.getButtonHolder(),this.panel.appendChild(this.controls))),this.addControls()},onChildEditorChange:function(t){this.refreshValue(),this.refreshTabs(!0),this._super(t)},getItemTitle:function(){if(!this.item_title)if(this.schema.items&&!Array.isArray(this.schema.items)){var t=this.jsoneditor.expandRefs(this.schema.items);this.item_title=t.title||"item"}else this.item_title="item";return this.item_title},getItemSchema:function(t){return Array.isArray(this.schema.items)?t>=this.schema.items.length?this.schema.additionalItems===!0?{}:this.schema.additionalItems?i({},this.schema.additionalItems):void 0:i({},this.schema.items[t]):this.schema.items?i({},this.schema.items):{}},getItemInfo:function(t){var e=this.getItemSchema(t);this.item_info=this.item_info||{};var i=JSON.stringify(e);return"undefined"!=typeof this.item_info[i]?this.item_info[i]:(e=this.jsoneditor.expandRefs(e),this.item_info[i]={title:e.title||"item","default":e["default"],width:12,child_editors:e.properties||e.items},this.item_info[i])},getElementEditor:function(t){var e=this.getItemInfo(t),i=this.getItemSchema(t);i=this.jsoneditor.expandRefs(i),i.title=e.title+" "+(t+1);var s,r=this.jsoneditor.getEditorClass(i);s=this.tabs_holder?this.theme.getTabContent():e.child_editors?this.theme.getChildEditorHolder():this.theme.getIndentedPanel(),this.row_holder.appendChild(s);var n=this.jsoneditor.createEditor(r,{jsoneditor:this.jsoneditor,schema:i,container:s,path:this.path+"."+t,parent:this,required:!0});return n.preBuild(),n.build(),n.postBuild(),n.title_controls||(n.array_controls=this.theme.getButtonHolder(),s.appendChild(n.array_controls)),n},destroy:function(){this.empty(!0),this.title&&this.title.parentNode&&this.title.parentNode.removeChild(this.title),this.description&&this.description.parentNode&&this.description.parentNode.removeChild(this.description),this.row_holder&&this.row_holder.parentNode&&this.row_holder.parentNode.removeChild(this.row_holder),this.controls&&this.controls.parentNode&&this.controls.parentNode.removeChild(this.controls),this.panel&&this.panel.parentNode&&this.panel.parentNode.removeChild(this.panel),this.rows=this.row_cache=this.title=this.description=this.row_holder=this.panel=this.controls=null,this._super()},empty:function(t){if(this.rows){var e=this;s(this.rows,function(i,s){t&&(s.tab&&s.tab.parentNode&&s.tab.parentNode.removeChild(s.tab),e.destroyRow(s,!0),e.row_cache[i]=null),e.rows[i]=null}),e.rows=[],t&&(e.row_cache=[])}},destroyRow:function(t,e){var i=t.container;e?(t.destroy(),i.parentNode&&i.parentNode.removeChild(i),t.tab&&t.tab.parentNode&&t.tab.parentNode.removeChild(t.tab)):(t.tab&&(t.tab.style.display="none"),i.style.display="none",t.unregister())},getMax:function(){return Array.isArray(this.schema.items)&&this.schema.additionalItems===!1?Math.min(this.schema.items.length,this.schema.maxItems||1/0):this.schema.maxItems||1/0},refreshTabs:function(t){var e=this;s(this.rows,function(i,s){s.tab&&(t?s.tab_text.textContent=s.getHeaderText():s.tab===e.active_tab?(e.theme.markTabActive(s.tab),s.container.style.display=""):(e.theme.markTabInactive(s.tab),s.container.style.display="none"))})},setValue:function(t,e){t=t||[],Array.isArray(t)||(t=[t]);var i=JSON.stringify(t);if(i!==this.serialized){if(this.schema.minItems)for(;t.length<this.schema.minItems;)t.push(this.getItemInfo(t.length)["default"]);this.getMax()&&t.length>this.getMax()&&(t=t.slice(0,this.getMax()));var r=this;s(t,function(t,i){r.rows[t]?r.rows[t].setValue(i,e):r.row_cache[t]?(r.rows[t]=r.row_cache[t],r.rows[t].setValue(i,e),r.rows[t].container.style.display="",r.rows[t].tab&&(r.rows[t].tab.style.display=""),r.rows[t].register()):r.addRow(i,e)});for(var n=t.length;n<r.rows.length;n++)r.destroyRow(r.rows[n]),r.rows[n]=null;r.rows=r.rows.slice(0,t.length);var o=null;s(r.rows,function(t,e){return e.tab===r.active_tab?(o=e.tab,!1):void 0}),!o&&r.rows.length&&(o=r.rows[0].tab),r.active_tab=o,r.refreshValue(e),r.refreshTabs(!0),r.refreshTabs(),r.onChange()}},refreshValue:function(t){var e=this,i=this.value?this.value.length:0;if(this.value=[],s(this.rows,function(t,i){e.value[t]=i.getValue()}),i!==this.value.length||t){var r=this.schema.minItems&&this.schema.minItems>=this.rows.length;s(this.rows,function(t,i){i.movedown_button&&(t===e.rows.length-1?i.movedown_button.style.display="none":i.movedown_button.style.display=""),i.delete_button&&(r?i.delete_button.style.display="none":i.delete_button.style.display=""),e.value[t]=i.getValue()});var n=!1;this.value.length?1===this.value.length?(this.remove_all_rows_button.style.display="none",r||this.hide_delete_buttons?this.delete_last_row_button.style.display="none":(this.delete_last_row_button.style.display="",n=!0)):r||this.hide_delete_buttons?(this.delete_last_row_button.style.display="none",this.remove_all_rows_button.style.display="none"):(this.delete_last_row_button.style.display="",this.remove_all_rows_button.style.display="",n=!0):(this.delete_last_row_button.style.display="none",this.remove_all_rows_button.style.display="none"),this.getMax()&&this.getMax()<=this.rows.length||this.hide_add_button?this.add_row_button.style.display="none":(this.add_row_button.style.display="",n=!0),!this.collapsed&&n?this.controls.style.display="inline-block":this.controls.style.display="none"}},addRow:function(t,e){var i=this,r=this.rows.length;i.rows[r]=this.getElementEditor(r),i.row_cache[r]=i.rows[r],i.tabs_holder&&(i.rows[r].tab_text=document.createElement("span"),i.rows[r].tab_text.textContent=i.rows[r].getHeaderText(),i.rows[r].tab=i.theme.getTab(i.rows[r].tab_text),i.rows[r].tab.addEventListener("click",function(t){i.active_tab=i.rows[r].tab,i.refreshTabs(),t.preventDefault(),t.stopPropagation()}),i.theme.addTab(i.tabs_holder,i.rows[r].tab));var n=i.rows[r].title_controls||i.rows[r].array_controls;i.hide_delete_buttons||(i.rows[r].delete_button=this.getButton(i.getItemTitle(),"delete","Delete "+i.getItemTitle()),i.rows[r].delete_button.className+=" delete",i.rows[r].delete_button.setAttribute("data-i",r),i.rows[r].delete_button.addEventListener("click",function(t){t.preventDefault(),t.stopPropagation();var e=1*this.getAttribute("data-i"),r=i.getValue(),n=[],o=null;s(r,function(t,s){return t===e?void(i.rows[t].tab===i.active_tab&&(i.rows[t+1]?o=i.rows[t].tab:t&&(o=i.rows[t-1].tab))):void n.push(s)}),i.setValue(n),o&&(i.active_tab=o,i.refreshTabs()),i.onChange(!0)}),n&&n.appendChild(i.rows[r].delete_button)),r&&!i.hide_move_buttons&&(i.rows[r].moveup_button=this.getButton("","moveup","Move up"),i.rows[r].moveup_button.className+=" moveup",i.rows[r].moveup_button.setAttribute("data-i",r),i.rows[r].moveup_button.addEventListener("click",function(t){t.preventDefault(),t.stopPropagation();var e=1*this.getAttribute("data-i");if(!(0>=e)){var s=i.getValue(),r=s[e-1];s[e-1]=s[e],s[e]=r,i.setValue(s),i.active_tab=i.rows[e-1].tab,i.refreshTabs(),i.onChange(!0)}}),n&&n.appendChild(i.rows[r].moveup_button)),i.hide_move_buttons||(i.rows[r].movedown_button=this.getButton("","movedown","Move down"),i.rows[r].movedown_button.className+=" movedown",i.rows[r].movedown_button.setAttribute("data-i",r),i.rows[r].movedown_button.addEventListener("click",function(t){t.preventDefault(),t.stopPropagation();var e=1*this.getAttribute("data-i"),s=i.getValue();if(!(e>=s.length-1)){var r=s[e+1];s[e+1]=s[e],s[e]=r,i.setValue(s),i.active_tab=i.rows[e+1].tab,i.refreshTabs(),i.onChange(!0)}}),n&&n.appendChild(i.rows[r].movedown_button)),t&&i.rows[r].setValue(t,e),i.refreshTabs()},addControls:function(){var t=this;this.collapsed=!1,this.toggle_button=this.getButton("","collapse","Collapse"),this.title_controls.appendChild(this.toggle_button);var e=t.row_holder.style.display,i=t.controls.style.display;this.toggle_button.addEventListener("click",function(s){s.preventDefault(),s.stopPropagation(),t.collapsed?(t.collapsed=!1,t.panel&&(t.panel.style.display=""),t.row_holder.style.display=e,t.tabs_holder&&(t.tabs_holder.style.display=""),t.controls.style.display=i,t.setButtonText(this,"","collapse","Collapse")):(t.collapsed=!0,t.row_holder.style.display="none",t.tabs_holder&&(t.tabs_holder.style.display="none"),t.controls.style.display="none",t.panel&&(t.panel.style.display="none"),t.setButtonText(this,"","expand","Expand"))}),this.options.collapsed&&r(this.toggle_button,"click"),this.schema.options&&"undefined"!=typeof this.schema.options.disable_collapse?this.schema.options.disable_collapse&&(this.toggle_button.style.display="none"):this.jsoneditor.options.disable_collapse&&(this.toggle_button.style.display="none"),this.add_row_button=this.getButton(this.getItemTitle(),"add","Add "+this.getItemTitle()),this.add_row_button.addEventListener("click",function(e){e.preventDefault(),e.stopPropagation();var i=t.rows.length;t.row_cache[i]?(t.rows[i]=t.row_cache[i],t.rows[i].setValue(t.rows[i].getDefault()),t.rows[i].container.style.display="",t.rows[i].tab&&(t.rows[i].tab.style.display=""),t.rows[i].register()):t.addRow(),t.active_tab=t.rows[i].tab,t.refreshTabs(),t.refreshValue(),t.onChange(!0)}),t.controls.appendChild(this.add_row_button),this.delete_last_row_button=this.getButton("Last "+this.getItemTitle(),"delete","Delete Last "+this.getItemTitle()),
+this.delete_last_row_button.addEventListener("click",function(e){e.preventDefault(),e.stopPropagation();var i=t.getValue(),s=null;t.rows.length>1&&t.rows[t.rows.length-1].tab===t.active_tab&&(s=t.rows[t.rows.length-2].tab),i.pop(),t.setValue(i),s&&(t.active_tab=s,t.refreshTabs()),t.onChange(!0)}),t.controls.appendChild(this.delete_last_row_button),this.remove_all_rows_button=this.getButton("All","delete","Delete All"),this.remove_all_rows_button.addEventListener("click",function(e){e.preventDefault(),e.stopPropagation(),t.setValue([]),t.onChange(!0)}),t.controls.appendChild(this.remove_all_rows_button),t.tabs&&(this.add_row_button.style.width="100%",this.add_row_button.style.textAlign="left",this.add_row_button.style.marginBottom="3px",this.delete_last_row_button.style.width="100%",this.delete_last_row_button.style.textAlign="left",this.delete_last_row_button.style.marginBottom="3px",this.remove_all_rows_button.style.width="100%",this.remove_all_rows_button.style.textAlign="left",this.remove_all_rows_button.style.marginBottom="3px")},showValidationErrors:function(t){var e=this,i=[],r=[];s(t,function(t,s){s.path===e.path?i.push(s):r.push(s)}),this.error_holder&&(i.length?(this.error_holder.innerHTML="",this.error_holder.style.display="",s(i,function(t,i){e.error_holder.appendChild(e.theme.getErrorMessage(i.message))})):this.error_holder.style.display="none"),s(this.rows,function(t,e){e.showValidationErrors(r)})}}),n.defaults.editors.table=n.defaults.editors.array.extend({register:function(){if(this._super(),this.rows)for(var t=0;t<this.rows.length;t++)this.rows[t].register()},unregister:function(){if(this._super(),this.rows)for(var t=0;t<this.rows.length;t++)this.rows[t].unregister()},getNumColumns:function(){return Math.max(Math.min(12,this.width),3)},preBuild:function(){var t=this.jsoneditor.expandRefs(this.schema.items||{});this.item_title=t.title||"row",this.item_default=t["default"]||null,this.item_has_child_editors=t.properties||t.items,this.width=12,this._super()},build:function(){var t=this;this.table=this.theme.getTable(),this.container.appendChild(this.table),this.thead=this.theme.getTableHead(),this.table.appendChild(this.thead),this.header_row=this.theme.getTableRow(),this.thead.appendChild(this.header_row),this.row_holder=this.theme.getTableBody(),this.table.appendChild(this.row_holder);var e=this.getElementEditor(0,!0);if(this.item_default=e.getDefault(),this.width=e.getNumColumns()+2,this.options.compact?(this.panel=document.createElement("div"),this.container.appendChild(this.panel)):(this.title=this.theme.getHeader(this.getTitle(),this.isRequired()),this.container.appendChild(this.title),this.title_controls=this.theme.getHeaderButtonHolder(),this.title.appendChild(this.title_controls),this.schema.description&&(this.description=this.theme.getDescription(this.schema.description),this.container.appendChild(this.description)),this.panel=this.theme.getIndentedPanel(),this.container.appendChild(this.panel),this.error_holder=document.createElement("div"),this.panel.appendChild(this.error_holder)),this.panel.appendChild(this.table),this.controls=this.theme.getButtonHolder(),this.panel.appendChild(this.controls),this.item_has_child_editors)for(var i=e.getChildEditors(),s=e.property_order||Object.keys(i),r=0;r<s.length;r++){var n=t.theme.getTableHeaderCell(i[s[r]].getTitle());i[s[r]].options.hidden&&(n.style.display="none"),t.header_row.appendChild(n)}else t.header_row.appendChild(t.theme.getTableHeaderCell(this.item_title));e.destroy(),this.row_holder.innerHTML="",this.controls_header_cell=t.theme.getTableHeaderCell(" "),t.header_row.appendChild(this.controls_header_cell),this.addControls()},onChildEditorChange:function(t){this.refreshValue(),this._super()},getItemDefault:function(){return i({},{"default":this.item_default})["default"]},getItemTitle:function(){return this.item_title},getElementEditor:function(t,e){var s=i({},this.schema.items),r=this.jsoneditor.getEditorClass(s,this.jsoneditor),n=this.row_holder.appendChild(this.theme.getTableRow()),o=n;this.item_has_child_editors||(o=this.theme.getTableCell(),n.appendChild(o));var a=this.jsoneditor.createEditor(r,{jsoneditor:this.jsoneditor,schema:s,container:o,path:this.path+"."+t,parent:this,compact:!0,table_row:!0});return a.preBuild(),e||(a.build(),a.postBuild(),a.controls_cell=n.appendChild(this.theme.getTableCell()),a.row=n,a.table_controls=this.theme.getButtonHolder(),a.controls_cell.appendChild(a.table_controls),a.table_controls.style.margin=0,a.table_controls.style.padding=0),a},destroy:function(){this.innerHTML="",this.title&&this.title.parentNode&&this.title.parentNode.removeChild(this.title),this.description&&this.description.parentNode&&this.description.parentNode.removeChild(this.description),this.row_holder&&this.row_holder.parentNode&&this.row_holder.parentNode.removeChild(this.row_holder),this.table&&this.table.parentNode&&this.table.parentNode.removeChild(this.table),this.panel&&this.panel.parentNode&&this.panel.parentNode.removeChild(this.panel),this.rows=this.title=this.description=this.row_holder=this.table=this.panel=null,this._super()},setValue:function(t,e){if(t=t||[],this.schema.minItems)for(;t.length<this.schema.minItems;)t.push(this.getItemDefault());this.schema.maxItems&&t.length>this.schema.maxItems&&(t=t.slice(0,this.schema.maxItems));var i=JSON.stringify(t);if(i!==this.serialized){var r=!1,n=this;s(t,function(t,e){n.rows[t]?n.rows[t].setValue(e):(n.addRow(e),r=!0)});for(var o=t.length;o<n.rows.length;o++){var a=n.rows[o].container;n.item_has_child_editors||n.rows[o].row.parentNode.removeChild(n.rows[o].row),n.rows[o].destroy(),a.parentNode&&a.parentNode.removeChild(a),n.rows[o]=null,r=!0}n.rows=n.rows.slice(0,t.length),n.refreshValue(),(r||e)&&n.refreshRowButtons(),n.onChange()}},refreshRowButtons:function(){var t=this,e=this.schema.minItems&&this.schema.minItems>=this.rows.length,i=!1;s(this.rows,function(s,r){r.movedown_button&&(s===t.rows.length-1?r.movedown_button.style.display="none":(i=!0,r.movedown_button.style.display="")),r.delete_button&&(e?r.delete_button.style.display="none":(i=!0,r.delete_button.style.display="")),r.moveup_button&&(i=!0)}),s(this.rows,function(t,e){i?e.controls_cell.style.display="":e.controls_cell.style.display="none"}),i?this.controls_header_cell.style.display="":this.controls_header_cell.style.display="none";var r=!1;this.value.length?1===this.value.length||this.hide_delete_buttons?(this.table.style.display="",this.remove_all_rows_button.style.display="none",e||this.hide_delete_buttons?this.delete_last_row_button.style.display="none":(this.delete_last_row_button.style.display="",r=!0)):(this.table.style.display="",e||this.hide_delete_buttons?(this.delete_last_row_button.style.display="none",this.remove_all_rows_button.style.display="none"):(this.delete_last_row_button.style.display="",this.remove_all_rows_button.style.display="",r=!0)):(this.delete_last_row_button.style.display="none",this.remove_all_rows_button.style.display="none",this.table.style.display="none"),this.schema.maxItems&&this.schema.maxItems<=this.rows.length||this.hide_add_button?this.add_row_button.style.display="none":(this.add_row_button.style.display="",r=!0),r?this.controls.style.display="":this.controls.style.display="none"},refreshValue:function(){var t=this;this.value=[],s(this.rows,function(e,i){t.value[e]=i.getValue()}),this.serialized=JSON.stringify(this.value)},addRow:function(t){var e=this,i=this.rows.length;e.rows[i]=this.getElementEditor(i);var r=e.rows[i].table_controls;this.hide_delete_buttons||(e.rows[i].delete_button=this.getButton("","delete","Delete"),e.rows[i].delete_button.className+=" delete",e.rows[i].delete_button.setAttribute("data-i",i),e.rows[i].delete_button.addEventListener("click",function(t){t.preventDefault(),t.stopPropagation();var i=1*this.getAttribute("data-i"),r=e.getValue(),n=[];s(r,function(t,e){t!==i&&n.push(e)}),e.setValue(n),e.onChange(!0)}),r.appendChild(e.rows[i].delete_button)),i&&!this.hide_move_buttons&&(e.rows[i].moveup_button=this.getButton("","moveup","Move up"),e.rows[i].moveup_button.className+=" moveup",e.rows[i].moveup_button.setAttribute("data-i",i),e.rows[i].moveup_button.addEventListener("click",function(t){t.preventDefault(),t.stopPropagation();var i=1*this.getAttribute("data-i");if(!(0>=i)){var s=e.getValue(),r=s[i-1];s[i-1]=s[i],s[i]=r,e.setValue(s),e.onChange(!0)}}),r.appendChild(e.rows[i].moveup_button)),this.hide_move_buttons||(e.rows[i].movedown_button=this.getButton("","movedown","Move down"),e.rows[i].movedown_button.className+=" movedown",e.rows[i].movedown_button.setAttribute("data-i",i),e.rows[i].movedown_button.addEventListener("click",function(t){t.preventDefault(),t.stopPropagation();var i=1*this.getAttribute("data-i"),s=e.getValue();if(!(i>=s.length-1)){var r=s[i+1];s[i+1]=s[i],s[i]=r,e.setValue(s),e.onChange(!0)}}),r.appendChild(e.rows[i].movedown_button)),t&&e.rows[i].setValue(t)},addControls:function(){var t=this;this.collapsed=!1,this.toggle_button=this.getButton("","collapse","Collapse"),this.title_controls&&(this.title_controls.appendChild(this.toggle_button),this.toggle_button.addEventListener("click",function(e){e.preventDefault(),e.stopPropagation(),t.collapsed?(t.collapsed=!1,t.panel.style.display="",t.setButtonText(this,"","collapse","Collapse")):(t.collapsed=!0,t.panel.style.display="none",t.setButtonText(this,"","expand","Expand"))}),this.options.collapsed&&r(this.toggle_button,"click"),this.schema.options&&"undefined"!=typeof this.schema.options.disable_collapse?this.schema.options.disable_collapse&&(this.toggle_button.style.display="none"):this.jsoneditor.options.disable_collapse&&(this.toggle_button.style.display="none")),this.add_row_button=this.getButton(this.getItemTitle(),"add","Add "+this.getItemTitle()),this.add_row_button.addEventListener("click",function(e){e.preventDefault(),e.stopPropagation(),t.addRow(),t.refreshValue(),t.refreshRowButtons(),t.onChange(!0)}),t.controls.appendChild(this.add_row_button),this.delete_last_row_button=this.getButton("Last "+this.getItemTitle(),"delete","Delete Last "+this.getItemTitle()),this.delete_last_row_button.addEventListener("click",function(e){e.preventDefault(),e.stopPropagation();var i=t.getValue();i.pop(),t.setValue(i),t.onChange(!0)}),t.controls.appendChild(this.delete_last_row_button),this.remove_all_rows_button=this.getButton("All","delete","Delete All"),this.remove_all_rows_button.addEventListener("click",function(e){e.preventDefault(),e.stopPropagation(),t.setValue([]),t.onChange(!0)}),t.controls.appendChild(this.remove_all_rows_button)}}),n.defaults.editors.multiple=n.AbstractEditor.extend({register:function(){if(this.editors){for(var t=0;t<this.editors.length;t++)this.editors[t]&&this.editors[t].unregister();this.editors[this.type]&&this.editors[this.type].register()}this._super()},unregister:function(){if(this._super(),this.editors)for(var t=0;t<this.editors.length;t++)this.editors[t]&&this.editors[t].unregister()},getNumColumns:function(){return this.editors[this.type]?Math.max(this.editors[this.type].getNumColumns(),4):4},enable:function(){if(this.editors)for(var t=0;t<this.editors.length;t++)this.editors[t]&&this.editors[t].enable();this.switcher.disabled=!1,this._super()},disable:function(){if(this.editors)for(var t=0;t<this.editors.length;t++)this.editors[t]&&this.editors[t].disable();this.switcher.disabled=!0,this._super()},switchEditor:function(t){var e=this;this.editors[t]||this.buildChildEditor(t),e.type=t,e.register();var i=e.getValue();s(e.editors,function(t,s){s&&(e.type===t?(e.keep_values&&s.setValue(i,!0),s.container.style.display=""):s.container.style.display="none")}),e.refreshValue(),e.refreshHeaderText()},buildChildEditor:function(t){var e=this,s=this.types[t],r=e.theme.getChildEditorHolder();e.editor_holder.appendChild(r);var n;"string"==typeof s?(n=i({},e.schema),n.type=s):(n=i({},e.schema,s),n=e.jsoneditor.expandRefs(n),s.required&&Array.isArray(s.required)&&e.schema.required&&Array.isArray(e.schema.required)&&(n.required=e.schema.required.concat(s.required)));var o=e.jsoneditor.getEditorClass(n);e.editors[t]=e.jsoneditor.createEditor(o,{jsoneditor:e.jsoneditor,schema:n,container:r,path:e.path,parent:e,required:!0}),e.editors[t].preBuild(),e.editors[t].build(),e.editors[t].postBuild(),e.editors[t].header&&(e.editors[t].header.style.display="none"),e.editors[t].option=e.switcher_options[t],r.addEventListener("change_header_text",function(){e.refreshHeaderText()}),t!==e.type&&(r.style.display="none")},preBuild:function(){if(this.types=[],this.type=0,this.editors=[],this.validators=[],this.keep_values=!0,"undefined"!=typeof this.jsoneditor.options.keep_oneof_values&&(this.keep_values=this.jsoneditor.options.keep_oneof_values),"undefined"!=typeof this.options.keep_oneof_values&&(this.keep_values=this.options.keep_oneof_values),this.schema.oneOf)this.oneOf=!0,this.types=this.schema.oneOf,s(this.types,function(t,e){}),delete this.schema.oneOf;else{if(this.schema.type&&"any"!==this.schema.type)Array.isArray(this.schema.type)?this.types=this.schema.type:this.types=[this.schema.type];else if(this.types=["string","number","integer","boolean","object","array","null"],this.schema.disallow){var t=this.schema.disallow;"object"==typeof t&&Array.isArray(t)||(t=[t]);var e=[];s(this.types,function(i,s){-1===t.indexOf(s)&&e.push(s)}),this.types=e}delete this.schema.type}this.display_text=this.getDisplayText(this.types)},build:function(){var t=this,e=this.container;this.header=this.label=this.theme.getFormInputLabel(this.getTitle(),this.isRequired()),this.container.appendChild(this.header),this.switcher=this.theme.getSwitcher(this.display_text),e.appendChild(this.switcher),this.switcher.addEventListener("change",function(e){e.preventDefault(),e.stopPropagation(),t.switchEditor(t.display_text.indexOf(this.value)),t.onChange(!0)}),this.editor_holder=document.createElement("div"),e.appendChild(this.editor_holder),this.switcher_options=this.theme.getSwitcherOptions(this.switcher),s(this.types,function(e,s){t.editors[e]=!1;var r;"string"==typeof s?(r=i({},t.schema),r.type=s):(r=i({},t.schema,s),s.required&&Array.isArray(s.required)&&t.schema.required&&Array.isArray(t.schema.required)&&(r.required=t.schema.required.concat(s.required))),t.validators[e]=new n.Validator(t.jsoneditor,r)}),this.switchEditor(0)},onChildEditorChange:function(t){this.editors[this.type]&&(this.refreshValue(),this.refreshHeaderText()),this._super()},refreshHeaderText:function(){var t=this.getDisplayText(this.types);s(this.switcher_options,function(e,i){i.textContent=t[e]})},refreshValue:function(){this.value=this.editors[this.type].getValue()},setValue:function(t,e){var i=this;s(this.validators,function(e,s){return s.validate(t).length?void 0:(i.type=e,i.switcher.value=i.display_text[e],!1)}),this.switchEditor(this.type),this.editors[this.type].setValue(t,e),this.refreshValue(),i.onChange()},destroy:function(){s(this.editors,function(t,e){e&&e.destroy()}),this.editor_holder&&this.editor_holder.parentNode&&this.editor_holder.parentNode.removeChild(this.editor_holder),this.switcher&&this.switcher.parentNode&&this.switcher.parentNode.removeChild(this.switcher),this._super()},showValidationErrors:function(t){var e=this;this.oneOf?s(this.editors,function(r,n){if(n){var o=e.path+".oneOf["+r+"]",a=[];s(t,function(t,s){if(s.path.substr(0,o.length)===o){var r=i({},s);r.path=e.path+r.path.substr(o.length),a.push(r)}}),n.showValidationErrors(a)}}):s(this.editors,function(e,i){i&&i.showValidationErrors(t)})}}),n.defaults.editors["enum"]=n.AbstractEditor.extend({getNumColumns:function(){return 4},build:function(){this.container,this.title=this.header=this.label=this.theme.getFormInputLabel(this.getTitle(),this.isRequired()),this.container.appendChild(this.title),this.options.enum_titles=this.options.enum_titles||[],this["enum"]=this.schema["enum"],this.selected=0,this.select_options=[],this.html_values=[];for(var t=this,e=0;e<this["enum"].length;e++)this.select_options[e]=this.options.enum_titles[e]||"Value "+(e+1),this.html_values[e]=this.getHTML(this["enum"][e]);this.switcher=this.theme.getSwitcher(this.select_options),this.container.appendChild(this.switcher),this.display_area=this.theme.getIndentedPanel(),this.container.appendChild(this.display_area),this.options.hide_display&&(this.display_area.style.display="none"),this.switcher.addEventListener("change",function(){t.selected=t.select_options.indexOf(this.value),t.value=t["enum"][t.selected],t.refreshValue(),t.onChange(!0)}),this.value=this["enum"][0],this.refreshValue(),1===this["enum"].length&&(this.switcher.style.display="none")},refreshValue:function(){var t=this;t.selected=-1;var e=JSON.stringify(this.value);return s(this["enum"],function(i,s){return e===JSON.stringify(s)?(t.selected=i,!1):void 0}),t.selected<0?void t.setValue(t["enum"][0]):(this.switcher.value=this.select_options[this.selected],void(this.display_area.innerHTML=this.html_values[this.selected]))},enable:function(){this.always_disabled||(this.switcher.disabled=!1),this._super()},disable:function(){this.switcher.disabled=!0,this._super()},getHTML:function(t){var e=this;if(null===t)return"<em>null</em>";if("object"==typeof t){var i="";return s(t,function(s,r){var n=e.getHTML(r);Array.isArray(t)||(n="<div><em>"+s+"</em>: "+n+"</div>"),i+="<li>"+n+"</li>"}),i=Array.isArray(t)?"<ol>"+i+"</ol>":"<ul style='margin-top:0;margin-bottom:0;padding-top:0;padding-bottom:0;'>"+i+"</ul>"}return"boolean"==typeof t?t?"true":"false":"string"==typeof t?t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"):t},setValue:function(t){this.value!==t&&(this.value=t,this.refreshValue(),this.onChange())},destroy:function(){this.display_area&&this.display_area.parentNode&&this.display_area.parentNode.removeChild(this.display_area),this.title&&this.title.parentNode&&this.title.parentNode.removeChild(this.title),this.switcher&&this.switcher.parentNode&&this.switcher.parentNode.removeChild(this.switcher),this._super()}}),n.defaults.editors.select=n.AbstractEditor.extend({setValue:function(t,e){t=this.typecast(t||"");var i=t;this.enum_values.indexOf(i)<0&&(i=this.enum_values[0]),this.value!==i&&(this.input.value=this.enum_options[this.enum_values.indexOf(i)],this.select2&&this.select2.select2("val",this.input.value),this.value=i,this.onChange())},register:function(){this._super(),this.input&&this.input.setAttribute("name",this.formname)},unregister:function(){this._super(),this.input&&this.input.removeAttribute("name")},getNumColumns:function(){if(!this.enum_options)return 3;for(var t=this.getTitle().length,e=0;e<this.enum_options.length;e++)t=Math.max(t,this.enum_options[e].length+4);return Math.min(12,Math.max(t/7,2))},typecast:function(t){return"boolean"===this.schema.type?!!t:"number"===this.schema.type?1*t:"integer"===this.schema.type?Math.floor(1*t):""+t},getValue:function(){return this.value},preBuild:function(){var t=this;if(this.input_type="select",this.enum_options=[],this.enum_values=[],this.enum_display=[],this.schema["enum"]){var e=this.schema.options&&this.schema.options.enum_titles||[];s(this.schema["enum"],function(i,s){t.enum_options[i]=""+s,t.enum_display[i]=""+(e[i]||s),t.enum_values[i]=t.typecast(s)}),this.isRequired()||(t.enum_display.unshift(" "),t.enum_options.unshift("undefined"),t.enum_values.unshift(void 0))}else if("boolean"===this.schema.type)t.enum_display=this.schema.options&&this.schema.options.enum_titles||["true","false"],t.enum_options=["1",""],t.enum_values=[!0,!1],this.isRequired()||(t.enum_display.unshift(" "),t.enum_options.unshift("undefined"),t.enum_values.unshift(void 0));else{if(!this.schema.enumSource)throw"'select' editor requires the enum property to be set.";if(this.enumSource=[],this.enum_display=[],this.enum_options=[],this.enum_values=[],Array.isArray(this.schema.enumSource))for(a=0;a<this.schema.enumSource.length;a++)"string"==typeof this.schema.enumSource[a]?this.enumSource[a]={source:this.schema.enumSource[a]}:Array.isArray(this.schema.enumSource[a])?this.enumSource[a]=this.schema.enumSource[a]:this.enumSource[a]=i({},this.schema.enumSource[a]);else this.schema.enumValue?this.enumSource=[{source:this.schema.enumSource,value:this.schema.enumValue}]:this.enumSource=[{source:this.schema.enumSource}];for(a=0;a<this.enumSource.length;a++)this.enumSource[a].value&&(this.enumSource[a].value=this.jsoneditor.compileTemplate(this.enumSource[a].value,this.template_engine)),this.enumSource[a].title&&(this.enumSource[a].title=this.jsoneditor.compileTemplate(this.enumSource[a].title,this.template_engine)),this.enumSource[a].filter&&(this.enumSource[a].filter=this.jsoneditor.compileTemplate(this.enumSource[a].filter,this.template_engine))}},build:function(){var t=this;this.options.compact||(this.header=this.label=this.theme.getFormInputLabel(this.getTitle(),this.isRequired())),this.schema.description&&(this.description=this.theme.getFormInputDescription(this.schema.description)),this.options.compact&&(this.container.className+=" compact"),this.input=this.theme.getSelectInput(this.enum_options),this.theme.setSelectOptions(this.input,this.enum_options,this.enum_display),(this.schema.readOnly||this.schema.readonly)&&(this.always_disabled=!0,this.input.disabled=!0),this.input.addEventListener("change",function(e){e.preventDefault(),e.stopPropagation(),t.onInputChange()}),this.control=this.theme.getFormControl(this.label,this.input,this.description),this.container.appendChild(this.control),this.value=this.enum_values[0]},onInputChange:function(){var t=this.input.value,e=t;-1===this.enum_options.indexOf(t)&&(e=this.enum_options[0]),this.value=this.enum_values[this.enum_options.indexOf(t)],this.onChange(!0)},setupSelect2:function(){if(window.jQuery&&window.jQuery.fn&&window.jQuery.fn.select2&&(this.enum_options.length>2||this.enum_options.length&&this.enumSource)){var t=i({},n.plugins.select2);this.schema.options&&this.schema.options.select2_options&&(t=i(t,this.schema.options.select2_options)),this.select2=window.jQuery(this.input).select2(t);var e=this;this.select2.on("select2-blur",function(){e.input.value=e.select2.select2("val"),e.onInputChange()})}else this.select2=null},postBuild:function(){this._super(),this.theme.afterInputReady(this.input),this.setupSelect2()},onWatchedFieldChange:function(){var t,e;if(this.enumSource){t=this.getWatchedFieldValues();for(var i=[],s=[],r=0;r<this.enumSource.length;r++)if(Array.isArray(this.enumSource[r]))i=i.concat(this.enumSource[r]),s=s.concat(this.enumSource[r]);else{var n=[];if(n=Array.isArray(this.enumSource[r].source)?this.enumSource[r].source:t[this.enumSource[r].source]){if(this.enumSource[r].slice&&(n=Array.prototype.slice.apply(n,this.enumSource[r].slice)),this.enumSource[r].filter){var o=[];for(e=0;e<n.length;e++)this.enumSource[r].filter({i:e,item:n[e],watched:t})&&o.push(n[e]);n=o}var a=[],h=[];for(e=0;e<n.length;e++){var l=n[e];this.enumSource[r].value?h[e]=this.enumSource[r].value({i:e,item:l}):h[e]=n[e],this.enumSource[r].title?a[e]=this.enumSource[r].title({i:e,item:l}):a[e]=h[e]}i=i.concat(h),s=s.concat(a)}}var d=this.value;this.theme.setSelectOptions(this.input,i,s),this.enum_options=i,this.enum_display=s,this.enum_values=i,this.select2&&this.select2.select2("destroy"),-1!==i.indexOf(d)?(this.input.value=d,this.value=d):(this.input.value=i[0],this.value=i[0]||"",this.parent?this.parent.onChildEditorChange(this):this.jsoneditor.onChange(),this.jsoneditor.notifyWatchers(this.path)),this.setupSelect2()}this._super()},enable:function(){this.always_disabled||(this.input.disabled=!1,this.select2&&this.select2.select2("enable",!0)),this._super()},disable:function(){this.input.disabled=!0,this.select2&&this.select2.select2("enable",!1),this._super()},destroy:function(){this.label&&this.label.parentNode&&this.label.parentNode.removeChild(this.label),this.description&&this.description.parentNode&&this.description.parentNode.removeChild(this.description),this.input&&this.input.parentNode&&this.input.parentNode.removeChild(this.input),this.select2&&(this.select2.select2("destroy"),this.select2=null),this._super()}}),n.defaults.editors.multiselect=n.AbstractEditor.extend({preBuild:function(){this._super(),this.select_options={},this.select_values={};var t=this.jsoneditor.expandRefs(this.schema.items||{}),e=t["enum"]||[];for(this.option_keys=[],a=0;a<e.length;a++)this.sanitize(e[a])===e[a]&&(this.option_keys.push(e[a]+""),this.select_values[e[a]+""]=e[a])},build:function(){var t,e=this;if(this.options.compact||(this.header=this.label=this.theme.getFormInputLabel(this.getTitle(),this.isRequired())),this.schema.description&&(this.description=this.theme.getFormInputDescription(this.schema.description)),!this.schema.format&&this.option_keys.length<8||"checkbox"===this.schema.format){for(this.input_type="checkboxes",this.inputs={},this.controls={},t=0;t<this.option_keys.length;t++){this.inputs[this.option_keys[t]]=this.theme.getCheckbox(),this.select_options[this.option_keys[t]]=this.inputs[this.option_keys[t]];var i=this.theme.getCheckboxLabel(this.option_keys[t]);this.controls[this.option_keys[t]]=this.theme.getFormControl(i,this.inputs[this.option_keys[t]])}this.control=this.theme.getMultiCheckboxHolder(this.controls,this.label,this.description)}else{for(this.input_type="select",this.input=this.theme.getSelectInput(this.option_keys),this.input.multiple=!0,this.input.size=Math.min(10,this.option_keys.length),t=0;t<this.option_keys.length;t++)this.select_options[this.option_keys[t]]=this.input.children[t];(this.schema.readOnly||this.schema.readonly)&&(this.always_disabled=!0,this.input.disabled=!0),this.control=this.theme.getFormControl(this.label,this.input,this.description)}this.container.appendChild(this.control),this.control.addEventListener("change",function(i){i.preventDefault(),i.stopPropagation();var s=[];for(t=0;t<e.option_keys.length;t++)(e.select_options[e.option_keys[t]].selected||e.select_options[e.option_keys[t]].checked)&&s.push(e.select_values[e.option_keys[t]]);e.updateValue(s),e.onChange(!0)})},setValue:function(t,e){var i;for(t=t||[],"object"!=typeof t?t=[t]:Array.isArray(t)||(t=[]),i=0;i<t.length;i++)"string"!=typeof t[i]&&(t[i]+="");for(i in this.select_options)this.select_options.hasOwnProperty(i)&&(this.select_options[i]["select"===this.input_type?"selected":"checked"]=-1!==t.indexOf(i));this.updateValue(t),this.onChange()},setupSelect2:function(){if(window.jQuery&&window.jQuery.fn&&window.jQuery.fn.select2){var t=window.jQuery.extend({},n.plugins.select2);this.schema.options&&this.schema.options.select2_options&&(t=i(t,this.schema.options.select2_options)),this.select2=window.jQuery(this.input).select2(t);var e=this;this.select2.on("select2-blur",function(){var t=e.select2.select2("val");e.value=t,e.onChange(!0)})}else this.select2=null},onInputChange:function(){this.value=this.input.value,this.onChange(!0)},postBuild:function(){this._super(),this.setupSelect2()},register:function(){this._super(),this.input&&this.input.setAttribute("name",this.formname)},unregister:function(){this._super(),this.input&&this.input.removeAttribute("name")},getNumColumns:function(){var t=this.getTitle().length;for(var e in this.select_values)this.select_values.hasOwnProperty(e)&&(t=Math.max(t,(this.select_values[e]+"").length+4));return Math.min(12,Math.max(t/7,2))},updateValue:function(t){for(var e=!1,i=[],s=0;s<t.length;s++)if(this.select_options[t[s]+""]){var r=this.sanitize(this.select_values[t[s]]);i.push(r),r!==t[s]&&(e=!0)}else e=!0;return this.value=i,this.select2&&this.select2.select2("val",this.value),e},sanitize:function(t){return"number"===this.schema.items.type?1*t:"integer"===this.schema.items.type?Math.floor(1*t):""+t},enable:function(){if(!this.always_disabled){if(this.input)this.input.disabled=!1;else if(this.inputs)for(var t in this.inputs)this.inputs.hasOwnProperty(t)&&(this.inputs[t].disabled=!1);this.select2&&this.select2.select2("enable",!0)}this._super()},disable:function(){if(this.input)this.input.disabled=!0;else if(this.inputs)for(var t in this.inputs)this.inputs.hasOwnProperty(t)&&(this.inputs[t].disabled=!0);this.select2&&this.select2.select2("enable",!1),this._super()},destroy:function(){this.select2&&(this.select2.select2("destroy"),this.select2=null),this._super()}}),n.defaults.editors.base64=n.AbstractEditor.extend({getNumColumns:function(){return 4},build:function(){var t=this;if(this.title=this.header=this.label=this.theme.getFormInputLabel(this.getTitle(),this.isRequired()),this.input=this.theme.getFormInputField("hidden"),this.container.appendChild(this.input),!this.schema.readOnly&&!this.schema.readonly){if(!window.FileReader)throw"FileReader required for base64 editor";this.uploader=this.theme.getFormInputField("file"),this.uploader.addEventListener("change",function(e){if(e.preventDefault(),e.stopPropagation(),this.files&&this.files.length){var i=new FileReader;i.onload=function(e){t.value=e.target.result,t.refreshPreview(),t.onChange(!0),i=null},i.readAsDataURL(this.files[0])}})}this.preview=this.theme.getFormInputDescription(this.schema.description),this.container.appendChild(this.preview),this.control=this.theme.getFormControl(this.label,this.uploader||this.input,this.preview),this.container.appendChild(this.control)},refreshPreview:function(){if(this.last_preview!==this.value&&(this.last_preview=this.value,this.preview.innerHTML="",this.value)){var t=this.value.match(/^data:([^;,]+)[;,]/);if(t&&(t=t[1]),t){if(this.preview.innerHTML="<strong>Type:</strong> "+t+", <strong>Size:</strong> "+Math.floor((this.value.length-this.value.split(",")[0].length-1)/1.33333)+" bytes","image"===t.substr(0,5)){this.preview.innerHTML+="<br>";var e=document.createElement("img");e.style.maxWidth="100%",e.style.maxHeight="100px",e.src=this.value,this.preview.appendChild(e)}}else this.preview.innerHTML="<em>Invalid data URI</em>"}},enable:function(){this.uploader&&(this.uploader.disabled=!1),this._super()},disable:function(){this.uploader&&(this.uploader.disabled=!0),this._super()},setValue:function(t){this.value!==t&&(this.value=t,this.input.value=this.value,this.refreshPreview(),this.onChange())},destroy:function(){this.preview&&this.preview.parentNode&&this.preview.parentNode.removeChild(this.preview),this.title&&this.title.parentNode&&this.title.parentNode.removeChild(this.title),this.input&&this.input.parentNode&&this.input.parentNode.removeChild(this.input),this.uploader&&this.uploader.parentNode&&this.uploader.parentNode.removeChild(this.uploader),this._super()}}),n.defaults.editors.upload=n.AbstractEditor.extend({getNumColumns:function(){return 4},build:function(){var t=this;if(this.title=this.header=this.label=this.theme.getFormInputLabel(this.getTitle(),this.isRequired()),this.input=this.theme.getFormInputField("hidden"),this.container.appendChild(this.input),!this.schema.readOnly&&!this.schema.readonly){if(!this.jsoneditor.options.upload)throw"Upload handler required for upload editor";this.uploader=this.theme.getFormInputField("file"),this.uploader.addEventListener("change",function(e){if(e.preventDefault(),e.stopPropagation(),this.files&&this.files.length){var i=new FileReader;i.onload=function(e){t.preview_value=e.target.result,t.refreshPreview(),t.onChange(!0),i=null},i.readAsDataURL(this.files[0])}})}var e=this.schema.description;e||(e=""),this.preview=this.theme.getFormInputDescription(e),this.container.appendChild(this.preview),this.control=this.theme.getFormControl(this.label,this.uploader||this.input,this.preview),this.container.appendChild(this.control)},refreshPreview:function(){if(this.last_preview!==this.preview_value&&(this.last_preview=this.preview_value,this.preview.innerHTML="",this.preview_value)){var t=this,e=this.preview_value.match(/^data:([^;,]+)[;,]/);e&&(e=e[1]),e||(e="unknown");var i=this.uploader.files[0];if(this.preview.innerHTML="<strong>Type:</strong> "+e+", <strong>Size:</strong> "+i.size+" bytes","image"===e.substr(0,5)){this.preview.innerHTML+="<br>";var s=document.createElement("img");s.style.maxWidth="100%",s.style.maxHeight="100px",s.src=this.preview_value,
+this.preview.appendChild(s)}this.preview.innerHTML+="<br>";var r=this.getButton("Upload","upload","Upload");this.preview.appendChild(r),r.addEventListener("click",function(e){e.preventDefault(),r.setAttribute("disabled","disabled"),t.theme.removeInputError(t.uploader),t.theme.getProgressBar&&(t.progressBar=t.theme.getProgressBar(),t.preview.appendChild(t.progressBar)),t.jsoneditor.options.upload(t.path,i,{success:function(e){t.setValue(e),t.parent?t.parent.onChildEditorChange(t):t.jsoneditor.onChange(),t.progressBar&&t.preview.removeChild(t.progressBar),r.removeAttribute("disabled")},failure:function(e){t.theme.addInputError(t.uploader,e),t.progressBar&&t.preview.removeChild(t.progressBar),r.removeAttribute("disabled")},updateProgress:function(e){t.progressBar&&(e?t.theme.updateProgressBar(t.progressBar,e):t.theme.updateProgressBarUnknown(t.progressBar))}})})}},enable:function(){this.uploader&&(this.uploader.disabled=!1),this._super()},disable:function(){this.uploader&&(this.uploader.disabled=!0),this._super()},setValue:function(t){this.value!==t&&(this.value=t,this.input.value=this.value,this.onChange())},destroy:function(){this.preview&&this.preview.parentNode&&this.preview.parentNode.removeChild(this.preview),this.title&&this.title.parentNode&&this.title.parentNode.removeChild(this.title),this.input&&this.input.parentNode&&this.input.parentNode.removeChild(this.input),this.uploader&&this.uploader.parentNode&&this.uploader.parentNode.removeChild(this.uploader),this._super()}}),n.defaults.editors.checkbox=n.AbstractEditor.extend({setValue:function(t,e){this.value=!!t,this.input.checked=this.value,this.onChange()},register:function(){this._super(),this.input&&this.input.setAttribute("name",this.formname)},unregister:function(){this._super(),this.input&&this.input.removeAttribute("name")},getNumColumns:function(){return Math.min(12,Math.max(this.getTitle().length/7,2))},build:function(){var t=this;this.options.compact||(this.label=this.header=this.theme.getCheckboxLabel(this.getTitle())),this.schema.description&&(this.description=this.theme.getFormInputDescription(this.schema.description)),this.options.compact&&(this.container.className+=" compact"),this.input=this.theme.getCheckbox(),this.control=this.theme.getFormControl(this.label,this.input,this.description),(this.schema.readOnly||this.schema.readonly)&&(this.always_disabled=!0,this.input.disabled=!0),this.input.addEventListener("change",function(e){e.preventDefault(),e.stopPropagation(),t.value=this.checked,t.onChange(!0)}),this.container.appendChild(this.control)},enable:function(){this.always_disabled||(this.input.disabled=!1),this._super()},disable:function(){this.input.disabled=!0,this._super()},destroy:function(){this.label&&this.label.parentNode&&this.label.parentNode.removeChild(this.label),this.description&&this.description.parentNode&&this.description.parentNode.removeChild(this.description),this.input&&this.input.parentNode&&this.input.parentNode.removeChild(this.input),this._super()}});var o=function(){var t=document.documentElement;return t.matches?"matches":t.webkitMatchesSelector?"webkitMatchesSelector":t.mozMatchesSelector?"mozMatchesSelector":t.msMatchesSelector?"msMatchesSelector":t.oMatchesSelector?"oMatchesSelector":void 0}();n.AbstractTheme=t.extend({getContainer:function(){return document.createElement("div")},getFloatRightLinkHolder:function(){var t=document.createElement("div");return t.style=t.style||{},t.style.cssFloat="right",t.style.marginLeft="10px",t},getModal:function(){var t=document.createElement("div");return t.style.backgroundColor="white",t.style.border="1px solid black",t.style.boxShadow="3px 3px black",t.style.position="absolute",t.style.zIndex="10",t.style.display="none",t},getGridContainer:function(){var t=document.createElement("div");return t},getGridRow:function(){var t=document.createElement("div");return t.className="row",t},getGridColumn:function(){var t=document.createElement("div");return t},setGridColumnSize:function(t,e){},getLink:function(t){var e=document.createElement("a");return e.setAttribute("href","#"),e.appendChild(document.createTextNode(t)),e},disableHeader:function(t){t.style.color="#ccc"},disableLabel:function(t){t.style.color="#ccc"},enableHeader:function(t){t.style.color=""},enableLabel:function(t){t.style.color=""},getFormInputLabel:function(t){var e=document.createElement("label");return e.appendChild(document.createTextNode(t)),e},getCheckboxLabel:function(t){var e=this.getFormInputLabel(t);return e.style.fontWeight="normal",e},getHeader:function(t,e){var i=document.createElement("h3");return"string"==typeof t?i.textContent=t:i.appendChild(t),e&&(i.className+=" required"),i},getCheckbox:function(){var t=this.getFormInputField("checkbox");return t.style.display="inline-block",t.style.width="auto",t},getMultiCheckboxHolder:function(t,e,i){var s=document.createElement("div");e&&(e.style.display="block",s.appendChild(e));for(var r in t)t.hasOwnProperty(r)&&(t[r].style.display="inline-block",t[r].style.marginRight="20px",s.appendChild(t[r]));return i&&s.appendChild(i),s},getSelectInput:function(t){var e=document.createElement("select");return t&&this.setSelectOptions(e,t),e},getSwitcher:function(t){var e=this.getSelectInput(t);return e.style.backgroundColor="transparent",e.style.display="inline-block",e.style.fontStyle="italic",e.style.fontWeight="normal",e.style.height="auto",e.style.marginBottom=0,e.style.marginLeft="5px",e.style.padding="0 0 0 3px",e.style.width="auto",e},getSwitcherOptions:function(t){return t.getElementsByTagName("option")},setSwitcherOptions:function(t,e,i){this.setSelectOptions(t,e,i)},setSelectOptions:function(t,e,i){i=i||[],t.innerHTML="";for(var s=0;s<e.length;s++){var r=document.createElement("option");r.setAttribute("value",e[s]),r.textContent=i[s]||e[s],t.appendChild(r)}},getTextareaInput:function(){var t=document.createElement("textarea");return t.style=t.style||{},t.style.width="100%",t.style.height="300px",t.style.boxSizing="border-box",t},getRangeInput:function(t,e,i){var s=this.getFormInputField("range");return s.setAttribute("min",t),s.setAttribute("max",e),s.setAttribute("step",i),s},getFormInputField:function(t){var e=document.createElement("input");return e.setAttribute("type",t),e},afterInputReady:function(t){},getFormControl:function(t,e,i){var s=document.createElement("div");return s.className="form-control",t&&s.appendChild(t),"checkbox"===e.type?t.insertBefore(e,t.firstChild):s.appendChild(e),i&&s.appendChild(i),s},getIndentedPanel:function(){var t=document.createElement("div");return t.style=t.style||{},t.style.paddingLeft="10px",t.style.marginLeft="10px",t.style.borderLeft="1px solid #ccc",t},getChildEditorHolder:function(){return document.createElement("div")},getDescription:function(t){var e=document.createElement("p");return e.innerHTML=t,e},getCheckboxDescription:function(t){return this.getDescription(t)},getFormInputDescription:function(t){return this.getDescription(t)},getHeaderButtonHolder:function(){return this.getButtonHolder()},getButtonHolder:function(){return document.createElement("div")},getButton:function(t,e,i){var s=document.createElement("button");return s.type="button",this.setButtonText(s,t,e,i),s},setButtonText:function(t,e,i,s){t.innerHTML="",i&&(t.appendChild(i),t.innerHTML+=" "),t.appendChild(document.createTextNode(e)),s&&t.setAttribute("title",s)},getTable:function(){return document.createElement("table")},getTableRow:function(){return document.createElement("tr")},getTableHead:function(){return document.createElement("thead")},getTableBody:function(){return document.createElement("tbody")},getTableHeaderCell:function(t){var e=document.createElement("th");return e.textContent=t,e},getTableCell:function(){var t=document.createElement("td");return t},getErrorMessage:function(t){var e=document.createElement("p");return e.style=e.style||{},e.style.color="red",e.appendChild(document.createTextNode(t)),e},addInputError:function(t,e){},removeInputError:function(t){},addTableRowError:function(t){},removeTableRowError:function(t){},getTabHolder:function(){var t=document.createElement("div");return t.innerHTML="<div style='float: left; width: 130px;' class='tabs'></div><div class='content' style='margin-left: 130px;'></div><div style='clear:both;'></div>",t},applyStyles:function(t,e){t.style=t.style||{};for(var i in e)e.hasOwnProperty(i)&&(t.style[i]=e[i])},closest:function(t,e){for(;t&&t!==document;){if(!o)return!1;if(t[o](e))return t;t=t.parentNode}return!1},getTab:function(t){var e=document.createElement("div");return e.appendChild(t),e.style=e.style||{},this.applyStyles(e,{border:"1px solid #ccc",borderWidth:"1px 0 1px 1px",textAlign:"center",lineHeight:"30px",borderRadius:"5px",borderBottomRightRadius:0,borderTopRightRadius:0,fontWeight:"bold",cursor:"pointer"}),e},getTabContentHolder:function(t){return t.children[1]},getTabContent:function(){return this.getIndentedPanel()},markTabActive:function(t){this.applyStyles(t,{opacity:1,background:"white"})},markTabInactive:function(t){this.applyStyles(t,{opacity:.5,background:""})},addTab:function(t,e){t.children[0].appendChild(e)},getBlockLink:function(){var t=document.createElement("a");return t.style.display="block",t},getBlockLinkHolder:function(){var t=document.createElement("div");return t},getLinksHolder:function(){var t=document.createElement("div");return t},createMediaLink:function(t,e,i){t.appendChild(e),i.style.width="100%",t.appendChild(i)},createImageLink:function(t,e,i){t.appendChild(e),e.appendChild(i)}}),n.defaults.themes.bootstrap2=n.AbstractTheme.extend({getRangeInput:function(t,e,i){return this._super(t,e,i)},getGridContainer:function(){var t=document.createElement("div");return t.className="container-fluid",t},getGridRow:function(){var t=document.createElement("div");return t.className="row-fluid",t},getFormInputLabel:function(t,e){var i=this._super(t);return i.style.display="inline-block",i.style.fontWeight="bold",e&&(i.className+=" required"),i},setGridColumnSize:function(t,e){t.className="span"+e},getSelectInput:function(t){var e=this._super(t);return e.style.width="auto",e.style.maxWidth="98%",e},getFormInputField:function(t){var e=this._super(t);return e.style.width="98%",e},afterInputReady:function(t){t.controlgroup||(t.controlgroup=this.closest(t,".control-group"),t.controls=this.closest(t,".controls"),this.closest(t,".compact")&&(t.controlgroup.className=t.controlgroup.className.replace(/control-group/g,"").replace(/[ ]{2,}/g," "),t.controls.className=t.controlgroup.className.replace(/controls/g,"").replace(/[ ]{2,}/g," "),t.style.marginBottom=0))},getIndentedPanel:function(){var t=document.createElement("div");return t.className="well well-small",t},getFormInputDescription:function(t){var e=document.createElement("p");return e.className="help-inline",e.textContent=t,e},getFormControl:function(t,e,i){var s=document.createElement("div");s.className="control-group";var r=document.createElement("div");return r.className="controls",t&&"checkbox"===e.getAttribute("type")?(s.appendChild(r),t.className+=" checkbox",t.appendChild(e),r.appendChild(t),r.style.height="30px"):(t&&(t.className+=" control-label",s.appendChild(t)),r.appendChild(e),s.appendChild(r)),i&&r.appendChild(i),s},getHeaderButtonHolder:function(){var t=this.getButtonHolder();return t.style.marginLeft="10px",t},getButtonHolder:function(){var t=document.createElement("div");return t.className="btn-group",t},getButton:function(t,e,i){var s=this._super(t,e,i);return s.className+=" btn btn-default",s},getTable:function(){var t=document.createElement("table");return t.className="table table-bordered",t.style.width="auto",t.style.maxWidth="none",t},addInputError:function(t,e){t.controlgroup&&t.controls&&(t.controlgroup.className+=" error",t.errmsg?t.errmsg.style.display="":(t.errmsg=document.createElement("p"),t.errmsg.className="help-block errormsg",t.controls.appendChild(t.errmsg)),t.errmsg.textContent=e)},removeInputError:function(t){t.errmsg&&(t.errmsg.style.display="none",t.controlgroup.className=t.controlgroup.className.replace(/\s?error/g,""))},getTabHolder:function(){var t=document.createElement("div");return t.className="tabbable tabs-left",t.innerHTML="<ul class='nav nav-tabs span2' style='margin-right: 0;'></ul><div class='tab-content span10' style='overflow:visible;'></div>",t},getTab:function(t){var e=document.createElement("li"),i=document.createElement("a");return i.setAttribute("href","#"),i.appendChild(t),e.appendChild(i),e},getTabContentHolder:function(t){return t.children[1]},getTabContent:function(){var t=document.createElement("div");return t.className="tab-pane active",t},markTabActive:function(t){t.className+=" active"},markTabInactive:function(t){t.className=t.className.replace(/\s?active/g,"")},addTab:function(t,e){t.children[0].appendChild(e)},getProgressBar:function(){var t=document.createElement("div");t.className="progress";var e=document.createElement("div");return e.className="bar",e.style.width="0%",t.appendChild(e),t},updateProgressBar:function(t,e){t&&(t.firstChild.style.width=e+"%")},updateProgressBarUnknown:function(t){t&&(t.className="progress progress-striped active",t.firstChild.style.width="100%")}}),n.defaults.themes.bootstrap3=n.AbstractTheme.extend({getSelectInput:function(t){var e=this._super(t);return e.className+="form-control",e},setGridColumnSize:function(t,e){t.className="col-md-"+e},afterInputReady:function(t){t.controlgroup||(t.controlgroup=this.closest(t,".form-group"),this.closest(t,".compact")&&(t.controlgroup.style.marginBottom=0))},getTextareaInput:function(){var t=document.createElement("textarea");return t.className="form-control",t},getRangeInput:function(t,e,i){return this._super(t,e,i)},getFormInputField:function(t){var e=this._super(t);return"checkbox"!==t&&(e.className+="form-control"),e},getFormControl:function(t,e,i){var s=document.createElement("div");return t&&"checkbox"===e.type?(s.className+=" checkbox",t.appendChild(e),t.style.fontSize="14px",s.style.marginTop="0",s.appendChild(t),e.style.position="relative",e.style.cssFloat="left"):(s.className+=" form-group",t&&(t.className+=" control-label",s.appendChild(t)),s.appendChild(e)),i&&s.appendChild(i),s},getIndentedPanel:function(){var t=document.createElement("div");return t.className="well well-sm",t},getFormInputDescription:function(t){var e=document.createElement("p");return e.className="help-block",e.innerHTML=t,e},getHeaderButtonHolder:function(){var t=this.getButtonHolder();return t.style.marginLeft="10px",t},getButtonHolder:function(){var t=document.createElement("div");return t.className="btn-group",t},getButton:function(t,e,i){var s=this._super(t,e,i);return s.className+="btn btn-default",s},getTable:function(){var t=document.createElement("table");return t.className="table table-bordered",t.style.width="auto",t.style.maxWidth="none",t},addInputError:function(t,e){t.controlgroup&&(t.controlgroup.className+=" has-error",t.errmsg?t.errmsg.style.display="":(t.errmsg=document.createElement("p"),t.errmsg.className="help-block errormsg",t.controlgroup.appendChild(t.errmsg)),t.errmsg.textContent=e)},removeInputError:function(t){t.errmsg&&(t.errmsg.style.display="none",t.controlgroup.className=t.controlgroup.className.replace(/\s?has-error/g,""))},getTabHolder:function(){var t=document.createElement("div");return t.innerHTML="<div class='tabs list-group col-md-2'></div><div class='col-md-10'></div>",t.className="rows",t},getTab:function(t){var e=document.createElement("a");return e.className="list-group-item",e.setAttribute("href","#"),e.appendChild(t),e},markTabActive:function(t){t.className+=" active"},markTabInactive:function(t){t.className=t.className.replace(/\s?active/g,"")},getProgressBar:function(){var t=0,e=100,i=0,s=document.createElement("div");s.className="progress";var r=document.createElement("div");return r.className="progress-bar",r.setAttribute("role","progressbar"),r.setAttribute("aria-valuenow",i),r.setAttribute("aria-valuemin",t),r.setAttribute("aria-valuenax",e),r.innerHTML=i+"%",s.appendChild(r),s},updateProgressBar:function(t,e){if(t){var i=t.firstChild,s=e+"%";i.setAttribute("aria-valuenow",e),i.style.width=s,i.innerHTML=s}},updateProgressBarUnknown:function(t){if(t){var e=t.firstChild;t.className="progress progress-striped active",e.removeAttribute("aria-valuenow"),e.style.width="100%",e.innerHTML=""}}}),n.defaults.themes.foundation=n.AbstractTheme.extend({getChildEditorHolder:function(){var t=document.createElement("div");return t.style.marginBottom="15px",t},getSelectInput:function(t){var e=this._super(t);return e.style.minWidth="none",e.style.padding="5px",e.style.marginTop="3px",e},getSwitcher:function(t){var e=this._super(t);return e.style.paddingRight="8px",e},afterInputReady:function(t){this.closest(t,".compact")&&(t.style.marginBottom=0),t.group=this.closest(t,".form-control")},getFormInputLabel:function(t,e){var i=this._super(t);return i.style.display="inline-block",e&&(i.className+=" required"),i},getFormInputField:function(t){var e=this._super(t);return e.style.width="100%",e.style.marginBottom="checkbox"===t?"0":"12px",e},getFormInputDescription:function(t){var e=document.createElement("p");return e.textContent=t,e.style.marginTop="-10px",e.style.fontStyle="italic",e},getIndentedPanel:function(){var t=document.createElement("div");return t.className="panel",t},getHeaderButtonHolder:function(){var t=this.getButtonHolder();return t.style.display="inline-block",t.style.marginLeft="10px",t.style.verticalAlign="middle",t},getButtonHolder:function(){var t=document.createElement("div");return t.className="button-group",t},getButton:function(t,e,i){var s=this._super(t,e,i);return s.className+=" small button",s},addInputError:function(t,e){t.group&&(t.group.className+=" error",t.errmsg?t.errmsg.style.display="":(t.insertAdjacentHTML("afterend",'<small class="error"></small>'),t.errmsg=t.parentNode.getElementsByClassName("error")[0]),t.errmsg.textContent=e)},removeInputError:function(t){t.errmsg&&(t.group.className=t.group.className.replace(/ error/g,""),t.errmsg.style.display="none")},getProgressBar:function(){var t=document.createElement("div");t.className="progress";var e=document.createElement("span");return e.className="meter",e.style.width="0%",t.appendChild(e),t},updateProgressBar:function(t,e){t&&(t.firstChild.style.width=e+"%")},updateProgressBarUnknown:function(t){t&&(t.firstChild.style.width="100%")}}),n.defaults.themes.foundation3=n.defaults.themes.foundation.extend({getHeaderButtonHolder:function(){var t=this._super();return t.style.fontSize=".6em",t},getFormInputLabel:function(t,e){var i=this._super(t);return i.style.fontWeight="bold",e&&(i.className+=" required"),i},getTabHolder:function(){var t=document.createElement("div");return t.className="row",t.innerHTML="<dl class='tabs vertical two columns'></dl><div class='tabs-content ten columns'></div>",t},setGridColumnSize:function(t,e){var i=["zero","one","two","three","four","five","six","seven","eight","nine","ten","eleven","twelve"];t.className="columns "+i[e]},getTab:function(t){var e=document.createElement("dd"),i=document.createElement("a");return i.setAttribute("href","#"),i.appendChild(t),e.appendChild(i),e},getTabContentHolder:function(t){return t.children[1]},getTabContent:function(){var t=document.createElement("div");return t.className="content active",t.style.paddingLeft="5px",t},markTabActive:function(t){t.className+=" active"},markTabInactive:function(t){t.className=t.className.replace(/\s*active/g,"")},addTab:function(t,e){t.children[0].appendChild(e)}}),n.defaults.themes.foundation4=n.defaults.themes.foundation.extend({getHeaderButtonHolder:function(){var t=this._super();return t.style.fontSize=".6em",t},setGridColumnSize:function(t,e){t.className="columns large-"+e},getFormInputDescription:function(t){var e=this._super(t);return e.style.fontSize=".8rem",e},getFormInputLabel:function(t,e){var i=this._super(t);return i.style.fontWeight="bold",e&&(i.className+=" required"),i}}),n.defaults.themes.foundation5=n.defaults.themes.foundation.extend({getFormInputDescription:function(t){var e=this._super(t);return e.style.fontSize=".8rem",e},setGridColumnSize:function(t,e){t.className="columns medium-"+e},getButton:function(t,e,i){var s=this._super(t,e,i);return s.className=s.className.replace(/\s*small/g,"")+" tiny",s},getTabHolder:function(){var t=document.createElement("div");return t.innerHTML="<dl class='tabs vertical'></dl><div class='tabs-content vertical'></div>",t},getTab:function(t){var e=document.createElement("dd"),i=document.createElement("a");return i.setAttribute("href","#"),i.appendChild(t),e.appendChild(i),e},getTabContentHolder:function(t){return t.children[1]},getTabContent:function(){var t=document.createElement("div");return t.className="content active",t.style.paddingLeft="5px",t},markTabActive:function(t){t.className+=" active"},markTabInactive:function(t){t.className=t.className.replace(/\s*active/g,"")},addTab:function(t,e){t.children[0].appendChild(e)}}),n.defaults.themes.html=n.AbstractTheme.extend({getFormInputLabel:function(t,e){var i=this._super(t);return i.style.display="block",i.style.marginBottom="3px",i.style.fontWeight="bold",e&&(i.className+=" required"),i},getFormInputDescription:function(t){var e=this._super(t);return e.style.fontSize=".8em",e.style.margin=0,e.style.display="inline-block",e.style.fontStyle="italic",e},getIndentedPanel:function(){var t=this._super();return t.style.border="1px solid #ddd",t.style.padding="5px",t.style.margin="5px",t.style.borderRadius="3px",t},getChildEditorHolder:function(){var t=this._super();return t.style.marginBottom="8px",t},getHeaderButtonHolder:function(){var t=this.getButtonHolder();return t.style.display="inline-block",t.style.marginLeft="10px",t.style.fontSize=".8em",t.style.verticalAlign="middle",t},getTable:function(){var t=this._super();return t.style.borderBottom="1px solid #ccc",t.style.marginBottom="5px",t},addInputError:function(t,e){if(t.style.borderColor="red",t.errmsg)t.errmsg.style.display="block";else{var i=this.closest(t,".form-control");t.errmsg=document.createElement("div"),t.errmsg.setAttribute("class","errmsg"),t.errmsg.style=t.errmsg.style||{},t.errmsg.style.color="red",i.appendChild(t.errmsg)}t.errmsg.innerHTML="",t.errmsg.appendChild(document.createTextNode(e))},removeInputError:function(t){t.style.borderColor="",t.errmsg&&(t.errmsg.style.display="none")},getProgressBar:function(){var t=100,e=0,i=document.createElement("progress");return i.setAttribute("max",t),i.setAttribute("value",e),i},updateProgressBar:function(t,e){t&&t.setAttribute("value",e)},updateProgressBarUnknown:function(t){t&&t.removeAttribute("value")}}),n.defaults.themes.jqueryui=n.AbstractTheme.extend({getTable:function(){var t=this._super();return t.setAttribute("cellpadding",5),t.setAttribute("cellspacing",0),t},getTableHeaderCell:function(t){var e=this._super(t);return e.className="ui-state-active",e.style.fontWeight="bold",e},getTableCell:function(){var t=this._super();return t.className="ui-widget-content",t},getHeaderButtonHolder:function(){var t=this.getButtonHolder();return t.style.marginLeft="10px",t.style.fontSize=".6em",t.style.display="inline-block",t},getFormInputDescription:function(t){var e=this.getDescription(t);return e.style.marginLeft="10px",e.style.display="inline-block",e},getFormControl:function(t,e,i){var s=this._super(t,e,i);return"checkbox"===e.type?(s.style.lineHeight="25px",s.style.padding="3px 0"):s.style.padding="4px 0 8px 0",s},getDescription:function(t){var e=document.createElement("span");return e.style.fontSize=".8em",e.style.fontStyle="italic",e.textContent=t,e},getButtonHolder:function(){var t=document.createElement("div");return t.className="ui-buttonset",t.style.fontSize=".7em",t},getFormInputLabel:function(t,e){var i=document.createElement("label");return i.style.fontWeight="bold",i.style.display="block",e&&(i.className+=" required"),i.textContent=t,i},getButton:function(t,e,i){var s=document.createElement("button");s.className="ui-button ui-widget ui-state-default ui-corner-all",e&&!t?(s.className+=" ui-button-icon-only",e.className+=" ui-button-icon-primary ui-icon-primary",s.appendChild(e)):e?(s.className+=" ui-button-text-icon-primary",e.className+=" ui-button-icon-primary ui-icon-primary",s.appendChild(e)):s.className+=" ui-button-text-only";var r=document.createElement("span");return r.className="ui-button-text",r.textContent=t||i||".",s.appendChild(r),s.setAttribute("title",i),s},setButtonText:function(t,e,i,s){t.innerHTML="",t.className="ui-button ui-widget ui-state-default ui-corner-all",i&&!e?(t.className+=" ui-button-icon-only",i.className+=" ui-button-icon-primary ui-icon-primary",t.appendChild(i)):i?(t.className+=" ui-button-text-icon-primary",i.className+=" ui-button-icon-primary ui-icon-primary",t.appendChild(i)):t.className+=" ui-button-text-only";var r=document.createElement("span");r.className="ui-button-text",r.textContent=e||s||".",t.appendChild(r),t.setAttribute("title",s)},getIndentedPanel:function(){var t=document.createElement("div");return t.className="ui-widget-content ui-corner-all",t.style.padding="1em 1.4em",t.style.marginBottom="20px",t},afterInputReady:function(t){t.controls||(t.controls=this.closest(t,".form-control"))},addInputError:function(t,e){t.controls&&(t.errmsg?t.errmsg.style.display="":(t.errmsg=document.createElement("div"),t.errmsg.className="ui-state-error",t.controls.appendChild(t.errmsg)),t.errmsg.textContent=e)},removeInputError:function(t){t.errmsg&&(t.errmsg.style.display="none")},markTabActive:function(t){t.className=t.className.replace(/\s*ui-widget-header/g,"")+" ui-state-active"},markTabInactive:function(t){t.className=t.className.replace(/\s*ui-state-active/g,"")+" ui-widget-header"}}),n.AbstractIconLib=t.extend({mapping:{collapse:"",expand:"","delete":"",edit:"",add:"",cancel:"",save:"",moveup:"",movedown:""},icon_prefix:"",getIconClass:function(t){return this.mapping[t]?this.icon_prefix+this.mapping[t]:null},getIcon:function(t){var e=this.getIconClass(t);if(!e)return null;var i=document.createElement("i");return i.className=e,i}}),n.defaults.iconlibs.bootstrap2=n.AbstractIconLib.extend({mapping:{collapse:"chevron-down",expand:"chevron-up","delete":"trash",edit:"pencil",add:"plus",cancel:"ban-circle",save:"ok",moveup:"arrow-up",movedown:"arrow-down"},icon_prefix:"icon-"}),n.defaults.iconlibs.bootstrap3=n.AbstractIconLib.extend({mapping:{collapse:"chevron-down",expand:"chevron-right","delete":"remove",edit:"pencil",add:"plus",cancel:"floppy-remove",save:"floppy-saved",moveup:"arrow-up",movedown:"arrow-down"},icon_prefix:"glyphicon glyphicon-"}),n.defaults.iconlibs.fontawesome3=n.AbstractIconLib.extend({mapping:{collapse:"chevron-down",expand:"chevron-right","delete":"remove",edit:"pencil",add:"plus",cancel:"ban-circle",save:"save",moveup:"arrow-up",movedown:"arrow-down"},icon_prefix:"icon-"}),n.defaults.iconlibs.fontawesome4=n.AbstractIconLib.extend({mapping:{collapse:"caret-square-o-down",expand:"caret-square-o-right","delete":"times",edit:"pencil",add:"plus",cancel:"ban",save:"save",moveup:"arrow-up",movedown:"arrow-down"},icon_prefix:"fa fa-"}),n.defaults.iconlibs.foundation2=n.AbstractIconLib.extend({mapping:{collapse:"minus",expand:"plus","delete":"remove",edit:"edit",add:"add-doc",cancel:"error",save:"checkmark",moveup:"up-arrow",movedown:"down-arrow"},icon_prefix:"foundicon-"}),n.defaults.iconlibs.foundation3=n.AbstractIconLib.extend({mapping:{collapse:"minus",expand:"plus","delete":"x",edit:"pencil",add:"page-add",cancel:"x-circle",save:"save",moveup:"arrow-up",movedown:"arrow-down"},icon_prefix:"fi-"}),n.defaults.iconlibs.jqueryui=n.AbstractIconLib.extend({mapping:{collapse:"triangle-1-s",expand:"triangle-1-e","delete":"trash",edit:"pencil",add:"plusthick",cancel:"closethick",save:"disk",moveup:"arrowthick-1-n",movedown:"arrowthick-1-s"},icon_prefix:"ui-icon ui-icon-"}),n.defaults.templates["default"]=function(){return{compile:function(t){var e=t.match(/{{\s*([a-zA-Z0-9\-_ \.]+)\s*}}/g),i=e&&e.length;if(!i)return function(){return t};for(var s=[],r=function(t){var i,r=e[t].replace(/[{}]+/g,"").trim().split("."),n=r.length;if(n>1){var o;i=function(e){for(o=e,t=0;n>t&&(o=o[r[t]]);t++);return o}}else r=r[0],i=function(t){return t[r]};s.push({s:e[t],r:i})},n=0;i>n;n++)r(n);return function(e){var r,o=t+"";for(n=0;i>n;n++)r=s[n],o=o.replace(r.s,r.r(e));return o}}}},n.defaults.templates.ejs=function(){return!!window.EJS&&{compile:function(t){var e=new window.EJS({text:t});return function(t){return e.render(t)}}}},n.defaults.templates.handlebars=function(){return window.Handlebars},n.defaults.templates.hogan=function(){return!!window.Hogan&&{compile:function(t){var e=window.Hogan.compile(t);return function(t){return e.render(t)}}}},n.defaults.templates.markup=function(){return!(!window.Mark||!window.Mark.up)&&{compile:function(t){return function(e){return window.Mark.up(t,e)}}}},n.defaults.templates.mustache=function(){return!!window.Mustache&&{compile:function(t){return function(e){return window.Mustache.render(t,e)}}}},n.defaults.templates.swig=function(){return window.swig},n.defaults.templates.underscore=function(){return!!window._&&{compile:function(t){return function(e){return window._.template(t,e)}}}},n.defaults.theme="html",n.defaults.template="default",n.defaults.options={},n.defaults.translate=function(t,e){var i=n.defaults.languages[n.defaults.language];if(!i)throw"Unknown language "+n.defaults.language;var s=i[t]||n.defaults.languages[n.defaults.default_language][t];if("undefined"==typeof s)throw"Unknown translate string "+t;if(e)for(var r=0;r<e.length;r++)s=s.replace(new RegExp("\\{\\{"+r+"}}","g"),e[r]);return s},n.defaults.default_language="en",n.defaults.language=n.defaults.default_language,n.defaults.languages.en={error_notset:"Property must be set",error_notempty:"Value required",error_enum:"Value must be one of the enumerated values",error_anyOf:"Value must validate against at least one of the provided schemas",error_oneOf:"Value must validate against exactly one of the provided schemas. It currently validates against {{0}} of the schemas.",error_not:"Value must not validate against the provided schema",error_type_union:"Value must be one of the provided types",error_type:"Value must be of type {{0}}",error_disallow_union:"Value must not be one of the provided disallowed types",error_disallow:"Value must not be of type {{0}}",error_multipleOf:"Value must be a multiple of {{0}}",error_maximum_excl:"Value must be less than {{0}}",error_maximum_incl:"Value must at most {{0}}",error_minimum_excl:"Value must be greater than {{0}}",error_minimum_incl:"Value must be at least {{0}}",error_maxLength:"Value must be at most {{0}} characters long",error_minLength:"Value must be at least {{0}} characters long",error_pattern:"Value must match the provided pattern",error_additionalItems:"No additional items allowed in this array",error_maxItems:"Value must have at most {{0}} items",error_minItems:"Value must have at least {{0}} items",error_uniqueItems:"Array must have unique items",error_maxProperties:"Object must have at most {{0}} properties",error_minProperties:"Object must have at least {{0}} properties",error_required:"Object is missing the required property '{{0}}'",error_additional_properties:"No additional properties allowed, but property {{0}} is set",error_dependency:"Must have property {{0}}"},n.plugins={ace:{theme:""},epiceditor:{},sceditor:{},select2:{}};for(var a in n.defaults.editors)n.defaults.editors.hasOwnProperty(a)&&(n.defaults.editors[a].options=n.defaults.editors.options||{});n.defaults.resolvers.unshift(function(t){return"string"!=typeof t.type?"multiple":void 0}),n.defaults.resolvers.unshift(function(t){return!t.type&&t.properties?"object":void 0}),n.defaults.resolvers.unshift(function(t){return"string"==typeof t.type?t.type:void 0}),n.defaults.resolvers.unshift(function(t){return"boolean"===t.type?"checkbox"===t.format||t.options&&t.options.checkbox?"checkbox":"select":void 0;
+}),n.defaults.resolvers.unshift(function(t){return"any"===t.type?"multiple":void 0}),n.defaults.resolvers.unshift(function(t){return"string"===t.type&&t.media&&"base64"===t.media.binaryEncoding?"base64":void 0}),n.defaults.resolvers.unshift(function(t){return"string"===t.type&&"url"===t.format&&t.options&&t.options.upload===!0&&window.FileReader?"upload":void 0}),n.defaults.resolvers.unshift(function(t){return"array"==t.type&&"table"==t.format?"table":void 0}),n.defaults.resolvers.unshift(function(t){return t.enumSource?"select":void 0}),n.defaults.resolvers.unshift(function(t){if(t["enum"]){if("array"===t.type||"object"===t.type)return"enum";if("number"===t.type||"integer"===t.type||"string"===t.type)return"select"}}),n.defaults.resolvers.unshift(function(t){return"array"===t.type&&t.items&&!Array.isArray(t.items)&&t.uniqueItems&&t.items["enum"]&&["string","number","integer"].indexOf(t.items.type)>=0?"multiselect":void 0}),n.defaults.resolvers.unshift(function(t){return t.oneOf?"multiple":void 0}),function(){if(window.jQuery||window.Zepto){var t=window.jQuery||window.Zepto;t.jsoneditor=n.defaults,t.fn.jsoneditor=function(t){var e=this,i=this.data("jsoneditor");if("value"===t){if(!i)throw"Must initialize jsoneditor before getting/setting the value";if(!(arguments.length>1))return i.getValue();i.setValue(arguments[1])}else{if("validate"===t){if(!i)throw"Must initialize jsoneditor before validating";return arguments.length>1?i.validate(arguments[1]):i.validate()}"destroy"===t?i&&(i.destroy(),this.data("jsoneditor",null)):(i&&i.destroy(),i=new n(this.get(0),t),this.data("jsoneditor",i),i.on("change",function(){e.trigger("change")}),i.on("ready",function(){e.trigger("ready")}))}return this}}}(),window.JSONEditor=n}();
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/lodash.min.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/lodash.min.js
new file mode 100644 (file)
index 0000000..3625da8
--- /dev/null
@@ -0,0 +1,2 @@
+(function(){function n(n,t){if(n!==t){var r=null===n,e=n===x,u=n===n,o=null===t,i=t===x,f=t===t;if(n>t&&!o||!u||r&&!i&&f||e&&f)return 1;if(n<t&&!r||!f||o&&!e&&u||i&&u)return-1}return 0}function t(n,t,r){for(var e=n.length,u=r?e:-1;r?u--:++u<e;)if(t(n[u],u,n))return u;return-1}function r(n,t,r){if(t!==t)return p(n,r);r-=1;for(var e=n.length;++r<e;)if(n[r]===t)return r;return-1}function e(n){return"function"==typeof n||!1}function u(n){return null==n?"":n+""}function o(n,t){for(var r=-1,e=n.length;++r<e&&-1<t.indexOf(n.charAt(r)););return r}function i(n,t){for(var r=n.length;r--&&-1<t.indexOf(n.charAt(r)););return r}function f(t,r){return n(t.a,r.a)||t.b-r.b}function c(n){return Nn[n]}function a(n){return Tn[n]}function l(n,t,r){return t?n=Bn[n]:r&&(n=Dn[n]),"\\"+n}function s(n){return"\\"+Dn[n]}function p(n,t,r){var e=n.length;for(t+=r?0:-1;r?t--:++t<e;){var u=n[t];if(u!==u)return t}return-1}function h(n){return!!n&&"object"==typeof n}function _(n){return 160>=n&&9<=n&&13>=n||32==n||160==n||5760==n||6158==n||8192<=n&&(8202>=n||8232==n||8233==n||8239==n||8287==n||12288==n||65279==n)}function v(n,t){for(var r=-1,e=n.length,u=-1,o=[];++r<e;)n[r]===t&&(n[r]=P,o[++u]=r);return o}function g(n){for(var t=-1,r=n.length;++t<r&&_(n.charCodeAt(t)););return t}function y(n){for(var t=n.length;t--&&_(n.charCodeAt(t)););return t}function d(n){return Pn[n]}function w(_){function Nn(n){if(h(n)&&!(Wo(n)||n instanceof zn)){if(n instanceof Pn)return n;if(eu.call(n,"__chain__")&&eu.call(n,"__wrapped__"))return qr(n)}return new Pn(n)}function Tn(){}function Pn(n,t,r){this.__wrapped__=n,this.__actions__=r||[],this.__chain__=!!t}function zn(n){this.__wrapped__=n,this.__actions__=[],this.__dir__=1,this.__filtered__=!1,this.__iteratees__=[],this.__takeCount__=Cu,this.__views__=[]}function Bn(){this.__data__={}}function Dn(n){var t=n?n.length:0;for(this.data={hash:wu(null),set:new hu};t--;)this.push(n[t])}function Mn(n,t){var r=n.data;return("string"==typeof t||de(t)?r.set.has(t):r.hash[t])?0:-1}function qn(n,t){var r=-1,e=n.length;for(t||(t=De(e));++r<e;)t[r]=n[r];return t}function Kn(n,t){for(var r=-1,e=n.length;++r<e&&!1!==t(n[r],r,n););return n}function Vn(n,t){for(var r=-1,e=n.length;++r<e;)if(!t(n[r],r,n))return!1;return!0}function Zn(n,t){for(var r=-1,e=n.length,u=-1,o=[];++r<e;){var i=n[r];t(i,r,n)&&(o[++u]=i)}return o}function Xn(n,t){for(var r=-1,e=n.length,u=De(e);++r<e;)u[r]=t(n[r],r,n);return u}function Hn(n,t){for(var r=-1,e=t.length,u=n.length;++r<e;)n[u+r]=t[r];return n}function Qn(n,t,r,e){var u=-1,o=n.length;for(e&&o&&(r=n[++u]);++u<o;)r=t(r,n[u],u,n);return r}function nt(n,t){for(var r=-1,e=n.length;++r<e;)if(t(n[r],r,n))return!0;return!1}function tt(n,t,r,e){return n!==x&&eu.call(e,r)?n:t}function rt(n,t,r){for(var e=-1,u=Ko(t),o=u.length;++e<o;){var i=u[e],f=n[i],c=r(f,t[i],i,n,t);(c===c?c===f:f!==f)&&(f!==x||i in n)||(n[i]=c)}return n}function et(n,t){return null==t?n:ot(t,Ko(t),n)}function ut(n,t){for(var r=-1,e=null==n,u=!e&&Sr(n),o=u?n.length:0,i=t.length,f=De(i);++r<i;){var c=t[r];f[r]=u?Ur(c,o)?n[c]:x:e?x:n[c]}return f}function ot(n,t,r){r||(r={});for(var e=-1,u=t.length;++e<u;){var o=t[e];r[o]=n[o]}return r}function it(n,t,r){var e=typeof n;return"function"==e?t===x?n:Dt(n,t,r):null==n?Ne:"object"==e?At(n):t===x?Be(n):jt(n,t)}function ft(n,t,r,e,u,o,i){var f;if(r&&(f=u?r(n,e,u):r(n)),f!==x)return f;if(!de(n))return n;if(e=Wo(n)){if(f=Ir(n),!t)return qn(n,f)}else{var c=ou.call(n),a=c==K;if(c!=Z&&c!=z&&(!a||u))return Ln[c]?Er(n,c,t):u?n:{};if(Gn(n))return u?n:{};if(f=Rr(a?{}:n),!t)return et(f,n)}for(o||(o=[]),i||(i=[]),u=o.length;u--;)if(o[u]==n)return i[u];return o.push(n),i.push(f),(e?Kn:gt)(n,function(e,u){f[u]=ft(e,t,r,u,n,o,i)}),f}function ct(n,t,r){if("function"!=typeof n)throw new Xe(T);return _u(function(){n.apply(x,r)},t)}function at(n,t){var e=n?n.length:0,u=[];if(!e)return u;var o=-1,i=jr(),f=i===r,c=f&&t.length>=F&&wu&&hu?new Dn(t):null,a=t.length;c&&(i=Mn,f=!1,t=c);n:for(;++o<e;)if(c=n[o],f&&c===c){for(var l=a;l--;)if(t[l]===c)continue n;u.push(c)}else 0>i(t,c,0)&&u.push(c);return u}function lt(n,t){var r=!0;return zu(n,function(n,e,u){return r=!!t(n,e,u)}),r}function st(n,t,r,e){var u=e,o=u;return zu(n,function(n,i,f){i=+t(n,i,f),(r(i,u)||i===e&&i===o)&&(u=i,o=n)}),o}function pt(n,t){var r=[];return zu(n,function(n,e,u){t(n,e,u)&&r.push(n)}),r}function ht(n,t,r,e){var u;return r(n,function(n,r,o){return t(n,r,o)?(u=e?r:n,!1):void 0}),u}function _t(n,t,r,e){e||(e=[]);for(var u=-1,o=n.length;++u<o;){var i=n[u];h(i)&&Sr(i)&&(r||Wo(i)||_e(i))?t?_t(i,t,r,e):Hn(e,i):r||(e[e.length]=i)}return e}function vt(n,t){return Du(n,t,Ee)}function gt(n,t){return Du(n,t,Ko)}function yt(n,t){return Mu(n,t,Ko)}function dt(n,t){for(var r=-1,e=t.length,u=-1,o=[];++r<e;){var i=t[r];ye(n[i])&&(o[++u]=i)}return o}function wt(n,t,r){if(null!=n){n=Dr(n),r!==x&&r in n&&(t=[r]),r=0;for(var e=t.length;null!=n&&r<e;)n=Dr(n)[t[r++]];return r&&r==e?n:x}}function xt(n,t,r,e,u,o){if(n===t)return!0;if(null==n||null==t||!de(n)&&!h(t))return n!==n&&t!==t;n:{var i=xt,f=Wo(n),c=Wo(t),a=B,l=B;f||(a=ou.call(n),a==z?a=Z:a!=Z&&(f=je(n))),c||(l=ou.call(t),l==z?l=Z:l!=Z&&je(t));var s=a==Z&&!Gn(n),c=l==Z&&!Gn(t),l=a==l;if(!l||f||s){if(!e&&(a=s&&eu.call(n,"__wrapped__"),c=c&&eu.call(t,"__wrapped__"),a||c)){n=i(a?n.value():n,c?t.value():t,r,e,u,o);break n}if(l){for(u||(u=[]),o||(o=[]),a=u.length;a--;)if(u[a]==n){n=o[a]==t;break n}u.push(n),o.push(t),n=(f?wr:br)(n,t,i,r,e,u,o),u.pop(),o.pop()}else n=!1}else n=xr(n,t,a)}return n}function bt(n,t,r){var e=t.length,u=e,o=!r;if(null==n)return!u;for(n=Dr(n);e--;){var i=t[e];if(o&&i[2]?i[1]!==n[i[0]]:!(i[0]in n))return!1}for(;++e<u;){var i=t[e],f=i[0],c=n[f],a=i[1];if(o&&i[2]){if(c===x&&!(f in n))return!1}else if(i=r?r(c,a,f):x,i===x?!xt(a,c,r,!0):!i)return!1}return!0}function mt(n,t){var r=-1,e=Sr(n)?De(n.length):[];return zu(n,function(n,u,o){e[++r]=t(n,u,o)}),e}function At(n){var t=kr(n);if(1==t.length&&t[0][2]){var r=t[0][0],e=t[0][1];return function(n){return null!=n&&(n=Dr(n),n[r]===e&&(e!==x||r in n))}}return function(n){return bt(n,t)}}function jt(n,t){var r=Wo(n),e=Wr(n)&&t===t&&!de(t),u=n+"";return n=Mr(n),function(o){if(null==o)return!1;var i=u;if(o=Dr(o),!(!r&&e||i in o)){if(o=1==n.length?o:wt(o,St(n,0,-1)),null==o)return!1;i=Gr(n),o=Dr(o)}return o[i]===t?t!==x||i in o:xt(t,o[i],x,!0)}}function kt(n,t,r,e,u){if(!de(n))return n;var o=Sr(t)&&(Wo(t)||je(t)),i=o?x:Ko(t);return Kn(i||t,function(f,c){if(i&&(c=f,f=t[c]),h(f)){e||(e=[]),u||(u=[]);n:{for(var a=c,l=e,s=u,p=l.length,_=t[a];p--;)if(l[p]==_){n[a]=s[p];break n}var p=n[a],v=r?r(p,_,a,n,t):x,g=v===x;g&&(v=_,Sr(_)&&(Wo(_)||je(_))?v=Wo(p)?p:Sr(p)?qn(p):[]:be(_)||_e(_)?v=_e(p)?Ie(p):be(p)?p:{}:g=!1),l.push(_),s.push(v),g?n[a]=kt(v,_,r,l,s):(v===v?v!==p:p===p)&&(n[a]=v)}}else a=n[c],l=r?r(a,f,c,n,t):x,(s=l===x)&&(l=f),l===x&&(!o||c in n)||!s&&(l===l?l===a:a!==a)||(n[c]=l)}),n}function Ot(n){return function(t){return null==t?x:Dr(t)[n]}}function It(n){var t=n+"";return n=Mr(n),function(r){return wt(r,n,t)}}function Rt(n,t){for(var r=n?t.length:0;r--;){var e=t[r];if(e!=u&&Ur(e)){var u=e;vu.call(n,e,1)}}return n}function Et(n,t){return n+xu(Ru()*(t-n+1))}function Ct(n,t,r,e,u){return u(n,function(n,u,o){r=e?(e=!1,n):t(r,n,u,o)}),r}function St(n,t,r){var e=-1,u=n.length;for(t=null==t?0:+t||0,0>t&&(t=-t>u?0:u+t),r=r===x||r>u?u:+r||0,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,r=De(u);++e<u;)r[e]=n[e+t];return r}function Ut(n,t){var r;return zu(n,function(n,e,u){return r=t(n,e,u),!r}),!!r}function $t(n,t){var r=n.length;for(n.sort(t);r--;)n[r]=n[r].c;return n}function Wt(t,r,e){var u=mr(),o=-1;return r=Xn(r,function(n){return u(n)}),t=mt(t,function(n){return{a:Xn(r,function(t){return t(n)}),b:++o,c:n}}),$t(t,function(t,r){var u;n:{for(var o=-1,i=t.a,f=r.a,c=i.length,a=e.length;++o<c;)if(u=n(i[o],f[o])){if(o>=a)break n;o=e[o],u*="asc"===o||!0===o?1:-1;break n}u=t.b-r.b}return u})}function Ft(n,t){var r=0;return zu(n,function(n,e,u){r+=+t(n,e,u)||0}),r}function Lt(n,t){var e=-1,u=jr(),o=n.length,i=u===r,f=i&&o>=F,c=f&&wu&&hu?new Dn((void 0)):null,a=[];c?(u=Mn,i=!1):(f=!1,c=t?[]:a);n:for(;++e<o;){var l=n[e],s=t?t(l,e,n):l;if(i&&l===l){for(var p=c.length;p--;)if(c[p]===s)continue n;t&&c.push(s),a.push(l)}else 0>u(c,s,0)&&((t||f)&&c.push(s),a.push(l))}return a}function Nt(n,t){for(var r=-1,e=t.length,u=De(e);++r<e;)u[r]=n[t[r]];return u}function Tt(n,t,r,e){for(var u=n.length,o=e?u:-1;(e?o--:++o<u)&&t(n[o],o,n););return r?St(n,e?0:o,e?o+1:u):St(n,e?o+1:0,e?u:o)}function Pt(n,t){var r=n;r instanceof zn&&(r=r.value());for(var e=-1,u=t.length;++e<u;)var o=t[e],r=o.func.apply(o.thisArg,Hn([r],o.args));return r}function zt(n,t,r){var e=0,u=n?n.length:e;if("number"==typeof t&&t===t&&u<=Uu){for(;e<u;){var o=e+u>>>1,i=n[o];(r?i<=t:i<t)&&null!==i?e=o+1:u=o}return u}return Bt(n,t,Ne,r)}function Bt(n,t,r,e){t=r(t);for(var u=0,o=n?n.length:0,i=t!==t,f=null===t,c=t===x;u<o;){var a=xu((u+o)/2),l=r(n[a]),s=l!==x,p=l===l;(i?p||e:f?p&&s&&(e||null!=l):c?p&&(e||s):null==l?0:e?l<=t:l<t)?u=a+1:o=a}return ku(o,Su)}function Dt(n,t,r){if("function"!=typeof n)return Ne;if(t===x)return n;switch(r){case 1:return function(r){return n.call(t,r)};case 3:return function(r,e,u){return n.call(t,r,e,u)};case 4:return function(r,e,u,o){return n.call(t,r,e,u,o)};case 5:return function(r,e,u,o,i){return n.call(t,r,e,u,o,i)}}return function(){return n.apply(t,arguments)}}function Mt(n){var t=new cu(n.byteLength);return new gu(t).set(new gu(n)),t}function qt(n,t,r){for(var e=r.length,u=-1,o=ju(n.length-e,0),i=-1,f=t.length,c=De(f+o);++i<f;)c[i]=t[i];for(;++u<e;)c[r[u]]=n[u];for(;o--;)c[i++]=n[u++];return c}function Kt(n,t,r){for(var e=-1,u=r.length,o=-1,i=ju(n.length-u,0),f=-1,c=t.length,a=De(i+c);++o<i;)a[o]=n[o];for(i=o;++f<c;)a[i+f]=t[f];for(;++e<u;)a[i+r[e]]=n[o++];return a}function Vt(n,t){return function(r,e,u){var o=t?t():{};if(e=mr(e,u,3),Wo(r)){u=-1;for(var i=r.length;++u<i;){var f=r[u];n(o,f,e(f,u,r),r)}}else zu(r,function(t,r,u){n(o,t,e(t,r,u),u)});return o}}function Zt(n){return pe(function(t,r){var e=-1,u=null==t?0:r.length,o=2<u?r[u-2]:x,i=2<u?r[2]:x,f=1<u?r[u-1]:x;for("function"==typeof o?(o=Dt(o,f,5),u-=2):(o="function"==typeof f?f:x,u-=o?1:0),i&&$r(r[0],r[1],i)&&(o=3>u?x:o,u=1);++e<u;)(i=r[e])&&n(t,i,o);return t})}function Yt(n,t){return function(r,e){var u=r?Vu(r):0;if(!Lr(u))return n(r,e);for(var o=t?u:-1,i=Dr(r);(t?o--:++o<u)&&!1!==e(i[o],o,i););return r}}function Gt(n){return function(t,r,e){var u=Dr(t);e=e(t);for(var o=e.length,i=n?o:-1;n?i--:++i<o;){var f=e[i];if(!1===r(u[f],f,u))break}return t}}function Jt(n,t){function r(){return(this&&this!==Yn&&this instanceof r?e:n).apply(t,arguments)}var e=Ht(n);return r}function Xt(n){return function(t){var r=-1;t=Fe(Ue(t));for(var e=t.length,u="";++r<e;)u=n(u,t[r],r);return u}}function Ht(n){return function(){var t=arguments;switch(t.length){case 0:return new n;case 1:return new n(t[0]);case 2:return new n(t[0],t[1]);case 3:return new n(t[0],t[1],t[2]);case 4:return new n(t[0],t[1],t[2],t[3]);case 5:return new n(t[0],t[1],t[2],t[3],t[4]);case 6:return new n(t[0],t[1],t[2],t[3],t[4],t[5]);case 7:return new n(t[0],t[1],t[2],t[3],t[4],t[5],t[6])}var r=Pu(n.prototype),t=n.apply(r,t);return de(t)?t:r}}function Qt(n){function t(r,e,u){return u&&$r(r,e,u)&&(e=x),r=dr(r,n,x,x,x,x,x,e),r.placeholder=t.placeholder,r}return t}function nr(n,t){return pe(function(r){var e=r[0];return null==e?e:(r.push(t),n.apply(x,r))})}function tr(n,t){return function(r,e,u){if(u&&$r(r,e,u)&&(e=x),e=mr(e,u,3),1==e.length){u=r=Wo(r)?r:Br(r);for(var o=e,i=-1,f=u.length,c=t,a=c;++i<f;){var l=u[i],s=+o(l);n(s,c)&&(c=s,a=l)}if(u=a,!r.length||u!==t)return u}return st(r,e,n,t)}}function rr(n,r){return function(e,u,o){return u=mr(u,o,3),Wo(e)?(u=t(e,u,r),-1<u?e[u]:x):ht(e,u,n)}}function er(n){return function(r,e,u){return r&&r.length?(e=mr(e,u,3),t(r,e,n)):-1}}function ur(n){return function(t,r,e){return r=mr(r,e,3),ht(t,r,n,!0)}}function or(n){return function(){for(var t,r=arguments.length,e=n?r:-1,u=0,o=De(r);n?e--:++e<r;){var i=o[u++]=arguments[e];if("function"!=typeof i)throw new Xe(T);!t&&Pn.prototype.thru&&"wrapper"==Ar(i)&&(t=new Pn([],(!0)))}for(e=t?-1:r;++e<r;){var i=o[e],u=Ar(i),f="wrapper"==u?Ku(i):x;t=f&&Fr(f[0])&&f[1]==(E|k|I|C)&&!f[4].length&&1==f[9]?t[Ar(f[0])].apply(t,f[3]):1==i.length&&Fr(i)?t[u]():t.thru(i)}return function(){var n=arguments,e=n[0];if(t&&1==n.length&&Wo(e)&&e.length>=F)return t.plant(e).value();for(var u=0,n=r?o[u].apply(this,n):e;++u<r;)n=o[u].call(this,n);return n}}}function ir(n,t){return function(r,e,u){return"function"==typeof e&&u===x&&Wo(r)?n(r,e):t(r,Dt(e,u,3))}}function fr(n){return function(t,r,e){return("function"!=typeof r||e!==x)&&(r=Dt(r,e,3)),n(t,r,Ee)}}function cr(n){return function(t,r,e){return("function"!=typeof r||e!==x)&&(r=Dt(r,e,3)),n(t,r)}}function ar(n){return function(t,r,e){var u={};return r=mr(r,e,3),gt(t,function(t,e,o){o=r(t,e,o),e=n?o:e,t=n?t:o,u[e]=t}),u}}function lr(n){return function(t,r,e){return t=u(t),(n?t:"")+_r(t,r,e)+(n?"":t)}}function sr(n){var t=pe(function(r,e){var u=v(e,t.placeholder);return dr(r,n,x,e,u)});return t}function pr(n,t){return function(r,e,u,o){var i=3>arguments.length;return"function"==typeof e&&o===x&&Wo(r)?n(r,e,u,i):Ct(r,mr(e,o,4),u,i,t)}}function hr(n,t,r,e,u,o,i,f,c,a){function l(){for(var w=arguments.length,b=w,j=De(w);b--;)j[b]=arguments[b];if(e&&(j=qt(j,e,u)),o&&(j=Kt(j,o,i)),_||y){var b=l.placeholder,k=v(j,b),w=w-k.length;if(w<a){var O=f?qn(f):x,w=ju(a-w,0),E=_?k:x,k=_?x:k,C=_?j:x,j=_?x:j;return t|=_?I:R,t&=~(_?R:I),g||(t&=~(m|A)),j=[n,t,r,C,E,j,k,O,c,w],O=hr.apply(x,j),Fr(n)&&Zu(O,j),O.placeholder=b,O}}if(b=p?r:this,O=h?b[n]:n,f)for(w=j.length,E=ku(f.length,w),k=qn(j);E--;)C=f[E],j[E]=Ur(C,w)?k[C]:x;return s&&c<j.length&&(j.length=c),this&&this!==Yn&&this instanceof l&&(O=d||Ht(n)),O.apply(b,j)}var s=t&E,p=t&m,h=t&A,_=t&k,g=t&j,y=t&O,d=h?x:Ht(n);return l}function _r(n,t,r){return n=n.length,t=+t,n<t&&mu(t)?(t-=n,r=null==r?" ":r+"",$e(r,du(t/r.length)).slice(0,t)):""}function vr(n,t,r,e){function u(){for(var t=-1,f=arguments.length,c=-1,a=e.length,l=De(a+f);++c<a;)l[c]=e[c];for(;f--;)l[c++]=arguments[++t];return(this&&this!==Yn&&this instanceof u?i:n).apply(o?r:this,l)}var o=t&m,i=Ht(n);return u}function gr(n){var t=Ve[n];return function(n,r){return(r=r===x?0:+r||0)?(r=su(10,r),t(n*r)/r):t(n)}}function yr(n){return function(t,r,e,u){var o=mr(e);return null==e&&o===it?zt(t,r,n):Bt(t,r,o(e,u,1),n)}}function dr(n,t,r,e,u,o,i,f){var c=t&A;if(!c&&"function"!=typeof n)throw new Xe(T);var a=e?e.length:0;if(a||(t&=~(I|R),e=u=x),a-=u?u.length:0,t&R){var l=e,s=u;e=u=x}var p=c?x:Ku(n);return r=[n,t,r,e,u,l,s,o,i,f],p&&(e=r[1],t=p[1],f=e|t,u=t==E&&e==k||t==E&&e==C&&r[7].length<=p[8]||t==(E|C)&&e==k,(f<E||u)&&(t&m&&(r[2]=p[2],f|=e&m?0:j),(e=p[3])&&(u=r[3],r[3]=u?qt(u,e,p[4]):qn(e),r[4]=u?v(r[3],P):qn(p[4])),(e=p[5])&&(u=r[5],r[5]=u?Kt(u,e,p[6]):qn(e),r[6]=u?v(r[5],P):qn(p[6])),(e=p[7])&&(r[7]=qn(e)),t&E&&(r[8]=null==r[8]?p[8]:ku(r[8],p[8])),null==r[9]&&(r[9]=p[9]),r[0]=p[0],r[1]=f),t=r[1],f=r[9]),r[9]=null==f?c?0:n.length:ju(f-a,0)||0,n=t==m?Jt(r[0],r[2]):t!=I&&t!=(m|I)||r[4].length?hr.apply(x,r):vr.apply(x,r),(p?qu:Zu)(n,r)}function wr(n,t,r,e,u,o,i){var f=-1,c=n.length,a=t.length;if(c!=a&&(!u||a<=c))return!1;for(;++f<c;){var l=n[f],a=t[f],s=e?e(u?a:l,u?l:a,f):x;if(s!==x){if(s)continue;return!1}if(u){if(!nt(t,function(n){return l===n||r(l,n,e,u,o,i)}))return!1}else if(l!==a&&!r(l,a,e,u,o,i))return!1}return!0}function xr(n,t,r){switch(r){case D:case M:return+n==+t;case q:return n.name==t.name&&n.message==t.message;case V:return n!=+n?t!=+t:n==+t;case Y:case G:return n==t+""}return!1}function br(n,t,r,e,u,o,i){var f=Ko(n),c=f.length,a=Ko(t).length;if(c!=a&&!u)return!1;for(a=c;a--;){var l=f[a];if(!(u?l in t:eu.call(t,l)))return!1}for(var s=u;++a<c;){var l=f[a],p=n[l],h=t[l],_=e?e(u?h:p,u?p:h,l):x;if(_===x?!r(p,h,e,u,o,i):!_)return!1;s||(s="constructor"==l)}return!(!s&&(r=n.constructor,e=t.constructor,r!=e&&"constructor"in n&&"constructor"in t&&!("function"==typeof r&&r instanceof r&&"function"==typeof e&&e instanceof e)))}function mr(n,t,r){var e=Nn.callback||Le,e=e===Le?it:e;return r?e(n,t,r):e}function Ar(n){for(var t=n.name+"",r=Fu[t],e=r?r.length:0;e--;){var u=r[e],o=u.func;if(null==o||o==n)return u.name}return t}function jr(n,t,e){var u=Nn.indexOf||Yr,u=u===Yr?r:u;return n?u(n,t,e):u}function kr(n){n=Ce(n);for(var t=n.length;t--;){var r,e=n[t];r=n[t][1],r=r===r&&!de(r),e[2]=r}return n}function Or(n,t){var r=null==n?x:n[t];return we(r)?r:x}function Ir(n){var t=n.length,r=new n.constructor(t);return t&&"string"==typeof n[0]&&eu.call(n,"index")&&(r.index=n.index,r.input=n.input),r}function Rr(n){return n=n.constructor,"function"==typeof n&&n instanceof n||(n=Ye),new n}function Er(n,t,r){var e=n.constructor;switch(t){case J:return Mt(n);case D:case M:return new e((+n));case X:case H:case Q:case nn:case tn:case rn:case en:case un:case on:return e instanceof e&&(e=Lu[t]),t=n.buffer,new e(r?Mt(t):t,n.byteOffset,n.length);case V:case G:return new e(n);case Y:var u=new e(n.source,kn.exec(n));u.lastIndex=n.lastIndex}return u}function Cr(n,t,r){return null==n||Wr(t,n)||(t=Mr(t),n=1==t.length?n:wt(n,St(t,0,-1)),t=Gr(t)),t=null==n?n:n[t],null==t?x:t.apply(n,r)}function Sr(n){return null!=n&&Lr(Vu(n))}function Ur(n,t){return n="number"==typeof n||Rn.test(n)?+n:-1,t=null==t?$u:t,-1<n&&0==n%1&&n<t}function $r(n,t,r){if(!de(r))return!1;var e=typeof t;return!!("number"==e?Sr(r)&&Ur(t,r.length):"string"==e&&t in r)&&(t=r[t],n===n?n===t:t!==t)}function Wr(n,t){var r=typeof n;return!!("string"==r&&dn.test(n)||"number"==r)||!Wo(n)&&(!yn.test(n)||null!=t&&n in Dr(t))}function Fr(n){var t=Ar(n),r=Nn[t];return"function"==typeof r&&t in zn.prototype&&(n===r||(t=Ku(r),!!t&&n===t[0]))}function Lr(n){return"number"==typeof n&&-1<n&&0==n%1&&n<=$u}function Nr(n,t){return n===x?t:Fo(n,t,Nr)}function Tr(n,t){n=Dr(n);for(var r=-1,e=t.length,u={};++r<e;){var o=t[r];o in n&&(u[o]=n[o])}return u}function Pr(n,t){var r={};return vt(n,function(n,e,u){t(n,e,u)&&(r[e]=n)}),r}function zr(n){for(var t=Ee(n),r=t.length,e=r&&n.length,u=!!e&&Lr(e)&&(Wo(n)||_e(n)||Ae(n)),o=-1,i=[];++o<r;){var f=t[o];(u&&Ur(f,e)||eu.call(n,f))&&i.push(f)}return i}function Br(n){return null==n?[]:Sr(n)?Nn.support.unindexedChars&&Ae(n)?n.split(""):de(n)?n:Ye(n):Se(n)}function Dr(n){if(Nn.support.unindexedChars&&Ae(n)){for(var t=-1,r=n.length,e=Ye(n);++t<r;)e[t]=n.charAt(t);return e}return de(n)?n:Ye(n)}function Mr(n){if(Wo(n))return n;var t=[];return u(n).replace(wn,function(n,r,e,u){t.push(e?u.replace(An,"$1"):r||n)}),t}function qr(n){return n instanceof zn?n.clone():new Pn(n.__wrapped__,n.__chain__,qn(n.__actions__))}function Kr(n,t,r){return n&&n.length?((r?$r(n,t,r):null==t)&&(t=1),St(n,0>t?0:t)):[]}function Vr(n,t,r){var e=n?n.length:0;return e?((r?$r(n,t,r):null==t)&&(t=1),t=e-(+t||0),St(n,0,0>t?0:t)):[]}function Zr(n){return n?n[0]:x}function Yr(n,t,e){var u=n?n.length:0;if(!u)return-1;if("number"==typeof e)e=0>e?ju(u+e,0):e;else if(e)return e=zt(n,t),e<u&&(t===t?t===n[e]:n[e]!==n[e])?e:-1;return r(n,t,e||0)}function Gr(n){var t=n?n.length:0;return t?n[t-1]:x}function Jr(n){return Kr(n,1)}function Xr(n,t,e,u){if(!n||!n.length)return[];null!=t&&"boolean"!=typeof t&&(u=e,e=$r(n,t,u)?x:t,t=!1);var o=mr();if((null!=e||o!==it)&&(e=o(e,u,3)),t&&jr()===r){t=e;var i;e=-1,u=n.length;for(var o=-1,f=[];++e<u;){var c=n[e],a=t?t(c,e,n):c;e&&i===a||(i=a,f[++o]=c)}n=f}else n=Lt(n,e);return n}function Hr(n){if(!n||!n.length)return[];var t=-1,r=0;n=Zn(n,function(n){return Sr(n)?(r=ju(n.length,r),!0):void 0});for(var e=De(r);++t<r;)e[t]=Xn(n,Ot(t));return e}function Qr(n,t,r){return n&&n.length?(n=Hr(n),null==t?n:(t=Dt(t,r,4),Xn(n,function(n){return Qn(n,t,x,!0)}))):[]}function ne(n,t){var r=-1,e=n?n.length:0,u={};for(!e||t||Wo(n[0])||(t=[]);++r<e;){var o=n[r];t?u[o]=t[r]:o&&(u[o[0]]=o[1])}return u}function te(n){return n=Nn(n),n.__chain__=!0,n}function re(n,t,r){return t.call(r,n)}function ee(n,t,r){var e=Wo(n)?Vn:lt;return r&&$r(n,t,r)&&(t=x),("function"!=typeof t||r!==x)&&(t=mr(t,r,3)),e(n,t)}function ue(n,t,r){var e=Wo(n)?Zn:pt;return t=mr(t,r,3),e(n,t)}function oe(n,t,r,e){var u=n?Vu(n):0;return Lr(u)||(n=Se(n),u=n.length),r="number"!=typeof r||e&&$r(t,r,e)?0:0>r?ju(u+r,0):r||0,"string"==typeof n||!Wo(n)&&Ae(n)?r<=u&&-1<n.indexOf(t,r):!!u&&-1<jr(n,t,r)}function ie(n,t,r){var e=Wo(n)?Xn:mt;return t=mr(t,r,3),e(n,t)}function fe(n,t,r){if(r?$r(n,t,r):null==t){n=Br(n);var e=n.length;return 0<e?n[Et(0,e-1)]:x}r=-1,n=Oe(n);var e=n.length,u=e-1;for(t=ku(0>t?0:+t||0,e);++r<t;){var e=Et(r,u),o=n[e];n[e]=n[r],n[r]=o}return n.length=t,n}function ce(n,t,r){var e=Wo(n)?nt:Ut;return r&&$r(n,t,r)&&(t=x),("function"!=typeof t||r!==x)&&(t=mr(t,r,3)),e(n,t)}function ae(n,t){var r;if("function"!=typeof t){if("function"!=typeof n)throw new Xe(T);var e=n;n=t,t=e}return function(){return 0<--n&&(r=t.apply(this,arguments)),1>=n&&(t=x),r}}function le(n,t,r){function e(t,r){r&&au(r),c=p=h=x,t&&(_=xo(),a=n.apply(s,f),p||c||(f=s=x))}function u(){var n=t-(xo()-l);0>=n||n>t?e(h,c):p=_u(u,n)}function o(){e(g,p)}function i(){if(f=arguments,l=xo(),s=this,h=g&&(p||!y),!1===v)var r=y&&!p;else{c||y||(_=l);var e=v-(l-_),i=0>=e||e>v;i?(c&&(c=au(c)),_=l,a=n.apply(s,f)):c||(c=_u(o,e))}return i&&p?p=au(p):p||t===v||(p=_u(u,t)),r&&(i=!0,a=n.apply(s,f)),!i||p||c||(f=s=x),a}var f,c,a,l,s,p,h,_=0,v=!1,g=!0;if("function"!=typeof n)throw new Xe(T);if(t=0>t?0:+t||0,!0===r)var y=!0,g=!1;else de(r)&&(y=!!r.leading,v="maxWait"in r&&ju(+r.maxWait||0,t),g="trailing"in r?!!r.trailing:g);return i.cancel=function(){p&&au(p),c&&au(c),_=0,c=p=h=x},i}function se(n,t){if("function"!=typeof n||t&&"function"!=typeof t)throw new Xe(T);var r=function(){var e=arguments,u=t?t.apply(this,e):e[0],o=r.cache;return o.has(u)?o.get(u):(e=n.apply(this,e),r.cache=o.set(u,e),e)};return r.cache=new se.Cache,r}function pe(n,t){if("function"!=typeof n)throw new Xe(T);return t=ju(t===x?n.length-1:+t||0,0),function(){for(var r=arguments,e=-1,u=ju(r.length-t,0),o=De(u);++e<u;)o[e]=r[t+e];switch(t){case 0:return n.call(this,o);case 1:return n.call(this,r[0],o);case 2:return n.call(this,r[0],r[1],o)}for(u=De(t+1),e=-1;++e<t;)u[e]=r[e];return u[t]=o,n.apply(this,u)}}function he(n,t){return n>t}function _e(n){return h(n)&&Sr(n)&&eu.call(n,"callee")&&!pu.call(n,"callee")}function ve(n,t,r,e){return e=(r="function"==typeof r?Dt(r,e,3):x)?r(n,t):x,e===x?xt(n,t,r):!!e}function ge(n){return h(n)&&"string"==typeof n.message&&ou.call(n)==q}function ye(n){return de(n)&&ou.call(n)==K}function de(n){var t=typeof n;return!!n&&("object"==t||"function"==t)}function we(n){return null!=n&&(ye(n)?fu.test(ru.call(n)):h(n)&&(Gn(n)?fu:In).test(n))}function xe(n){return"number"==typeof n||h(n)&&ou.call(n)==V}function be(n){var t;if(!h(n)||ou.call(n)!=Z||Gn(n)||_e(n)||!(eu.call(n,"constructor")||(t=n.constructor,"function"!=typeof t||t instanceof t)))return!1;var r;return Nn.support.ownLast?(vt(n,function(n,t,e){return r=eu.call(e,t),!1}),!1!==r):(vt(n,function(n,t){r=t}),r===x||eu.call(n,r))}function me(n){return de(n)&&ou.call(n)==Y}function Ae(n){return"string"==typeof n||h(n)&&ou.call(n)==G}function je(n){return h(n)&&Lr(n.length)&&!!Fn[ou.call(n)]}function ke(n,t){return n<t}function Oe(n){var t=n?Vu(n):0;return Lr(t)?t?Nn.support.unindexedChars&&Ae(n)?n.split(""):qn(n):[]:Se(n)}function Ie(n){return ot(n,Ee(n))}function Re(n){return dt(n,Ee(n))}function Ee(n){if(null==n)return[];de(n)||(n=Ye(n));for(var t=n.length,r=Nn.support,t=t&&Lr(t)&&(Wo(n)||_e(n)||Ae(n))&&t||0,e=n.constructor,u=-1,e=ye(e)&&e.prototype||nu,o=e===n,i=De(t),f=0<t,c=r.enumErrorProps&&(n===Qe||n instanceof qe),a=r.enumPrototypes&&ye(n);++u<t;)i[u]=u+"";for(var l in n)a&&"prototype"==l||c&&("message"==l||"name"==l)||f&&Ur(l,t)||"constructor"==l&&(o||!eu.call(n,l))||i.push(l);if(r.nonEnumShadows&&n!==nu)for(t=n===tu?G:n===Qe?q:ou.call(n),r=Nu[t]||Nu[Z],t==Z&&(e=nu),t=Wn.length;t--;)l=Wn[t],u=r[l],o&&u||(u?!eu.call(n,l):n[l]===e[l])||i.push(l);return i}function Ce(n){n=Dr(n);for(var t=-1,r=Ko(n),e=r.length,u=De(e);++t<e;){var o=r[t];u[t]=[o,n[o]]}return u}function Se(n){return Nt(n,Ko(n))}function Ue(n){return(n=u(n))&&n.replace(En,c).replace(mn,"")}function $e(n,t){var r="";if(n=u(n),t=+t,1>t||!n||!mu(t))return r;do t%2&&(r+=n),t=xu(t/2),n+=n;while(t);return r}function We(n,t,r){var e=n;return(n=u(n))?(r?$r(e,t,r):null==t)?n.slice(g(n),y(n)+1):(t+="",n.slice(o(n,t),i(n,t)+1)):n}function Fe(n,t,r){return r&&$r(n,t,r)&&(t=x),n=u(n),n.match(t||Un)||[]}function Le(n,t,r){return r&&$r(n,t,r)&&(t=x),h(n)?Te(n):it(n,t)}function Ne(n){return n}function Te(n){return At(ft(n,!0))}function Pe(n,t,r){if(null==r){var e=de(t),u=e?Ko(t):x;((u=u&&u.length?dt(t,u):x)?u.length:e)||(u=!1,r=t,t=n,n=this)}u||(u=dt(t,Ko(t)));var o=!0,e=-1,i=ye(n),f=u.length;!1===r?o=!1:de(r)&&"chain"in r&&(o=r.chain);for(;++e<f;){r=u[e];var c=t[r];n[r]=c,i&&(n.prototype[r]=function(t){return function(){var r=this.__chain__;if(o||r){var e=n(this.__wrapped__);return(e.__actions__=qn(this.__actions__)).push({func:t,args:arguments,thisArg:n}),e.__chain__=r,e}return t.apply(n,Hn([this.value()],arguments))}}(c))}return n}function ze(){}function Be(n){return Wr(n)?Ot(n):It(n)}_=_?Jn.defaults(Yn.Object(),_,Jn.pick(Yn,$n)):Yn;var De=_.Array,Me=_.Date,qe=_.Error,Ke=_.Function,Ve=_.Math,Ze=_.Number,Ye=_.Object,Ge=_.RegExp,Je=_.String,Xe=_.TypeError,He=De.prototype,Qe=qe.prototype,nu=Ye.prototype,tu=Je.prototype,ru=Ke.prototype.toString,eu=nu.hasOwnProperty,uu=0,ou=nu.toString,iu=Yn._,fu=Ge("^"+ru.call(eu).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),cu=_.ArrayBuffer,au=_.clearTimeout,lu=_.parseFloat,su=Ve.pow,pu=nu.propertyIsEnumerable,hu=Or(_,"Set"),_u=_.setTimeout,vu=He.splice,gu=_.Uint8Array,yu=Or(_,"WeakMap"),du=Ve.ceil,wu=Or(Ye,"create"),xu=Ve.floor,bu=Or(De,"isArray"),mu=_.isFinite,Au=Or(Ye,"keys"),ju=Ve.max,ku=Ve.min,Ou=Or(Me,"now"),Iu=_.parseInt,Ru=Ve.random,Eu=Ze.NEGATIVE_INFINITY,Cu=Ze.POSITIVE_INFINITY,Su=4294967294,Uu=2147483647,$u=9007199254740991,Wu=yu&&new yu,Fu={},Lu={};Lu[X]=_.Float32Array,Lu[H]=_.Float64Array,Lu[Q]=_.Int8Array,Lu[nn]=_.Int16Array,Lu[tn]=_.Int32Array,Lu[rn]=gu,Lu[en]=_.Uint8ClampedArray,Lu[un]=_.Uint16Array,Lu[on]=_.Uint32Array;var Nu={};Nu[B]=Nu[M]=Nu[V]={constructor:!0,toLocaleString:!0,toString:!0,valueOf:!0},Nu[D]=Nu[G]={constructor:!0,toString:!0,valueOf:!0},Nu[q]=Nu[K]=Nu[Y]={constructor:!0,toString:!0},Nu[Z]={constructor:!0},Kn(Wn,function(n){for(var t in Nu)if(eu.call(Nu,t)){var r=Nu[t];r[n]=eu.call(r,n)}});var Tu=Nn.support={};!function(n){var t=function(){this.x=n},r={0:n,length:n},e=[];t.prototype={valueOf:n,y:n};for(var u in new t)e.push(u);Tu.enumErrorProps=pu.call(Qe,"message")||pu.call(Qe,"name"),Tu.enumPrototypes=pu.call(t,"prototype"),Tu.nonEnumShadows=!/valueOf/.test(e),Tu.ownLast="x"!=e[0],Tu.spliceObjects=(vu.call(r,0,1),!r[0]),Tu.unindexedChars="xx"!="x"[0]+Ye("x")[0]}(1,0),Nn.templateSettings={escape:_n,evaluate:vn,interpolate:gn,variable:"",imports:{_:Nn}};var Pu=function(){function n(){}return function(t){if(de(t)){n.prototype=t;var r=new n;n.prototype=x}return r||{}}}(),zu=Yt(gt),Bu=Yt(yt,!0),Du=Gt(),Mu=Gt(!0),qu=Wu?function(n,t){return Wu.set(n,t),n}:Ne,Ku=Wu?function(n){return Wu.get(n)}:ze,Vu=Ot("length"),Zu=function(){var n=0,t=0;return function(r,e){var u=xo(),o=W-(u-t);if(t=u,0<o){if(++n>=$)return r}else n=0;return qu(r,e)}}(),Yu=pe(function(n,t){return h(n)&&Sr(n)?at(n,_t(t,!1,!0)):[]}),Gu=er(),Ju=er(!0),Xu=pe(function(n){for(var t=n.length,e=t,u=De(l),o=jr(),i=o===r,f=[];e--;){var c=n[e]=Sr(c=n[e])?c:[];u[e]=i&&120<=c.length&&wu&&hu?new Dn(e&&c):null}var i=n[0],a=-1,l=i?i.length:0,s=u[0];n:for(;++a<l;)if(c=i[a],0>(s?Mn(s,c):o(f,c,0))){for(e=t;--e;){var p=u[e];if(0>(p?Mn(p,c):o(n[e],c,0)))continue n}s&&s.push(c),f.push(c)}return f}),Hu=pe(function(t,r){r=_t(r);var e=ut(t,r);return Rt(t,r.sort(n)),e}),Qu=yr(),no=yr(!0),to=pe(function(n){return Lt(_t(n,!1,!0))}),ro=pe(function(n,t){return Sr(n)?at(n,t):[]}),eo=pe(Hr),uo=pe(function(n){var t=n.length,r=2<t?n[t-2]:x,e=1<t?n[t-1]:x;return 2<t&&"function"==typeof r?t-=2:(r=1<t&&"function"==typeof e?(--t,e):x,e=x),n.length=t,Qr(n,r,e)}),oo=pe(function(n){return n=_t(n),this.thru(function(t){t=Wo(t)?t:[Dr(t)];for(var r=n,e=-1,u=t.length,o=-1,i=r.length,f=De(u+i);++e<u;)f[e]=t[e];for(;++o<i;)f[e++]=r[o];return f})}),io=pe(function(n,t){return Sr(n)&&(n=Br(n)),ut(n,_t(t))}),fo=Vt(function(n,t,r){eu.call(n,r)?++n[r]:n[r]=1}),co=rr(zu),ao=rr(Bu,!0),lo=ir(Kn,zu),so=ir(function(n,t){for(var r=n.length;r--&&!1!==t(n[r],r,n););return n},Bu),po=Vt(function(n,t,r){eu.call(n,r)?n[r].push(t):n[r]=[t]}),ho=Vt(function(n,t,r){n[r]=t}),_o=pe(function(n,t,r){var e=-1,u="function"==typeof t,o=Wr(t),i=Sr(n)?De(n.length):[];return zu(n,function(n){var f=u?t:o&&null!=n?n[t]:x;i[++e]=f?f.apply(n,r):Cr(n,t,r)}),i}),vo=Vt(function(n,t,r){n[r?0:1].push(t)},function(){return[[],[]]}),go=pr(Qn,zu),yo=pr(function(n,t,r,e){var u=n.length;for(e&&u&&(r=n[--u]);u--;)r=t(r,n[u],u,n);return r},Bu),wo=pe(function(n,t){if(null==n)return[];var r=t[2];return r&&$r(t[0],t[1],r)&&(t.length=1),Wt(n,_t(t),[])}),xo=Ou||function(){return(new Me).getTime()},bo=pe(function(n,t,r){var e=m;if(r.length)var u=v(r,bo.placeholder),e=e|I;return dr(n,e,t,r,u)}),mo=pe(function(n,t){t=t.length?_t(t):Re(n);for(var r=-1,e=t.length;++r<e;){var u=t[r];n[u]=dr(n[u],m,n)}return n}),Ao=pe(function(n,t,r){var e=m|A;if(r.length)var u=v(r,Ao.placeholder),e=e|I;return dr(t,e,n,r,u)}),jo=Qt(k),ko=Qt(O),Oo=pe(function(n,t){return ct(n,1,t)}),Io=pe(function(n,t,r){return ct(n,t,r)}),Ro=or(),Eo=or(!0),Co=pe(function(n,t){if(t=_t(t),"function"!=typeof n||!Vn(t,e))throw new Xe(T);var r=t.length;return pe(function(e){for(var u=ku(e.length,r);u--;)e[u]=t[u](e[u]);return n.apply(this,e)})}),So=sr(I),Uo=sr(R),$o=pe(function(n,t){return dr(n,C,x,x,x,_t(t))}),Wo=bu||function(n){return h(n)&&Lr(n.length)&&ou.call(n)==B},Fo=Zt(kt),Lo=Zt(function(n,t,r){return r?rt(n,t,r):et(n,t)}),No=nr(Lo,function(n,t){return n===x?t:n}),To=nr(Fo,Nr),Po=ur(gt),zo=ur(yt),Bo=fr(Du),Do=fr(Mu),Mo=cr(gt),qo=cr(yt),Ko=Au?function(n){var t=null==n?x:n.constructor;return"function"==typeof t&&t.prototype===n||("function"==typeof n?Nn.support.enumPrototypes:Sr(n))?zr(n):de(n)?Au(n):[]}:zr,Vo=ar(!0),Zo=ar(),Yo=pe(function(n,t){if(null==n)return{};if("function"!=typeof t[0])return t=Xn(_t(t),Je),Tr(n,at(Ee(n),t));var r=Dt(t[0],t[1],3);return Pr(n,function(n,t,e){return!r(n,t,e)})}),Go=pe(function(n,t){return null==n?{}:"function"==typeof t[0]?Pr(n,Dt(t[0],t[1],3)):Tr(n,_t(t))}),Jo=Xt(function(n,t,r){return t=t.toLowerCase(),n+(r?t.charAt(0).toUpperCase()+t.slice(1):t)}),Xo=Xt(function(n,t,r){return n+(r?"-":"")+t.toLowerCase()}),Ho=lr(),Qo=lr(!0),ni=Xt(function(n,t,r){return n+(r?"_":"")+t.toLowerCase()}),ti=Xt(function(n,t,r){return n+(r?" ":"")+(t.charAt(0).toUpperCase()+t.slice(1))}),ri=pe(function(n,t){try{return n.apply(x,t)}catch(r){return ge(r)?r:new qe(r)}}),ei=pe(function(n,t){return function(r){return Cr(r,n,t)}}),ui=pe(function(n,t){return function(r){return Cr(n,r,t)}}),oi=gr("ceil"),ii=gr("floor"),fi=tr(he,Eu),ci=tr(ke,Cu),ai=gr("round");return Nn.prototype=Tn.prototype,Pn.prototype=Pu(Tn.prototype),Pn.prototype.constructor=Pn,zn.prototype=Pu(Tn.prototype),zn.prototype.constructor=zn,Bn.prototype["delete"]=function(n){return this.has(n)&&delete this.__data__[n]},Bn.prototype.get=function(n){return"__proto__"==n?x:this.__data__[n]},Bn.prototype.has=function(n){return"__proto__"!=n&&eu.call(this.__data__,n)},Bn.prototype.set=function(n,t){return"__proto__"!=n&&(this.__data__[n]=t),this},Dn.prototype.push=function(n){var t=this.data;"string"==typeof n||de(n)?t.set.add(n):t.hash[n]=!0},se.Cache=Bn,Nn.after=function(n,t){if("function"!=typeof t){if("function"!=typeof n)throw new Xe(T);var r=n;n=t,t=r}return n=mu(n=+n)?n:0,function(){return 1>--n?t.apply(this,arguments):void 0}},Nn.ary=function(n,t,r){return r&&$r(n,t,r)&&(t=x),t=n&&null==t?n.length:ju(+t||0,0),dr(n,E,x,x,x,x,t)},Nn.assign=Lo,Nn.at=io,Nn.before=ae,Nn.bind=bo,Nn.bindAll=mo,
+Nn.bindKey=Ao,Nn.callback=Le,Nn.chain=te,Nn.chunk=function(n,t,r){t=(r?$r(n,t,r):null==t)?1:ju(xu(t)||1,1),r=0;for(var e=n?n.length:0,u=-1,o=De(du(e/t));r<e;)o[++u]=St(n,r,r+=t);return o},Nn.compact=function(n){for(var t=-1,r=n?n.length:0,e=-1,u=[];++t<r;){var o=n[t];o&&(u[++e]=o)}return u},Nn.constant=function(n){return function(){return n}},Nn.countBy=fo,Nn.create=function(n,t,r){var e=Pu(n);return r&&$r(n,t,r)&&(t=x),t?et(e,t):e},Nn.curry=jo,Nn.curryRight=ko,Nn.debounce=le,Nn.defaults=No,Nn.defaultsDeep=To,Nn.defer=Oo,Nn.delay=Io,Nn.difference=Yu,Nn.drop=Kr,Nn.dropRight=Vr,Nn.dropRightWhile=function(n,t,r){return n&&n.length?Tt(n,mr(t,r,3),!0,!0):[]},Nn.dropWhile=function(n,t,r){return n&&n.length?Tt(n,mr(t,r,3),!0):[]},Nn.fill=function(n,t,r,e){var u=n?n.length:0;if(!u)return[];for(r&&"number"!=typeof r&&$r(n,t,r)&&(r=0,e=u),u=n.length,r=null==r?0:+r||0,0>r&&(r=-r>u?0:u+r),e=e===x||e>u?u:+e||0,0>e&&(e+=u),u=r>e?0:e>>>0,r>>>=0;r<u;)n[r++]=t;return n},Nn.filter=ue,Nn.flatten=function(n,t,r){var e=n?n.length:0;return r&&$r(n,t,r)&&(t=!1),e?_t(n,t):[]},Nn.flattenDeep=function(n){return n&&n.length?_t(n,!0):[]},Nn.flow=Ro,Nn.flowRight=Eo,Nn.forEach=lo,Nn.forEachRight=so,Nn.forIn=Bo,Nn.forInRight=Do,Nn.forOwn=Mo,Nn.forOwnRight=qo,Nn.functions=Re,Nn.groupBy=po,Nn.indexBy=ho,Nn.initial=function(n){return Vr(n,1)},Nn.intersection=Xu,Nn.invert=function(n,t,r){r&&$r(n,t,r)&&(t=x),r=-1;for(var e=Ko(n),u=e.length,o={};++r<u;){var i=e[r],f=n[i];t?eu.call(o,f)?o[f].push(i):o[f]=[i]:o[f]=i}return o},Nn.invoke=_o,Nn.keys=Ko,Nn.keysIn=Ee,Nn.map=ie,Nn.mapKeys=Vo,Nn.mapValues=Zo,Nn.matches=Te,Nn.matchesProperty=function(n,t){return jt(n,ft(t,!0))},Nn.memoize=se,Nn.merge=Fo,Nn.method=ei,Nn.methodOf=ui,Nn.mixin=Pe,Nn.modArgs=Co,Nn.negate=function(n){if("function"!=typeof n)throw new Xe(T);return function(){return!n.apply(this,arguments)}},Nn.omit=Yo,Nn.once=function(n){return ae(2,n)},Nn.pairs=Ce,Nn.partial=So,Nn.partialRight=Uo,Nn.partition=vo,Nn.pick=Go,Nn.pluck=function(n,t){return ie(n,Be(t))},Nn.property=Be,Nn.propertyOf=function(n){return function(t){return wt(n,Mr(t),t+"")}},Nn.pull=function(){var n=arguments,t=n[0];if(!t||!t.length)return t;for(var r=0,e=jr(),u=n.length;++r<u;)for(var o=0,i=n[r];-1<(o=e(t,i,o));)vu.call(t,o,1);return t},Nn.pullAt=Hu,Nn.range=function(n,t,r){r&&$r(n,t,r)&&(t=r=x),n=+n||0,r=null==r?1:+r||0,null==t?(t=n,n=0):t=+t||0;var e=-1;t=ju(du((t-n)/(r||1)),0);for(var u=De(t);++e<t;)u[e]=n,n+=r;return u},Nn.rearg=$o,Nn.reject=function(n,t,r){var e=Wo(n)?Zn:pt;return t=mr(t,r,3),e(n,function(n,r,e){return!t(n,r,e)})},Nn.remove=function(n,t,r){var e=[];if(!n||!n.length)return e;var u=-1,o=[],i=n.length;for(t=mr(t,r,3);++u<i;)r=n[u],t(r,u,n)&&(e.push(r),o.push(u));return Rt(n,o),e},Nn.rest=Jr,Nn.restParam=pe,Nn.set=function(n,t,r){if(null==n)return n;var e=t+"";t=null!=n[e]||Wr(t,n)?[e]:Mr(t);for(var e=-1,u=t.length,o=u-1,i=n;null!=i&&++e<u;){var f=t[e];de(i)&&(e==o?i[f]=r:null==i[f]&&(i[f]=Ur(t[e+1])?[]:{})),i=i[f]}return n},Nn.shuffle=function(n){return fe(n,Cu)},Nn.slice=function(n,t,r){var e=n?n.length:0;return e?(r&&"number"!=typeof r&&$r(n,t,r)&&(t=0,r=e),St(n,t,r)):[]},Nn.sortBy=function(n,t,r){if(null==n)return[];r&&$r(n,t,r)&&(t=x);var e=-1;return t=mr(t,r,3),n=mt(n,function(n,r,u){return{a:t(n,r,u),b:++e,c:n}}),$t(n,f)},Nn.sortByAll=wo,Nn.sortByOrder=function(n,t,r,e){return null==n?[]:(e&&$r(t,r,e)&&(r=x),Wo(t)||(t=null==t?[]:[t]),Wo(r)||(r=null==r?[]:[r]),Wt(n,t,r))},Nn.spread=function(n){if("function"!=typeof n)throw new Xe(T);return function(t){return n.apply(this,t)}},Nn.take=function(n,t,r){return n&&n.length?((r?$r(n,t,r):null==t)&&(t=1),St(n,0,0>t?0:t)):[]},Nn.takeRight=function(n,t,r){var e=n?n.length:0;return e?((r?$r(n,t,r):null==t)&&(t=1),t=e-(+t||0),St(n,0>t?0:t)):[]},Nn.takeRightWhile=function(n,t,r){return n&&n.length?Tt(n,mr(t,r,3),!1,!0):[]},Nn.takeWhile=function(n,t,r){return n&&n.length?Tt(n,mr(t,r,3)):[]},Nn.tap=function(n,t,r){return t.call(r,n),n},Nn.throttle=function(n,t,r){var e=!0,u=!0;if("function"!=typeof n)throw new Xe(T);return!1===r?e=!1:de(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),le(n,t,{leading:e,maxWait:+t,trailing:u})},Nn.thru=re,Nn.times=function(n,t,r){if(n=xu(n),1>n||!mu(n))return[];var e=-1,u=De(ku(n,4294967295));for(t=Dt(t,r,1);++e<n;)4294967295>e?u[e]=t(e):t(e);return u},Nn.toArray=Oe,Nn.toPlainObject=Ie,Nn.transform=function(n,t,r,e){var u=Wo(n)||je(n);return t=mr(t,e,4),null==r&&(u||de(n)?(e=n.constructor,r=u?Wo(n)?new e:[]:Pu(ye(e)?e.prototype:x)):r={}),(u?Kn:gt)(n,function(n,e,u){return t(r,n,e,u)}),r},Nn.union=to,Nn.uniq=Xr,Nn.unzip=Hr,Nn.unzipWith=Qr,Nn.values=Se,Nn.valuesIn=function(n){return Nt(n,Ee(n))},Nn.where=function(n,t){return ue(n,At(t))},Nn.without=ro,Nn.wrap=function(n,t){return t=null==t?Ne:t,dr(t,I,x,[n],[])},Nn.xor=function(){for(var n=-1,t=arguments.length;++n<t;){var r=arguments[n];if(Sr(r))var e=e?Hn(at(e,r),at(r,e)):r}return e?Lt(e):[]},Nn.zip=eo,Nn.zipObject=ne,Nn.zipWith=uo,Nn.backflow=Eo,Nn.collect=ie,Nn.compose=Eo,Nn.each=lo,Nn.eachRight=so,Nn.extend=Lo,Nn.iteratee=Le,Nn.methods=Re,Nn.object=ne,Nn.select=ue,Nn.tail=Jr,Nn.unique=Xr,Pe(Nn,Nn),Nn.add=function(n,t){return(+n||0)+(+t||0)},Nn.attempt=ri,Nn.camelCase=Jo,Nn.capitalize=function(n){return(n=u(n))&&n.charAt(0).toUpperCase()+n.slice(1)},Nn.ceil=oi,Nn.clone=function(n,t,r,e){return t&&"boolean"!=typeof t&&$r(n,t,r)?t=!1:"function"==typeof t&&(e=r,r=t,t=!1),"function"==typeof r?ft(n,t,Dt(r,e,3)):ft(n,t)},Nn.cloneDeep=function(n,t,r){return"function"==typeof t?ft(n,!0,Dt(t,r,3)):ft(n,!0)},Nn.deburr=Ue,Nn.endsWith=function(n,t,r){n=u(n),t+="";var e=n.length;return r=r===x?e:ku(0>r?0:+r||0,e),r-=t.length,0<=r&&n.indexOf(t,r)==r},Nn.escape=function(n){return(n=u(n))&&hn.test(n)?n.replace(sn,a):n},Nn.escapeRegExp=function(n){return(n=u(n))&&bn.test(n)?n.replace(xn,l):n||"(?:)"},Nn.every=ee,Nn.find=co,Nn.findIndex=Gu,Nn.findKey=Po,Nn.findLast=ao,Nn.findLastIndex=Ju,Nn.findLastKey=zo,Nn.findWhere=function(n,t){return co(n,At(t))},Nn.first=Zr,Nn.floor=ii,Nn.get=function(n,t,r){return n=null==n?x:wt(n,Mr(t),t+""),n===x?r:n},Nn.gt=he,Nn.gte=function(n,t){return n>=t},Nn.has=function(n,t){if(null==n)return!1;var r=eu.call(n,t);if(!r&&!Wr(t)){if(t=Mr(t),n=1==t.length?n:wt(n,St(t,0,-1)),null==n)return!1;t=Gr(t),r=eu.call(n,t)}return r||Lr(n.length)&&Ur(t,n.length)&&(Wo(n)||_e(n)||Ae(n))},Nn.identity=Ne,Nn.includes=oe,Nn.indexOf=Yr,Nn.inRange=function(n,t,r){return t=+t||0,r===x?(r=t,t=0):r=+r||0,n>=ku(t,r)&&n<ju(t,r)},Nn.isArguments=_e,Nn.isArray=Wo,Nn.isBoolean=function(n){return!0===n||!1===n||h(n)&&ou.call(n)==D},Nn.isDate=function(n){return h(n)&&ou.call(n)==M},Nn.isElement=function(n){return!!n&&1===n.nodeType&&h(n)&&!be(n)},Nn.isEmpty=function(n){return null==n||(Sr(n)&&(Wo(n)||Ae(n)||_e(n)||h(n)&&ye(n.splice))?!n.length:!Ko(n).length)},Nn.isEqual=ve,Nn.isError=ge,Nn.isFinite=function(n){return"number"==typeof n&&mu(n)},Nn.isFunction=ye,Nn.isMatch=function(n,t,r,e){return r="function"==typeof r?Dt(r,e,3):x,bt(n,kr(t),r)},Nn.isNaN=function(n){return xe(n)&&n!=+n},Nn.isNative=we,Nn.isNull=function(n){return null===n},Nn.isNumber=xe,Nn.isObject=de,Nn.isPlainObject=be,Nn.isRegExp=me,Nn.isString=Ae,Nn.isTypedArray=je,Nn.isUndefined=function(n){return n===x},Nn.kebabCase=Xo,Nn.last=Gr,Nn.lastIndexOf=function(n,t,r){var e=n?n.length:0;if(!e)return-1;var u=e;if("number"==typeof r)u=(0>r?ju(e+r,0):ku(r||0,e-1))+1;else if(r)return u=zt(n,t,!0)-1,n=n[u],(t===t?t===n:n!==n)?u:-1;if(t!==t)return p(n,u,!0);for(;u--;)if(n[u]===t)return u;return-1},Nn.lt=ke,Nn.lte=function(n,t){return n<=t},Nn.max=fi,Nn.min=ci,Nn.noConflict=function(){return Yn._=iu,this},Nn.noop=ze,Nn.now=xo,Nn.pad=function(n,t,r){n=u(n),t=+t;var e=n.length;return e<t&&mu(t)?(e=(t-e)/2,t=xu(e),e=du(e),r=_r("",e,r),r.slice(0,t)+n+r):n},Nn.padLeft=Ho,Nn.padRight=Qo,Nn.parseInt=function(n,t,r){return(r?$r(n,t,r):null==t)?t=0:t&&(t=+t),n=We(n),Iu(n,t||(On.test(n)?16:10))},Nn.random=function(n,t,r){r&&$r(n,t,r)&&(t=r=x);var e=null==n,u=null==t;return null==r&&(u&&"boolean"==typeof n?(r=n,n=1):"boolean"==typeof t&&(r=t,u=!0)),e&&u&&(t=1,u=!1),n=+n||0,u?(t=n,n=0):t=+t||0,r||n%1||t%1?(r=Ru(),ku(n+r*(t-n+lu("1e-"+((r+"").length-1))),t)):Et(n,t)},Nn.reduce=go,Nn.reduceRight=yo,Nn.repeat=$e,Nn.result=function(n,t,r){var e=null==n?x:Dr(n)[t];return e===x&&(null==n||Wr(t,n)||(t=Mr(t),n=1==t.length?n:wt(n,St(t,0,-1)),e=null==n?x:Dr(n)[Gr(t)]),e=e===x?r:e),ye(e)?e.call(n):e},Nn.round=ai,Nn.runInContext=w,Nn.size=function(n){var t=n?Vu(n):0;return Lr(t)?t:Ko(n).length},Nn.snakeCase=ni,Nn.some=ce,Nn.sortedIndex=Qu,Nn.sortedLastIndex=no,Nn.startCase=ti,Nn.startsWith=function(n,t,r){return n=u(n),r=null==r?0:ku(0>r?0:+r||0,n.length),n.lastIndexOf(t,r)==r},Nn.sum=function(n,t,r){if(r&&$r(n,t,r)&&(t=x),t=mr(t,r,3),1==t.length){n=Wo(n)?n:Br(n),r=n.length;for(var e=0;r--;)e+=+t(n[r])||0;n=e}else n=Ft(n,t);return n},Nn.template=function(n,t,r){var e=Nn.templateSettings;r&&$r(n,t,r)&&(t=r=x),n=u(n),t=rt(et({},r||t),e,tt),r=rt(et({},t.imports),e.imports,tt);var o,i,f=Ko(r),c=Nt(r,f),a=0;r=t.interpolate||Cn;var l="__p+='";r=Ge((t.escape||Cn).source+"|"+r.source+"|"+(r===gn?jn:Cn).source+"|"+(t.evaluate||Cn).source+"|$","g");var p="sourceURL"in t?"//# sourceURL="+t.sourceURL+"\n":"";if(n.replace(r,function(t,r,e,u,f,c){return e||(e=u),l+=n.slice(a,c).replace(Sn,s),r&&(o=!0,l+="'+__e("+r+")+'"),f&&(i=!0,l+="';"+f+";\n__p+='"),e&&(l+="'+((__t=("+e+"))==null?'':__t)+'"),a=c+t.length,t}),l+="';",(t=t.variable)||(l="with(obj){"+l+"}"),l=(i?l.replace(fn,""):l).replace(cn,"$1").replace(an,"$1;"),l="function("+(t||"obj")+"){"+(t?"":"obj||(obj={});")+"var __t,__p=''"+(o?",__e=_.escape":"")+(i?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+l+"return __p}",t=ri(function(){return Ke(f,p+"return "+l).apply(x,c)}),t.source=l,ge(t))throw t;return t},Nn.trim=We,Nn.trimLeft=function(n,t,r){var e=n;return(n=u(n))?n.slice((r?$r(e,t,r):null==t)?g(n):o(n,t+"")):n},Nn.trimRight=function(n,t,r){var e=n;return(n=u(n))?(r?$r(e,t,r):null==t)?n.slice(0,y(n)+1):n.slice(0,i(n,t+"")+1):n},Nn.trunc=function(n,t,r){r&&$r(n,t,r)&&(t=x);var e=S;if(r=U,null!=t)if(de(t)){var o="separator"in t?t.separator:o,e="length"in t?+t.length||0:e;r="omission"in t?u(t.omission):r}else e=+t||0;if(n=u(n),e>=n.length)return n;if(e-=r.length,1>e)return r;if(t=n.slice(0,e),null==o)return t+r;if(me(o)){if(n.slice(e).search(o)){var i,f=n.slice(0,e);for(o.global||(o=Ge(o.source,(kn.exec(o)||"")+"g")),o.lastIndex=0;n=o.exec(f);)i=n.index;t=t.slice(0,null==i?e:i)}}else n.indexOf(o,e)!=e&&(o=t.lastIndexOf(o),-1<o&&(t=t.slice(0,o)));return t+r},Nn.unescape=function(n){return(n=u(n))&&pn.test(n)?n.replace(ln,d):n},Nn.uniqueId=function(n){var t=++uu;return u(n)+t},Nn.words=Fe,Nn.all=ee,Nn.any=ce,Nn.contains=oe,Nn.eq=ve,Nn.detect=co,Nn.foldl=go,Nn.foldr=yo,Nn.head=Zr,Nn.include=oe,Nn.inject=go,Pe(Nn,function(){var n={};return gt(Nn,function(t,r){Nn.prototype[r]||(n[r]=t)}),n}(),!1),Nn.sample=fe,Nn.prototype.sample=function(n){return this.__chain__||null!=n?this.thru(function(t){return fe(t,n)}):fe(this.value())},Nn.VERSION=b,Kn("bind bindKey curry curryRight partial partialRight".split(" "),function(n){Nn[n].placeholder=Nn}),Kn(["drop","take"],function(n,t){zn.prototype[n]=function(r){var e=this.__filtered__;if(e&&!t)return new zn(this);r=null==r?1:ju(xu(r)||0,0);var u=this.clone();return e?u.__takeCount__=ku(u.__takeCount__,r):u.__views__.push({size:r,type:n+(0>u.__dir__?"Right":"")}),u},zn.prototype[n+"Right"]=function(t){return this.reverse()[n](t).reverse()}}),Kn(["filter","map","takeWhile"],function(n,t){var r=t+1,e=r!=N;zn.prototype[n]=function(n,t){var u=this.clone();return u.__iteratees__.push({iteratee:mr(n,t,1),type:r}),u.__filtered__=u.__filtered__||e,u}}),Kn(["first","last"],function(n,t){var r="take"+(t?"Right":"");zn.prototype[n]=function(){return this[r](1).value()[0]}}),Kn(["initial","rest"],function(n,t){var r="drop"+(t?"":"Right");zn.prototype[n]=function(){return this.__filtered__?new zn(this):this[r](1)}}),Kn(["pluck","where"],function(n,t){var r=t?"filter":"map",e=t?At:Be;zn.prototype[n]=function(n){return this[r](e(n))}}),zn.prototype.compact=function(){return this.filter(Ne)},zn.prototype.reject=function(n,t){return n=mr(n,t,1),this.filter(function(t){return!n(t)})},zn.prototype.slice=function(n,t){n=null==n?0:+n||0;var r=this;return r.__filtered__&&(0<n||0>t)?new zn(r):(0>n?r=r.takeRight(-n):n&&(r=r.drop(n)),t!==x&&(t=+t||0,r=0>t?r.dropRight(-t):r.take(t-n)),r)},zn.prototype.takeRightWhile=function(n,t){return this.reverse().takeWhile(n,t).reverse()},zn.prototype.toArray=function(){return this.take(Cu)},gt(zn.prototype,function(n,t){var r=/^(?:filter|map|reject)|While$/.test(t),e=/^(?:first|last)$/.test(t),u=Nn[e?"take"+("last"==t?"Right":""):t];u&&(Nn.prototype[t]=function(){var t=e?[1]:arguments,o=this.__chain__,i=this.__wrapped__,f=!!this.__actions__.length,c=i instanceof zn,a=t[0],l=c||Wo(i);l&&r&&"function"==typeof a&&1!=a.length&&(c=l=!1);var s=function(n){return e&&o?u(n,1)[0]:u.apply(x,Hn([n],t))},a={func:re,args:[s],thisArg:x},f=c&&!f;return e&&!o?f?(i=i.clone(),i.__actions__.push(a),n.call(i)):u.call(x,this.value())[0]:!e&&l?(i=f?i:new zn(this),i=n.apply(i,t),i.__actions__.push(a),new Pn(i,o)):this.thru(s)})}),Kn("join pop push replace shift sort splice split unshift".split(" "),function(n){var t=(/^(?:replace|split)$/.test(n)?tu:He)[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=!Tu.spliceObjects&&/^(?:pop|shift|splice)$/.test(n),u=/^(?:join|pop|replace|shift)$/.test(n),o=e?function(){var n=t.apply(this,arguments);return 0===this.length&&delete this[0],n}:t;Nn.prototype[n]=function(){var n=arguments;return u&&!this.__chain__?o.apply(this.value(),n):this[r](function(t){return o.apply(t,n)})}}),gt(zn.prototype,function(n,t){var r=Nn[t];if(r){var e=r.name+"";(Fu[e]||(Fu[e]=[])).push({name:t,func:r})}}),Fu[hr(x,A).name]=[{name:"wrapper",func:x}],zn.prototype.clone=function(){var n=new zn(this.__wrapped__);return n.__actions__=qn(this.__actions__),n.__dir__=this.__dir__,n.__filtered__=this.__filtered__,n.__iteratees__=qn(this.__iteratees__),n.__takeCount__=this.__takeCount__,n.__views__=qn(this.__views__),n},zn.prototype.reverse=function(){if(this.__filtered__){var n=new zn(this);n.__dir__=-1,n.__filtered__=!0}else n=this.clone(),n.__dir__*=-1;return n},zn.prototype.value=function(){var n,t=this.__wrapped__.value(),r=this.__dir__,e=Wo(t),u=0>r,o=e?t.length:0;n=0;for(var i=o,f=this.__views__,c=-1,a=f.length;++c<a;){var l=f[c],s=l.size;switch(l.type){case"drop":n+=s;break;case"dropRight":i-=s;break;case"take":i=ku(i,n+s);break;case"takeRight":n=ju(n,i-s)}}if(n={start:n,end:i},i=n.start,f=n.end,n=f-i,u=u?f:i-1,i=this.__iteratees__,f=i.length,c=0,a=ku(n,this.__takeCount__),!e||o<F||o==n&&a==n)return Pt(t,this.__actions__);e=[];n:for(;n--&&c<a;){for(u+=r,o=-1,l=t[u];++o<f;){var p=i[o],s=p.type,p=p.iteratee(l);if(s==N)l=p;else if(!p){if(s==L)continue n;break n}}e[c++]=l}return e},Nn.prototype.chain=function(){return te(this)},Nn.prototype.commit=function(){return new Pn(this.value(),this.__chain__)},Nn.prototype.concat=oo,Nn.prototype.plant=function(n){for(var t,r=this;r instanceof Tn;){var e=qr(r);t?u.__wrapped__=e:t=e;var u=e,r=r.__wrapped__}return u.__wrapped__=n,t},Nn.prototype.reverse=function(){var n=this.__wrapped__,t=function(n){return n.reverse()};return n instanceof zn?(this.__actions__.length&&(n=new zn(this)),n=n.reverse(),n.__actions__.push({func:re,args:[t],thisArg:x}),new Pn(n,this.__chain__)):this.thru(t)},Nn.prototype.toString=function(){return this.value()+""},Nn.prototype.run=Nn.prototype.toJSON=Nn.prototype.valueOf=Nn.prototype.value=function(){return Pt(this.__wrapped__,this.__actions__)},Nn.prototype.collect=Nn.prototype.map,Nn.prototype.head=Nn.prototype.first,Nn.prototype.select=Nn.prototype.filter,Nn.prototype.tail=Nn.prototype.rest,Nn}var x,b="3.10.1",m=1,A=2,j=4,k=8,O=16,I=32,R=64,E=128,C=256,S=30,U="...",$=150,W=16,F=200,L=1,N=2,T="Expected a function",P="__lodash_placeholder__",z="[object Arguments]",B="[object Array]",D="[object Boolean]",M="[object Date]",q="[object Error]",K="[object Function]",V="[object Number]",Z="[object Object]",Y="[object RegExp]",G="[object String]",J="[object ArrayBuffer]",X="[object Float32Array]",H="[object Float64Array]",Q="[object Int8Array]",nn="[object Int16Array]",tn="[object Int32Array]",rn="[object Uint8Array]",en="[object Uint8ClampedArray]",un="[object Uint16Array]",on="[object Uint32Array]",fn=/\b__p\+='';/g,cn=/\b(__p\+=)''\+/g,an=/(__e\(.*?\)|\b__t\))\+'';/g,ln=/&(?:amp|lt|gt|quot|#39|#96);/g,sn=/[&<>"'`]/g,pn=RegExp(ln.source),hn=RegExp(sn.source),_n=/<%-([\s\S]+?)%>/g,vn=/<%([\s\S]+?)%>/g,gn=/<%=([\s\S]+?)%>/g,yn=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/,dn=/^\w*$/,wn=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g,xn=/^[:!,]|[\\^$.*+?()[\]{}|\/]|(^[0-9a-fA-Fnrtuvx])|([\n\r\u2028\u2029])/g,bn=RegExp(xn.source),mn=/[\u0300-\u036f\ufe20-\ufe23]/g,An=/\\(\\)?/g,jn=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,kn=/\w*$/,On=/^0[xX]/,In=/^\[object .+?Constructor\]$/,Rn=/^\d+$/,En=/[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g,Cn=/($^)/,Sn=/['\n\r\u2028\u2029\\]/g,Un=RegExp("[A-Z\\xc0-\\xd6\\xd8-\\xde]+(?=[A-Z\\xc0-\\xd6\\xd8-\\xde][a-z\\xdf-\\xf6\\xf8-\\xff]+)|[A-Z\\xc0-\\xd6\\xd8-\\xde]?[a-z\\xdf-\\xf6\\xf8-\\xff]+|[A-Z\\xc0-\\xd6\\xd8-\\xde]+|[0-9]+","g"),$n="Array ArrayBuffer Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Math Number Object RegExp Set String _ clearTimeout isFinite parseFloat parseInt setTimeout TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap".split(" "),Wn="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),Fn={};Fn[X]=Fn[H]=Fn[Q]=Fn[nn]=Fn[tn]=Fn[rn]=Fn[en]=Fn[un]=Fn[on]=!0,Fn[z]=Fn[B]=Fn[J]=Fn[D]=Fn[M]=Fn[q]=Fn[K]=Fn["[object Map]"]=Fn[V]=Fn[Z]=Fn[Y]=Fn["[object Set]"]=Fn[G]=Fn["[object WeakMap]"]=!1;var Ln={};Ln[z]=Ln[B]=Ln[J]=Ln[D]=Ln[M]=Ln[X]=Ln[H]=Ln[Q]=Ln[nn]=Ln[tn]=Ln[V]=Ln[Z]=Ln[Y]=Ln[G]=Ln[rn]=Ln[en]=Ln[un]=Ln[on]=!0,Ln[q]=Ln[K]=Ln["[object Map]"]=Ln["[object Set]"]=Ln["[object WeakMap]"]=!1;var Nn={"À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","Ç":"C","ç":"c","Ð":"D","ð":"d","È":"E","É":"E","Ê":"E","Ë":"E","è":"e","é":"e","ê":"e","ë":"e","Ì":"I","Í":"I","Î":"I","Ï":"I","ì":"i","í":"i","î":"i","ï":"i","Ñ":"N","ñ":"n","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","Ù":"U","Ú":"U","Û":"U","Ü":"U","ù":"u","ú":"u","û":"u","ü":"u","Ý":"Y","ý":"y","ÿ":"y","Æ":"Ae","æ":"ae","Þ":"Th","þ":"th","ß":"ss"},Tn={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;","`":"&#96;"},Pn={"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"',"&#39;":"'","&#96;":"`"},zn={"function":!0,object:!0},Bn={0:"x30",1:"x31",2:"x32",3:"x33",4:"x34",5:"x35",6:"x36",7:"x37",8:"x38",9:"x39",A:"x41",B:"x42",C:"x43",D:"x44",E:"x45",F:"x46",a:"x61",b:"x62",c:"x63",d:"x64",e:"x65",f:"x66",n:"x6e",r:"x72",t:"x74",u:"x75",v:"x76",x:"x78"},Dn={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Mn=zn[typeof exports]&&exports&&!exports.nodeType&&exports,qn=zn[typeof module]&&module&&!module.nodeType&&module,Kn=zn[typeof self]&&self&&self.Object&&self,Vn=zn[typeof window]&&window&&window.Object&&window,Zn=qn&&qn.exports===Mn&&Mn,Yn=Mn&&qn&&"object"==typeof global&&global&&global.Object&&global||Vn!==(this&&this.window)&&Vn||Kn||this,Gn=function(){try{Object({toString:0}+"")}catch(n){return function(){return!1}}return function(n){return"function"!=typeof n.toString&&"string"==typeof(n+"")}}(),Jn=w();"function"==typeof define&&"object"==typeof define.amd&&define.amd?(Yn._=Jn,define(function(){return Jn})):Mn&&qn?Zn?(qn.exports=Jn)._=Jn:Mn._=Jn:Yn._=Jn}).call(this);
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/marked.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/marked.js
new file mode 100644 (file)
index 0000000..c334bff
--- /dev/null
@@ -0,0 +1 @@
+(function(){function e(e){this.tokens=[],this.tokens.links={},this.options=e||a.defaults,this.rules=p.normal,this.options.gfm&&(this.options.tables?this.rules=p.tables:this.rules=p.gfm)}function t(e,t){if(this.options=t||a.defaults,this.links=e,this.rules=u.normal,this.renderer=this.options.renderer||new n,this.renderer.options=this.options,!this.links)throw new Error("Tokens array requires a `links` property.");this.options.gfm?this.options.breaks?this.rules=u.breaks:this.rules=u.gfm:this.options.pedantic&&(this.rules=u.pedantic)}function n(e){this.options=e||{}}function r(e){this.tokens=[],this.token=null,this.options=e||a.defaults,this.options.renderer=this.options.renderer||new n,this.renderer=this.options.renderer,this.renderer.options=this.options}function s(e,t){return e.replace(t?/&/g:/&(?!#?\w+;)/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function i(e){return e.replace(/&([#\w]+);/g,function(e,t){return t=t.toLowerCase(),"colon"===t?":":"#"===t.charAt(0)?"x"===t.charAt(1)?String.fromCharCode(parseInt(t.substring(2),16)):String.fromCharCode(+t.substring(1)):""})}function l(e,t){return e=e.source,t=t||"",function n(r,s){return r?(s=s.source||s,s=s.replace(/(^|[^\[])\^/g,"$1"),e=e.replace(r,s),n):new RegExp(e,t)}}function o(){}function h(e){for(var t,n,r=1;r<arguments.length;r++){t=arguments[r];for(n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])}return e}function a(t,n,i){if(i||"function"==typeof n){i||(i=n,n=null),n=h({},a.defaults,n||{});var l,o,p=n.highlight,u=0;try{l=e.lex(t,n)}catch(c){return i(c)}o=l.length;var g=function(e){if(e)return n.highlight=p,i(e);var t;try{t=r.parse(l,n)}catch(s){e=s}return n.highlight=p,e?i(e):i(null,t)};if(!p||p.length<3)return g();if(delete n.highlight,!o)return g();for(;u<l.length;u++)!function(e){return"code"!==e.type?--o||g():p(e.text,e.lang,function(t,n){return t?g(t):null==n||n===e.text?--o||g():(e.text=n,e.escaped=!0,void(--o||g()))})}(l[u])}else try{return n&&(n=h({},a.defaults,n)),r.parse(e.lex(t,n),n)}catch(c){if(c.message+="\nPlease report this to https://github.com/chjj/marked.",(n||a.defaults).silent)return"<p>An error occured:</p><pre>"+s(c.message+"",!0)+"</pre>";throw c}}var p={newline:/^\n+/,code:/^( {4}[^\n]+\n*)+/,fences:o,hr:/^( *[-*_]){3,} *(?:\n+|$)/,heading:/^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,nptable:o,lheading:/^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,blockquote:/^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,list:/^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,html:/^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,def:/^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,table:o,paragraph:/^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,text:/^[^\n]+/};p.bullet=/(?:[*+-]|\d+\.)/,p.item=/^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/,p.item=l(p.item,"gm")(/bull/g,p.bullet)(),p.list=l(p.list)(/bull/g,p.bullet)("hr","\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))")("def","\\n+(?="+p.def.source+")")(),p.blockquote=l(p.blockquote)("def",p.def)(),p._tag="(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b",p.html=l(p.html)("comment",/<!--[\s\S]*?-->/)("closed",/<(tag)[\s\S]+?<\/\1>/)("closing",/<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)(/tag/g,p._tag)(),p.paragraph=l(p.paragraph)("hr",p.hr)("heading",p.heading)("lheading",p.lheading)("blockquote",p.blockquote)("tag","<"+p._tag)("def",p.def)(),p.normal=h({},p),p.gfm=h({},p.normal,{fences:/^ *(`{3,}|~{3,}) *(\S+)? *\n([\s\S]+?)\s*\1 *(?:\n+|$)/,paragraph:/^/}),p.gfm.paragraph=l(p.paragraph)("(?!","(?!"+p.gfm.fences.source.replace("\\1","\\2")+"|"+p.list.source.replace("\\1","\\3")+"|")(),p.tables=h({},p.gfm,{nptable:/^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,table:/^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/}),e.rules=p,e.lex=function(t,n){var r=new e(n);return r.lex(t)},e.prototype.lex=function(e){return e=e.replace(/\r\n|\r/g,"\n").replace(/\t/g,"    ").replace(/\u00a0/g," ").replace(/\u2424/g,"\n"),this.token(e,!0)},e.prototype.token=function(e,t,n){for(var r,s,i,l,o,h,a,u,c,e=e.replace(/^ +$/gm,"");e;)if((i=this.rules.newline.exec(e))&&(e=e.substring(i[0].length),i[0].length>1&&this.tokens.push({type:"space"})),i=this.rules.code.exec(e))e=e.substring(i[0].length),i=i[0].replace(/^ {4}/gm,""),this.tokens.push({type:"code",text:this.options.pedantic?i:i.replace(/\n+$/,"")});else if(i=this.rules.fences.exec(e))e=e.substring(i[0].length),this.tokens.push({type:"code",lang:i[2],text:i[3]});else if(i=this.rules.heading.exec(e))e=e.substring(i[0].length),this.tokens.push({type:"heading",depth:i[1].length,text:i[2]});else if(t&&(i=this.rules.nptable.exec(e))){for(e=e.substring(i[0].length),h={type:"table",header:i[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:i[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:i[3].replace(/\n$/,"").split("\n")},u=0;u<h.align.length;u++)/^ *-+: *$/.test(h.align[u])?h.align[u]="right":/^ *:-+: *$/.test(h.align[u])?h.align[u]="center":/^ *:-+ *$/.test(h.align[u])?h.align[u]="left":h.align[u]=null;for(u=0;u<h.cells.length;u++)h.cells[u]=h.cells[u].split(/ *\| */);this.tokens.push(h)}else if(i=this.rules.lheading.exec(e))e=e.substring(i[0].length),this.tokens.push({type:"heading",depth:"="===i[2]?1:2,text:i[1]});else if(i=this.rules.hr.exec(e))e=e.substring(i[0].length),this.tokens.push({type:"hr"});else if(i=this.rules.blockquote.exec(e))e=e.substring(i[0].length),this.tokens.push({type:"blockquote_start"}),i=i[0].replace(/^ *> ?/gm,""),this.token(i,t,!0),this.tokens.push({type:"blockquote_end"});else if(i=this.rules.list.exec(e)){for(e=e.substring(i[0].length),l=i[2],this.tokens.push({type:"list_start",ordered:l.length>1}),i=i[0].match(this.rules.item),r=!1,c=i.length,u=0;u<c;u++)h=i[u],a=h.length,h=h.replace(/^ *([*+-]|\d+\.) +/,""),~h.indexOf("\n ")&&(a-=h.length,h=this.options.pedantic?h.replace(/^ {1,4}/gm,""):h.replace(new RegExp("^ {1,"+a+"}","gm"),"")),this.options.smartLists&&u!==c-1&&(o=p.bullet.exec(i[u+1])[0],l===o||l.length>1&&o.length>1||(e=i.slice(u+1).join("\n")+e,u=c-1)),s=r||/\n\n(?!\s*$)/.test(h),u!==c-1&&(r="\n"===h.charAt(h.length-1),s||(s=r)),this.tokens.push({type:s?"loose_item_start":"list_item_start"}),this.token(h,!1,n),this.tokens.push({type:"list_item_end"});this.tokens.push({type:"list_end"})}else if(i=this.rules.html.exec(e))e=e.substring(i[0].length),this.tokens.push({type:this.options.sanitize?"paragraph":"html",pre:"pre"===i[1]||"script"===i[1]||"style"===i[1],text:i[0]});else if(!n&&t&&(i=this.rules.def.exec(e)))e=e.substring(i[0].length),this.tokens.links[i[1].toLowerCase()]={href:i[2],title:i[3]};else if(t&&(i=this.rules.table.exec(e))){for(e=e.substring(i[0].length),h={type:"table",header:i[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:i[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:i[3].replace(/(?: *\| *)?\n$/,"").split("\n")},u=0;u<h.align.length;u++)/^ *-+: *$/.test(h.align[u])?h.align[u]="right":/^ *:-+: *$/.test(h.align[u])?h.align[u]="center":/^ *:-+ *$/.test(h.align[u])?h.align[u]="left":h.align[u]=null;for(u=0;u<h.cells.length;u++)h.cells[u]=h.cells[u].replace(/^ *\| *| *\| *$/g,"").split(/ *\| */);this.tokens.push(h)}else if(t&&(i=this.rules.paragraph.exec(e)))e=e.substring(i[0].length),this.tokens.push({type:"paragraph",text:"\n"===i[1].charAt(i[1].length-1)?i[1].slice(0,-1):i[1]});else if(i=this.rules.text.exec(e))e=e.substring(i[0].length),this.tokens.push({type:"text",text:i[0]});else if(e)throw new Error("Infinite loop on byte: "+e.charCodeAt(0));return this.tokens};var u={escape:/^\\([\\`*{}\[\]()#+\-.!_>])/,autolink:/^<([^ >]+(@|:\/)[^ >]+)>/,url:o,tag:/^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,link:/^!?\[(inside)\]\(href\)/,reflink:/^!?\[(inside)\]\s*\[([^\]]*)\]/,nolink:/^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,strong:/^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,em:/^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,code:/^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,br:/^ {2,}\n(?!\s*$)/,del:o,text:/^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/};u._inside=/(?:\[[^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*/,u._href=/\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/,u.link=l(u.link)("inside",u._inside)("href",u._href)(),u.reflink=l(u.reflink)("inside",u._inside)(),u.normal=h({},u),u.pedantic=h({},u.normal,{strong:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,em:/^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/}),u.gfm=h({},u.normal,{escape:l(u.escape)("])","~|])")(),url:/^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,del:/^~~(?=\S)([\s\S]*?\S)~~/,text:l(u.text)("]|","~]|")("|","|https?://|")()}),u.breaks=h({},u.gfm,{br:l(u.br)("{2,}","*")(),text:l(u.gfm.text)("{2,}","*")()}),t.rules=u,t.output=function(e,n,r){var s=new t(n,r);return s.output(e)},t.prototype.output=function(e){for(var t,n,r,i,l="";e;)if(i=this.rules.escape.exec(e))e=e.substring(i[0].length),l+=i[1];else if(i=this.rules.autolink.exec(e))e=e.substring(i[0].length),"@"===i[2]?(n=":"===i[1].charAt(6)?this.mangle(i[1].substring(7)):this.mangle(i[1]),r=this.mangle("mailto:")+n):(n=s(i[1]),r=n),l+=this.renderer.link(r,null,n);else if(this.inLink||!(i=this.rules.url.exec(e))){if(i=this.rules.tag.exec(e))!this.inLink&&/^<a /i.test(i[0])?this.inLink=!0:this.inLink&&/^<\/a>/i.test(i[0])&&(this.inLink=!1),e=e.substring(i[0].length),l+=this.options.sanitize?s(i[0]):i[0];else if(i=this.rules.link.exec(e))e=e.substring(i[0].length),this.inLink=!0,l+=this.outputLink(i,{href:i[2],title:i[3]}),this.inLink=!1;else if((i=this.rules.reflink.exec(e))||(i=this.rules.nolink.exec(e))){if(e=e.substring(i[0].length),t=(i[2]||i[1]).replace(/\s+/g," "),t=this.links[t.toLowerCase()],!t||!t.href){l+=i[0].charAt(0),e=i[0].substring(1)+e;continue}this.inLink=!0,l+=this.outputLink(i,t),this.inLink=!1}else if(i=this.rules.strong.exec(e))e=e.substring(i[0].length),l+=this.renderer.strong(this.output(i[2]||i[1]));else if(i=this.rules.em.exec(e))e=e.substring(i[0].length),l+=this.renderer.em(this.output(i[2]||i[1]));else if(i=this.rules.code.exec(e))e=e.substring(i[0].length),l+=this.renderer.codespan(s(i[2],!0));else if(i=this.rules.br.exec(e))e=e.substring(i[0].length),l+=this.renderer.br();else if(i=this.rules.del.exec(e))e=e.substring(i[0].length),l+=this.renderer.del(this.output(i[1]));else if(i=this.rules.text.exec(e))e=e.substring(i[0].length),l+=s(this.smartypants(i[0]));else if(e)throw new Error("Infinite loop on byte: "+e.charCodeAt(0))}else e=e.substring(i[0].length),n=s(i[1]),r=n,l+=this.renderer.link(r,null,n);return l},t.prototype.outputLink=function(e,t){var n=s(t.href),r=t.title?s(t.title):null;return"!"!==e[0].charAt(0)?this.renderer.link(n,r,this.output(e[1])):this.renderer.image(n,r,s(e[1]))},t.prototype.smartypants=function(e){return this.options.smartypants?e.replace(/--/g,"—").replace(/(^|[-\u2014\/(\[{"\s])'/g,"$1‘").replace(/'/g,"’").replace(/(^|[-\u2014\/(\[{\u2018\s])"/g,"$1“").replace(/"/g,"”").replace(/\.{3}/g,"…"):e},t.prototype.mangle=function(e){for(var t,n="",r=e.length,s=0;s<r;s++)t=e.charCodeAt(s),Math.random()>.5&&(t="x"+t.toString(16)),n+="&#"+t+";";return n},n.prototype.code=function(e,t,n){if(this.options.highlight){var r=this.options.highlight(e,t);null!=r&&r!==e&&(n=!0,e=r)}return t?'<pre><code class="'+this.options.langPrefix+s(t,!0)+'">'+(n?e:s(e,!0))+"\n</code></pre>\n":"<pre><code>"+(n?e:s(e,!0))+"\n</code></pre>"},n.prototype.blockquote=function(e){return"<blockquote>\n"+e+"</blockquote>\n"},n.prototype.html=function(e){return e},n.prototype.heading=function(e,t,n){return"<h"+t+' id="'+this.options.headerPrefix+n.toLowerCase().replace(/[^\w]+/g,"-")+'">'+e+"</h"+t+">\n"},n.prototype.hr=function(){return this.options.xhtml?"<hr/>\n":"<hr>\n"},n.prototype.list=function(e,t){var n=t?"ol":"ul";return"<"+n+">\n"+e+"</"+n+">\n"},n.prototype.listitem=function(e){return"<li>"+e+"</li>\n"},n.prototype.paragraph=function(e){return"<p>"+e+"</p>\n"},n.prototype.table=function(e,t){return"<table>\n<thead>\n"+e+"</thead>\n<tbody>\n"+t+"</tbody>\n</table>\n"},n.prototype.tablerow=function(e){return"<tr>\n"+e+"</tr>\n"},n.prototype.tablecell=function(e,t){var n=t.header?"th":"td",r=t.align?"<"+n+' style="text-align:'+t.align+'">':"<"+n+">";return r+e+"</"+n+">\n"},n.prototype.strong=function(e){return"<strong>"+e+"</strong>"},n.prototype.em=function(e){return"<em>"+e+"</em>"},n.prototype.codespan=function(e){return"<code>"+e+"</code>"},n.prototype.br=function(){return this.options.xhtml?"<br/>":"<br>"},n.prototype.del=function(e){return"<del>"+e+"</del>"},n.prototype.link=function(e,t,n){if(this.options.sanitize){try{var r=decodeURIComponent(i(e)).replace(/[^\w:]/g,"").toLowerCase()}catch(s){return""}if(0===r.indexOf("javascript:"))return""}var l='<a href="'+e+'"';return t&&(l+=' title="'+t+'"'),l+=">"+n+"</a>"},n.prototype.image=function(e,t,n){var r='<img src="'+e+'" alt="'+n+'"';return t&&(r+=' title="'+t+'"'),r+=this.options.xhtml?"/>":">"},r.parse=function(e,t,n){var s=new r(t,n);return s.parse(e)},r.prototype.parse=function(e){this.inline=new t(e.links,this.options,this.renderer),this.tokens=e.reverse();for(var n="";this.next();)n+=this.tok();return n},r.prototype.next=function(){return this.token=this.tokens.pop()},r.prototype.peek=function(){return this.tokens[this.tokens.length-1]||0},r.prototype.parseText=function(){for(var e=this.token.text;"text"===this.peek().type;)e+="\n"+this.next().text;return this.inline.output(e)},r.prototype.tok=function(){switch(this.token.type){case"space":return"";case"hr":return this.renderer.hr();case"heading":return this.renderer.heading(this.inline.output(this.token.text),this.token.depth,this.token.text);case"code":return this.renderer.code(this.token.text,this.token.lang,this.token.escaped);case"table":var e,t,n,r,s,i="",l="";for(n="",e=0;e<this.token.header.length;e++)r={header:!0,align:this.token.align[e]},n+=this.renderer.tablecell(this.inline.output(this.token.header[e]),{header:!0,align:this.token.align[e]});for(i+=this.renderer.tablerow(n),e=0;e<this.token.cells.length;e++){for(t=this.token.cells[e],n="",s=0;s<t.length;s++)n+=this.renderer.tablecell(this.inline.output(t[s]),{header:!1,align:this.token.align[s]});l+=this.renderer.tablerow(n)}return this.renderer.table(i,l);case"blockquote_start":for(var l="";"blockquote_end"!==this.next().type;)l+=this.tok();return this.renderer.blockquote(l);case"list_start":for(var l="",o=this.token.ordered;"list_end"!==this.next().type;)l+=this.tok();return this.renderer.list(l,o);case"list_item_start":for(var l="";"list_item_end"!==this.next().type;)l+="text"===this.token.type?this.parseText():this.tok();return this.renderer.listitem(l);case"loose_item_start":for(var l="";"list_item_end"!==this.next().type;)l+=this.tok();return this.renderer.listitem(l);case"html":var h=this.token.pre||this.options.pedantic?this.token.text:this.inline.output(this.token.text);return this.renderer.html(h);case"paragraph":return this.renderer.paragraph(this.inline.output(this.token.text));case"text":return this.renderer.paragraph(this.parseText())}},o.exec=o,a.options=a.setOptions=function(e){return h(a.defaults,e),a},a.defaults={gfm:!0,tables:!0,breaks:!1,pedantic:!1,sanitize:!1,smartLists:!1,silent:!1,highlight:null,langPrefix:"lang-",smartypants:!1,headerPrefix:"",renderer:new n,xhtml:!1},a.Parser=r,a.parser=r.parse,a.Renderer=n,a.Lexer=e,a.lexer=e.lex,a.InlineLexer=t,a.inlineLexer=t.output,a.parse=a,"undefined"!=typeof module&&"object"==typeof exports?module.exports=a:"function"==typeof define&&define.amd?define(function(){return a}):this.marked=a}).call(function(){return this||("undefined"!=typeof window?window:global)}());
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/object-assign-pollyfill.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/object-assign-pollyfill.js
new file mode 100644 (file)
index 0000000..b34d63c
--- /dev/null
@@ -0,0 +1 @@
+"function"!=typeof Object.assign&&!function(){Object.assign=function(n){"use strict";if(void 0===n||null===n)throw new TypeError("Cannot convert undefined or null to object");for(var t=Object(n),o=1;o<arguments.length;o++){var r=arguments[o];if(void 0!==r&&null!==r)for(var e in r)Object.prototype.hasOwnProperty.call(r,e)&&(t[e]=r[e])}return t}}();
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/sanitize-html.min.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/sanitize-html.min.js
new file mode 100644 (file)
index 0000000..ade2508
--- /dev/null
@@ -0,0 +1,4 @@
+!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.sanitizeHtml=t()}}(function(){return function t(e,r,n){function i(o,a){if(!r[o]){if(!e[o]){var c="function"==typeof require&&require;if(!a&&c)return c(o,!0);if(s)return s(o,!0);var u=new Error("Cannot find module '"+o+"'");throw u.code="MODULE_NOT_FOUND",u}var h=r[o]={exports:{}};e[o][0].call(h.exports,function(t){var r=e[o][1][t];return i(r?r:t)},h,h.exports,t,e,r,n)}return r[o].exports}for(var s="function"==typeof require&&require,o=0;o<n.length;o++)i(n[o]);return i}({1:[function(t,e,r){function n(t,e){t&&Object.keys(t).forEach(function(r){e(t[r],r)})}function i(t,e){return{}.hasOwnProperty.call(t,e)}function s(t,e,r){function h(t,e){var r=this;this.tag=t,this.attribs=e||{},this.tagPosition=d.length,this.text="",this.updateParentNodeText=function(){if(x.length){var t=x[x.length-1];t.text+=r.text}}}function l(t){return"string"!=typeof t&&(t+=""),t.replace(/\&/g,"&amp;").replace(/</g,"&lt;").replace(/\>/g,"&gt;").replace(/\"/g,"&quot;")}function f(t,r){r=r.replace(/[\x00-\x20]+/g,""),r=r.replace(/<\!\-\-.*?\-\-\>/g,"");var n=r.match(/^([a-zA-Z]+)\:/);if(!n)return!1;var s=n[1].toLowerCase();return i(e.allowedSchemesByTag,t)?e.allowedSchemesByTag[t].indexOf(s)===-1:!e.allowedSchemes||e.allowedSchemes.indexOf(s)===-1}function p(t,e){return e?(t=t.split(/\s+/),t.filter(function(t){return e.indexOf(t)!==-1}).join(" ")):t}var d="";e?(e=a(s.defaults,e),e.parser?e.parser=a(u,e.parser):e.parser=u):(e=s.defaults,e.parser=u);var g,_,m=e.nonTextTags||["script","style","textarea"];e.allowedAttributes&&(g={},_={},n(e.allowedAttributes,function(t,e){g[e]=[];var r=[];t.forEach(function(t){t.indexOf("*")>=0?r.push(c(t).replace(/\\\*/g,".*")):g[e].push(t)}),_[e]=new RegExp("^("+r.join("|")+")$")}));var b={};n(e.allowedClasses,function(t,e){g&&(i(g,e)||(g[e]=[]),g[e].push("class")),b[e]=t});var y,v={};n(e.transformTags,function(t,e){var r;"function"==typeof t?r=t:"string"==typeof t&&(r=s.simpleTransform(t)),"*"===e?y=r:v[e]=r});var w=0,x=[],S={},E={},T=!1,A=0,k=new o.Parser({onopentag:function(t,r){if(T)return void A++;var s=new h(t,r);x.push(s);var o,a=!1,c=!!s.text;i(v,t)&&(o=v[t](t,r),s.attribs=r=o.attribs,void 0!==o.text&&(s.innerText=o.text),t!==o.tagName&&(s.name=t=o.tagName,E[w]=o.tagName)),y&&(o=y(t,r),s.attribs=r=o.attribs,t!==o.tagName&&(s.name=t=o.tagName,E[w]=o.tagName)),e.allowedTags&&e.allowedTags.indexOf(t)===-1&&(a=!0,m.indexOf(t)!==-1&&(T=!0,A=1),S[w]=!0),w++,a||(d+="<"+t,(!g||i(g,t)||g["*"])&&n(r,function(e,r){if(!g||i(g,t)&&g[t].indexOf(r)!==-1||g["*"]&&g["*"].indexOf(r)!==-1||i(_,t)&&_[t].test(r)||_["*"]&&_["*"].test(r)){if(("href"===r||"src"===r)&&f(t,e))return void delete s.attribs[r];if("class"===r&&(e=p(e,b[t]),!e.length))return void delete s.attribs[r];d+=" "+r,e.length&&(d+='="'+l(e)+'"')}else delete s.attribs[r]}),e.selfClosing.indexOf(t)!==-1?d+=" />":(d+=">",!s.innerText||c||e.textFilter||(d+=s.innerText)))},ontext:function(t){if(!T){var r,n=x[x.length-1];if(n&&(r=n.tag,t=void 0!==n.innerText?n.innerText:t),"script"===r||"style"===r)d+=t;else{var i=l(t);d+=e.textFilter?e.textFilter(i):i}if(x.length){var s=x[x.length-1];s.text+=t}}},onclosetag:function(t){if(T){if(A--,A)return;T=!1}var r=x.pop();if(r){if(T=!1,w--,S[w])return delete S[w],void r.updateParentNodeText();if(E[w]&&(t=E[w],delete E[w]),e.exclusiveFilter&&e.exclusiveFilter(r))return void(d=d.substr(0,r.tagPosition));r.updateParentNodeText(),e.selfClosing.indexOf(t)===-1&&(d+="</"+t+">")}}},e.parser);return k.write(t),k.end(),d}var o=t("htmlparser2"),a=t("xtend"),c=t("regexp-quote");e.exports=s;var u={decodeEntities:!0};s.defaults={allowedTags:["h3","h4","h5","h6","blockquote","p","a","ul","ol","nl","li","b","i","strong","em","strike","code","hr","br","div","table","thead","caption","tbody","tr","th","td","pre"],allowedAttributes:{a:["href","name","target"],img:["src"]},selfClosing:["img","br","hr","area","base","basefont","input","link","meta"],allowedSchemes:["http","https","ftp","mailto"],allowedSchemesByTag:{}},s.simpleTransform=function(t,e,r){return r=void 0===r||r,e=e||{},function(n,i){var s;if(r)for(s in e)i[s]=e[s];else i=e;return{tagName:t,attribs:i}}}},{htmlparser2:36,"regexp-quote":54,xtend:58}],2:[function(t,e,r){"use strict";function n(){for(var t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",e=0,r=t.length;e<r;++e)c[e]=t[e],u[t.charCodeAt(e)]=e;u["-".charCodeAt(0)]=62,u["_".charCodeAt(0)]=63}function i(t){var e,r,n,i,s,o,a=t.length;if(a%4>0)throw new Error("Invalid string. Length must be a multiple of 4");s="="===t[a-2]?2:"="===t[a-1]?1:0,o=new h(3*a/4-s),n=s>0?a-4:a;var c=0;for(e=0,r=0;e<n;e+=4,r+=3)i=u[t.charCodeAt(e)]<<18|u[t.charCodeAt(e+1)]<<12|u[t.charCodeAt(e+2)]<<6|u[t.charCodeAt(e+3)],o[c++]=i>>16&255,o[c++]=i>>8&255,o[c++]=255&i;return 2===s?(i=u[t.charCodeAt(e)]<<2|u[t.charCodeAt(e+1)]>>4,o[c++]=255&i):1===s&&(i=u[t.charCodeAt(e)]<<10|u[t.charCodeAt(e+1)]<<4|u[t.charCodeAt(e+2)]>>2,o[c++]=i>>8&255,o[c++]=255&i),o}function s(t){return c[t>>18&63]+c[t>>12&63]+c[t>>6&63]+c[63&t]}function o(t,e,r){for(var n,i=[],o=e;o<r;o+=3)n=(t[o]<<16)+(t[o+1]<<8)+t[o+2],i.push(s(n));return i.join("")}function a(t){for(var e,r=t.length,n=r%3,i="",s=[],a=16383,u=0,h=r-n;u<h;u+=a)s.push(o(t,u,u+a>h?h:u+a));return 1===n?(e=t[r-1],i+=c[e>>2],i+=c[e<<4&63],i+="=="):2===n&&(e=(t[r-2]<<8)+t[r-1],i+=c[e>>10],i+=c[e>>4&63],i+=c[e<<2&63],i+="="),s.push(i),s.join("")}r.toByteArray=i,r.fromByteArray=a;var c=[],u=[],h="undefined"!=typeof Uint8Array?Uint8Array:Array;n()},{}],3:[function(t,e,r){},{}],4:[function(t,e,r){(function(e){"use strict";var n=t("buffer"),i=n.Buffer,s=n.SlowBuffer,o=n.kMaxLength||2147483647;r.alloc=function(t,e,r){if("function"==typeof i.alloc)return i.alloc(t,e,r);if("number"==typeof r)throw new TypeError("encoding must not be number");if("number"!=typeof t)throw new TypeError("size must be a number");if(t>o)throw new RangeError("size is too large");var n=r,s=e;void 0===s&&(n=void 0,s=0);var a=new i(t);if("string"==typeof s)for(var c=new i(s,n),u=c.length,h=-1;++h<t;)a[h]=c[h%u];else a.fill(s);return a},r.allocUnsafe=function(t){if("function"==typeof i.allocUnsafe)return i.allocUnsafe(t);if("number"!=typeof t)throw new TypeError("size must be a number");if(t>o)throw new RangeError("size is too large");return new i(t)},r.from=function(t,r,n){if("function"==typeof i.from&&(!e.Uint8Array||Uint8Array.from!==i.from))return i.from(t,r,n);if("number"==typeof t)throw new TypeError('"value" argument must not be a number');if("string"==typeof t)return new i(t,r);if("undefined"!=typeof ArrayBuffer&&t instanceof ArrayBuffer){var s=r;if(1===arguments.length)return new i(t);"undefined"==typeof s&&(s=0);var o=n;if("undefined"==typeof o&&(o=t.byteLength-s),s>=t.byteLength)throw new RangeError("'offset' is out of bounds");if(o>t.byteLength-s)throw new RangeError("'length' is out of bounds");return new i(t.slice(s,s+o))}if(i.isBuffer(t)){var a=new i(t.length);return t.copy(a,0,0,t.length),a}if(t){if(Array.isArray(t)||"undefined"!=typeof ArrayBuffer&&t.buffer instanceof ArrayBuffer||"length"in t)return new i(t);if("Buffer"===t.type&&Array.isArray(t.data))return new i(t.data)}throw new TypeError("First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.")},r.allocUnsafeSlow=function(t){if("function"==typeof i.allocUnsafeSlow)return i.allocUnsafeSlow(t);if("number"!=typeof t)throw new TypeError("size must be a number");if(t>=o)throw new RangeError("size is too large");return new s(t)}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{buffer:5}],5:[function(t,e,r){(function(e){"use strict";function n(){try{var t=new Uint8Array(1);return t.__proto__={__proto__:Uint8Array.prototype,foo:function(){return 42}},42===t.foo()&&"function"==typeof t.subarray&&0===t.subarray(1,1).byteLength}catch(e){return!1}}function i(){return o.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function s(t,e){if(i()<e)throw new RangeError("Invalid typed array length");return o.TYPED_ARRAY_SUPPORT?(t=new Uint8Array(e),t.__proto__=o.prototype):(null===t&&(t=new o(e)),t.length=e),t}function o(t,e,r){if(!(o.TYPED_ARRAY_SUPPORT||this instanceof o))return new o(t,e,r);if("number"==typeof t){if("string"==typeof e)throw new Error("If encoding is specified then the first argument must be a string");return h(this,t)}return a(this,t,e,r)}function a(t,e,r,n){if("number"==typeof e)throw new TypeError('"value" argument must not be a number');return"undefined"!=typeof ArrayBuffer&&e instanceof ArrayBuffer?p(t,e,r,n):"string"==typeof e?l(t,e,r):d(t,e)}function c(t){if("number"!=typeof t)throw new TypeError('"size" argument must be a number');if(t<0)throw new RangeError('"size" argument must not be negative')}function u(t,e,r,n){return c(e),e<=0?s(t,e):void 0!==r?"string"==typeof n?s(t,e).fill(r,n):s(t,e).fill(r):s(t,e)}function h(t,e){if(c(e),t=s(t,e<0?0:0|g(e)),!o.TYPED_ARRAY_SUPPORT)for(var r=0;r<e;++r)t[r]=0;return t}function l(t,e,r){if("string"==typeof r&&""!==r||(r="utf8"),!o.isEncoding(r))throw new TypeError('"encoding" must be a valid string encoding');var n=0|m(e,r);t=s(t,n);var i=t.write(e,r);return i!==n&&(t=t.slice(0,i)),t}function f(t,e){var r=e.length<0?0:0|g(e.length);t=s(t,r);for(var n=0;n<r;n+=1)t[n]=255&e[n];return t}function p(t,e,r,n){if(e.byteLength,r<0||e.byteLength<r)throw new RangeError("'offset' is out of bounds");if(e.byteLength<r+(n||0))throw new RangeError("'length' is out of bounds");return e=void 0===r&&void 0===n?new Uint8Array(e):void 0===n?new Uint8Array(e,r):new Uint8Array(e,r,n),o.TYPED_ARRAY_SUPPORT?(t=e,t.__proto__=o.prototype):t=f(t,e),t}function d(t,e){if(o.isBuffer(e)){var r=0|g(e.length);return t=s(t,r),0===t.length?t:(e.copy(t,0,0,r),t)}if(e){if("undefined"!=typeof ArrayBuffer&&e.buffer instanceof ArrayBuffer||"length"in e)return"number"!=typeof e.length||J(e.length)?s(t,0):f(t,e);if("Buffer"===e.type&&$(e.data))return f(t,e.data)}throw new TypeError("First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.")}function g(t){if(t>=i())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+i().toString(16)+" bytes");return 0|t}function _(t){return+t!=t&&(t=0),o.alloc(+t)}function m(t,e){if(o.isBuffer(t))return t.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(t)||t instanceof ArrayBuffer))return t.byteLength;"string"!=typeof t&&(t=""+t);var r=t.length;if(0===r)return 0;for(var n=!1;;)switch(e){case"ascii":case"latin1":case"binary":return r;case"utf8":case"utf-8":case void 0:return F(t).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*r;case"hex":return r>>>1;case"base64":return X(t).length;default:if(n)return F(t).length;e=(""+e).toLowerCase(),n=!0}}function b(t,e,r){var n=!1;if((void 0===e||e<0)&&(e=0),e>this.length)return"";if((void 0===r||r>this.length)&&(r=this.length),r<=0)return"";if(r>>>=0,e>>>=0,r<=e)return"";for(t||(t="utf8");;)switch(t){case"hex":return D(this,e,r);case"utf8":case"utf-8":return q(this,e,r);case"ascii":return C(this,e,r);case"latin1":case"binary":return B(this,e,r);case"base64":return L(this,e,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return j(this,e,r);default:if(n)throw new TypeError("Unknown encoding: "+t);t=(t+"").toLowerCase(),n=!0}}function y(t,e,r){var n=t[e];t[e]=t[r],t[r]=n}function v(t,e,r,n,i){if(0===t.length)return-1;if("string"==typeof r?(n=r,r=0):r>2147483647?r=2147483647:r<-2147483648&&(r=-2147483648),r=+r,isNaN(r)&&(r=i?0:t.length-1),r<0&&(r=t.length+r),r>=t.length){if(i)return-1;r=t.length-1}else if(r<0){if(!i)return-1;r=0}if("string"==typeof e&&(e=o.from(e,n)),o.isBuffer(e))return 0===e.length?-1:w(t,e,r,n,i);if("number"==typeof e)return e=255&e,o.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(t,e,r):Uint8Array.prototype.lastIndexOf.call(t,e,r):w(t,[e],r,n,i);throw new TypeError("val must be string, number or Buffer")}function w(t,e,r,n,i){function s(t,e){return 1===o?t[e]:t.readUInt16BE(e*o)}var o=1,a=t.length,c=e.length;if(void 0!==n&&(n=String(n).toLowerCase(),"ucs2"===n||"ucs-2"===n||"utf16le"===n||"utf-16le"===n)){if(t.length<2||e.length<2)return-1;o=2,a/=2,c/=2,r/=2}var u;if(i){var h=-1;for(u=r;u<a;u++)if(s(t,u)===s(e,h===-1?0:u-h)){if(h===-1&&(h=u),u-h+1===c)return h*o}else h!==-1&&(u-=u-h),h=-1}else for(r+c>a&&(r=a-c),u=r;u>=0;u--){for(var l=!0,f=0;f<c;f++)if(s(t,u+f)!==s(e,f)){l=!1;break}if(l)return u}return-1}function x(t,e,r,n){r=Number(r)||0;var i=t.length-r;n?(n=Number(n),n>i&&(n=i)):n=i;var s=e.length;if(s%2!==0)throw new TypeError("Invalid hex string");n>s/2&&(n=s/2);for(var o=0;o<n;++o){var a=parseInt(e.substr(2*o,2),16);if(isNaN(a))return o;t[r+o]=a}return o}function S(t,e,r,n){return Q(F(e,t.length-r),t,r,n)}function E(t,e,r,n){return Q(G(e),t,r,n)}function T(t,e,r,n){return E(t,e,r,n)}function A(t,e,r,n){return Q(X(e),t,r,n)}function k(t,e,r,n){return Q(W(e,t.length-r),t,r,n)}function L(t,e,r){return 0===e&&r===t.length?Z.fromByteArray(t):Z.fromByteArray(t.slice(e,r))}function q(t,e,r){r=Math.min(t.length,r);for(var n=[],i=e;i<r;){var s=t[i],o=null,a=s>239?4:s>223?3:s>191?2:1;if(i+a<=r){var c,u,h,l;switch(a){case 1:s<128&&(o=s);break;case 2:c=t[i+1],128===(192&c)&&(l=(31&s)<<6|63&c,l>127&&(o=l));break;case 3:c=t[i+1],u=t[i+2],128===(192&c)&&128===(192&u)&&(l=(15&s)<<12|(63&c)<<6|63&u,l>2047&&(l<55296||l>57343)&&(o=l));break;case 4:c=t[i+1],u=t[i+2],h=t[i+3],128===(192&c)&&128===(192&u)&&128===(192&h)&&(l=(15&s)<<18|(63&c)<<12|(63&u)<<6|63&h,l>65535&&l<1114112&&(o=l))}}null===o?(o=65533,a=1):o>65535&&(o-=65536,n.push(o>>>10&1023|55296),o=56320|1023&o),n.push(o),i+=a}return R(n)}function R(t){var e=t.length;if(e<=tt)return String.fromCharCode.apply(String,t);for(var r="",n=0;n<e;)r+=String.fromCharCode.apply(String,t.slice(n,n+=tt));return r}function C(t,e,r){var n="";r=Math.min(t.length,r);for(var i=e;i<r;++i)n+=String.fromCharCode(127&t[i]);return n}function B(t,e,r){var n="";r=Math.min(t.length,r);for(var i=e;i<r;++i)n+=String.fromCharCode(t[i]);return n}function D(t,e,r){var n=t.length;(!e||e<0)&&(e=0),(!r||r<0||r>n)&&(r=n);for(var i="",s=e;s<r;++s)i+=Y(t[s]);return i}function j(t,e,r){for(var n=t.slice(e,r),i="",s=0;s<n.length;s+=2)i+=String.fromCharCode(n[s]+256*n[s+1]);return i}function N(t,e,r){if(t%1!==0||t<0)throw new RangeError("offset is not uint");if(t+e>r)throw new RangeError("Trying to access beyond buffer length")}function O(t,e,r,n,i,s){if(!o.isBuffer(t))throw new TypeError('"buffer" argument must be a Buffer instance');if(e>i||e<s)throw new RangeError('"value" argument is out of bounds');if(r+n>t.length)throw new RangeError("Index out of range")}function M(t,e,r,n){e<0&&(e=65535+e+1);for(var i=0,s=Math.min(t.length-r,2);i<s;++i)t[r+i]=(e&255<<8*(n?i:1-i))>>>8*(n?i:1-i)}function I(t,e,r,n){e<0&&(e=4294967295+e+1);for(var i=0,s=Math.min(t.length-r,4);i<s;++i)t[r+i]=e>>>8*(n?i:3-i)&255}function P(t,e,r,n,i,s){if(r+n>t.length)throw new RangeError("Index out of range");if(r<0)throw new RangeError("Index out of range")}function U(t,e,r,n,i){return i||P(t,e,r,4,3.4028234663852886e38,-3.4028234663852886e38),K.write(t,e,r,n,23,4),r+4}function H(t,e,r,n,i){return i||P(t,e,r,8,1.7976931348623157e308,-1.7976931348623157e308),K.write(t,e,r,n,52,8),r+8}function V(t){if(t=z(t).replace(et,""),t.length<2)return"";for(;t.length%4!==0;)t+="=";return t}function z(t){return t.trim?t.trim():t.replace(/^\s+|\s+$/g,"")}function Y(t){return t<16?"0"+t.toString(16):t.toString(16)}function F(t,e){e=e||1/0;for(var r,n=t.length,i=null,s=[],o=0;o<n;++o){if(r=t.charCodeAt(o),r>55295&&r<57344){if(!i){if(r>56319){(e-=3)>-1&&s.push(239,191,189);continue}if(o+1===n){(e-=3)>-1&&s.push(239,191,189);continue}i=r;continue}if(r<56320){(e-=3)>-1&&s.push(239,191,189),i=r;continue}r=(i-55296<<10|r-56320)+65536}else i&&(e-=3)>-1&&s.push(239,191,189);if(i=null,r<128){if((e-=1)<0)break;s.push(r)}else if(r<2048){if((e-=2)<0)break;s.push(r>>6|192,63&r|128)}else if(r<65536){if((e-=3)<0)break;s.push(r>>12|224,r>>6&63|128,63&r|128)}else{if(!(r<1114112))throw new Error("Invalid code point");if((e-=4)<0)break;s.push(r>>18|240,r>>12&63|128,r>>6&63|128,63&r|128)}}return s}function G(t){for(var e=[],r=0;r<t.length;++r)e.push(255&t.charCodeAt(r));return e}function W(t,e){for(var r,n,i,s=[],o=0;o<t.length&&!((e-=2)<0);++o)r=t.charCodeAt(o),n=r>>8,i=r%256,s.push(i),s.push(n);return s}function X(t){return Z.toByteArray(V(t))}function Q(t,e,r,n){for(var i=0;i<n&&!(i+r>=e.length||i>=t.length);++i)e[i+r]=t[i];return i}function J(t){return t!==t}var Z=t("base64-js"),K=t("ieee754"),$=t("isarray");r.Buffer=o,r.SlowBuffer=_,r.INSPECT_MAX_BYTES=50,o.TYPED_ARRAY_SUPPORT=void 0!==e.TYPED_ARRAY_SUPPORT?e.TYPED_ARRAY_SUPPORT:n(),r.kMaxLength=i(),o.poolSize=8192,o._augment=function(t){return t.__proto__=o.prototype,t},o.from=function(t,e,r){return a(null,t,e,r)},o.TYPED_ARRAY_SUPPORT&&(o.prototype.__proto__=Uint8Array.prototype,o.__proto__=Uint8Array,"undefined"!=typeof Symbol&&Symbol.species&&o[Symbol.species]===o&&Object.defineProperty(o,Symbol.species,{value:null,configurable:!0})),o.alloc=function(t,e,r){return u(null,t,e,r)},o.allocUnsafe=function(t){return h(null,t)},o.allocUnsafeSlow=function(t){return h(null,t)},o.isBuffer=function(t){return!(null==t||!t._isBuffer)},o.compare=function(t,e){if(!o.isBuffer(t)||!o.isBuffer(e))throw new TypeError("Arguments must be Buffers");if(t===e)return 0;for(var r=t.length,n=e.length,i=0,s=Math.min(r,n);i<s;++i)if(t[i]!==e[i]){r=t[i],n=e[i];break}return r<n?-1:n<r?1:0},o.isEncoding=function(t){switch(String(t).toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"latin1":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return!0;default:return!1}},o.concat=function(t,e){if(!$(t))throw new TypeError('"list" argument must be an Array of Buffers');if(0===t.length)return o.alloc(0);var r;if(void 0===e)for(e=0,r=0;r<t.length;++r)e+=t[r].length;var n=o.allocUnsafe(e),i=0;for(r=0;r<t.length;++r){var s=t[r];if(!o.isBuffer(s))throw new TypeError('"list" argument must be an Array of Buffers');s.copy(n,i),i+=s.length}return n},o.byteLength=m,o.prototype._isBuffer=!0,o.prototype.swap16=function(){var t=this.length;if(t%2!==0)throw new RangeError("Buffer size must be a multiple of 16-bits");for(var e=0;e<t;e+=2)y(this,e,e+1);return this},o.prototype.swap32=function(){var t=this.length;if(t%4!==0)throw new RangeError("Buffer size must be a multiple of 32-bits");for(var e=0;e<t;e+=4)y(this,e,e+3),y(this,e+1,e+2);return this},o.prototype.swap64=function(){var t=this.length;if(t%8!==0)throw new RangeError("Buffer size must be a multiple of 64-bits");for(var e=0;e<t;e+=8)y(this,e,e+7),y(this,e+1,e+6),y(this,e+2,e+5),y(this,e+3,e+4);return this},o.prototype.toString=function(){var t=0|this.length;return 0===t?"":0===arguments.length?q(this,0,t):b.apply(this,arguments)},o.prototype.equals=function(t){if(!o.isBuffer(t))throw new TypeError("Argument must be a Buffer");return this===t||0===o.compare(this,t)},o.prototype.inspect=function(){var t="",e=r.INSPECT_MAX_BYTES;return this.length>0&&(t=this.toString("hex",0,e).match(/.{2}/g).join(" "),this.length>e&&(t+=" ... ")),"<Buffer "+t+">"},o.prototype.compare=function(t,e,r,n,i){if(!o.isBuffer(t))throw new TypeError("Argument must be a Buffer");if(void 0===e&&(e=0),void 0===r&&(r=t?t.length:0),void 0===n&&(n=0),void 0===i&&(i=this.length),e<0||r>t.length||n<0||i>this.length)throw new RangeError("out of range index");if(n>=i&&e>=r)return 0;if(n>=i)return-1;if(e>=r)return 1;if(e>>>=0,r>>>=0,n>>>=0,i>>>=0,this===t)return 0;for(var s=i-n,a=r-e,c=Math.min(s,a),u=this.slice(n,i),h=t.slice(e,r),l=0;l<c;++l)if(u[l]!==h[l]){s=u[l],a=h[l];break}return s<a?-1:a<s?1:0},o.prototype.includes=function(t,e,r){return this.indexOf(t,e,r)!==-1},o.prototype.indexOf=function(t,e,r){return v(this,t,e,r,!0)},o.prototype.lastIndexOf=function(t,e,r){return v(this,t,e,r,!1)},o.prototype.write=function(t,e,r,n){if(void 0===e)n="utf8",r=this.length,e=0;else if(void 0===r&&"string"==typeof e)n=e,r=this.length,e=0;else{if(!isFinite(e))throw new Error("Buffer.write(string, encoding, offset[, length]) is no longer supported");e=0|e,isFinite(r)?(r=0|r,void 0===n&&(n="utf8")):(n=r,r=void 0)}var i=this.length-e;if((void 0===r||r>i)&&(r=i),t.length>0&&(r<0||e<0)||e>this.length)throw new RangeError("Attempt to write outside buffer bounds");n||(n="utf8");for(var s=!1;;)switch(n){case"hex":return x(this,t,e,r);case"utf8":case"utf-8":return S(this,t,e,r);case"ascii":return E(this,t,e,r);case"latin1":case"binary":return T(this,t,e,r);case"base64":return A(this,t,e,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return k(this,t,e,r);default:if(s)throw new TypeError("Unknown encoding: "+n);n=(""+n).toLowerCase(),s=!0}},o.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var tt=4096;o.prototype.slice=function(t,e){var r=this.length;t=~~t,e=void 0===e?r:~~e,t<0?(t+=r,t<0&&(t=0)):t>r&&(t=r),e<0?(e+=r,e<0&&(e=0)):e>r&&(e=r),e<t&&(e=t);var n;if(o.TYPED_ARRAY_SUPPORT)n=this.subarray(t,e),n.__proto__=o.prototype;else{var i=e-t;n=new o(i,(void 0));for(var s=0;s<i;++s)n[s]=this[s+t]}return n},o.prototype.readUIntLE=function(t,e,r){t=0|t,e=0|e,r||N(t,e,this.length);for(var n=this[t],i=1,s=0;++s<e&&(i*=256);)n+=this[t+s]*i;return n},o.prototype.readUIntBE=function(t,e,r){t=0|t,e=0|e,r||N(t,e,this.length);for(var n=this[t+--e],i=1;e>0&&(i*=256);)n+=this[t+--e]*i;return n},o.prototype.readUInt8=function(t,e){return e||N(t,1,this.length),this[t]},o.prototype.readUInt16LE=function(t,e){return e||N(t,2,this.length),this[t]|this[t+1]<<8},o.prototype.readUInt16BE=function(t,e){return e||N(t,2,this.length),this[t]<<8|this[t+1]},o.prototype.readUInt32LE=function(t,e){return e||N(t,4,this.length),(this[t]|this[t+1]<<8|this[t+2]<<16)+16777216*this[t+3]},o.prototype.readUInt32BE=function(t,e){return e||N(t,4,this.length),16777216*this[t]+(this[t+1]<<16|this[t+2]<<8|this[t+3])},o.prototype.readIntLE=function(t,e,r){t=0|t,e=0|e,r||N(t,e,this.length);for(var n=this[t],i=1,s=0;++s<e&&(i*=256);)n+=this[t+s]*i;return i*=128,n>=i&&(n-=Math.pow(2,8*e)),n},o.prototype.readIntBE=function(t,e,r){t=0|t,e=0|e,r||N(t,e,this.length);for(var n=e,i=1,s=this[t+--n];n>0&&(i*=256);)s+=this[t+--n]*i;return i*=128,s>=i&&(s-=Math.pow(2,8*e)),s},o.prototype.readInt8=function(t,e){return e||N(t,1,this.length),128&this[t]?(255-this[t]+1)*-1:this[t]},o.prototype.readInt16LE=function(t,e){e||N(t,2,this.length);var r=this[t]|this[t+1]<<8;return 32768&r?4294901760|r:r},o.prototype.readInt16BE=function(t,e){e||N(t,2,this.length);var r=this[t+1]|this[t]<<8;return 32768&r?4294901760|r:r},o.prototype.readInt32LE=function(t,e){return e||N(t,4,this.length),this[t]|this[t+1]<<8|this[t+2]<<16|this[t+3]<<24},o.prototype.readInt32BE=function(t,e){return e||N(t,4,this.length),this[t]<<24|this[t+1]<<16|this[t+2]<<8|this[t+3]},o.prototype.readFloatLE=function(t,e){return e||N(t,4,this.length),K.read(this,t,!0,23,4)},o.prototype.readFloatBE=function(t,e){return e||N(t,4,this.length),K.read(this,t,!1,23,4)},o.prototype.readDoubleLE=function(t,e){return e||N(t,8,this.length),K.read(this,t,!0,52,8)},o.prototype.readDoubleBE=function(t,e){return e||N(t,8,this.length),K.read(this,t,!1,52,8)},o.prototype.writeUIntLE=function(t,e,r,n){if(t=+t,e=0|e,r=0|r,!n){var i=Math.pow(2,8*r)-1;O(this,t,e,r,i,0)}var s=1,o=0;for(this[e]=255&t;++o<r&&(s*=256);)this[e+o]=t/s&255;return e+r},o.prototype.writeUIntBE=function(t,e,r,n){if(t=+t,e=0|e,r=0|r,!n){var i=Math.pow(2,8*r)-1;O(this,t,e,r,i,0)}var s=r-1,o=1;for(this[e+s]=255&t;--s>=0&&(o*=256);)this[e+s]=t/o&255;return e+r},o.prototype.writeUInt8=function(t,e,r){return t=+t,e=0|e,r||O(this,t,e,1,255,0),o.TYPED_ARRAY_SUPPORT||(t=Math.floor(t)),this[e]=255&t,e+1},o.prototype.writeUInt16LE=function(t,e,r){return t=+t,e=0|e,r||O(this,t,e,2,65535,0),o.TYPED_ARRAY_SUPPORT?(this[e]=255&t,this[e+1]=t>>>8):M(this,t,e,!0),e+2},o.prototype.writeUInt16BE=function(t,e,r){return t=+t,e=0|e,r||O(this,t,e,2,65535,0),o.TYPED_ARRAY_SUPPORT?(this[e]=t>>>8,this[e+1]=255&t):M(this,t,e,!1),e+2},o.prototype.writeUInt32LE=function(t,e,r){return t=+t,e=0|e,r||O(this,t,e,4,4294967295,0),o.TYPED_ARRAY_SUPPORT?(this[e+3]=t>>>24,this[e+2]=t>>>16,this[e+1]=t>>>8,this[e]=255&t):I(this,t,e,!0),e+4},o.prototype.writeUInt32BE=function(t,e,r){return t=+t,e=0|e,r||O(this,t,e,4,4294967295,0),o.TYPED_ARRAY_SUPPORT?(this[e]=t>>>24,this[e+1]=t>>>16,this[e+2]=t>>>8,this[e+3]=255&t):I(this,t,e,!1),e+4},o.prototype.writeIntLE=function(t,e,r,n){if(t=+t,e=0|e,!n){var i=Math.pow(2,8*r-1);O(this,t,e,r,i-1,-i)}var s=0,o=1,a=0;for(this[e]=255&t;++s<r&&(o*=256);)t<0&&0===a&&0!==this[e+s-1]&&(a=1),this[e+s]=(t/o>>0)-a&255;return e+r},o.prototype.writeIntBE=function(t,e,r,n){if(t=+t,e=0|e,!n){var i=Math.pow(2,8*r-1);O(this,t,e,r,i-1,-i)}var s=r-1,o=1,a=0;for(this[e+s]=255&t;--s>=0&&(o*=256);)t<0&&0===a&&0!==this[e+s+1]&&(a=1),this[e+s]=(t/o>>0)-a&255;return e+r},o.prototype.writeInt8=function(t,e,r){return t=+t,e=0|e,r||O(this,t,e,1,127,-128),o.TYPED_ARRAY_SUPPORT||(t=Math.floor(t)),t<0&&(t=255+t+1),this[e]=255&t,e+1},o.prototype.writeInt16LE=function(t,e,r){return t=+t,e=0|e,r||O(this,t,e,2,32767,-32768),o.TYPED_ARRAY_SUPPORT?(this[e]=255&t,this[e+1]=t>>>8):M(this,t,e,!0),e+2},o.prototype.writeInt16BE=function(t,e,r){return t=+t,e=0|e,r||O(this,t,e,2,32767,-32768),o.TYPED_ARRAY_SUPPORT?(this[e]=t>>>8,this[e+1]=255&t):M(this,t,e,!1),e+2},o.prototype.writeInt32LE=function(t,e,r){return t=+t,e=0|e,r||O(this,t,e,4,2147483647,-2147483648),o.TYPED_ARRAY_SUPPORT?(this[e]=255&t,this[e+1]=t>>>8,this[e+2]=t>>>16,this[e+3]=t>>>24):I(this,t,e,!0),e+4},o.prototype.writeInt32BE=function(t,e,r){return t=+t,e=0|e,r||O(this,t,e,4,2147483647,-2147483648),t<0&&(t=4294967295+t+1),o.TYPED_ARRAY_SUPPORT?(this[e]=t>>>24,this[e+1]=t>>>16,this[e+2]=t>>>8,this[e+3]=255&t):I(this,t,e,!1),e+4},o.prototype.writeFloatLE=function(t,e,r){return U(this,t,e,!0,r)},o.prototype.writeFloatBE=function(t,e,r){return U(this,t,e,!1,r)},o.prototype.writeDoubleLE=function(t,e,r){return H(this,t,e,!0,r)},o.prototype.writeDoubleBE=function(t,e,r){return H(this,t,e,!1,r)},o.prototype.copy=function(t,e,r,n){if(r||(r=0),n||0===n||(n=this.length),e>=t.length&&(e=t.length),e||(e=0),n>0&&n<r&&(n=r),n===r)return 0;if(0===t.length||0===this.length)return 0;if(e<0)throw new RangeError("targetStart out of bounds");if(r<0||r>=this.length)throw new RangeError("sourceStart out of bounds");if(n<0)throw new RangeError("sourceEnd out of bounds");n>this.length&&(n=this.length),t.length-e<n-r&&(n=t.length-e+r);var i,s=n-r;if(this===t&&r<e&&e<n)for(i=s-1;i>=0;--i)t[i+e]=this[i+r];else if(s<1e3||!o.TYPED_ARRAY_SUPPORT)for(i=0;i<s;++i)t[i+e]=this[i+r];else Uint8Array.prototype.set.call(t,this.subarray(r,r+s),e);return s},o.prototype.fill=function(t,e,r,n){if("string"==typeof t){if("string"==typeof e?(n=e,e=0,r=this.length):"string"==typeof r&&(n=r,r=this.length),1===t.length){var i=t.charCodeAt(0);i<256&&(t=i)}if(void 0!==n&&"string"!=typeof n)throw new TypeError("encoding must be a string");if("string"==typeof n&&!o.isEncoding(n))throw new TypeError("Unknown encoding: "+n)}else"number"==typeof t&&(t=255&t);if(e<0||this.length<e||this.length<r)throw new RangeError("Out of range index");if(r<=e)return this;e>>>=0,r=void 0===r?this.length:r>>>0,t||(t=0);var s;if("number"==typeof t)for(s=e;s<r;++s)this[s]=t;else{var a=o.isBuffer(t)?t:F(new o(t,n).toString()),c=a.length;for(s=0;s<r-e;++s)this[s+e]=a[s%c]}return this};var et=/[^+\/0-9A-Za-z-_]/g}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"base64-js":2,ieee754:37,isarray:40}],6:[function(t,e,r){(function(t){function e(t){return Array.isArray?Array.isArray(t):"[object Array]"===_(t)}function n(t){return"boolean"==typeof t}function i(t){return null===t}function s(t){return null==t}function o(t){return"number"==typeof t}function a(t){return"string"==typeof t}function c(t){return"symbol"==typeof t}function u(t){return void 0===t}function h(t){return"[object RegExp]"===_(t)}function l(t){return"object"==typeof t&&null!==t}function f(t){return"[object Date]"===_(t)}function p(t){return"[object Error]"===_(t)||t instanceof Error}function d(t){return"function"==typeof t}function g(t){return null===t||"boolean"==typeof t||"number"==typeof t||"string"==typeof t||"symbol"==typeof t||"undefined"==typeof t}function _(t){return Object.prototype.toString.call(t)}r.isArray=e,r.isBoolean=n,r.isNull=i,r.isNullOrUndefined=s,r.isNumber=o,r.isString=a,r.isSymbol=c,r.isUndefined=u,r.isRegExp=h,r.isObject=l,r.isDate=f,r.isError=p,r.isFunction=d,r.isPrimitive=g,r.isBuffer=t.isBuffer}).call(this,{isBuffer:t("../../is-buffer/index.js")})},{"../../is-buffer/index.js":39}],7:[function(t,e,r){function n(t,e){if(t){var r,n="";for(var i in t)r=t[i],n&&(n+=" "),n+=!r&&l[i]?i:i+'="'+(e.decodeEntities?h.encodeXML(r):r)+'"';return n}}function i(t,e){"svg"===t.name&&(e={decodeEntities:e.decodeEntities,xmlMode:!0});var r="<"+t.name,i=n(t.attribs,e);return i&&(r+=" "+i),!e.xmlMode||t.children&&0!==t.children.length?(r+=">",t.children&&(r+=d(t.children,e)),p[t.name]&&!e.xmlMode||(r+="</"+t.name+">")):r+="/>",r}function s(t){return"<"+t.data+">"}function o(t,e){var r=t.data||"";return!e.decodeEntities||t.parent&&t.parent.name in f||(r=h.encodeXML(r)),r}function a(t){return"<![CDATA["+t.children[0].data+"]]>"}function c(t){return"<!--"+t.data+"-->"}var u=t("domelementtype"),h=t("entities"),l={__proto__:null,allowfullscreen:!0,async:!0,autofocus:!0,autoplay:!0,checked:!0,controls:!0,"default":!0,defer:!0,disabled:!0,hidden:!0,ismap:!0,loop:!0,multiple:!0,muted:!0,open:!0,readonly:!0,required:!0,reversed:!0,scoped:!0,seamless:!0,selected:!0,typemustmatch:!0},f={__proto__:null,style:!0,script:!0,xmp:!0,iframe:!0,noembed:!0,noframes:!0,plaintext:!0,noscript:!0},p={__proto__:null,area:!0,base:!0,basefont:!0,br:!0,col:!0,command:!0,embed:!0,frame:!0,hr:!0,img:!0,input:!0,isindex:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0},d=e.exports=function(t,e){Array.isArray(t)||t.cheerio||(t=[t]),e=e||{};for(var r="",n=0;n<t.length;n++){var h=t[n];r+="root"===h.type?d(h.children,e):u.isTag(h)?i(h,e):h.type===u.Directive?s(h):h.type===u.Comment?c(h):h.type===u.CDATA?a(h):o(h,e)}return r}},{domelementtype:8,entities:20}],8:[function(t,e,r){e.exports={Text:"text",Directive:"directive",Comment:"comment",Script:"script",Style:"style",Tag:"tag",CDATA:"cdata",isTag:function(t){return"tag"===t.type||"script"===t.type||"style"===t.type}}},{}],9:[function(t,e,r){e.exports={Text:"text",Directive:"directive",Comment:"comment",Script:"script",Style:"style",Tag:"tag",CDATA:"cdata",Doctype:"doctype",isTag:function(t){return"tag"===t.type||"script"===t.type||"style"===t.type}}},{}],10:[function(t,e,r){function n(t,e,r){"object"==typeof t?(r=e,e=t,t=null):"function"==typeof e&&(r=e,e=c),this._callback=t,this._options=e||c,this._elementCB=r,this.dom=[],this._done=!1,this._tagStack=[],this._parser=this._parser||null}var i=t("domelementtype"),s=/\s+/g,o=t("./lib/node"),a=t("./lib/element"),c={normalizeWhitespace:!1,withStartIndices:!1};n.prototype.onparserinit=function(t){this._parser=t},n.prototype.onreset=function(){n.call(this,this._callback,this._options,this._elementCB)},n.prototype.onend=function(){this._done||(this._done=!0,this._parser=null,this._handleCallback(null))},n.prototype._handleCallback=n.prototype.onerror=function(t){if("function"==typeof this._callback)this._callback(t,this.dom);else if(t)throw t},n.prototype.onclosetag=function(){var t=this._tagStack.pop();this._elementCB&&this._elementCB(t)},n.prototype._addDomElement=function(t){var e=this._tagStack[this._tagStack.length-1],r=e?e.children:this.dom,n=r[r.length-1];
+t.next=null,this._options.withStartIndices&&(t.startIndex=this._parser.startIndex),this._options.withDomLvl1&&(t.__proto__="tag"===t.type?a:o),n?(t.prev=n,n.next=t):t.prev=null,r.push(t),t.parent=e||null},n.prototype.onopentag=function(t,e){var r={type:"script"===t?i.Script:"style"===t?i.Style:i.Tag,name:t,attribs:e,children:[]};this._addDomElement(r),this._tagStack.push(r)},n.prototype.ontext=function(t){var e,r=this._options.normalizeWhitespace||this._options.ignoreWhitespace;!this._tagStack.length&&this.dom.length&&(e=this.dom[this.dom.length-1]).type===i.Text?r?e.data=(e.data+t).replace(s," "):e.data+=t:this._tagStack.length&&(e=this._tagStack[this._tagStack.length-1])&&(e=e.children[e.children.length-1])&&e.type===i.Text?r?e.data=(e.data+t).replace(s," "):e.data+=t:(r&&(t=t.replace(s," ")),this._addDomElement({data:t,type:i.Text}))},n.prototype.oncomment=function(t){var e=this._tagStack[this._tagStack.length-1];if(e&&e.type===i.Comment)return void(e.data+=t);var r={data:t,type:i.Comment};this._addDomElement(r),this._tagStack.push(r)},n.prototype.oncdatastart=function(){var t={children:[{data:"",type:i.Text}],type:i.CDATA};this._addDomElement(t),this._tagStack.push(t)},n.prototype.oncommentend=n.prototype.oncdataend=function(){this._tagStack.pop()},n.prototype.onprocessinginstruction=function(t,e){this._addDomElement({name:t,data:e,type:i.Directive})},e.exports=n},{"./lib/element":11,"./lib/node":12,domelementtype:9}],11:[function(t,e,r){var n=t("./node"),i=e.exports=Object.create(n),s={tagName:"name"};Object.keys(s).forEach(function(t){var e=s[t];Object.defineProperty(i,t,{get:function(){return this[e]||null},set:function(t){return this[e]=t,t}})})},{"./node":12}],12:[function(t,e,r){var n=e.exports={get firstChild(){var t=this.children;return t&&t[0]||null},get lastChild(){var t=this.children;return t&&t[t.length-1]||null},get nodeType(){return s[this.type]||s.element}},i={tagName:"name",childNodes:"children",parentNode:"parent",previousSibling:"prev",nextSibling:"next",nodeValue:"data"},s={element:1,text:3,cdata:4,comment:8};Object.keys(i).forEach(function(t){var e=i[t];Object.defineProperty(n,t,{get:function(){return this[e]||null},set:function(t){return this[e]=t,t}})})},{}],13:[function(t,e,r){var n=e.exports;[t("./lib/stringify"),t("./lib/traversal"),t("./lib/manipulation"),t("./lib/querying"),t("./lib/legacy"),t("./lib/helpers")].forEach(function(t){Object.keys(t).forEach(function(e){n[e]=t[e].bind(n)})})},{"./lib/helpers":14,"./lib/legacy":15,"./lib/manipulation":16,"./lib/querying":17,"./lib/stringify":18,"./lib/traversal":19}],14:[function(t,e,r){r.removeSubsets=function(t){for(var e,r,n,i=t.length;--i>-1;){for(e=r=t[i],t[i]=null,n=!0;r;){if(t.indexOf(r)>-1){n=!1,t.splice(i,1);break}r=r.parent}n&&(t[i]=e)}return t};var n={DISCONNECTED:1,PRECEDING:2,FOLLOWING:4,CONTAINS:8,CONTAINED_BY:16},i=r.compareDocumentPosition=function(t,e){var r,i,s,o,a,c,u=[],h=[];if(t===e)return 0;for(r=t;r;)u.unshift(r),r=r.parent;for(r=e;r;)h.unshift(r),r=r.parent;for(c=0;u[c]===h[c];)c++;return 0===c?n.DISCONNECTED:(i=u[c-1],s=i.children,o=u[c],a=h[c],s.indexOf(o)>s.indexOf(a)?i===e?n.FOLLOWING|n.CONTAINED_BY:n.FOLLOWING:i===t?n.PRECEDING|n.CONTAINS:n.PRECEDING)};r.uniqueSort=function(t){var e,r,s=t.length;for(t=t.slice();--s>-1;)e=t[s],r=t.indexOf(e),r>-1&&r<s&&t.splice(s,1);return t.sort(function(t,e){var r=i(t,e);return r&n.PRECEDING?-1:r&n.FOLLOWING?1:0}),t}},{}],15:[function(t,e,r){function n(t,e){return"function"==typeof e?function(r){return r.attribs&&e(r.attribs[t])}:function(r){return r.attribs&&r.attribs[t]===e}}function i(t,e){return function(r){return t(r)||e(r)}}var s=t("domelementtype"),o=r.isTag=s.isTag;r.testElement=function(t,e){for(var r in t)if(t.hasOwnProperty(r)){if("tag_name"===r){if(!o(e)||!t.tag_name(e.name))return!1}else if("tag_type"===r){if(!t.tag_type(e.type))return!1}else if("tag_contains"===r){if(o(e)||!t.tag_contains(e.data))return!1}else if(!e.attribs||!t[r](e.attribs[r]))return!1}else;return!0};var a={tag_name:function(t){return"function"==typeof t?function(e){return o(e)&&t(e.name)}:"*"===t?o:function(e){return o(e)&&e.name===t}},tag_type:function(t){return"function"==typeof t?function(e){return t(e.type)}:function(e){return e.type===t}},tag_contains:function(t){return"function"==typeof t?function(e){return!o(e)&&t(e.data)}:function(e){return!o(e)&&e.data===t}}};r.getElements=function(t,e,r,s){var o=Object.keys(t).map(function(e){var r=t[e];return e in a?a[e](r):n(e,r)});return 0===o.length?[]:this.filter(o.reduce(i),e,r,s)},r.getElementById=function(t,e,r){return Array.isArray(e)||(e=[e]),this.findOne(n("id",t),e,r!==!1)},r.getElementsByTagName=function(t,e,r,n){return this.filter(a.tag_name(t),e,r,n)},r.getElementsByTagType=function(t,e,r,n){return this.filter(a.tag_type(t),e,r,n)}},{domelementtype:9}],16:[function(t,e,r){r.removeElement=function(t){if(t.prev&&(t.prev.next=t.next),t.next&&(t.next.prev=t.prev),t.parent){var e=t.parent.children;e.splice(e.lastIndexOf(t),1)}},r.replaceElement=function(t,e){var r=e.prev=t.prev;r&&(r.next=e);var n=e.next=t.next;n&&(n.prev=e);var i=e.parent=t.parent;if(i){var s=i.children;s[s.lastIndexOf(t)]=e}},r.appendChild=function(t,e){if(e.parent=t,1!==t.children.push(e)){var r=t.children[t.children.length-2];r.next=e,e.prev=r,e.next=null}},r.append=function(t,e){var r=t.parent,n=t.next;if(e.next=n,e.prev=t,t.next=e,e.parent=r,n){if(n.prev=e,r){var i=r.children;i.splice(i.lastIndexOf(n),0,e)}}else r&&r.children.push(e)},r.prepend=function(t,e){var r=t.parent;if(r){var n=r.children;n.splice(n.lastIndexOf(t),0,e)}t.prev&&(t.prev.next=e),e.parent=r,e.prev=t.prev,e.next=t,t.prev=e}},{}],17:[function(t,e,r){function n(t,e,r,n){return Array.isArray(e)||(e=[e]),"number"==typeof n&&isFinite(n)||(n=1/0),i(t,e,r!==!1,n)}function i(t,e,r,n){for(var s,o=[],a=0,c=e.length;a<c&&!(t(e[a])&&(o.push(e[a]),--n<=0))&&(s=e[a].children,!(r&&s&&s.length>0&&(s=i(t,s,r,n),o=o.concat(s),n-=s.length,n<=0)));a++);return o}function s(t,e){for(var r=0,n=e.length;r<n;r++)if(t(e[r]))return e[r];return null}function o(t,e){for(var r=null,n=0,i=e.length;n<i&&!r;n++)u(e[n])&&(t(e[n])?r=e[n]:e[n].children.length>0&&(r=o(t,e[n].children)));return r}function a(t,e){for(var r=0,n=e.length;r<n;r++)if(u(e[r])&&(t(e[r])||e[r].children.length>0&&a(t,e[r].children)))return!0;return!1}function c(t,e){for(var r=[],n=0,i=e.length;n<i;n++)u(e[n])&&(t(e[n])&&r.push(e[n]),e[n].children.length>0&&(r=r.concat(c(t,e[n].children))));return r}var u=t("domelementtype").isTag;e.exports={filter:n,find:i,findOneChild:s,findOne:o,existsOne:a,findAll:c}},{domelementtype:9}],18:[function(t,e,r){function n(t,e){return t.children?t.children.map(function(t){return o(t,e)}).join(""):""}function i(t){return Array.isArray(t)?t.map(i).join(""):a(t)||t.type===s.CDATA?i(t.children):t.type===s.Text?t.data:""}var s=t("domelementtype"),o=t("dom-serializer"),a=s.isTag;e.exports={getInnerHTML:n,getOuterHTML:o,getText:i}},{"dom-serializer":7,domelementtype:9}],19:[function(t,e,r){var n=r.getChildren=function(t){return t.children},i=r.getParent=function(t){return t.parent};r.getSiblings=function(t){var e=i(t);return e?n(e):[t]},r.getAttributeValue=function(t,e){return t.attribs&&t.attribs[e]},r.hasAttrib=function(t,e){return!!t.attribs&&hasOwnProperty.call(t.attribs,e)},r.getName=function(t){return t.name}},{}],20:[function(t,e,r){var n=t("./lib/encode.js"),i=t("./lib/decode.js");r.decode=function(t,e){return(!e||e<=0?i.XML:i.HTML)(t)},r.decodeStrict=function(t,e){return(!e||e<=0?i.XML:i.HTMLStrict)(t)},r.encode=function(t,e){return(!e||e<=0?n.XML:n.HTML)(t)},r.encodeXML=n.XML,r.encodeHTML4=r.encodeHTML5=r.encodeHTML=n.HTML,r.decodeXML=r.decodeXMLStrict=i.XML,r.decodeHTML4=r.decodeHTML5=r.decodeHTML=i.HTML,r.decodeHTML4Strict=r.decodeHTML5Strict=r.decodeHTMLStrict=i.HTMLStrict,r.escape=n.escape},{"./lib/decode.js":21,"./lib/encode.js":23}],21:[function(t,e,r){function n(t){var e=Object.keys(t).join("|"),r=s(t);e+="|#[xX][\\da-fA-F]+|#\\d+";var n=new RegExp("&(?:"+e+");","g");return function(t){return String(t).replace(n,r)}}function i(t,e){return t<e?1:-1}function s(t){return function(e){return"#"===e.charAt(1)?u("X"===e.charAt(2)||"x"===e.charAt(2)?parseInt(e.substr(3),16):parseInt(e.substr(2),10)):t[e.slice(1,-1)]}}var o=t("../maps/entities.json"),a=t("../maps/legacy.json"),c=t("../maps/xml.json"),u=t("./decode_codepoint.js"),h=n(c),l=n(o),f=function(){function t(t){return";"!==t.substr(-1)&&(t+=";"),h(t)}for(var e=Object.keys(a).sort(i),r=Object.keys(o).sort(i),n=0,c=0;n<r.length;n++)e[c]===r[n]?(r[n]+=";?",c++):r[n]+=";";var u=new RegExp("&(?:"+r.join("|")+"|#[xX][\\da-fA-F]+;?|#\\d+;?)","g"),h=s(o);return function(e){return String(e).replace(u,t)}}();e.exports={XML:h,HTML:f,HTMLStrict:l}},{"../maps/entities.json":25,"../maps/legacy.json":26,"../maps/xml.json":27,"./decode_codepoint.js":22}],22:[function(t,e,r){function n(t){if(t>=55296&&t<=57343||t>1114111)return"�";t in i&&(t=i[t]);var e="";return t>65535&&(t-=65536,e+=String.fromCharCode(t>>>10&1023|55296),t=56320|1023&t),e+=String.fromCharCode(t)}var i=t("../maps/decode.json");e.exports=n},{"../maps/decode.json":24}],23:[function(t,e,r){function n(t){return Object.keys(t).sort().reduce(function(e,r){return e[t[r]]="&"+r+";",e},{})}function i(t){var e=[],r=[];return Object.keys(t).forEach(function(t){1===t.length?e.push("\\"+t):r.push(t)}),r.unshift("["+e.join("")+"]"),new RegExp(r.join("|"),"g")}function s(t){return"&#x"+t.charCodeAt(0).toString(16).toUpperCase()+";"}function o(t){var e=t.charCodeAt(0),r=t.charCodeAt(1),n=1024*(e-55296)+r-56320+65536;return"&#x"+n.toString(16).toUpperCase()+";"}function a(t,e){function r(e){return t[e]}return function(t){return t.replace(e,r).replace(d,o).replace(p,s)}}function c(t){return t.replace(g,s).replace(d,o).replace(p,s)}var u=n(t("../maps/xml.json")),h=i(u);r.XML=a(u,h);var l=n(t("../maps/entities.json")),f=i(l);r.HTML=a(l,f);var p=/[^\0-\x7F]/g,d=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,g=i(u);r.escape=c},{"../maps/entities.json":25,"../maps/xml.json":27}],24:[function(t,e,r){e.exports={0:65533,128:8364,130:8218,131:402,132:8222,133:8230,134:8224,135:8225,136:710,137:8240,138:352,139:8249,140:338,142:381,145:8216,146:8217,147:8220,148:8221,149:8226,150:8211,151:8212,152:732,153:8482,154:353,155:8250,156:339,158:382,159:376}},{}],25:[function(t,e,r){e.exports={Aacute:"Á",aacute:"á",Abreve:"Ă",abreve:"ă",ac:"∾",acd:"∿",acE:"∾̳",Acirc:"Â",acirc:"â",acute:"´",Acy:"А",acy:"а",AElig:"Æ",aelig:"æ",af:"⁡",Afr:"𝔄",afr:"𝔞",Agrave:"À",agrave:"à",alefsym:"ℵ",aleph:"ℵ",Alpha:"Α",alpha:"α",Amacr:"Ā",amacr:"ā",amalg:"⨿",amp:"&",AMP:"&",andand:"⩕",And:"⩓",and:"∧",andd:"⩜",andslope:"⩘",andv:"⩚",ang:"∠",ange:"⦤",angle:"∠",angmsdaa:"⦨",angmsdab:"⦩",angmsdac:"⦪",angmsdad:"⦫",angmsdae:"⦬",angmsdaf:"⦭",angmsdag:"⦮",angmsdah:"⦯",angmsd:"∡",angrt:"∟",angrtvb:"⊾",angrtvbd:"⦝",angsph:"∢",angst:"Å",angzarr:"⍼",Aogon:"Ą",aogon:"ą",Aopf:"𝔸",aopf:"𝕒",apacir:"⩯",ap:"≈",apE:"⩰",ape:"≊",apid:"≋",apos:"'",ApplyFunction:"⁡",approx:"≈",approxeq:"≊",Aring:"Å",aring:"å",Ascr:"𝒜",ascr:"𝒶",Assign:"≔",ast:"*",asymp:"≈",asympeq:"≍",Atilde:"Ã",atilde:"ã",Auml:"Ä",auml:"ä",awconint:"∳",awint:"⨑",backcong:"≌",backepsilon:"϶",backprime:"‵",backsim:"∽",backsimeq:"⋍",Backslash:"∖",Barv:"⫧",barvee:"⊽",barwed:"⌅",Barwed:"⌆",barwedge:"⌅",bbrk:"⎵",bbrktbrk:"⎶",bcong:"≌",Bcy:"Б",bcy:"б",bdquo:"„",becaus:"∵",because:"∵",Because:"∵",bemptyv:"⦰",bepsi:"϶",bernou:"ℬ",Bernoullis:"ℬ",Beta:"Β",beta:"β",beth:"ℶ",between:"≬",Bfr:"𝔅",bfr:"𝔟",bigcap:"⋂",bigcirc:"◯",bigcup:"⋃",bigodot:"⨀",bigoplus:"⨁",bigotimes:"⨂",bigsqcup:"⨆",bigstar:"★",bigtriangledown:"▽",bigtriangleup:"△",biguplus:"⨄",bigvee:"⋁",bigwedge:"⋀",bkarow:"⤍",blacklozenge:"⧫",blacksquare:"▪",blacktriangle:"▴",blacktriangledown:"▾",blacktriangleleft:"◂",blacktriangleright:"▸",blank:"␣",blk12:"▒",blk14:"░",blk34:"▓",block:"█",bne:"=⃥",bnequiv:"≡⃥",bNot:"⫭",bnot:"⌐",Bopf:"𝔹",bopf:"𝕓",bot:"⊥",bottom:"⊥",bowtie:"⋈",boxbox:"⧉",boxdl:"┐",boxdL:"╕",boxDl:"╖",boxDL:"╗",boxdr:"┌",boxdR:"╒",boxDr:"╓",boxDR:"╔",boxh:"─",boxH:"═",boxhd:"┬",boxHd:"╤",boxhD:"╥",boxHD:"╦",boxhu:"┴",boxHu:"╧",boxhU:"╨",boxHU:"╩",boxminus:"⊟",boxplus:"⊞",boxtimes:"⊠",boxul:"┘",boxuL:"╛",boxUl:"╜",boxUL:"╝",boxur:"└",boxuR:"╘",boxUr:"╙",boxUR:"╚",boxv:"│",boxV:"║",boxvh:"┼",boxvH:"╪",boxVh:"╫",boxVH:"╬",boxvl:"┤",boxvL:"╡",boxVl:"╢",boxVL:"╣",boxvr:"├",boxvR:"╞",boxVr:"╟",boxVR:"╠",bprime:"‵",breve:"˘",Breve:"˘",brvbar:"¦",bscr:"𝒷",Bscr:"ℬ",bsemi:"⁏",bsim:"∽",bsime:"⋍",bsolb:"⧅",bsol:"\\",bsolhsub:"⟈",bull:"•",bullet:"•",bump:"≎",bumpE:"⪮",bumpe:"≏",Bumpeq:"≎",bumpeq:"≏",Cacute:"Ć",cacute:"ć",capand:"⩄",capbrcup:"⩉",capcap:"⩋",cap:"∩",Cap:"⋒",capcup:"⩇",capdot:"⩀",CapitalDifferentialD:"ⅅ",caps:"∩︀",caret:"⁁",caron:"ˇ",Cayleys:"ℭ",ccaps:"⩍",Ccaron:"Č",ccaron:"č",Ccedil:"Ç",ccedil:"ç",Ccirc:"Ĉ",ccirc:"ĉ",Cconint:"∰",ccups:"⩌",ccupssm:"⩐",Cdot:"Ċ",cdot:"ċ",cedil:"¸",Cedilla:"¸",cemptyv:"⦲",cent:"¢",centerdot:"·",CenterDot:"·",cfr:"𝔠",Cfr:"ℭ",CHcy:"Ч",chcy:"ч",check:"✓",checkmark:"✓",Chi:"Χ",chi:"χ",circ:"ˆ",circeq:"≗",circlearrowleft:"↺",circlearrowright:"↻",circledast:"⊛",circledcirc:"⊚",circleddash:"⊝",CircleDot:"⊙",circledR:"®",circledS:"Ⓢ",CircleMinus:"⊖",CirclePlus:"⊕",CircleTimes:"⊗",cir:"○",cirE:"⧃",cire:"≗",cirfnint:"⨐",cirmid:"⫯",cirscir:"⧂",ClockwiseContourIntegral:"∲",CloseCurlyDoubleQuote:"”",CloseCurlyQuote:"’",clubs:"♣",clubsuit:"♣",colon:":",Colon:"∷",Colone:"⩴",colone:"≔",coloneq:"≔",comma:",",commat:"@",comp:"∁",compfn:"∘",complement:"∁",complexes:"ℂ",cong:"≅",congdot:"⩭",Congruent:"≡",conint:"∮",Conint:"∯",ContourIntegral:"∮",copf:"𝕔",Copf:"ℂ",coprod:"∐",Coproduct:"∐",copy:"©",COPY:"©",copysr:"℗",CounterClockwiseContourIntegral:"∳",crarr:"↵",cross:"✗",Cross:"⨯",Cscr:"𝒞",cscr:"𝒸",csub:"⫏",csube:"⫑",csup:"⫐",csupe:"⫒",ctdot:"⋯",cudarrl:"⤸",cudarrr:"⤵",cuepr:"⋞",cuesc:"⋟",cularr:"↶",cularrp:"⤽",cupbrcap:"⩈",cupcap:"⩆",CupCap:"≍",cup:"∪",Cup:"⋓",cupcup:"⩊",cupdot:"⊍",cupor:"⩅",cups:"∪︀",curarr:"↷",curarrm:"⤼",curlyeqprec:"⋞",curlyeqsucc:"⋟",curlyvee:"⋎",curlywedge:"⋏",curren:"¤",curvearrowleft:"↶",curvearrowright:"↷",cuvee:"⋎",cuwed:"⋏",cwconint:"∲",cwint:"∱",cylcty:"⌭",dagger:"†",Dagger:"‡",daleth:"ℸ",darr:"↓",Darr:"↡",dArr:"⇓",dash:"‐",Dashv:"⫤",dashv:"⊣",dbkarow:"⤏",dblac:"˝",Dcaron:"Ď",dcaron:"ď",Dcy:"Д",dcy:"д",ddagger:"‡",ddarr:"⇊",DD:"ⅅ",dd:"ⅆ",DDotrahd:"⤑",ddotseq:"⩷",deg:"°",Del:"∇",Delta:"Δ",delta:"δ",demptyv:"⦱",dfisht:"⥿",Dfr:"𝔇",dfr:"𝔡",dHar:"⥥",dharl:"⇃",dharr:"⇂",DiacriticalAcute:"´",DiacriticalDot:"˙",DiacriticalDoubleAcute:"˝",DiacriticalGrave:"`",DiacriticalTilde:"˜",diam:"⋄",diamond:"⋄",Diamond:"⋄",diamondsuit:"♦",diams:"♦",die:"¨",DifferentialD:"ⅆ",digamma:"ϝ",disin:"⋲",div:"÷",divide:"÷",divideontimes:"⋇",divonx:"⋇",DJcy:"Ђ",djcy:"ђ",dlcorn:"⌞",dlcrop:"⌍",dollar:"$",Dopf:"𝔻",dopf:"𝕕",Dot:"¨",dot:"˙",DotDot:"⃜",doteq:"≐",doteqdot:"≑",DotEqual:"≐",dotminus:"∸",dotplus:"∔",dotsquare:"⊡",doublebarwedge:"⌆",DoubleContourIntegral:"∯",DoubleDot:"¨",DoubleDownArrow:"⇓",DoubleLeftArrow:"⇐",DoubleLeftRightArrow:"⇔",DoubleLeftTee:"⫤",DoubleLongLeftArrow:"⟸",DoubleLongLeftRightArrow:"⟺",DoubleLongRightArrow:"⟹",DoubleRightArrow:"⇒",DoubleRightTee:"⊨",DoubleUpArrow:"⇑",DoubleUpDownArrow:"⇕",DoubleVerticalBar:"∥",DownArrowBar:"⤓",downarrow:"↓",DownArrow:"↓",Downarrow:"⇓",DownArrowUpArrow:"⇵",DownBreve:"̑",downdownarrows:"⇊",downharpoonleft:"⇃",downharpoonright:"⇂",DownLeftRightVector:"⥐",DownLeftTeeVector:"⥞",DownLeftVectorBar:"⥖",DownLeftVector:"↽",DownRightTeeVector:"⥟",DownRightVectorBar:"⥗",DownRightVector:"⇁",DownTeeArrow:"↧",DownTee:"⊤",drbkarow:"⤐",drcorn:"⌟",drcrop:"⌌",Dscr:"𝒟",dscr:"𝒹",DScy:"Ѕ",dscy:"ѕ",dsol:"⧶",Dstrok:"Đ",dstrok:"đ",dtdot:"⋱",dtri:"▿",dtrif:"▾",duarr:"⇵",duhar:"⥯",dwangle:"⦦",DZcy:"Џ",dzcy:"џ",dzigrarr:"⟿",Eacute:"É",eacute:"é",easter:"⩮",Ecaron:"Ě",ecaron:"ě",Ecirc:"Ê",ecirc:"ê",ecir:"≖",ecolon:"≕",Ecy:"Э",ecy:"э",eDDot:"⩷",Edot:"Ė",edot:"ė",eDot:"≑",ee:"ⅇ",efDot:"≒",Efr:"𝔈",efr:"𝔢",eg:"⪚",Egrave:"È",egrave:"è",egs:"⪖",egsdot:"⪘",el:"⪙",Element:"∈",elinters:"⏧",ell:"ℓ",els:"⪕",elsdot:"⪗",Emacr:"Ē",emacr:"ē",empty:"∅",emptyset:"∅",EmptySmallSquare:"◻",emptyv:"∅",EmptyVerySmallSquare:"▫",emsp13:" ",emsp14:" ",emsp:" ",ENG:"Ŋ",eng:"ŋ",ensp:" ",Eogon:"Ę",eogon:"ę",Eopf:"𝔼",eopf:"𝕖",epar:"⋕",eparsl:"⧣",eplus:"⩱",epsi:"ε",Epsilon:"Ε",epsilon:"ε",epsiv:"ϵ",eqcirc:"≖",eqcolon:"≕",eqsim:"≂",eqslantgtr:"⪖",eqslantless:"⪕",Equal:"⩵",equals:"=",EqualTilde:"≂",equest:"≟",Equilibrium:"⇌",equiv:"≡",equivDD:"⩸",eqvparsl:"⧥",erarr:"⥱",erDot:"≓",escr:"ℯ",Escr:"ℰ",esdot:"≐",Esim:"⩳",esim:"≂",Eta:"Η",eta:"η",ETH:"Ð",eth:"ð",Euml:"Ë",euml:"ë",euro:"€",excl:"!",exist:"∃",Exists:"∃",expectation:"ℰ",exponentiale:"ⅇ",ExponentialE:"ⅇ",fallingdotseq:"≒",Fcy:"Ф",fcy:"ф",female:"♀",ffilig:"ffi",fflig:"ff",ffllig:"ffl",Ffr:"𝔉",ffr:"𝔣",filig:"fi",FilledSmallSquare:"◼",FilledVerySmallSquare:"▪",fjlig:"fj",flat:"♭",fllig:"fl",fltns:"▱",fnof:"ƒ",Fopf:"𝔽",fopf:"𝕗",forall:"∀",ForAll:"∀",fork:"⋔",forkv:"⫙",Fouriertrf:"ℱ",fpartint:"⨍",frac12:"½",frac13:"⅓",frac14:"¼",frac15:"⅕",frac16:"⅙",frac18:"⅛",frac23:"⅔",frac25:"⅖",frac34:"¾",frac35:"⅗",frac38:"⅜",frac45:"⅘",frac56:"⅚",frac58:"⅝",frac78:"⅞",frasl:"⁄",frown:"⌢",fscr:"𝒻",Fscr:"ℱ",gacute:"ǵ",Gamma:"Γ",gamma:"γ",Gammad:"Ϝ",gammad:"ϝ",gap:"⪆",Gbreve:"Ğ",gbreve:"ğ",Gcedil:"Ģ",Gcirc:"Ĝ",gcirc:"ĝ",Gcy:"Г",gcy:"г",Gdot:"Ġ",gdot:"ġ",ge:"≥",gE:"≧",gEl:"⪌",gel:"⋛",geq:"≥",geqq:"≧",geqslant:"⩾",gescc:"⪩",ges:"⩾",gesdot:"⪀",gesdoto:"⪂",gesdotol:"⪄",gesl:"⋛︀",gesles:"⪔",Gfr:"𝔊",gfr:"𝔤",gg:"≫",Gg:"⋙",ggg:"⋙",gimel:"ℷ",GJcy:"Ѓ",gjcy:"ѓ",gla:"⪥",gl:"≷",glE:"⪒",glj:"⪤",gnap:"⪊",gnapprox:"⪊",gne:"⪈",gnE:"≩",gneq:"⪈",gneqq:"≩",gnsim:"⋧",Gopf:"𝔾",gopf:"𝕘",grave:"`",GreaterEqual:"≥",GreaterEqualLess:"⋛",GreaterFullEqual:"≧",GreaterGreater:"⪢",GreaterLess:"≷",GreaterSlantEqual:"⩾",GreaterTilde:"≳",Gscr:"𝒢",gscr:"ℊ",gsim:"≳",gsime:"⪎",gsiml:"⪐",gtcc:"⪧",gtcir:"⩺",gt:">",GT:">",Gt:"≫",gtdot:"⋗",gtlPar:"⦕",gtquest:"⩼",gtrapprox:"⪆",gtrarr:"⥸",gtrdot:"⋗",gtreqless:"⋛",gtreqqless:"⪌",gtrless:"≷",gtrsim:"≳",gvertneqq:"≩︀",gvnE:"≩︀",Hacek:"ˇ",hairsp:" ",half:"½",hamilt:"ℋ",HARDcy:"Ъ",hardcy:"ъ",harrcir:"⥈",harr:"↔",hArr:"⇔",harrw:"↭",Hat:"^",hbar:"ℏ",Hcirc:"Ĥ",hcirc:"ĥ",hearts:"♥",heartsuit:"♥",hellip:"…",hercon:"⊹",hfr:"𝔥",Hfr:"ℌ",HilbertSpace:"ℋ",hksearow:"⤥",hkswarow:"⤦",hoarr:"⇿",homtht:"∻",hookleftarrow:"↩",hookrightarrow:"↪",hopf:"𝕙",Hopf:"ℍ",horbar:"―",HorizontalLine:"─",hscr:"𝒽",Hscr:"ℋ",hslash:"ℏ",Hstrok:"Ħ",hstrok:"ħ",HumpDownHump:"≎",HumpEqual:"≏",hybull:"⁃",hyphen:"‐",Iacute:"Í",iacute:"í",ic:"⁣",Icirc:"Î",icirc:"î",Icy:"И",icy:"и",Idot:"İ",IEcy:"Е",iecy:"е",iexcl:"¡",iff:"⇔",ifr:"𝔦",Ifr:"ℑ",Igrave:"Ì",igrave:"ì",ii:"ⅈ",iiiint:"⨌",iiint:"∭",iinfin:"⧜",iiota:"℩",IJlig:"IJ",ijlig:"ij",Imacr:"Ī",imacr:"ī",image:"ℑ",ImaginaryI:"ⅈ",imagline:"ℐ",imagpart:"ℑ",imath:"ı",Im:"ℑ",imof:"⊷",imped:"Ƶ",Implies:"⇒",incare:"℅","in":"∈",infin:"∞",infintie:"⧝",inodot:"ı",intcal:"⊺","int":"∫",Int:"∬",integers:"ℤ",Integral:"∫",intercal:"⊺",Intersection:"⋂",intlarhk:"⨗",intprod:"⨼",InvisibleComma:"⁣",InvisibleTimes:"⁢",IOcy:"Ё",iocy:"ё",Iogon:"Į",iogon:"į",Iopf:"𝕀",iopf:"𝕚",Iota:"Ι",iota:"ι",iprod:"⨼",iquest:"¿",iscr:"𝒾",Iscr:"ℐ",isin:"∈",isindot:"⋵",isinE:"⋹",isins:"⋴",isinsv:"⋳",isinv:"∈",it:"⁢",Itilde:"Ĩ",itilde:"ĩ",Iukcy:"І",iukcy:"і",Iuml:"Ï",iuml:"ï",Jcirc:"Ĵ",jcirc:"ĵ",Jcy:"Й",jcy:"й",Jfr:"𝔍",jfr:"𝔧",jmath:"ȷ",Jopf:"𝕁",jopf:"𝕛",Jscr:"𝒥",jscr:"𝒿",Jsercy:"Ј",jsercy:"ј",Jukcy:"Є",jukcy:"є",Kappa:"Κ",kappa:"κ",kappav:"ϰ",Kcedil:"Ķ",kcedil:"ķ",Kcy:"К",kcy:"к",Kfr:"𝔎",kfr:"𝔨",kgreen:"ĸ",KHcy:"Х",khcy:"х",KJcy:"Ќ",kjcy:"ќ",Kopf:"𝕂",kopf:"𝕜",Kscr:"𝒦",kscr:"𝓀",lAarr:"⇚",Lacute:"Ĺ",lacute:"ĺ",laemptyv:"⦴",lagran:"ℒ",Lambda:"Λ",lambda:"λ",lang:"⟨",Lang:"⟪",langd:"⦑",langle:"⟨",lap:"⪅",Laplacetrf:"ℒ",laquo:"«",larrb:"⇤",larrbfs:"⤟",larr:"←",Larr:"↞",lArr:"⇐",larrfs:"⤝",larrhk:"↩",larrlp:"↫",larrpl:"⤹",larrsim:"⥳",larrtl:"↢",latail:"⤙",lAtail:"⤛",lat:"⪫",late:"⪭",lates:"⪭︀",lbarr:"⤌",lBarr:"⤎",lbbrk:"❲",lbrace:"{",lbrack:"[",lbrke:"⦋",lbrksld:"⦏",lbrkslu:"⦍",Lcaron:"Ľ",lcaron:"ľ",Lcedil:"Ļ",lcedil:"ļ",lceil:"⌈",lcub:"{",Lcy:"Л",lcy:"л",ldca:"⤶",ldquo:"“",ldquor:"„",ldrdhar:"⥧",ldrushar:"⥋",ldsh:"↲",le:"≤",lE:"≦",LeftAngleBracket:"⟨",LeftArrowBar:"⇤",leftarrow:"←",LeftArrow:"←",Leftarrow:"⇐",LeftArrowRightArrow:"⇆",leftarrowtail:"↢",LeftCeiling:"⌈",LeftDoubleBracket:"⟦",LeftDownTeeVector:"⥡",LeftDownVectorBar:"⥙",LeftDownVector:"⇃",LeftFloor:"⌊",leftharpoondown:"↽",leftharpoonup:"↼",leftleftarrows:"⇇",leftrightarrow:"↔",LeftRightArrow:"↔",Leftrightarrow:"⇔",leftrightarrows:"⇆",leftrightharpoons:"⇋",leftrightsquigarrow:"↭",LeftRightVector:"⥎",LeftTeeArrow:"↤",LeftTee:"⊣",LeftTeeVector:"⥚",leftthreetimes:"⋋",LeftTriangleBar:"⧏",LeftTriangle:"⊲",LeftTriangleEqual:"⊴",LeftUpDownVector:"⥑",LeftUpTeeVector:"⥠",LeftUpVectorBar:"⥘",LeftUpVector:"↿",LeftVectorBar:"⥒",LeftVector:"↼",lEg:"⪋",leg:"⋚",leq:"≤",leqq:"≦",leqslant:"⩽",lescc:"⪨",les:"⩽",lesdot:"⩿",lesdoto:"⪁",lesdotor:"⪃",lesg:"⋚︀",lesges:"⪓",lessapprox:"⪅",lessdot:"⋖",lesseqgtr:"⋚",lesseqqgtr:"⪋",LessEqualGreater:"⋚",LessFullEqual:"≦",LessGreater:"≶",lessgtr:"≶",LessLess:"⪡",lesssim:"≲",LessSlantEqual:"⩽",LessTilde:"≲",lfisht:"⥼",lfloor:"⌊",Lfr:"𝔏",lfr:"𝔩",lg:"≶",lgE:"⪑",lHar:"⥢",lhard:"↽",lharu:"↼",lharul:"⥪",lhblk:"▄",LJcy:"Љ",ljcy:"љ",llarr:"⇇",ll:"≪",Ll:"⋘",llcorner:"⌞",Lleftarrow:"⇚",llhard:"⥫",lltri:"◺",Lmidot:"Ŀ",lmidot:"ŀ",lmoustache:"⎰",lmoust:"⎰",lnap:"⪉",lnapprox:"⪉",lne:"⪇",lnE:"≨",lneq:"⪇",lneqq:"≨",lnsim:"⋦",loang:"⟬",loarr:"⇽",lobrk:"⟦",longleftarrow:"⟵",LongLeftArrow:"⟵",Longleftarrow:"⟸",longleftrightarrow:"⟷",LongLeftRightArrow:"⟷",Longleftrightarrow:"⟺",longmapsto:"⟼",longrightarrow:"⟶",LongRightArrow:"⟶",Longrightarrow:"⟹",looparrowleft:"↫",looparrowright:"↬",lopar:"⦅",Lopf:"𝕃",lopf:"𝕝",loplus:"⨭",lotimes:"⨴",lowast:"∗",lowbar:"_",LowerLeftArrow:"↙",LowerRightArrow:"↘",loz:"◊",lozenge:"◊",lozf:"⧫",lpar:"(",lparlt:"⦓",lrarr:"⇆",lrcorner:"⌟",lrhar:"⇋",lrhard:"⥭",lrm:"‎",lrtri:"⊿",lsaquo:"‹",lscr:"𝓁",Lscr:"ℒ",lsh:"↰",Lsh:"↰",lsim:"≲",lsime:"⪍",lsimg:"⪏",lsqb:"[",lsquo:"‘",lsquor:"‚",Lstrok:"Ł",lstrok:"ł",ltcc:"⪦",ltcir:"⩹",lt:"<",LT:"<",Lt:"≪",ltdot:"⋖",lthree:"⋋",ltimes:"⋉",ltlarr:"⥶",ltquest:"⩻",ltri:"◃",ltrie:"⊴",ltrif:"◂",ltrPar:"⦖",lurdshar:"⥊",luruhar:"⥦",lvertneqq:"≨︀",lvnE:"≨︀",macr:"¯",male:"♂",malt:"✠",maltese:"✠",Map:"⤅",map:"↦",mapsto:"↦",mapstodown:"↧",mapstoleft:"↤",mapstoup:"↥",marker:"▮",mcomma:"⨩",Mcy:"М",mcy:"м",mdash:"—",mDDot:"∺",measuredangle:"∡",MediumSpace:" ",Mellintrf:"ℳ",Mfr:"𝔐",mfr:"𝔪",mho:"℧",micro:"µ",midast:"*",midcir:"⫰",mid:"∣",middot:"·",minusb:"⊟",minus:"−",minusd:"∸",minusdu:"⨪",MinusPlus:"∓",mlcp:"⫛",mldr:"…",mnplus:"∓",models:"⊧",Mopf:"𝕄",mopf:"𝕞",mp:"∓",mscr:"𝓂",Mscr:"ℳ",mstpos:"∾",Mu:"Μ",mu:"μ",multimap:"⊸",mumap:"⊸",nabla:"∇",Nacute:"Ń",nacute:"ń",nang:"∠⃒",nap:"≉",napE:"⩰̸",napid:"≋̸",napos:"ʼn",napprox:"≉",natural:"♮",naturals:"ℕ",natur:"♮",nbsp:" ",nbump:"≎̸",nbumpe:"≏̸",ncap:"⩃",Ncaron:"Ň",ncaron:"ň",Ncedil:"Ņ",ncedil:"ņ",ncong:"≇",ncongdot:"⩭̸",ncup:"⩂",Ncy:"Н",ncy:"н",ndash:"–",nearhk:"⤤",nearr:"↗",neArr:"⇗",nearrow:"↗",ne:"≠",nedot:"≐̸",NegativeMediumSpace:"​",NegativeThickSpace:"​",NegativeThinSpace:"​",NegativeVeryThinSpace:"​",nequiv:"≢",nesear:"⤨",nesim:"≂̸",NestedGreaterGreater:"≫",NestedLessLess:"≪",NewLine:"\n",nexist:"∄",nexists:"∄",Nfr:"𝔑",nfr:"𝔫",ngE:"≧̸",nge:"≱",ngeq:"≱",ngeqq:"≧̸",ngeqslant:"⩾̸",nges:"⩾̸",nGg:"⋙̸",ngsim:"≵",nGt:"≫⃒",ngt:"≯",ngtr:"≯",nGtv:"≫̸",nharr:"↮",nhArr:"⇎",nhpar:"⫲",ni:"∋",nis:"⋼",nisd:"⋺",niv:"∋",NJcy:"Њ",njcy:"њ",nlarr:"↚",nlArr:"⇍",nldr:"‥",nlE:"≦̸",nle:"≰",nleftarrow:"↚",nLeftarrow:"⇍",nleftrightarrow:"↮",nLeftrightarrow:"⇎",nleq:"≰",nleqq:"≦̸",nleqslant:"⩽̸",nles:"⩽̸",nless:"≮",nLl:"⋘̸",nlsim:"≴",nLt:"≪⃒",nlt:"≮",nltri:"⋪",nltrie:"⋬",nLtv:"≪̸",nmid:"∤",NoBreak:"⁠",NonBreakingSpace:" ",nopf:"𝕟",Nopf:"ℕ",Not:"⫬",not:"¬",NotCongruent:"≢",NotCupCap:"≭",NotDoubleVerticalBar:"∦",NotElement:"∉",NotEqual:"≠",NotEqualTilde:"≂̸",NotExists:"∄",NotGreater:"≯",NotGreaterEqual:"≱",NotGreaterFullEqual:"≧̸",NotGreaterGreater:"≫̸",NotGreaterLess:"≹",NotGreaterSlantEqual:"⩾̸",NotGreaterTilde:"≵",NotHumpDownHump:"≎̸",NotHumpEqual:"≏̸",notin:"∉",notindot:"⋵̸",notinE:"⋹̸",notinva:"∉",notinvb:"⋷",notinvc:"⋶",NotLeftTriangleBar:"⧏̸",NotLeftTriangle:"⋪",NotLeftTriangleEqual:"⋬",NotLess:"≮",NotLessEqual:"≰",NotLessGreater:"≸",NotLessLess:"≪̸",NotLessSlantEqual:"⩽̸",NotLessTilde:"≴",NotNestedGreaterGreater:"⪢̸",NotNestedLessLess:"⪡̸",notni:"∌",notniva:"∌",notnivb:"⋾",notnivc:"⋽",NotPrecedes:"⊀",NotPrecedesEqual:"⪯̸",NotPrecedesSlantEqual:"⋠",NotReverseElement:"∌",NotRightTriangleBar:"⧐̸",NotRightTriangle:"⋫",NotRightTriangleEqual:"⋭",NotSquareSubset:"⊏̸",NotSquareSubsetEqual:"⋢",NotSquareSuperset:"⊐̸",NotSquareSupersetEqual:"⋣",NotSubset:"⊂⃒",NotSubsetEqual:"⊈",NotSucceeds:"⊁",NotSucceedsEqual:"⪰̸",NotSucceedsSlantEqual:"⋡",NotSucceedsTilde:"≿̸",NotSuperset:"⊃⃒",NotSupersetEqual:"⊉",NotTilde:"≁",NotTildeEqual:"≄",NotTildeFullEqual:"≇",NotTildeTilde:"≉",NotVerticalBar:"∤",nparallel:"∦",npar:"∦",nparsl:"⫽⃥",npart:"∂̸",npolint:"⨔",npr:"⊀",nprcue:"⋠",nprec:"⊀",npreceq:"⪯̸",npre:"⪯̸",nrarrc:"⤳̸",nrarr:"↛",nrArr:"⇏",nrarrw:"↝̸",nrightarrow:"↛",nRightarrow:"⇏",nrtri:"⋫",nrtrie:"⋭",nsc:"⊁",nsccue:"⋡",nsce:"⪰̸",Nscr:"𝒩",nscr:"𝓃",nshortmid:"∤",nshortparallel:"∦",nsim:"≁",nsime:"≄",nsimeq:"≄",nsmid:"∤",nspar:"∦",nsqsube:"⋢",nsqsupe:"⋣",nsub:"⊄",nsubE:"⫅̸",nsube:"⊈",nsubset:"⊂⃒",nsubseteq:"⊈",nsubseteqq:"⫅̸",nsucc:"⊁",nsucceq:"⪰̸",nsup:"⊅",nsupE:"⫆̸",nsupe:"⊉",nsupset:"⊃⃒",nsupseteq:"⊉",nsupseteqq:"⫆̸",ntgl:"≹",Ntilde:"Ñ",ntilde:"ñ",ntlg:"≸",ntriangleleft:"⋪",ntrianglelefteq:"⋬",ntriangleright:"⋫",ntrianglerighteq:"⋭",Nu:"Ν",nu:"ν",num:"#",numero:"№",numsp:" ",nvap:"≍⃒",nvdash:"⊬",nvDash:"⊭",nVdash:"⊮",nVDash:"⊯",nvge:"≥⃒",nvgt:">⃒",nvHarr:"⤄",nvinfin:"⧞",nvlArr:"⤂",nvle:"≤⃒",nvlt:"<⃒",nvltrie:"⊴⃒",nvrArr:"⤃",nvrtrie:"⊵⃒",nvsim:"∼⃒",nwarhk:"⤣",nwarr:"↖",nwArr:"⇖",nwarrow:"↖",nwnear:"⤧",Oacute:"Ó",oacute:"ó",oast:"⊛",Ocirc:"Ô",ocirc:"ô",ocir:"⊚",Ocy:"О",ocy:"о",odash:"⊝",Odblac:"Ő",odblac:"ő",odiv:"⨸",odot:"⊙",odsold:"⦼",OElig:"Œ",oelig:"œ",ofcir:"⦿",Ofr:"𝔒",ofr:"𝔬",ogon:"˛",Ograve:"Ò",ograve:"ò",ogt:"⧁",ohbar:"⦵",ohm:"Ω",oint:"∮",olarr:"↺",olcir:"⦾",olcross:"⦻",oline:"‾",olt:"⧀",Omacr:"Ō",omacr:"ō",Omega:"Ω",omega:"ω",Omicron:"Ο",omicron:"ο",omid:"⦶",ominus:"⊖",Oopf:"𝕆",oopf:"𝕠",opar:"⦷",OpenCurlyDoubleQuote:"“",OpenCurlyQuote:"‘",operp:"⦹",oplus:"⊕",orarr:"↻",Or:"⩔",or:"∨",ord:"⩝",order:"ℴ",orderof:"ℴ",ordf:"ª",ordm:"º",origof:"⊶",oror:"⩖",orslope:"⩗",orv:"⩛",oS:"Ⓢ",Oscr:"𝒪",oscr:"ℴ",Oslash:"Ø",oslash:"ø",osol:"⊘",Otilde:"Õ",otilde:"õ",otimesas:"⨶",Otimes:"⨷",otimes:"⊗",Ouml:"Ö",ouml:"ö",ovbar:"⌽",OverBar:"‾",OverBrace:"⏞",OverBracket:"⎴",OverParenthesis:"⏜",para:"¶",parallel:"∥",par:"∥",parsim:"⫳",parsl:"⫽",part:"∂",PartialD:"∂",Pcy:"П",pcy:"п",percnt:"%",period:".",permil:"‰",perp:"⊥",pertenk:"‱",Pfr:"𝔓",pfr:"𝔭",Phi:"Φ",phi:"φ",phiv:"ϕ",phmmat:"ℳ",phone:"☎",Pi:"Π",pi:"π",pitchfork:"⋔",piv:"ϖ",planck:"ℏ",planckh:"ℎ",plankv:"ℏ",plusacir:"⨣",plusb:"⊞",pluscir:"⨢",plus:"+",plusdo:"∔",plusdu:"⨥",pluse:"⩲",PlusMinus:"±",plusmn:"±",plussim:"⨦",plustwo:"⨧",pm:"±",Poincareplane:"ℌ",pointint:"⨕",popf:"𝕡",Popf:"ℙ",pound:"£",prap:"⪷",Pr:"⪻",pr:"≺",prcue:"≼",precapprox:"⪷",prec:"≺",preccurlyeq:"≼",Precedes:"≺",PrecedesEqual:"⪯",PrecedesSlantEqual:"≼",PrecedesTilde:"≾",preceq:"⪯",precnapprox:"⪹",precneqq:"⪵",precnsim:"⋨",pre:"⪯",prE:"⪳",precsim:"≾",prime:"′",Prime:"″",primes:"ℙ",prnap:"⪹",prnE:"⪵",prnsim:"⋨",prod:"∏",Product:"∏",profalar:"⌮",profline:"⌒",profsurf:"⌓",prop:"∝",Proportional:"∝",Proportion:"∷",propto:"∝",prsim:"≾",prurel:"⊰",Pscr:"𝒫",pscr:"𝓅",Psi:"Ψ",psi:"ψ",puncsp:" ",Qfr:"𝔔",qfr:"𝔮",qint:"⨌",qopf:"𝕢",Qopf:"ℚ",qprime:"⁗",Qscr:"𝒬",qscr:"𝓆",quaternions:"ℍ",quatint:"⨖",quest:"?",questeq:"≟",quot:'"',QUOT:'"',rAarr:"⇛",race:"∽̱",Racute:"Ŕ",racute:"ŕ",radic:"√",raemptyv:"⦳",rang:"⟩",Rang:"⟫",rangd:"⦒",range:"⦥",rangle:"⟩",raquo:"»",rarrap:"⥵",rarrb:"⇥",rarrbfs:"⤠",rarrc:"⤳",rarr:"→",Rarr:"↠",rArr:"⇒",rarrfs:"⤞",rarrhk:"↪",rarrlp:"↬",rarrpl:"⥅",rarrsim:"⥴",Rarrtl:"⤖",rarrtl:"↣",rarrw:"↝",ratail:"⤚",rAtail:"⤜",ratio:"∶",rationals:"ℚ",rbarr:"⤍",rBarr:"⤏",RBarr:"⤐",rbbrk:"❳",rbrace:"}",rbrack:"]",rbrke:"⦌",rbrksld:"⦎",rbrkslu:"⦐",Rcaron:"Ř",rcaron:"ř",Rcedil:"Ŗ",rcedil:"ŗ",rceil:"⌉",rcub:"}",Rcy:"Р",rcy:"р",rdca:"⤷",rdldhar:"⥩",rdquo:"”",rdquor:"”",rdsh:"↳",real:"ℜ",realine:"ℛ",realpart:"ℜ",reals:"ℝ",Re:"ℜ",rect:"▭",reg:"®",REG:"®",ReverseElement:"∋",ReverseEquilibrium:"⇋",ReverseUpEquilibrium:"⥯",rfisht:"⥽",rfloor:"⌋",rfr:"𝔯",Rfr:"ℜ",rHar:"⥤",rhard:"⇁",rharu:"⇀",rharul:"⥬",Rho:"Ρ",rho:"ρ",rhov:"ϱ",RightAngleBracket:"⟩",RightArrowBar:"⇥",rightarrow:"→",RightArrow:"→",Rightarrow:"⇒",RightArrowLeftArrow:"⇄",rightarrowtail:"↣",RightCeiling:"⌉",RightDoubleBracket:"⟧",RightDownTeeVector:"⥝",RightDownVectorBar:"⥕",RightDownVector:"⇂",RightFloor:"⌋",rightharpoondown:"⇁",rightharpoonup:"⇀",rightleftarrows:"⇄",rightleftharpoons:"⇌",rightrightarrows:"⇉",rightsquigarrow:"↝",RightTeeArrow:"↦",RightTee:"⊢",RightTeeVector:"⥛",rightthreetimes:"⋌",RightTriangleBar:"⧐",RightTriangle:"⊳",RightTriangleEqual:"⊵",RightUpDownVector:"⥏",RightUpTeeVector:"⥜",RightUpVectorBar:"⥔",RightUpVector:"↾",RightVectorBar:"⥓",RightVector:"⇀",ring:"˚",risingdotseq:"≓",rlarr:"⇄",rlhar:"⇌",rlm:"‏",rmoustache:"⎱",rmoust:"⎱",rnmid:"⫮",roang:"⟭",roarr:"⇾",robrk:"⟧",ropar:"⦆",ropf:"𝕣",Ropf:"ℝ",roplus:"⨮",rotimes:"⨵",RoundImplies:"⥰",rpar:")",rpargt:"⦔",rppolint:"⨒",rrarr:"⇉",Rrightarrow:"⇛",rsaquo:"›",rscr:"𝓇",Rscr:"ℛ",rsh:"↱",Rsh:"↱",rsqb:"]",rsquo:"’",rsquor:"’",rthree:"⋌",rtimes:"⋊",rtri:"▹",rtrie:"⊵",rtrif:"▸",rtriltri:"⧎",RuleDelayed:"⧴",ruluhar:"⥨",rx:"℞",Sacute:"Ś",sacute:"ś",sbquo:"‚",scap:"⪸",Scaron:"Š",scaron:"š",Sc:"⪼",sc:"≻",sccue:"≽",sce:"⪰",scE:"⪴",Scedil:"Ş",scedil:"ş",Scirc:"Ŝ",scirc:"ŝ",scnap:"⪺",scnE:"⪶",scnsim:"⋩",scpolint:"⨓",scsim:"≿",Scy:"С",scy:"с",sdotb:"⊡",sdot:"⋅",sdote:"⩦",searhk:"⤥",searr:"↘",seArr:"⇘",searrow:"↘",sect:"§",semi:";",seswar:"⤩",setminus:"∖",setmn:"∖",sext:"✶",Sfr:"𝔖",sfr:"𝔰",sfrown:"⌢",sharp:"♯",SHCHcy:"Щ",shchcy:"щ",SHcy:"Ш",shcy:"ш",ShortDownArrow:"↓",ShortLeftArrow:"←",shortmid:"∣",shortparallel:"∥",ShortRightArrow:"→",ShortUpArrow:"↑",shy:"­",Sigma:"Σ",sigma:"σ",sigmaf:"ς",sigmav:"ς",sim:"∼",simdot:"⩪",sime:"≃",simeq:"≃",simg:"⪞",simgE:"⪠",siml:"⪝",simlE:"⪟",simne:"≆",simplus:"⨤",simrarr:"⥲",slarr:"←",SmallCircle:"∘",smallsetminus:"∖",smashp:"⨳",smeparsl:"⧤",smid:"∣",smile:"⌣",smt:"⪪",smte:"⪬",smtes:"⪬︀",SOFTcy:"Ь",softcy:"ь",solbar:"⌿",solb:"⧄",sol:"/",Sopf:"𝕊",sopf:"𝕤",spades:"♠",spadesuit:"♠",spar:"∥",sqcap:"⊓",sqcaps:"⊓︀",sqcup:"⊔",sqcups:"⊔︀",Sqrt:"√",sqsub:"⊏",sqsube:"⊑",sqsubset:"⊏",sqsubseteq:"⊑",sqsup:"⊐",sqsupe:"⊒",sqsupset:"⊐",sqsupseteq:"⊒",square:"□",Square:"□",SquareIntersection:"⊓",SquareSubset:"⊏",SquareSubsetEqual:"⊑",SquareSuperset:"⊐",SquareSupersetEqual:"⊒",SquareUnion:"⊔",squarf:"▪",squ:"□",squf:"▪",srarr:"→",Sscr:"𝒮",sscr:"𝓈",ssetmn:"∖",ssmile:"⌣",sstarf:"⋆",Star:"⋆",star:"☆",starf:"★",straightepsilon:"ϵ",straightphi:"ϕ",strns:"¯",sub:"⊂",Sub:"⋐",subdot:"⪽",subE:"⫅",sube:"⊆",subedot:"⫃",submult:"⫁",subnE:"⫋",subne:"⊊",subplus:"⪿",subrarr:"⥹",subset:"⊂",Subset:"⋐",subseteq:"⊆",subseteqq:"⫅",SubsetEqual:"⊆",subsetneq:"⊊",subsetneqq:"⫋",subsim:"⫇",subsub:"⫕",subsup:"⫓",succapprox:"⪸",succ:"≻",succcurlyeq:"≽",Succeeds:"≻",SucceedsEqual:"⪰",SucceedsSlantEqual:"≽",SucceedsTilde:"≿",succeq:"⪰",succnapprox:"⪺",succneqq:"⪶",succnsim:"⋩",succsim:"≿",SuchThat:"∋",sum:"∑",Sum:"∑",sung:"♪",sup1:"¹",sup2:"²",sup3:"³",sup:"⊃",Sup:"⋑",supdot:"⪾",supdsub:"⫘",supE:"⫆",supe:"⊇",supedot:"⫄",Superset:"⊃",SupersetEqual:"⊇",suphsol:"⟉",suphsub:"⫗",suplarr:"⥻",supmult:"⫂",supnE:"⫌",supne:"⊋",supplus:"⫀",supset:"⊃",Supset:"⋑",supseteq:"⊇",supseteqq:"⫆",supsetneq:"⊋",supsetneqq:"⫌",supsim:"⫈",supsub:"⫔",supsup:"⫖",swarhk:"⤦",swarr:"↙",swArr:"⇙",swarrow:"↙",swnwar:"⤪",szlig:"ß",Tab:"\t",target:"⌖",Tau:"Τ",tau:"τ",tbrk:"⎴",Tcaron:"Ť",tcaron:"ť",Tcedil:"Ţ",tcedil:"ţ",Tcy:"Т",tcy:"т",tdot:"⃛",telrec:"⌕",Tfr:"𝔗",tfr:"𝔱",there4:"∴",therefore:"∴",Therefore:"∴",Theta:"Θ",theta:"θ",thetasym:"ϑ",thetav:"ϑ",thickapprox:"≈",thicksim:"∼",
+ThickSpace:"  ",ThinSpace:" ",thinsp:" ",thkap:"≈",thksim:"∼",THORN:"Þ",thorn:"þ",tilde:"˜",Tilde:"∼",TildeEqual:"≃",TildeFullEqual:"≅",TildeTilde:"≈",timesbar:"⨱",timesb:"⊠",times:"×",timesd:"⨰",tint:"∭",toea:"⤨",topbot:"⌶",topcir:"⫱",top:"⊤",Topf:"𝕋",topf:"𝕥",topfork:"⫚",tosa:"⤩",tprime:"‴",trade:"™",TRADE:"™",triangle:"▵",triangledown:"▿",triangleleft:"◃",trianglelefteq:"⊴",triangleq:"≜",triangleright:"▹",trianglerighteq:"⊵",tridot:"◬",trie:"≜",triminus:"⨺",TripleDot:"⃛",triplus:"⨹",trisb:"⧍",tritime:"⨻",trpezium:"⏢",Tscr:"𝒯",tscr:"𝓉",TScy:"Ц",tscy:"ц",TSHcy:"Ћ",tshcy:"ћ",Tstrok:"Ŧ",tstrok:"ŧ",twixt:"≬",twoheadleftarrow:"↞",twoheadrightarrow:"↠",Uacute:"Ú",uacute:"ú",uarr:"↑",Uarr:"↟",uArr:"⇑",Uarrocir:"⥉",Ubrcy:"Ў",ubrcy:"ў",Ubreve:"Ŭ",ubreve:"ŭ",Ucirc:"Û",ucirc:"û",Ucy:"У",ucy:"у",udarr:"⇅",Udblac:"Ű",udblac:"ű",udhar:"⥮",ufisht:"⥾",Ufr:"𝔘",ufr:"𝔲",Ugrave:"Ù",ugrave:"ù",uHar:"⥣",uharl:"↿",uharr:"↾",uhblk:"▀",ulcorn:"⌜",ulcorner:"⌜",ulcrop:"⌏",ultri:"◸",Umacr:"Ū",umacr:"ū",uml:"¨",UnderBar:"_",UnderBrace:"⏟",UnderBracket:"⎵",UnderParenthesis:"⏝",Union:"⋃",UnionPlus:"⊎",Uogon:"Ų",uogon:"ų",Uopf:"𝕌",uopf:"𝕦",UpArrowBar:"⤒",uparrow:"↑",UpArrow:"↑",Uparrow:"⇑",UpArrowDownArrow:"⇅",updownarrow:"↕",UpDownArrow:"↕",Updownarrow:"⇕",UpEquilibrium:"⥮",upharpoonleft:"↿",upharpoonright:"↾",uplus:"⊎",UpperLeftArrow:"↖",UpperRightArrow:"↗",upsi:"υ",Upsi:"ϒ",upsih:"ϒ",Upsilon:"Υ",upsilon:"υ",UpTeeArrow:"↥",UpTee:"⊥",upuparrows:"⇈",urcorn:"⌝",urcorner:"⌝",urcrop:"⌎",Uring:"Ů",uring:"ů",urtri:"◹",Uscr:"𝒰",uscr:"𝓊",utdot:"⋰",Utilde:"Ũ",utilde:"ũ",utri:"▵",utrif:"▴",uuarr:"⇈",Uuml:"Ü",uuml:"ü",uwangle:"⦧",vangrt:"⦜",varepsilon:"ϵ",varkappa:"ϰ",varnothing:"∅",varphi:"ϕ",varpi:"ϖ",varpropto:"∝",varr:"↕",vArr:"⇕",varrho:"ϱ",varsigma:"ς",varsubsetneq:"⊊︀",varsubsetneqq:"⫋︀",varsupsetneq:"⊋︀",varsupsetneqq:"⫌︀",vartheta:"ϑ",vartriangleleft:"⊲",vartriangleright:"⊳",vBar:"⫨",Vbar:"⫫",vBarv:"⫩",Vcy:"В",vcy:"в",vdash:"⊢",vDash:"⊨",Vdash:"⊩",VDash:"⊫",Vdashl:"⫦",veebar:"⊻",vee:"∨",Vee:"⋁",veeeq:"≚",vellip:"⋮",verbar:"|",Verbar:"‖",vert:"|",Vert:"‖",VerticalBar:"∣",VerticalLine:"|",VerticalSeparator:"❘",VerticalTilde:"≀",VeryThinSpace:" ",Vfr:"𝔙",vfr:"𝔳",vltri:"⊲",vnsub:"⊂⃒",vnsup:"⊃⃒",Vopf:"𝕍",vopf:"𝕧",vprop:"∝",vrtri:"⊳",Vscr:"𝒱",vscr:"𝓋",vsubnE:"⫋︀",vsubne:"⊊︀",vsupnE:"⫌︀",vsupne:"⊋︀",Vvdash:"⊪",vzigzag:"⦚",Wcirc:"Ŵ",wcirc:"ŵ",wedbar:"⩟",wedge:"∧",Wedge:"⋀",wedgeq:"≙",weierp:"℘",Wfr:"𝔚",wfr:"𝔴",Wopf:"𝕎",wopf:"𝕨",wp:"℘",wr:"≀",wreath:"≀",Wscr:"𝒲",wscr:"𝓌",xcap:"⋂",xcirc:"◯",xcup:"⋃",xdtri:"▽",Xfr:"𝔛",xfr:"𝔵",xharr:"⟷",xhArr:"⟺",Xi:"Ξ",xi:"ξ",xlarr:"⟵",xlArr:"⟸",xmap:"⟼",xnis:"⋻",xodot:"⨀",Xopf:"𝕏",xopf:"𝕩",xoplus:"⨁",xotime:"⨂",xrarr:"⟶",xrArr:"⟹",Xscr:"𝒳",xscr:"𝓍",xsqcup:"⨆",xuplus:"⨄",xutri:"△",xvee:"⋁",xwedge:"⋀",Yacute:"Ý",yacute:"ý",YAcy:"Я",yacy:"я",Ycirc:"Ŷ",ycirc:"ŷ",Ycy:"Ы",ycy:"ы",yen:"¥",Yfr:"𝔜",yfr:"𝔶",YIcy:"Ї",yicy:"ї",Yopf:"𝕐",yopf:"𝕪",Yscr:"𝒴",yscr:"𝓎",YUcy:"Ю",yucy:"ю",yuml:"ÿ",Yuml:"Ÿ",Zacute:"Ź",zacute:"ź",Zcaron:"Ž",zcaron:"ž",Zcy:"З",zcy:"з",Zdot:"Ż",zdot:"ż",zeetrf:"ℨ",ZeroWidthSpace:"​",Zeta:"Ζ",zeta:"ζ",zfr:"𝔷",Zfr:"ℨ",ZHcy:"Ж",zhcy:"ж",zigrarr:"⇝",zopf:"𝕫",Zopf:"ℤ",Zscr:"𝒵",zscr:"𝓏",zwj:"‍",zwnj:"‌"}},{}],26:[function(t,e,r){e.exports={Aacute:"Á",aacute:"á",Acirc:"Â",acirc:"â",acute:"´",AElig:"Æ",aelig:"æ",Agrave:"À",agrave:"à",amp:"&",AMP:"&",Aring:"Å",aring:"å",Atilde:"Ã",atilde:"ã",Auml:"Ä",auml:"ä",brvbar:"¦",Ccedil:"Ç",ccedil:"ç",cedil:"¸",cent:"¢",copy:"©",COPY:"©",curren:"¤",deg:"°",divide:"÷",Eacute:"É",eacute:"é",Ecirc:"Ê",ecirc:"ê",Egrave:"È",egrave:"è",ETH:"Ð",eth:"ð",Euml:"Ë",euml:"ë",frac12:"½",frac14:"¼",frac34:"¾",gt:">",GT:">",Iacute:"Í",iacute:"í",Icirc:"Î",icirc:"î",iexcl:"¡",Igrave:"Ì",igrave:"ì",iquest:"¿",Iuml:"Ï",iuml:"ï",laquo:"«",lt:"<",LT:"<",macr:"¯",micro:"µ",middot:"·",nbsp:" ",not:"¬",Ntilde:"Ñ",ntilde:"ñ",Oacute:"Ó",oacute:"ó",Ocirc:"Ô",ocirc:"ô",Ograve:"Ò",ograve:"ò",ordf:"ª",ordm:"º",Oslash:"Ø",oslash:"ø",Otilde:"Õ",otilde:"õ",Ouml:"Ö",ouml:"ö",para:"¶",plusmn:"±",pound:"£",quot:'"',QUOT:'"',raquo:"»",reg:"®",REG:"®",sect:"§",shy:"­",sup1:"¹",sup2:"²",sup3:"³",szlig:"ß",THORN:"Þ",thorn:"þ",times:"×",Uacute:"Ú",uacute:"ú",Ucirc:"Û",ucirc:"û",Ugrave:"Ù",ugrave:"ù",uml:"¨",Uuml:"Ü",uuml:"ü",Yacute:"Ý",yacute:"ý",yen:"¥",yuml:"ÿ"}},{}],27:[function(t,e,r){e.exports={amp:"&",apos:"'",gt:">",lt:"<",quot:'"'}},{}],28:[function(t,e,r){function n(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function i(t){return"function"==typeof t}function s(t){return"number"==typeof t}function o(t){return"object"==typeof t&&null!==t}function a(t){return void 0===t}e.exports=n,n.EventEmitter=n,n.prototype._events=void 0,n.prototype._maxListeners=void 0,n.defaultMaxListeners=10,n.prototype.setMaxListeners=function(t){if(!s(t)||t<0||isNaN(t))throw TypeError("n must be a positive number");return this._maxListeners=t,this},n.prototype.emit=function(t){var e,r,n,s,c,u;if(this._events||(this._events={}),"error"===t&&(!this._events.error||o(this._events.error)&&!this._events.error.length)){if(e=arguments[1],e instanceof Error)throw e;var h=new Error('Uncaught, unspecified "error" event. ('+e+")");throw h.context=e,h}if(r=this._events[t],a(r))return!1;if(i(r))switch(arguments.length){case 1:r.call(this);break;case 2:r.call(this,arguments[1]);break;case 3:r.call(this,arguments[1],arguments[2]);break;default:s=Array.prototype.slice.call(arguments,1),r.apply(this,s)}else if(o(r))for(s=Array.prototype.slice.call(arguments,1),u=r.slice(),n=u.length,c=0;c<n;c++)u[c].apply(this,s);return!0},n.prototype.addListener=function(t,e){var r;if(!i(e))throw TypeError("listener must be a function");return this._events||(this._events={}),this._events.newListener&&this.emit("newListener",t,i(e.listener)?e.listener:e),this._events[t]?o(this._events[t])?this._events[t].push(e):this._events[t]=[this._events[t],e]:this._events[t]=e,o(this._events[t])&&!this._events[t].warned&&(r=a(this._maxListeners)?n.defaultMaxListeners:this._maxListeners,r&&r>0&&this._events[t].length>r&&(this._events[t].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[t].length),"function"==typeof console.trace&&console.trace())),this},n.prototype.on=n.prototype.addListener,n.prototype.once=function(t,e){function r(){this.removeListener(t,r),n||(n=!0,e.apply(this,arguments))}if(!i(e))throw TypeError("listener must be a function");var n=!1;return r.listener=e,this.on(t,r),this},n.prototype.removeListener=function(t,e){var r,n,s,a;if(!i(e))throw TypeError("listener must be a function");if(!this._events||!this._events[t])return this;if(r=this._events[t],s=r.length,n=-1,r===e||i(r.listener)&&r.listener===e)delete this._events[t],this._events.removeListener&&this.emit("removeListener",t,e);else if(o(r)){for(a=s;a-- >0;)if(r[a]===e||r[a].listener&&r[a].listener===e){n=a;break}if(n<0)return this;1===r.length?(r.length=0,delete this._events[t]):r.splice(n,1),this._events.removeListener&&this.emit("removeListener",t,e)}return this},n.prototype.removeAllListeners=function(t){var e,r;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[t]&&delete this._events[t],this;if(0===arguments.length){for(e in this._events)"removeListener"!==e&&this.removeAllListeners(e);return this.removeAllListeners("removeListener"),this._events={},this}if(r=this._events[t],i(r))this.removeListener(t,r);else if(r)for(;r.length;)this.removeListener(t,r[r.length-1]);return delete this._events[t],this},n.prototype.listeners=function(t){var e;return e=this._events&&this._events[t]?i(this._events[t])?[this._events[t]]:this._events[t].slice():[]},n.prototype.listenerCount=function(t){if(this._events){var e=this._events[t];if(i(e))return 1;if(e)return e.length}return 0},n.listenerCount=function(t,e){return t.listenerCount(e)}},{}],29:[function(t,e,r){function n(t){this._cbs=t||{},this.events=[]}e.exports=n;var i=t("./").EVENTS;Object.keys(i).forEach(function(t){if(0===i[t])t="on"+t,n.prototype[t]=function(){this.events.push([t]),this._cbs[t]&&this._cbs[t]()};else if(1===i[t])t="on"+t,n.prototype[t]=function(e){this.events.push([t,e]),this._cbs[t]&&this._cbs[t](e)};else{if(2!==i[t])throw Error("wrong number of arguments");t="on"+t,n.prototype[t]=function(e,r){this.events.push([t,e,r]),this._cbs[t]&&this._cbs[t](e,r)}}}),n.prototype.onreset=function(){this.events=[],this._cbs.onreset&&this._cbs.onreset()},n.prototype.restart=function(){this._cbs.onreset&&this._cbs.onreset();for(var t=0,e=this.events.length;t<e;t++)if(this._cbs[this.events[t][0]]){var r=this.events[t].length;1===r?this._cbs[this.events[t][0]]():2===r?this._cbs[this.events[t][0]](this.events[t][1]):this._cbs[this.events[t][0]](this.events[t][1],this.events[t][2])}}},{"./":36}],30:[function(t,e,r){function n(t,e){this.init(t,e)}function i(t,e){return h.getElementsByTagName(t,e,!0)}function s(t,e){return h.getElementsByTagName(t,e,!0,1)[0]}function o(t,e,r){return h.getText(h.getElementsByTagName(t,e,r,1)).trim()}function a(t,e,r,n,i){var s=o(r,n,i);s&&(t[e]=s)}var c=t("./index.js"),u=c.DomHandler,h=c.DomUtils;t("inherits")(n,u),n.prototype.init=u;var l=function(t){return"rss"===t||"feed"===t||"rdf:RDF"===t};n.prototype.onend=function(){var t,e,r={},n=s(l,this.dom);n&&("feed"===n.name?(e=n.children,r.type="atom",a(r,"id","id",e),a(r,"title","title",e),(t=s("link",e))&&(t=t.attribs)&&(t=t.href)&&(r.link=t),a(r,"description","subtitle",e),(t=o("updated",e))&&(r.updated=new Date(t)),a(r,"author","email",e,!0),r.items=i("entry",e).map(function(t){var e,r={};return t=t.children,a(r,"id","id",t),a(r,"title","title",t),(e=s("link",t))&&(e=e.attribs)&&(e=e.href)&&(r.link=e),(e=o("summary",t)||o("content",t))&&(r.description=e),(e=o("updated",t))&&(r.pubDate=new Date(e)),r})):(e=s("channel",n.children).children,r.type=n.name.substr(0,3),r.id="",a(r,"title","title",e),a(r,"link","link",e),a(r,"description","description",e),(t=o("lastBuildDate",e))&&(r.updated=new Date(t)),a(r,"author","managingEditor",e,!0),r.items=i("item",n.children).map(function(t){var e,r={};return t=t.children,a(r,"id","guid",t),a(r,"title","title",t),a(r,"link","link",t),a(r,"description","description",t),(e=o("pubDate",t))&&(r.pubDate=new Date(e)),r}))),this.dom=r,u.prototype._handleCallback.call(this,n?null:Error("couldn't find root of feed"))},e.exports=n},{"./index.js":36,inherits:38}],31:[function(t,e,r){function n(t,e){this._options=e||{},this._cbs=t||{},this._tagname="",this._attribname="",this._attribvalue="",this._attribs=null,this._stack=[],this.startIndex=0,this.endIndex=null,this._lowerCaseTagNames="lowerCaseTags"in this._options?!!this._options.lowerCaseTags:!this._options.xmlMode,this._lowerCaseAttributeNames="lowerCaseAttributeNames"in this._options?!!this._options.lowerCaseAttributeNames:!this._options.xmlMode,this._options.Tokenizer&&(i=this._options.Tokenizer),this._tokenizer=new i(this._options,this),this._cbs.onparserinit&&this._cbs.onparserinit(this)}var i=t("./Tokenizer.js"),s={input:!0,option:!0,optgroup:!0,select:!0,button:!0,datalist:!0,textarea:!0},o={tr:{tr:!0,th:!0,td:!0},th:{th:!0},td:{thead:!0,th:!0,td:!0},body:{head:!0,link:!0,script:!0},li:{li:!0},p:{p:!0},h1:{p:!0},h2:{p:!0},h3:{p:!0},h4:{p:!0},h5:{p:!0},h6:{p:!0},select:s,input:s,output:s,button:s,datalist:s,textarea:s,option:{option:!0},optgroup:{optgroup:!0}},a={__proto__:null,area:!0,base:!0,basefont:!0,br:!0,col:!0,command:!0,embed:!0,frame:!0,hr:!0,img:!0,input:!0,isindex:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0,path:!0,circle:!0,ellipse:!0,line:!0,rect:!0,use:!0,stop:!0,polyline:!0,polygon:!0},c=/\s|\//;t("inherits")(n,t("events").EventEmitter),n.prototype._updatePosition=function(t){null===this.endIndex?this._tokenizer._sectionStart<=t?this.startIndex=0:this.startIndex=this._tokenizer._sectionStart-t:this.startIndex=this.endIndex+1,this.endIndex=this._tokenizer.getAbsoluteIndex()},n.prototype.ontext=function(t){this._updatePosition(1),this.endIndex--,this._cbs.ontext&&this._cbs.ontext(t)},n.prototype.onopentagname=function(t){if(this._lowerCaseTagNames&&(t=t.toLowerCase()),this._tagname=t,!this._options.xmlMode&&t in o)for(var e;(e=this._stack[this._stack.length-1])in o[t];this.onclosetag(e));!this._options.xmlMode&&t in a||this._stack.push(t),this._cbs.onopentagname&&this._cbs.onopentagname(t),this._cbs.onopentag&&(this._attribs={})},n.prototype.onopentagend=function(){this._updatePosition(1),this._attribs&&(this._cbs.onopentag&&this._cbs.onopentag(this._tagname,this._attribs),this._attribs=null),!this._options.xmlMode&&this._cbs.onclosetag&&this._tagname in a&&this._cbs.onclosetag(this._tagname),this._tagname=""},n.prototype.onclosetag=function(t){if(this._updatePosition(1),this._lowerCaseTagNames&&(t=t.toLowerCase()),!this._stack.length||t in a&&!this._options.xmlMode)this._options.xmlMode||"br"!==t&&"p"!==t||(this.onopentagname(t),this._closeCurrentTag());else{var e=this._stack.lastIndexOf(t);if(e!==-1)if(this._cbs.onclosetag)for(e=this._stack.length-e;e--;)this._cbs.onclosetag(this._stack.pop());else this._stack.length=e;else"p"!==t||this._options.xmlMode||(this.onopentagname(t),this._closeCurrentTag())}},n.prototype.onselfclosingtag=function(){this._options.xmlMode||this._options.recognizeSelfClosing?this._closeCurrentTag():this.onopentagend()},n.prototype._closeCurrentTag=function(){var t=this._tagname;this.onopentagend(),this._stack[this._stack.length-1]===t&&(this._cbs.onclosetag&&this._cbs.onclosetag(t),this._stack.pop())},n.prototype.onattribname=function(t){this._lowerCaseAttributeNames&&(t=t.toLowerCase()),this._attribname=t},n.prototype.onattribdata=function(t){this._attribvalue+=t},n.prototype.onattribend=function(){this._cbs.onattribute&&this._cbs.onattribute(this._attribname,this._attribvalue),this._attribs&&!Object.prototype.hasOwnProperty.call(this._attribs,this._attribname)&&(this._attribs[this._attribname]=this._attribvalue),this._attribname="",this._attribvalue=""},n.prototype._getInstructionName=function(t){var e=t.search(c),r=e<0?t:t.substr(0,e);return this._lowerCaseTagNames&&(r=r.toLowerCase()),r},n.prototype.ondeclaration=function(t){if(this._cbs.onprocessinginstruction){var e=this._getInstructionName(t);this._cbs.onprocessinginstruction("!"+e,"!"+t)}},n.prototype.onprocessinginstruction=function(t){if(this._cbs.onprocessinginstruction){var e=this._getInstructionName(t);this._cbs.onprocessinginstruction("?"+e,"?"+t)}},n.prototype.oncomment=function(t){this._updatePosition(4),this._cbs.oncomment&&this._cbs.oncomment(t),this._cbs.oncommentend&&this._cbs.oncommentend()},n.prototype.oncdata=function(t){this._updatePosition(1),this._options.xmlMode||this._options.recognizeCDATA?(this._cbs.oncdatastart&&this._cbs.oncdatastart(),this._cbs.ontext&&this._cbs.ontext(t),this._cbs.oncdataend&&this._cbs.oncdataend()):this.oncomment("[CDATA["+t+"]]")},n.prototype.onerror=function(t){this._cbs.onerror&&this._cbs.onerror(t)},n.prototype.onend=function(){if(this._cbs.onclosetag)for(var t=this._stack.length;t>0;this._cbs.onclosetag(this._stack[--t]));this._cbs.onend&&this._cbs.onend()},n.prototype.reset=function(){this._cbs.onreset&&this._cbs.onreset(),this._tokenizer.reset(),this._tagname="",this._attribname="",this._attribs=null,this._stack=[],this._cbs.onparserinit&&this._cbs.onparserinit(this)},n.prototype.parseComplete=function(t){this.reset(),this.end(t)},n.prototype.write=function(t){this._tokenizer.write(t)},n.prototype.end=function(t){this._tokenizer.end(t)},n.prototype.pause=function(){this._tokenizer.pause()},n.prototype.resume=function(){this._tokenizer.resume()},n.prototype.parseChunk=n.prototype.write,n.prototype.done=n.prototype.end,e.exports=n},{"./Tokenizer.js":34,events:28,inherits:38}],32:[function(t,e,r){function n(t){this._cbs=t||{}}e.exports=n;var i=t("./").EVENTS;Object.keys(i).forEach(function(t){if(0===i[t])t="on"+t,n.prototype[t]=function(){this._cbs[t]&&this._cbs[t]()};else if(1===i[t])t="on"+t,n.prototype[t]=function(e){this._cbs[t]&&this._cbs[t](e)};else{if(2!==i[t])throw Error("wrong number of arguments");t="on"+t,n.prototype[t]=function(e,r){this._cbs[t]&&this._cbs[t](e,r)}}})},{"./":36}],33:[function(t,e,r){function n(t){s.call(this,new i(this),t)}function i(t){this.scope=t}e.exports=n;var s=t("./WritableStream.js");t("inherits")(n,s),n.prototype.readable=!0;var o=t("../").EVENTS;Object.keys(o).forEach(function(t){if(0===o[t])i.prototype["on"+t]=function(){this.scope.emit(t)};else if(1===o[t])i.prototype["on"+t]=function(e){this.scope.emit(t,e)};else{if(2!==o[t])throw Error("wrong number of arguments!");i.prototype["on"+t]=function(e,r){this.scope.emit(t,e,r)}}})},{"../":36,"./WritableStream.js":35,inherits:38}],34:[function(t,e,r){function n(t){return" "===t||"\n"===t||"\t"===t||"\f"===t||"\r"===t}function i(t,e){return function(r){r===t&&(this._state=e)}}function s(t,e,r){var n=t.toLowerCase();return t===n?function(t){t===n?this._state=e:(this._state=r,this._index--)}:function(i){i===n||i===t?this._state=e:(this._state=r,this._index--)}}function o(t,e){var r=t.toLowerCase();return function(n){n===r||n===t?this._state=e:(this._state=g,this._index--)}}function a(t,e){this._state=p,this._buffer="",this._sectionStart=0,this._index=0,this._bufferOffset=0,this._baseState=p,this._special=gt,this._cbs=e,this._running=!0,this._ended=!1,this._xmlMode=!(!t||!t.xmlMode),this._decodeEntities=!(!t||!t.decodeEntities)}e.exports=a;var c=t("entities/lib/decode_codepoint.js"),u=t("entities/maps/entities.json"),h=t("entities/maps/legacy.json"),l=t("entities/maps/xml.json"),f=0,p=f++,d=f++,g=f++,_=f++,m=f++,b=f++,y=f++,v=f++,w=f++,x=f++,S=f++,E=f++,T=f++,A=f++,k=f++,L=f++,q=f++,R=f++,C=f++,B=f++,D=f++,j=f++,N=f++,O=f++,M=f++,I=f++,P=f++,U=f++,H=f++,V=f++,z=f++,Y=f++,F=f++,G=f++,W=f++,X=f++,Q=f++,J=f++,Z=f++,K=f++,$=f++,tt=f++,et=f++,rt=f++,nt=f++,it=f++,st=f++,ot=f++,at=f++,ct=f++,ut=f++,ht=f++,lt=f++,ft=f++,pt=f++,dt=0,gt=dt++,_t=dt++,mt=dt++;a.prototype._stateText=function(t){"<"===t?(this._index>this._sectionStart&&this._cbs.ontext(this._getSection()),this._state=d,this._sectionStart=this._index):this._decodeEntities&&this._special===gt&&"&"===t&&(this._index>this._sectionStart&&this._cbs.ontext(this._getSection()),this._baseState=p,this._state=ut,this._sectionStart=this._index)},a.prototype._stateBeforeTagName=function(t){"/"===t?this._state=m:"<"===t?(this._cbs.ontext(this._getSection()),this._sectionStart=this._index):">"===t||this._special!==gt||n(t)?this._state=p:"!"===t?(this._state=k,this._sectionStart=this._index+1):"?"===t?(this._state=q,this._sectionStart=this._index+1):(this._state=this._xmlMode||"s"!==t&&"S"!==t?g:z,this._sectionStart=this._index)},a.prototype._stateInTagName=function(t){("/"===t||">"===t||n(t))&&(this._emitToken("onopentagname"),this._state=v,this._index--)},a.prototype._stateBeforeCloseingTagName=function(t){n(t)||(">"===t?this._state=p:this._special!==gt?"s"===t||"S"===t?this._state=Y:(this._state=p,this._index--):(this._state=b,this._sectionStart=this._index))},a.prototype._stateInCloseingTagName=function(t){(">"===t||n(t))&&(this._emitToken("onclosetag"),this._state=y,this._index--)},a.prototype._stateAfterCloseingTagName=function(t){">"===t&&(this._state=p,this._sectionStart=this._index+1)},a.prototype._stateBeforeAttributeName=function(t){">"===t?(this._cbs.onopentagend(),this._state=p,this._sectionStart=this._index+1):"/"===t?this._state=_:n(t)||(this._state=w,this._sectionStart=this._index)},a.prototype._stateInSelfClosingTag=function(t){">"===t?(this._cbs.onselfclosingtag(),this._state=p,this._sectionStart=this._index+1):n(t)||(this._state=v,this._index--)},a.prototype._stateInAttributeName=function(t){("="===t||"/"===t||">"===t||n(t))&&(this._cbs.onattribname(this._getSection()),this._sectionStart=-1,this._state=x,this._index--)},a.prototype._stateAfterAttributeName=function(t){"="===t?this._state=S:"/"===t||">"===t?(this._cbs.onattribend(),this._state=v,this._index--):n(t)||(this._cbs.onattribend(),this._state=w,this._sectionStart=this._index)},a.prototype._stateBeforeAttributeValue=function(t){'"'===t?(this._state=E,this._sectionStart=this._index+1):"'"===t?(this._state=T,this._sectionStart=this._index+1):n(t)||(this._state=A,this._sectionStart=this._index,this._index--)},a.prototype._stateInAttributeValueDoubleQuotes=function(t){'"'===t?(this._emitToken("onattribdata"),this._cbs.onattribend(),this._state=v):this._decodeEntities&&"&"===t&&(this._emitToken("onattribdata"),this._baseState=this._state,this._state=ut,this._sectionStart=this._index)},a.prototype._stateInAttributeValueSingleQuotes=function(t){"'"===t?(this._emitToken("onattribdata"),this._cbs.onattribend(),this._state=v):this._decodeEntities&&"&"===t&&(this._emitToken("onattribdata"),this._baseState=this._state,this._state=ut,this._sectionStart=this._index)},a.prototype._stateInAttributeValueNoQuotes=function(t){n(t)||">"===t?(this._emitToken("onattribdata"),this._cbs.onattribend(),this._state=v,this._index--):this._decodeEntities&&"&"===t&&(this._emitToken("onattribdata"),this._baseState=this._state,this._state=ut,this._sectionStart=this._index)},a.prototype._stateBeforeDeclaration=function(t){this._state="["===t?j:"-"===t?R:L},a.prototype._stateInDeclaration=function(t){">"===t&&(this._cbs.ondeclaration(this._getSection()),this._state=p,this._sectionStart=this._index+1)},a.prototype._stateInProcessingInstruction=function(t){">"===t&&(this._cbs.onprocessinginstruction(this._getSection()),this._state=p,this._sectionStart=this._index+1)},a.prototype._stateBeforeComment=function(t){"-"===t?(this._state=C,this._sectionStart=this._index+1):this._state=L},a.prototype._stateInComment=function(t){"-"===t&&(this._state=B)},a.prototype._stateAfterComment1=function(t){"-"===t?this._state=D:this._state=C},a.prototype._stateAfterComment2=function(t){">"===t?(this._cbs.oncomment(this._buffer.substring(this._sectionStart,this._index-2)),this._state=p,this._sectionStart=this._index+1):"-"!==t&&(this._state=C)},a.prototype._stateBeforeCdata1=s("C",N,L),a.prototype._stateBeforeCdata2=s("D",O,L),a.prototype._stateBeforeCdata3=s("A",M,L),a.prototype._stateBeforeCdata4=s("T",I,L),a.prototype._stateBeforeCdata5=s("A",P,L),a.prototype._stateBeforeCdata6=function(t){"["===t?(this._state=U,this._sectionStart=this._index+1):(this._state=L,this._index--)},a.prototype._stateInCdata=function(t){"]"===t&&(this._state=H)},a.prototype._stateAfterCdata1=i("]",V),a.prototype._stateAfterCdata2=function(t){">"===t?(this._cbs.oncdata(this._buffer.substring(this._sectionStart,this._index-2)),this._state=p,this._sectionStart=this._index+1):"]"!==t&&(this._state=U)},a.prototype._stateBeforeSpecial=function(t){"c"===t||"C"===t?this._state=F:"t"===t||"T"===t?this._state=et:(this._state=g,this._index--)},a.prototype._stateBeforeSpecialEnd=function(t){this._special!==_t||"c"!==t&&"C"!==t?this._special!==mt||"t"!==t&&"T"!==t?this._state=p:this._state=st:this._state=J},a.prototype._stateBeforeScript1=o("R",G),a.prototype._stateBeforeScript2=o("I",W),a.prototype._stateBeforeScript3=o("P",X),a.prototype._stateBeforeScript4=o("T",Q),a.prototype._stateBeforeScript5=function(t){("/"===t||">"===t||n(t))&&(this._special=_t),this._state=g,this._index--},a.prototype._stateAfterScript1=s("R",Z,p),a.prototype._stateAfterScript2=s("I",K,p),a.prototype._stateAfterScript3=s("P",$,p),a.prototype._stateAfterScript4=s("T",tt,p),a.prototype._stateAfterScript5=function(t){">"===t||n(t)?(this._special=gt,this._state=b,this._sectionStart=this._index-6,this._index--):this._state=p},a.prototype._stateBeforeStyle1=o("Y",rt),a.prototype._stateBeforeStyle2=o("L",nt),a.prototype._stateBeforeStyle3=o("E",it),a.prototype._stateBeforeStyle4=function(t){("/"===t||">"===t||n(t))&&(this._special=mt),this._state=g,this._index--},a.prototype._stateAfterStyle1=s("Y",ot,p),a.prototype._stateAfterStyle2=s("L",at,p),a.prototype._stateAfterStyle3=s("E",ct,p),a.prototype._stateAfterStyle4=function(t){">"===t||n(t)?(this._special=gt,this._state=b,this._sectionStart=this._index-5,this._index--):this._state=p},a.prototype._stateBeforeEntity=s("#",ht,lt),a.prototype._stateBeforeNumericEntity=s("X",pt,ft),a.prototype._parseNamedEntityStrict=function(){if(this._sectionStart+1<this._index){var t=this._buffer.substring(this._sectionStart+1,this._index),e=this._xmlMode?l:u;e.hasOwnProperty(t)&&(this._emitPartial(e[t]),this._sectionStart=this._index+1)}},a.prototype._parseLegacyEntity=function(){var t=this._sectionStart+1,e=this._index-t;for(e>6&&(e=6);e>=2;){var r=this._buffer.substr(t,e);if(h.hasOwnProperty(r))return this._emitPartial(h[r]),void(this._sectionStart+=e+1);e--}},a.prototype._stateInNamedEntity=function(t){";"===t?(this._parseNamedEntityStrict(),this._sectionStart+1<this._index&&!this._xmlMode&&this._parseLegacyEntity(),this._state=this._baseState):(t<"a"||t>"z")&&(t<"A"||t>"Z")&&(t<"0"||t>"9")&&(this._xmlMode||this._sectionStart+1===this._index||(this._baseState!==p?"="!==t&&this._parseNamedEntityStrict():this._parseLegacyEntity()),this._state=this._baseState,this._index--)},a.prototype._decodeNumericEntity=function(t,e){var r=this._sectionStart+t;if(r!==this._index){var n=this._buffer.substring(r,this._index),i=parseInt(n,e);this._emitPartial(c(i)),this._sectionStart=this._index}else this._sectionStart--;this._state=this._baseState},a.prototype._stateInNumericEntity=function(t){";"===t?(this._decodeNumericEntity(2,10),this._sectionStart++):(t<"0"||t>"9")&&(this._xmlMode?this._state=this._baseState:this._decodeNumericEntity(2,10),this._index--)},a.prototype._stateInHexEntity=function(t){";"===t?(this._decodeNumericEntity(3,16),this._sectionStart++):(t<"a"||t>"f")&&(t<"A"||t>"F")&&(t<"0"||t>"9")&&(this._xmlMode?this._state=this._baseState:this._decodeNumericEntity(3,16),this._index--)},a.prototype._cleanup=function(){this._sectionStart<0?(this._buffer="",this._index=0,this._bufferOffset+=this._index):this._running&&(this._state===p?(this._sectionStart!==this._index&&this._cbs.ontext(this._buffer.substr(this._sectionStart)),this._buffer="",this._bufferOffset+=this._index,this._index=0):this._sectionStart===this._index?(this._buffer="",this._bufferOffset+=this._index,this._index=0):(this._buffer=this._buffer.substr(this._sectionStart),this._index-=this._sectionStart,this._bufferOffset+=this._sectionStart),this._sectionStart=0)},a.prototype.write=function(t){this._ended&&this._cbs.onerror(Error(".write() after done!")),this._buffer+=t,this._parse()},a.prototype._parse=function(){for(;this._index<this._buffer.length&&this._running;){var t=this._buffer.charAt(this._index);this._state===p?this._stateText(t):this._state===d?this._stateBeforeTagName(t):this._state===g?this._stateInTagName(t):this._state===m?this._stateBeforeCloseingTagName(t):this._state===b?this._stateInCloseingTagName(t):this._state===y?this._stateAfterCloseingTagName(t):this._state===_?this._stateInSelfClosingTag(t):this._state===v?this._stateBeforeAttributeName(t):this._state===w?this._stateInAttributeName(t):this._state===x?this._stateAfterAttributeName(t):this._state===S?this._stateBeforeAttributeValue(t):this._state===E?this._stateInAttributeValueDoubleQuotes(t):this._state===T?this._stateInAttributeValueSingleQuotes(t):this._state===A?this._stateInAttributeValueNoQuotes(t):this._state===k?this._stateBeforeDeclaration(t):this._state===L?this._stateInDeclaration(t):this._state===q?this._stateInProcessingInstruction(t):this._state===R?this._stateBeforeComment(t):this._state===C?this._stateInComment(t):this._state===B?this._stateAfterComment1(t):this._state===D?this._stateAfterComment2(t):this._state===j?this._stateBeforeCdata1(t):this._state===N?this._stateBeforeCdata2(t):this._state===O?this._stateBeforeCdata3(t):this._state===M?this._stateBeforeCdata4(t):this._state===I?this._stateBeforeCdata5(t):this._state===P?this._stateBeforeCdata6(t):this._state===U?this._stateInCdata(t):this._state===H?this._stateAfterCdata1(t):this._state===V?this._stateAfterCdata2(t):this._state===z?this._stateBeforeSpecial(t):this._state===Y?this._stateBeforeSpecialEnd(t):this._state===F?this._stateBeforeScript1(t):this._state===G?this._stateBeforeScript2(t):this._state===W?this._stateBeforeScript3(t):this._state===X?this._stateBeforeScript4(t):this._state===Q?this._stateBeforeScript5(t):this._state===J?this._stateAfterScript1(t):this._state===Z?this._stateAfterScript2(t):this._state===K?this._stateAfterScript3(t):this._state===$?this._stateAfterScript4(t):this._state===tt?this._stateAfterScript5(t):this._state===et?this._stateBeforeStyle1(t):this._state===rt?this._stateBeforeStyle2(t):this._state===nt?this._stateBeforeStyle3(t):this._state===it?this._stateBeforeStyle4(t):this._state===st?this._stateAfterStyle1(t):this._state===ot?this._stateAfterStyle2(t):this._state===at?this._stateAfterStyle3(t):this._state===ct?this._stateAfterStyle4(t):this._state===ut?this._stateBeforeEntity(t):this._state===ht?this._stateBeforeNumericEntity(t):this._state===lt?this._stateInNamedEntity(t):this._state===ft?this._stateInNumericEntity(t):this._state===pt?this._stateInHexEntity(t):this._cbs.onerror(Error("unknown _state"),this._state),this._index++}this._cleanup()},a.prototype.pause=function(){this._running=!1},a.prototype.resume=function(){this._running=!0,this._index<this._buffer.length&&this._parse(),this._ended&&this._finish()},a.prototype.end=function(t){this._ended&&this._cbs.onerror(Error(".end() after done!")),t&&this.write(t),this._ended=!0,this._running&&this._finish()},a.prototype._finish=function(){this._sectionStart<this._index&&this._handleTrailingData(),this._cbs.onend()},a.prototype._handleTrailingData=function(){var t=this._buffer.substr(this._sectionStart);this._state===U||this._state===H||this._state===V?this._cbs.oncdata(t):this._state===C||this._state===B||this._state===D?this._cbs.oncomment(t):this._state!==lt||this._xmlMode?this._state!==ft||this._xmlMode?this._state!==pt||this._xmlMode?this._state!==g&&this._state!==v&&this._state!==S&&this._state!==x&&this._state!==w&&this._state!==T&&this._state!==E&&this._state!==A&&this._state!==b&&this._cbs.ontext(t):(this._decodeNumericEntity(3,16),this._sectionStart<this._index&&(this._state=this._baseState,this._handleTrailingData())):(this._decodeNumericEntity(2,10),this._sectionStart<this._index&&(this._state=this._baseState,this._handleTrailingData())):(this._parseLegacyEntity(),this._sectionStart<this._index&&(this._state=this._baseState,this._handleTrailingData()))},a.prototype.reset=function(){a.call(this,{xmlMode:this._xmlMode,decodeEntities:this._decodeEntities},this._cbs)},a.prototype.getAbsoluteIndex=function(){return this._bufferOffset+this._index},a.prototype._getSection=function(){return this._buffer.substring(this._sectionStart,this._index)},a.prototype._emitToken=function(t){this._cbs[t](this._getSection()),this._sectionStart=-1},a.prototype._emitPartial=function(t){this._baseState!==p?this._cbs.onattribdata(t):this._cbs.ontext(t)}},{"entities/lib/decode_codepoint.js":22,"entities/maps/entities.json":25,"entities/maps/legacy.json":26,"entities/maps/xml.json":27}],35:[function(t,e,r){function n(t,e){var r=this._parser=new i(t,e),n=this._decoder=new o;s.call(this,{decodeStrings:!1}),this.once("finish",function(){r.end(n.end())})}e.exports=n;var i=t("./Parser.js"),s=t("stream").Writable||t("readable-stream").Writable,o=t("string_decoder").StringDecoder,a=t("buffer").Buffer;t("inherits")(n,s),s.prototype._write=function(t,e,r){t instanceof a&&(t=this._decoder.write(t)),this._parser.write(t),r()}},{"./Parser.js":31,buffer:5,inherits:38,"readable-stream":3,stream:55,string_decoder:56}],36:[function(t,e,r){function n(t,r){return delete e.exports[t],e.exports[t]=r,r}var i=t("./Parser.js"),s=t("domhandler");e.exports={Parser:i,Tokenizer:t("./Tokenizer.js"),ElementType:t("domelementtype"),DomHandler:s,get FeedHandler(){return n("FeedHandler",t("./FeedHandler.js"))},get Stream(){return n("Stream",t("./Stream.js"))},get WritableStream(){return n("WritableStream",t("./WritableStream.js"));
+},get ProxyHandler(){return n("ProxyHandler",t("./ProxyHandler.js"))},get DomUtils(){return n("DomUtils",t("domutils"))},get CollectingHandler(){return n("CollectingHandler",t("./CollectingHandler.js"))},DefaultHandler:s,get RssHandler(){return n("RssHandler",this.FeedHandler)},parseDOM:function(t,e){var r=new s(e);return new i(r,e).end(t),r.dom},parseFeed:function(t,r){var n=new e.exports.FeedHandler(r);return new i(n,r).end(t),n.dom},createDomStream:function(t,e,r){var n=new s(t,e,r);return new i(n,e)},EVENTS:{attribute:2,cdatastart:0,cdataend:0,text:1,processinginstruction:2,comment:1,commentend:0,closetag:1,opentag:2,opentagname:1,error:1,end:0}}},{"./CollectingHandler.js":29,"./FeedHandler.js":30,"./Parser.js":31,"./ProxyHandler.js":32,"./Stream.js":33,"./Tokenizer.js":34,"./WritableStream.js":35,domelementtype:9,domhandler:10,domutils:13}],37:[function(t,e,r){r.read=function(t,e,r,n,i){var s,o,a=8*i-n-1,c=(1<<a)-1,u=c>>1,h=-7,l=r?i-1:0,f=r?-1:1,p=t[e+l];for(l+=f,s=p&(1<<-h)-1,p>>=-h,h+=a;h>0;s=256*s+t[e+l],l+=f,h-=8);for(o=s&(1<<-h)-1,s>>=-h,h+=n;h>0;o=256*o+t[e+l],l+=f,h-=8);if(0===s)s=1-u;else{if(s===c)return o?NaN:(p?-1:1)*(1/0);o+=Math.pow(2,n),s-=u}return(p?-1:1)*o*Math.pow(2,s-n)},r.write=function(t,e,r,n,i,s){var o,a,c,u=8*s-i-1,h=(1<<u)-1,l=h>>1,f=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,p=n?0:s-1,d=n?1:-1,g=e<0||0===e&&1/e<0?1:0;for(e=Math.abs(e),isNaN(e)||e===1/0?(a=isNaN(e)?1:0,o=h):(o=Math.floor(Math.log(e)/Math.LN2),e*(c=Math.pow(2,-o))<1&&(o--,c*=2),e+=o+l>=1?f/c:f*Math.pow(2,1-l),e*c>=2&&(o++,c/=2),o+l>=h?(a=0,o=h):o+l>=1?(a=(e*c-1)*Math.pow(2,i),o+=l):(a=e*Math.pow(2,l-1)*Math.pow(2,i),o=0));i>=8;t[r+p]=255&a,p+=d,a/=256,i-=8);for(o=o<<i|a,u+=i;u>0;t[r+p]=255&o,p+=d,o/=256,u-=8);t[r+p-d]|=128*g}},{}],38:[function(t,e,r){"function"==typeof Object.create?e.exports=function(t,e){t.super_=e,t.prototype=Object.create(e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}})}:e.exports=function(t,e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}},{}],39:[function(t,e,r){function n(t){return!!t.constructor&&"function"==typeof t.constructor.isBuffer&&t.constructor.isBuffer(t)}function i(t){return"function"==typeof t.readFloatLE&&"function"==typeof t.slice&&n(t.slice(0,0))}e.exports=function(t){return null!=t&&(n(t)||i(t)||!!t._isBuffer)}},{}],40:[function(t,e,r){var n={}.toString;e.exports=Array.isArray||function(t){return"[object Array]"==n.call(t)}},{}],41:[function(t,e,r){(function(t){"use strict";function r(e,r,n,i){if("function"!=typeof e)throw new TypeError('"callback" argument must be a function');var s,o,a=arguments.length;switch(a){case 0:case 1:return t.nextTick(e);case 2:return t.nextTick(function(){e.call(null,r)});case 3:return t.nextTick(function(){e.call(null,r,n)});case 4:return t.nextTick(function(){e.call(null,r,n,i)});default:for(s=new Array(a-1),o=0;o<s.length;)s[o++]=arguments[o];return t.nextTick(function(){e.apply(null,s)})}}!t.version||0===t.version.indexOf("v0.")||0===t.version.indexOf("v1.")&&0!==t.version.indexOf("v1.8.")?e.exports=r:e.exports=t.nextTick}).call(this,t("_process"))},{_process:42}],42:[function(t,e,r){function n(){throw new Error("setTimeout has not been defined")}function i(){throw new Error("clearTimeout has not been defined")}function s(t){if(l===setTimeout)return setTimeout(t,0);if((l===n||!l)&&setTimeout)return l=setTimeout,setTimeout(t,0);try{return l(t,0)}catch(e){try{return l.call(null,t,0)}catch(e){return l.call(this,t,0)}}}function o(t){if(f===clearTimeout)return clearTimeout(t);if((f===i||!f)&&clearTimeout)return f=clearTimeout,clearTimeout(t);try{return f(t)}catch(e){try{return f.call(null,t)}catch(e){return f.call(this,t)}}}function a(){_&&d&&(_=!1,d.length?g=d.concat(g):m=-1,g.length&&c())}function c(){if(!_){var t=s(a);_=!0;for(var e=g.length;e;){for(d=g,g=[];++m<e;)d&&d[m].run();m=-1,e=g.length}d=null,_=!1,o(t)}}function u(t,e){this.fun=t,this.array=e}function h(){}var l,f,p=e.exports={};!function(){try{l="function"==typeof setTimeout?setTimeout:n}catch(t){l=n}try{f="function"==typeof clearTimeout?clearTimeout:i}catch(t){f=i}}();var d,g=[],_=!1,m=-1;p.nextTick=function(t){var e=new Array(arguments.length-1);if(arguments.length>1)for(var r=1;r<arguments.length;r++)e[r-1]=arguments[r];g.push(new u(t,e)),1!==g.length||_||s(c)},u.prototype.run=function(){this.fun.apply(null,this.array)},p.title="browser",p.browser=!0,p.env={},p.argv=[],p.version="",p.versions={},p.on=h,p.addListener=h,p.once=h,p.off=h,p.removeListener=h,p.removeAllListeners=h,p.emit=h,p.binding=function(t){throw new Error("process.binding is not supported")},p.cwd=function(){return"/"},p.chdir=function(t){throw new Error("process.chdir is not supported")},p.umask=function(){return 0}},{}],43:[function(t,e,r){e.exports=t("./lib/_stream_duplex.js")},{"./lib/_stream_duplex.js":44}],44:[function(t,e,r){"use strict";function n(t){return this instanceof n?(u.call(this,t),h.call(this,t),t&&t.readable===!1&&(this.readable=!1),t&&t.writable===!1&&(this.writable=!1),this.allowHalfOpen=!0,t&&t.allowHalfOpen===!1&&(this.allowHalfOpen=!1),void this.once("end",i)):new n(t)}function i(){this.allowHalfOpen||this._writableState.ended||a(s,this)}function s(t){t.end()}var o=Object.keys||function(t){var e=[];for(var r in t)e.push(r);return e};e.exports=n;var a=t("process-nextick-args"),c=t("core-util-is");c.inherits=t("inherits");var u=t("./_stream_readable"),h=t("./_stream_writable");c.inherits(n,u);for(var l=o(h.prototype),f=0;f<l.length;f++){var p=l[f];n.prototype[p]||(n.prototype[p]=h.prototype[p])}},{"./_stream_readable":46,"./_stream_writable":48,"core-util-is":6,inherits:38,"process-nextick-args":41}],45:[function(t,e,r){"use strict";function n(t){return this instanceof n?void i.call(this,t):new n(t)}e.exports=n;var i=t("./_stream_transform"),s=t("core-util-is");s.inherits=t("inherits"),s.inherits(n,i),n.prototype._transform=function(t,e,r){r(null,t)}},{"./_stream_transform":47,"core-util-is":6,inherits:38}],46:[function(t,e,r){(function(r){"use strict";function n(t,e,r){return"function"==typeof t.prependListener?t.prependListener(e,r):void(t._events&&t._events[e]?R(t._events[e])?t._events[e].unshift(r):t._events[e]=[r,t._events[e]]:t.on(e,r))}function i(e,r){U=U||t("./_stream_duplex"),e=e||{},this.objectMode=!!e.objectMode,r instanceof U&&(this.objectMode=this.objectMode||!!e.readableObjectMode);var n=e.highWaterMark,i=this.objectMode?16:16384;this.highWaterMark=n||0===n?n:i,this.highWaterMark=~~this.highWaterMark,this.buffer=new P,this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=null,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.resumeScheduled=!1,this.defaultEncoding=e.defaultEncoding||"utf8",this.ranOut=!1,this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,e.encoding&&(I||(I=t("string_decoder/").StringDecoder),this.decoder=new I(e.encoding),this.encoding=e.encoding)}function s(e){return U=U||t("./_stream_duplex"),this instanceof s?(this._readableState=new i(e,this),this.readable=!0,e&&"function"==typeof e.read&&(this._read=e.read),void C.call(this)):new s(e)}function o(t,e,r,n,i){var s=h(e,r);if(s)t.emit("error",s);else if(null===r)e.reading=!1,l(t,e);else if(e.objectMode||r&&r.length>0)if(e.ended&&!i){var o=new Error("stream.push() after EOF");t.emit("error",o)}else if(e.endEmitted&&i){var c=new Error("stream.unshift() after end event");t.emit("error",c)}else{var u;!e.decoder||i||n||(r=e.decoder.write(r),u=!e.objectMode&&0===r.length),i||(e.reading=!1),u||(e.flowing&&0===e.length&&!e.sync?(t.emit("data",r),t.read(0)):(e.length+=e.objectMode?1:r.length,i?e.buffer.unshift(r):e.buffer.push(r),e.needReadable&&f(t))),d(t,e)}else i||(e.reading=!1);return a(e)}function a(t){return!t.ended&&(t.needReadable||t.length<t.highWaterMark||0===t.length)}function c(t){return t>=H?t=H:(t--,t|=t>>>1,t|=t>>>2,t|=t>>>4,t|=t>>>8,t|=t>>>16,t++),t}function u(t,e){return t<=0||0===e.length&&e.ended?0:e.objectMode?1:t!==t?e.flowing&&e.length?e.buffer.head.data.length:e.length:(t>e.highWaterMark&&(e.highWaterMark=c(t)),t<=e.length?t:e.ended?e.length:(e.needReadable=!0,0))}function h(t,e){var r=null;return D.isBuffer(e)||"string"==typeof e||null===e||void 0===e||t.objectMode||(r=new TypeError("Invalid non-string/buffer chunk")),r}function l(t,e){if(!e.ended){if(e.decoder){var r=e.decoder.end();r&&r.length&&(e.buffer.push(r),e.length+=e.objectMode?1:r.length)}e.ended=!0,f(t)}}function f(t){var e=t._readableState;e.needReadable=!1,e.emittedReadable||(M("emitReadable",e.flowing),e.emittedReadable=!0,e.sync?q(p,t):p(t))}function p(t){M("emit readable"),t.emit("readable"),v(t)}function d(t,e){e.readingMore||(e.readingMore=!0,q(g,t,e))}function g(t,e){for(var r=e.length;!e.reading&&!e.flowing&&!e.ended&&e.length<e.highWaterMark&&(M("maybeReadMore read 0"),t.read(0),r!==e.length);)r=e.length;e.readingMore=!1}function _(t){return function(){var e=t._readableState;M("pipeOnDrain",e.awaitDrain),e.awaitDrain&&e.awaitDrain--,0===e.awaitDrain&&B(t,"data")&&(e.flowing=!0,v(t))}}function m(t){M("readable nexttick read 0"),t.read(0)}function b(t,e){e.resumeScheduled||(e.resumeScheduled=!0,q(y,t,e))}function y(t,e){e.reading||(M("resume read 0"),t.read(0)),e.resumeScheduled=!1,e.awaitDrain=0,t.emit("resume"),v(t),e.flowing&&!e.reading&&t.read(0)}function v(t){var e=t._readableState;for(M("flow",e.flowing);e.flowing&&null!==t.read(););}function w(t,e){if(0===e.length)return null;var r;return e.objectMode?r=e.buffer.shift():!t||t>=e.length?(r=e.decoder?e.buffer.join(""):1===e.buffer.length?e.buffer.head.data:e.buffer.concat(e.length),e.buffer.clear()):r=x(t,e.buffer,e.decoder),r}function x(t,e,r){var n;return t<e.head.data.length?(n=e.head.data.slice(0,t),e.head.data=e.head.data.slice(t)):n=t===e.head.data.length?e.shift():r?S(t,e):E(t,e),n}function S(t,e){var r=e.head,n=1,i=r.data;for(t-=i.length;r=r.next;){var s=r.data,o=t>s.length?s.length:t;if(i+=o===s.length?s:s.slice(0,t),t-=o,0===t){o===s.length?(++n,r.next?e.head=r.next:e.head=e.tail=null):(e.head=r,r.data=s.slice(o));break}++n}return e.length-=n,i}function E(t,e){var r=j.allocUnsafe(t),n=e.head,i=1;for(n.data.copy(r),t-=n.data.length;n=n.next;){var s=n.data,o=t>s.length?s.length:t;if(s.copy(r,r.length-t,0,o),t-=o,0===t){o===s.length?(++i,n.next?e.head=n.next:e.head=e.tail=null):(e.head=n,n.data=s.slice(o));break}++i}return e.length-=i,r}function T(t){var e=t._readableState;if(e.length>0)throw new Error('"endReadable()" called on non-empty stream');e.endEmitted||(e.ended=!0,q(A,e,t))}function A(t,e){t.endEmitted||0!==t.length||(t.endEmitted=!0,e.readable=!1,e.emit("end"))}function k(t,e){for(var r=0,n=t.length;r<n;r++)e(t[r],r)}function L(t,e){for(var r=0,n=t.length;r<n;r++)if(t[r]===e)return r;return-1}e.exports=s;var q=t("process-nextick-args"),R=t("isarray");s.ReadableState=i;var C,B=(t("events").EventEmitter,function(t,e){return t.listeners(e).length});!function(){try{C=t("stream")}catch(e){}finally{C||(C=t("events").EventEmitter)}}();var D=t("buffer").Buffer,j=t("buffer-shims"),N=t("core-util-is");N.inherits=t("inherits");var O=t("util"),M=void 0;M=O&&O.debuglog?O.debuglog("stream"):function(){};var I,P=t("./internal/streams/BufferList");N.inherits(s,C);var U,U;s.prototype.push=function(t,e){var r=this._readableState;return r.objectMode||"string"!=typeof t||(e=e||r.defaultEncoding,e!==r.encoding&&(t=j.from(t,e),e="")),o(this,r,t,e,!1)},s.prototype.unshift=function(t){var e=this._readableState;return o(this,e,t,"",!0)},s.prototype.isPaused=function(){return this._readableState.flowing===!1},s.prototype.setEncoding=function(e){return I||(I=t("string_decoder/").StringDecoder),this._readableState.decoder=new I(e),this._readableState.encoding=e,this};var H=8388608;s.prototype.read=function(t){M("read",t),t=parseInt(t,10);var e=this._readableState,r=t;if(0!==t&&(e.emittedReadable=!1),0===t&&e.needReadable&&(e.length>=e.highWaterMark||e.ended))return M("read: emitReadable",e.length,e.ended),0===e.length&&e.ended?T(this):f(this),null;if(t=u(t,e),0===t&&e.ended)return 0===e.length&&T(this),null;var n=e.needReadable;M("need readable",n),(0===e.length||e.length-t<e.highWaterMark)&&(n=!0,M("length less than watermark",n)),e.ended||e.reading?(n=!1,M("reading or ended",n)):n&&(M("do read"),e.reading=!0,e.sync=!0,0===e.length&&(e.needReadable=!0),this._read(e.highWaterMark),e.sync=!1,e.reading||(t=u(r,e)));var i;return i=t>0?w(t,e):null,null===i?(e.needReadable=!0,t=0):e.length-=t,0===e.length&&(e.ended||(e.needReadable=!0),r!==t&&e.ended&&T(this)),null!==i&&this.emit("data",i),i},s.prototype._read=function(t){this.emit("error",new Error("not implemented"))},s.prototype.pipe=function(t,e){function i(t){M("onunpipe"),t===f&&o()}function s(){M("onend"),t.end()}function o(){M("cleanup"),t.removeListener("close",u),t.removeListener("finish",h),t.removeListener("drain",m),t.removeListener("error",c),t.removeListener("unpipe",i),f.removeListener("end",s),f.removeListener("end",o),f.removeListener("data",a),b=!0,!p.awaitDrain||t._writableState&&!t._writableState.needDrain||m()}function a(e){M("ondata"),y=!1;var r=t.write(e);!1!==r||y||((1===p.pipesCount&&p.pipes===t||p.pipesCount>1&&L(p.pipes,t)!==-1)&&!b&&(M("false write response, pause",f._readableState.awaitDrain),f._readableState.awaitDrain++,y=!0),f.pause())}function c(e){M("onerror",e),l(),t.removeListener("error",c),0===B(t,"error")&&t.emit("error",e)}function u(){t.removeListener("finish",h),l()}function h(){M("onfinish"),t.removeListener("close",u),l()}function l(){M("unpipe"),f.unpipe(t)}var f=this,p=this._readableState;switch(p.pipesCount){case 0:p.pipes=t;break;case 1:p.pipes=[p.pipes,t];break;default:p.pipes.push(t)}p.pipesCount+=1,M("pipe count=%d opts=%j",p.pipesCount,e);var d=(!e||e.end!==!1)&&t!==r.stdout&&t!==r.stderr,g=d?s:o;p.endEmitted?q(g):f.once("end",g),t.on("unpipe",i);var m=_(f);t.on("drain",m);var b=!1,y=!1;return f.on("data",a),n(t,"error",c),t.once("close",u),t.once("finish",h),t.emit("pipe",f),p.flowing||(M("pipe resume"),f.resume()),t},s.prototype.unpipe=function(t){var e=this._readableState;if(0===e.pipesCount)return this;if(1===e.pipesCount)return t&&t!==e.pipes?this:(t||(t=e.pipes),e.pipes=null,e.pipesCount=0,e.flowing=!1,t&&t.emit("unpipe",this),this);if(!t){var r=e.pipes,n=e.pipesCount;e.pipes=null,e.pipesCount=0,e.flowing=!1;for(var i=0;i<n;i++)r[i].emit("unpipe",this);return this}var s=L(e.pipes,t);return s===-1?this:(e.pipes.splice(s,1),e.pipesCount-=1,1===e.pipesCount&&(e.pipes=e.pipes[0]),t.emit("unpipe",this),this)},s.prototype.on=function(t,e){var r=C.prototype.on.call(this,t,e);if("data"===t)this._readableState.flowing!==!1&&this.resume();else if("readable"===t){var n=this._readableState;n.endEmitted||n.readableListening||(n.readableListening=n.needReadable=!0,n.emittedReadable=!1,n.reading?n.length&&f(this,n):q(m,this))}return r},s.prototype.addListener=s.prototype.on,s.prototype.resume=function(){var t=this._readableState;return t.flowing||(M("resume"),t.flowing=!0,b(this,t)),this},s.prototype.pause=function(){return M("call pause flowing=%j",this._readableState.flowing),!1!==this._readableState.flowing&&(M("pause"),this._readableState.flowing=!1,this.emit("pause")),this},s.prototype.wrap=function(t){var e=this._readableState,r=!1,n=this;t.on("end",function(){if(M("wrapped end"),e.decoder&&!e.ended){var t=e.decoder.end();t&&t.length&&n.push(t)}n.push(null)}),t.on("data",function(i){if(M("wrapped data"),e.decoder&&(i=e.decoder.write(i)),(!e.objectMode||null!==i&&void 0!==i)&&(e.objectMode||i&&i.length)){var s=n.push(i);s||(r=!0,t.pause())}});for(var i in t)void 0===this[i]&&"function"==typeof t[i]&&(this[i]=function(e){return function(){return t[e].apply(t,arguments)}}(i));var s=["error","close","destroy","pause","resume"];return k(s,function(e){t.on(e,n.emit.bind(n,e))}),n._read=function(e){M("wrapped _read",e),r&&(r=!1,t.resume())},n},s._fromList=w}).call(this,t("_process"))},{"./_stream_duplex":44,"./internal/streams/BufferList":49,_process:42,buffer:5,"buffer-shims":4,"core-util-is":6,events:28,inherits:38,isarray:40,"process-nextick-args":41,"string_decoder/":56,util:3}],47:[function(t,e,r){"use strict";function n(t){this.afterTransform=function(e,r){return i(t,e,r)},this.needTransform=!1,this.transforming=!1,this.writecb=null,this.writechunk=null,this.writeencoding=null}function i(t,e,r){var n=t._transformState;n.transforming=!1;var i=n.writecb;if(!i)return t.emit("error",new Error("no writecb in Transform class"));n.writechunk=null,n.writecb=null,null!==r&&void 0!==r&&t.push(r),i(e);var s=t._readableState;s.reading=!1,(s.needReadable||s.length<s.highWaterMark)&&t._read(s.highWaterMark)}function s(t){if(!(this instanceof s))return new s(t);a.call(this,t),this._transformState=new n(this);var e=this;this._readableState.needReadable=!0,this._readableState.sync=!1,t&&("function"==typeof t.transform&&(this._transform=t.transform),"function"==typeof t.flush&&(this._flush=t.flush)),this.once("prefinish",function(){"function"==typeof this._flush?this._flush(function(t){o(e,t)}):o(e)})}function o(t,e){if(e)return t.emit("error",e);var r=t._writableState,n=t._transformState;if(r.length)throw new Error("Calling transform done when ws.length != 0");if(n.transforming)throw new Error("Calling transform done when still transforming");return t.push(null)}e.exports=s;var a=t("./_stream_duplex"),c=t("core-util-is");c.inherits=t("inherits"),c.inherits(s,a),s.prototype.push=function(t,e){return this._transformState.needTransform=!1,a.prototype.push.call(this,t,e)},s.prototype._transform=function(t,e,r){throw new Error("Not implemented")},s.prototype._write=function(t,e,r){var n=this._transformState;if(n.writecb=r,n.writechunk=t,n.writeencoding=e,!n.transforming){var i=this._readableState;(n.needTransform||i.needReadable||i.length<i.highWaterMark)&&this._read(i.highWaterMark)}},s.prototype._read=function(t){var e=this._transformState;null!==e.writechunk&&e.writecb&&!e.transforming?(e.transforming=!0,this._transform(e.writechunk,e.writeencoding,e.afterTransform)):e.needTransform=!0}},{"./_stream_duplex":44,"core-util-is":6,inherits:38}],48:[function(t,e,r){(function(r){"use strict";function n(){}function i(t,e,r){this.chunk=t,this.encoding=e,this.callback=r,this.next=null}function s(e,r){R=R||t("./_stream_duplex"),e=e||{},this.objectMode=!!e.objectMode,r instanceof R&&(this.objectMode=this.objectMode||!!e.writableObjectMode);var n=e.highWaterMark,i=this.objectMode?16:16384;this.highWaterMark=n||0===n?n:i,this.highWaterMark=~~this.highWaterMark,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1;var s=e.decodeStrings===!1;this.decodeStrings=!s,this.defaultEncoding=e.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(t){d(r,t)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.bufferedRequestCount=0,this.corkedRequestsFree=new x(this)}function o(e){return R=R||t("./_stream_duplex"),this instanceof o||this instanceof R?(this._writableState=new s(e,this),this.writable=!0,e&&("function"==typeof e.write&&(this._write=e.write),"function"==typeof e.writev&&(this._writev=e.writev)),void A.call(this)):new o(e)}function a(t,e){var r=new Error("write after end");t.emit("error",r),S(e,r)}function c(t,e,r,n){var i=!0,s=!1;return null===r?s=new TypeError("May not write null values to stream"):L.isBuffer(r)||"string"==typeof r||void 0===r||e.objectMode||(s=new TypeError("Invalid non-string/buffer chunk")),s&&(t.emit("error",s),S(n,s),i=!1),i}function u(t,e,r){return t.objectMode||t.decodeStrings===!1||"string"!=typeof e||(e=q.from(e,r)),e}function h(t,e,r,n,s){r=u(e,r,n),L.isBuffer(r)&&(n="buffer");var o=e.objectMode?1:r.length;e.length+=o;var a=e.length<e.highWaterMark;if(a||(e.needDrain=!0),e.writing||e.corked){var c=e.lastBufferedRequest;e.lastBufferedRequest=new i(r,n,s),c?c.next=e.lastBufferedRequest:e.bufferedRequest=e.lastBufferedRequest,e.bufferedRequestCount+=1}else l(t,e,!1,o,r,n,s);return a}function l(t,e,r,n,i,s,o){e.writelen=n,e.writecb=o,e.writing=!0,e.sync=!0,r?t._writev(i,e.onwrite):t._write(i,s,e.onwrite),e.sync=!1}function f(t,e,r,n,i){--e.pendingcb,r?S(i,n):i(n),t._writableState.errorEmitted=!0,t.emit("error",n)}function p(t){t.writing=!1,t.writecb=null,t.length-=t.writelen,t.writelen=0}function d(t,e){var r=t._writableState,n=r.sync,i=r.writecb;if(p(r),e)f(t,r,n,e,i);else{var s=b(r);s||r.corked||r.bufferProcessing||!r.bufferedRequest||m(t,r),n?E(g,t,r,s,i):g(t,r,s,i)}}function g(t,e,r,n){r||_(t,e),e.pendingcb--,n(),v(t,e)}function _(t,e){0===e.length&&e.needDrain&&(e.needDrain=!1,t.emit("drain"))}function m(t,e){e.bufferProcessing=!0;var r=e.bufferedRequest;if(t._writev&&r&&r.next){var n=e.bufferedRequestCount,i=new Array(n),s=e.corkedRequestsFree;s.entry=r;for(var o=0;r;)i[o]=r,r=r.next,o+=1;l(t,e,!0,e.length,i,"",s.finish),e.pendingcb++,e.lastBufferedRequest=null,s.next?(e.corkedRequestsFree=s.next,s.next=null):e.corkedRequestsFree=new x(e)}else{for(;r;){var a=r.chunk,c=r.encoding,u=r.callback,h=e.objectMode?1:a.length;if(l(t,e,!1,h,a,c,u),r=r.next,e.writing)break}null===r&&(e.lastBufferedRequest=null)}e.bufferedRequestCount=0,e.bufferedRequest=r,e.bufferProcessing=!1}function b(t){return t.ending&&0===t.length&&null===t.bufferedRequest&&!t.finished&&!t.writing}function y(t,e){e.prefinished||(e.prefinished=!0,t.emit("prefinish"))}function v(t,e){var r=b(e);return r&&(0===e.pendingcb?(y(t,e),e.finished=!0,t.emit("finish")):y(t,e)),r}function w(t,e,r){e.ending=!0,v(t,e),r&&(e.finished?S(r):t.once("finish",r)),e.ended=!0,t.writable=!1}function x(t){var e=this;this.next=null,this.entry=null,this.finish=function(r){var n=e.entry;for(e.entry=null;n;){var i=n.callback;t.pendingcb--,i(r),n=n.next}t.corkedRequestsFree?t.corkedRequestsFree.next=e:t.corkedRequestsFree=e}}e.exports=o;var S=t("process-nextick-args"),E=!r.browser&&["v0.10","v0.9."].indexOf(r.version.slice(0,5))>-1?setImmediate:S;o.WritableState=s;var T=t("core-util-is");T.inherits=t("inherits");var A,k={deprecate:t("util-deprecate")};!function(){try{A=t("stream")}catch(e){}finally{A||(A=t("events").EventEmitter)}}();var L=t("buffer").Buffer,q=t("buffer-shims");T.inherits(o,A);var R;s.prototype.getBuffer=function(){for(var t=this.bufferedRequest,e=[];t;)e.push(t),t=t.next;return e},function(){try{Object.defineProperty(s.prototype,"buffer",{get:k.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.")})}catch(t){}}();var R;o.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe, not readable"))},o.prototype.write=function(t,e,r){var i=this._writableState,s=!1;return"function"==typeof e&&(r=e,e=null),L.isBuffer(t)?e="buffer":e||(e=i.defaultEncoding),"function"!=typeof r&&(r=n),i.ended?a(this,r):c(this,i,t,r)&&(i.pendingcb++,s=h(this,i,t,e,r)),s},o.prototype.cork=function(){var t=this._writableState;t.corked++},o.prototype.uncork=function(){var t=this._writableState;t.corked&&(t.corked--,t.writing||t.corked||t.finished||t.bufferProcessing||!t.bufferedRequest||m(this,t))},o.prototype.setDefaultEncoding=function(t){if("string"==typeof t&&(t=t.toLowerCase()),!(["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le","raw"].indexOf((t+"").toLowerCase())>-1))throw new TypeError("Unknown encoding: "+t);return this._writableState.defaultEncoding=t,this},o.prototype._write=function(t,e,r){r(new Error("not implemented"))},o.prototype._writev=null,o.prototype.end=function(t,e,r){var n=this._writableState;"function"==typeof t?(r=t,t=null,e=null):"function"==typeof e&&(r=e,e=null),null!==t&&void 0!==t&&this.write(t,e),n.corked&&(n.corked=1,this.uncork()),n.ending||n.finished||w(this,n,r)}}).call(this,t("_process"))},{"./_stream_duplex":44,_process:42,buffer:5,"buffer-shims":4,"core-util-is":6,events:28,inherits:38,"process-nextick-args":41,"util-deprecate":57}],49:[function(t,e,r){"use strict";function n(){this.head=null,this.tail=null,this.length=0}var i=(t("buffer").Buffer,t("buffer-shims"));e.exports=n,n.prototype.push=function(t){var e={data:t,next:null};this.length>0?this.tail.next=e:this.head=e,this.tail=e,++this.length},n.prototype.unshift=function(t){var e={data:t,next:this.head};0===this.length&&(this.tail=e),this.head=e,++this.length},n.prototype.shift=function(){if(0!==this.length){var t=this.head.data;return 1===this.length?this.head=this.tail=null:this.head=this.head.next,--this.length,t}},n.prototype.clear=function(){this.head=this.tail=null,this.length=0},n.prototype.join=function(t){if(0===this.length)return"";for(var e=this.head,r=""+e.data;e=e.next;)r+=t+e.data;return r},n.prototype.concat=function(t){if(0===this.length)return i.alloc(0);if(1===this.length)return this.head.data;for(var e=i.allocUnsafe(t>>>0),r=this.head,n=0;r;)r.data.copy(e,n),n+=r.data.length,r=r.next;return e}},{buffer:5,"buffer-shims":4}],50:[function(t,e,r){e.exports=t("./lib/_stream_passthrough.js")},{"./lib/_stream_passthrough.js":45}],51:[function(t,e,r){(function(n){var i=function(){try{return t("stream")}catch(e){}}();r=e.exports=t("./lib/_stream_readable.js"),r.Stream=i||r,r.Readable=r,r.Writable=t("./lib/_stream_writable.js"),r.Duplex=t("./lib/_stream_duplex.js"),r.Transform=t("./lib/_stream_transform.js"),r.PassThrough=t("./lib/_stream_passthrough.js"),!n.browser&&"disable"===n.env.READABLE_STREAM&&i&&(e.exports=i)}).call(this,t("_process"))},{"./lib/_stream_duplex.js":44,"./lib/_stream_passthrough.js":45,"./lib/_stream_readable.js":46,"./lib/_stream_transform.js":47,"./lib/_stream_writable.js":48,_process:42}],52:[function(t,e,r){e.exports=t("./lib/_stream_transform.js")},{"./lib/_stream_transform.js":47}],53:[function(t,e,r){e.exports=t("./lib/_stream_writable.js")},{"./lib/_stream_writable.js":48}],54:[function(t,e,r){e.exports=function(t){return t.replace(/[-\\^$*+?.()|[\]{}]/g,"\\$&")}},{}],55:[function(t,e,r){function n(){i.call(this)}e.exports=n;var i=t("events").EventEmitter,s=t("inherits");s(n,i),n.Readable=t("readable-stream/readable.js"),n.Writable=t("readable-stream/writable.js"),n.Duplex=t("readable-stream/duplex.js"),n.Transform=t("readable-stream/transform.js"),n.PassThrough=t("readable-stream/passthrough.js"),n.Stream=n,n.prototype.pipe=function(t,e){function r(e){t.writable&&!1===t.write(e)&&u.pause&&u.pause()}function n(){u.readable&&u.resume&&u.resume()}function s(){h||(h=!0,t.end())}function o(){h||(h=!0,"function"==typeof t.destroy&&t.destroy())}function a(t){if(c(),0===i.listenerCount(this,"error"))throw t}function c(){u.removeListener("data",r),t.removeListener("drain",n),u.removeListener("end",s),u.removeListener("close",o),u.removeListener("error",a),t.removeListener("error",a),u.removeListener("end",c),u.removeListener("close",c),t.removeListener("close",c)}var u=this;u.on("data",r),t.on("drain",n),t._isStdio||e&&e.end===!1||(u.on("end",s),u.on("close",o));var h=!1;return u.on("error",a),t.on("error",a),u.on("end",c),u.on("close",c),t.on("close",c),t.emit("pipe",u),t}},{events:28,inherits:38,"readable-stream/duplex.js":43,"readable-stream/passthrough.js":50,"readable-stream/readable.js":51,"readable-stream/transform.js":52,"readable-stream/writable.js":53}],56:[function(t,e,r){function n(t){if(t&&!c(t))throw new Error("Unknown encoding: "+t)}function i(t){return t.toString(this.encoding)}function s(t){this.charReceived=t.length%2,this.charLength=this.charReceived?2:0}function o(t){this.charReceived=t.length%3,this.charLength=this.charReceived?3:0}var a=t("buffer").Buffer,c=a.isEncoding||function(t){switch(t&&t.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}},u=r.StringDecoder=function(t){switch(this.encoding=(t||"utf8").toLowerCase().replace(/[-_]/,""),n(t),this.encoding){case"utf8":this.surrogateSize=3;break;case"ucs2":case"utf16le":this.surrogateSize=2,this.detectIncompleteChar=s;break;case"base64":this.surrogateSize=3,this.detectIncompleteChar=o;break;default:return void(this.write=i)}this.charBuffer=new a(6),this.charReceived=0,this.charLength=0};u.prototype.write=function(t){for(var e="";this.charLength;){var r=t.length>=this.charLength-this.charReceived?this.charLength-this.charReceived:t.length;if(t.copy(this.charBuffer,this.charReceived,0,r),this.charReceived+=r,this.charReceived<this.charLength)return"";t=t.slice(r,t.length),e=this.charBuffer.slice(0,this.charLength).toString(this.encoding);var n=e.charCodeAt(e.length-1);if(!(n>=55296&&n<=56319)){if(this.charReceived=this.charLength=0,0===t.length)return e;break}this.charLength+=this.surrogateSize,e=""}this.detectIncompleteChar(t);var i=t.length;this.charLength&&(t.copy(this.charBuffer,0,t.length-this.charReceived,i),i-=this.charReceived),e+=t.toString(this.encoding,0,i);var i=e.length-1,n=e.charCodeAt(i);if(n>=55296&&n<=56319){var s=this.surrogateSize;return this.charLength+=s,this.charReceived+=s,this.charBuffer.copy(this.charBuffer,s,0,s),t.copy(this.charBuffer,0,0,s),e.substring(0,i)}return e},u.prototype.detectIncompleteChar=function(t){for(var e=t.length>=3?3:t.length;e>0;e--){var r=t[t.length-e];if(1==e&&r>>5==6){this.charLength=2;break}if(e<=2&&r>>4==14){this.charLength=3;break}if(e<=3&&r>>3==30){this.charLength=4;break}}this.charReceived=e},u.prototype.end=function(t){var e="";if(t&&t.length&&(e=this.write(t)),this.charReceived){var r=this.charReceived,n=this.charBuffer,i=this.encoding;e+=n.slice(0,r).toString(i)}return e}},{buffer:5}],57:[function(t,e,r){(function(t){function r(t,e){function r(){if(!i){if(n("throwDeprecation"))throw new Error(e);n("traceDeprecation")?console.trace(e):console.warn(e),i=!0}return t.apply(this,arguments)}if(n("noDeprecation"))return t;var i=!1;return r}function n(e){try{if(!t.localStorage)return!1}catch(r){return!1}var n=t.localStorage[e];return null!=n&&"true"===String(n).toLowerCase()}e.exports=r}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],58:[function(t,e,r){function n(){for(var t={},e=0;e<arguments.length;e++){var r=arguments[e];for(var n in r)i.call(r,n)&&(t[n]=r[n])}return t}e.exports=n;var i=Object.prototype.hasOwnProperty},{}]},{},[1])(1)});
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/swagger-oauth.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/lib/swagger-oauth.js
new file mode 100644 (file)
index 0000000..f18764c
--- /dev/null
@@ -0,0 +1 @@
+function handleLogin(){var e=[],o=window.swaggerUiAuth.authSchemes||window.swaggerUiAuth.securityDefinitions;if(o){var i,n=o;for(i in n){var a=n[i];if("oauth2"===a.type&&a.scopes){var t;if(Array.isArray(a.scopes)){var p;for(p=0;p<a.scopes.length;p++)e.push(a.scopes[p])}else for(t in a.scopes)e.push({scope:t,description:a.scopes[t],OAuthSchemeKey:i})}}}for(window.swaggerUi.api&&window.swaggerUi.api.info&&(appName=window.swaggerUi.api.info.title),$(".api-popup-dialog").remove(),popupDialog=$(['<div class="api-popup-dialog">','<div class="api-popup-title">Select OAuth2.0 Scopes</div>','<div class="api-popup-content">',"<p>Scopes are used to grant an application different levels of access to data on behalf of the end user. Each API may declare one or more scopes.",'<a href="#">Learn how to use</a>',"</p>","<p><strong>"+appName+"</strong> API requires the following scopes. Select which ones you want to grant to Swagger UI.</p>",'<ul class="api-popup-scopes">',"</ul>",'<p class="error-msg"></p>','<div class="api-popup-actions"><button class="api-popup-authbtn api-button green" type="button" data-sw-translate>Authorize</button><button class="api-popup-cancel api-button gray" type="button">Cancel</button></div>',"</div>","</div>"].join("")),$(document.body).append(popupDialog),popup=popupDialog.find("ul.api-popup-scopes").empty(),p=0;p<e.length;p++)t=e[p],str='<li><input type="checkbox" id="scope_'+p+'" scope="'+t.scope+'"" oauthtype="'+t.OAuthSchemeKey+'"/><label for="scope_'+p+'">'+t.scope,t.description&&($.map(o,function(e,o){return o}).length>1?str+='<br/><span class="api-scope-desc">'+t.description+" ("+t.OAuthSchemeKey+")</span>":str+='<br/><span class="api-scope-desc">'+t.description+"</span>"),str+="</label></li>",popup.append(str);var r=$(window),s=r.width(),c=r.height(),l=r.scrollTop(),d=popupDialog.outerWidth(),u=popupDialog.outerHeight(),h=(c-u)/2+l,g=(s-d)/2;popupDialog.css({top:(h<0?0:h)+"px",left:(g<0?0:g)+"px"}),popupDialog.find("button.api-popup-cancel").click(function(){popupMask.hide(),popupDialog.hide(),popupDialog.empty(),popupDialog=[]}),$("button.api-popup-authbtn").unbind(),popupDialog.find("button.api-popup-authbtn").click(function(){function e(e){return e.vendorExtensions["x-tokenName"]||e.tokenName}popupMask.hide(),popupDialog.hide();var o,i=window.swaggerUi.api.authSchemes,n=window.location,a=location.pathname.substring(0,location.pathname.lastIndexOf("/")),t=n.protocol+"//"+n.host+a+"/o2c.html",p=window.oAuthRedirectUrl||t,r=null,s=[],c=popup.find("input:checked"),l=[];for(k=0;k<c.length;k++){var d=$(c[k]).attr("scope");s.indexOf(d)===-1&&s.push(d);var u=$(c[k]).attr("oauthtype");l.indexOf(u)===-1&&l.push(u)}window.enabledScopes=s;for(var h in i)if(i.hasOwnProperty(h)&&l.indexOf(h)!=-1){var g=i[h].flow;if("oauth2"!==i[h].type||!g||"implicit"!==g&&"accessCode"!==g){if("oauth2"===i[h].type&&g&&"application"===g){var w=i[h];return window.swaggerUi.tokenName=e(w)||"access_token",void clientCredentialsFlow(s,w.tokenUrl,h)}if(i[h].grantTypes){var c=i[h].grantTypes;for(var f in c)if(c.hasOwnProperty(f)&&"implicit"===f){var w=c[f];w.loginEndpoint.url;r=w.loginEndpoint.url+"?response_type=token",window.swaggerUi.tokenName=e(w)}else if(c.hasOwnProperty(f)&&"accessCode"===f){var w=c[f];w.tokenRequestEndpoint.url;r=w.tokenRequestEndpoint.url+"?response_type=code",window.swaggerUi.tokenName=e(w)}}}else{var w=i[h];r=w.authorizationUrl+"?response_type="+("implicit"===g?"token":"code"),window.swaggerUi.tokenName=e(w)||"access_token",window.swaggerUi.tokenUrl="accessCode"===g?w.tokenUrl:null,o=h}}redirect_uri=p,r+="&redirect_uri="+encodeURIComponent(p),r+="&realm="+encodeURIComponent(realm),r+="&client_id="+encodeURIComponent(clientId),r+="&scope="+encodeURIComponent(s.join(scopeSeparator)),r+="&state="+encodeURIComponent(o);for(var h in additionalQueryStringParams)r+="&"+h+"="+encodeURIComponent(additionalQueryStringParams[h]);window.open(r)}),popupMask.show(),popupDialog.show()}function handleLogout(){for(key in window.swaggerUi.api.clientAuthorizations.authz)window.swaggerUi.api.clientAuthorizations.remove(key);window.enabledScopes=null,$(".api-ic.ic-on").addClass("ic-off"),$(".api-ic.ic-on").removeClass("ic-on"),$(".api-ic.ic-warning").addClass("ic-error"),$(".api-ic.ic-warning").removeClass("ic-warning")}function initOAuth(e){var o=e||{},i=[];return appName=o.appName||i.push("missing appName"),popupMask=o.popupMask||$("#api-common-mask"),popupDialog=o.popupDialog||$(".api-popup-dialog"),clientId=o.clientId||i.push("missing client id"),clientSecret=o.clientSecret||null,realm=o.realm||i.push("missing realm"),scopeSeparator=o.scopeSeparator||" ",additionalQueryStringParams=o.additionalQueryStringParams||{},i.length>0?void log("auth unable initialize oauth: "+i):($("pre code").each(function(e,o){hljs.highlightBlock(o)}),$(".api-ic").unbind(),void $(".api-ic").click(function(e){$(e.target).hasClass("ic-off")?handleLogin():handleLogout()}))}function clientCredentialsFlow(e,o,i){var n={client_id:clientId,client_secret:clientSecret,scope:e.join(" "),grant_type:"client_credentials"};$.ajax({url:o,type:"POST",data:n,success:function(e,o,n){onOAuthComplete(e,i)},error:function(e,o,i){onOAuthComplete("")}})}var appName,popupMask,popupDialog,clientId,realm,redirect_uri,clientSecret,scopeSeparator,additionalQueryStringParams;window.processOAuthCode=function(e){var o=e.state,i=window.location,n=location.pathname.substring(0,location.pathname.lastIndexOf("/")),a=i.protocol+"//"+i.host+n+"/o2c.html",t=window.oAuthRedirectUrl||a,p={client_id:clientId,code:e.code,grant_type:"authorization_code",redirect_uri:t};clientSecret&&(p.client_secret=clientSecret),$.ajax({url:window.swaggerUiAuth.tokenUrl,type:"POST",data:p,success:function(e,i,n){onOAuthComplete(e,o)},error:function(e,o,i){onOAuthComplete("")}})},window.onOAuthComplete=function(e,o){if(e)if(e.error){var i=$("input[type=checkbox],.secured");i.each(function(e){i[e].checked=!1}),alert(e.error)}else{var n=e[window.swaggerUiAuth.tokenName];if(o||(o=e.state),n){var a=null;$.each($(".auth .api-ic .api_information_panel"),function(e,o){var i=o;if(i&&i.childNodes){var n=[];$.each(i.childNodes,function(e,o){var i=o.innerHTML;i&&n.push(i)});for(var t=[],p=0;p<n.length;p++){var r=n[p];window.enabledScopes&&window.enabledScopes.indexOf(r)==-1&&t.push(r)}t.length>0?(a=o.parentNode.parentNode,$(a.parentNode).find(".api-ic.ic-on").addClass("ic-off"),$(a.parentNode).find(".api-ic.ic-on").removeClass("ic-on"),$(a).find(".api-ic").addClass("ic-warning"),$(a).find(".api-ic").removeClass("ic-error")):(a=o.parentNode.parentNode,$(a.parentNode).find(".api-ic.ic-off").addClass("ic-on"),$(a.parentNode).find(".api-ic.ic-off").removeClass("ic-off"),$(a).find(".api-ic").addClass("ic-info"),$(a).find(".api-ic").removeClass("ic-warning"),$(a).find(".api-ic").removeClass("ic-error"))}}),"undefined"!=typeof window.swaggerUi&&(window.swaggerUi.api.clientAuthorizations.add(window.swaggerUiAuth.OAuthSchemeKey,new SwaggerClient.ApiKeyAuthorization("Authorization","Bearer "+n,"header")),window.swaggerUi.load())}}};
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/o2c.html b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/o2c.html
new file mode 100644 (file)
index 0000000..a4fe7a1
--- /dev/null
@@ -0,0 +1,36 @@
+<!--
+  ~ Modifications Copyright © 2017-2018 AT&T Intellectual Property.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<script>
+var qp = null;
+if(/code|token|error/.test(window.location.hash)) {
+  qp = location.hash.substring(1);
+}
+else {
+  qp = location.search.substring(1);
+}
+qp = qp ? JSON.parse('{"' + qp.replace(/&/g, '","').replace(/=/g,'":"') + '"}',
+  function(key, value) {
+    return key===""?value:decodeURIComponent(value) }
+  ):{}
+
+if (window.opener.swaggerUiAuth.tokenUrl)
+    window.opener.processOAuthCode(qp);
+else
+    window.opener.onOAuthComplete(qp);
+
+window.close();
+</script>
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/swagger-ui.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/swagger-ui.js
new file mode 100644 (file)
index 0000000..c76ffb7
--- /dev/null
@@ -0,0 +1,25378 @@
+/**
+ * swagger-ui - Swagger UI is a dependency-free collection of HTML, JavaScript, and CSS assets that dynamically generate beautiful documentation from a Swagger-compliant API
+ * @version v2.2.10
+ * @link http://swagger.io
+ * @license Apache-2.0
+ */
+(function(){/* jshint ignore:start */
+ {(function() {
+  var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
+templates['apikey_auth'] = template({"1":function(container,depth0,helpers,partials,data) {
+    var stack1;
+
+  return "                <span class=\"key_auth__value\">"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.value : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "</span>\n";
+},"3":function(container,depth0,helpers,partials,data) {
+    return "                <input placeholder=\"api_key\" class=\"auth_input input_apiKey_entry\" name=\"apiKey\" type=\"text\"/>\n";
+},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
+
+  return "<div class=\"key_input_container\">\n    <h3 class=\"auth__title\">Api key authorization</h3>\n    <div class=\"auth__description\">"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "</div>\n    <div>\n        <div class=\"key_auth__field\">\n            <span class=\"key_auth__label\">name:</span>\n            <span class=\"key_auth__value\">"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "</span>\n        </div>\n        <div class=\"key_auth__field\">\n            <span class=\"key_auth__label\">in:</span>\n            <span class=\"key_auth__value\">"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0["in"] : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "</span>\n        </div>\n        <div class=\"key_auth__field\">\n            <span class=\"key_auth__label\">value:</span>\n"
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isLogout : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(3, data, 0),"data":data})) != null ? stack1 : "")
+    + "        </div>\n    </div>\n</div>\n";
+},"useData":true});
+templates['auth_button'] = template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+    return "<a class='authorize__btn' href=\"#\" data-sw-translate>Authorize</a>\n";
+},"useData":true});
+templates['auth_button_operation'] = template({"1":function(container,depth0,helpers,partials,data) {
+    return "        authorize__btn_operation_login\n";
+},"3":function(container,depth0,helpers,partials,data) {
+    return "        authorize__btn_operation_logout\n";
+},"5":function(container,depth0,helpers,partials,data) {
+    var stack1;
+
+  return "        <ul class=\"authorize-scopes\">\n"
+    + ((stack1 = helpers.each.call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.scopes : depth0),{"name":"each","hash":{},"fn":container.program(6, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "        </ul>\n";
+},"6":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
+
+  return "                <li class=\"authorize__scope\" title=\""
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "\">"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.scope : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "</li>\n";
+},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {};
+
+  return "<div class=\"authorize__btn authorize__btn_operation\n"
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isLogout : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(3, data, 0),"data":data})) != null ? stack1 : "")
+    + "\">\n"
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.scopes : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "</div>\n";
+},"useData":true});
+templates['auth_view'] = template({"1":function(container,depth0,helpers,partials,data) {
+    return "            <button type=\"button\" class=\"auth__button auth_submit__button\" data-sw-translate>Authorize</button>\n";
+},"3":function(container,depth0,helpers,partials,data) {
+    return "            <button type=\"button\" class=\"auth__button auth_logout__button\" data-sw-translate>Logout</button>\n";
+},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {};
+
+  return "<div class=\"auth_container\">\n\n    <div class=\"auth_inner\"></div>\n    <div class=\"auth_submit\">\n"
+    + ((stack1 = helpers.unless.call(alias1,(depth0 != null ? depth0.isLogout : depth0),{"name":"unless","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isAuthorized : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "    </div>\n\n</div>\n";
+},"useData":true});
+templates['basic_auth'] = template({"1":function(container,depth0,helpers,partials,data) {
+    return " - authorized";
+},"3":function(container,depth0,helpers,partials,data) {
+    var stack1;
+
+  return "                <span class=\"basic_auth__value\">"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.username : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "</span>\n";
+},"5":function(container,depth0,helpers,partials,data) {
+    return "                <input required placeholder=\"username\" class=\"basic_auth__username auth_input\" name=\"username\" type=\"text\"/>\n";
+},"7":function(container,depth0,helpers,partials,data) {
+    return "            <div class=\"auth_label\">\n                <span class=\"basic_auth__label\" data-sw-translate>password:</span>\n                <input required placeholder=\"password\" class=\"basic_auth__password auth_input\" name=\"password\" type=\"password\"/></label>\n            </div>\n";
+},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {};
+
+  return "<div class='basic_auth_container'>\n    <h3 class=\"auth__title\">Basic authentication"
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isLogout : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "</h3>\n    <form class=\"basic_input_container\">\n        <div class=\"auth__description\">"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "</div>\n        <div class=\"auth_label\">\n            <span class=\"basic_auth__label\" data-sw-translate>username:</span>\n"
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isLogout : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.program(5, data, 0),"data":data})) != null ? stack1 : "")
+    + "        </div>\n"
+    + ((stack1 = helpers.unless.call(alias1,(depth0 != null ? depth0.isLogout : depth0),{"name":"unless","hash":{},"fn":container.program(7, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "    </form>\n</div>\n";
+},"useData":true});
+templates['content_type'] = template({"1":function(container,depth0,helpers,partials,data) {
+    var stack1;
+
+  return ((stack1 = helpers.each.call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.produces : depth0),{"name":"each","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "");
+},"2":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
+
+  return "     <option value=\""
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,depth0,{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "\">"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,depth0,{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "</option>\n";
+},"4":function(container,depth0,helpers,partials,data) {
+    return "  <option value=\"application/json\">application/json</option>\n";
+},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
+
+  return "<label data-sw-translate for=\""
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.contentTypeId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "\">Response Content Type</label>\n<select name=\"contentType\" id=\""
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.contentTypeId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "\">\n"
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.produces : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(4, data, 0),"data":data})) != null ? stack1 : "")
+    + "</select>\n";
+},"useData":true});
+templates['main'] = template({"1":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
+
+  return "  <div class=\"info_title\">"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.title : stack1),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "</div>\n  <div class=\"info_description markdown\">"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.description : stack1),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "</div>\n"
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.externalDocs : depth0),{"name":"if","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "  "
+    + ((stack1 = helpers["if"].call(alias1,((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.termsOfServiceUrl : stack1),{"name":"if","hash":{},"fn":container.program(4, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "\n  "
+    + ((stack1 = helpers["if"].call(alias1,((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.name : stack1),{"name":"if","hash":{},"fn":container.program(6, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "\n  "
+    + ((stack1 = helpers["if"].call(alias1,((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.url : stack1),{"name":"if","hash":{},"fn":container.program(8, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "\n  "
+    + ((stack1 = helpers["if"].call(alias1,((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.email : stack1),{"name":"if","hash":{},"fn":container.program(10, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "\n  "
+    + ((stack1 = helpers["if"].call(alias1,((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.license : stack1),{"name":"if","hash":{},"fn":container.program(12, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "\n";
+},"2":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
+
+  return "  <p>"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,((stack1 = (depth0 != null ? depth0.externalDocs : depth0)) != null ? stack1.description : stack1),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "</p>\n  <a href=\""
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,((stack1 = (depth0 != null ? depth0.externalDocs : depth0)) != null ? stack1.url : stack1),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "\" target=\"_blank\">"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,((stack1 = (depth0 != null ? depth0.externalDocs : depth0)) != null ? stack1.url : stack1),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "</a>\n";
+},"4":function(container,depth0,helpers,partials,data) {
+    var stack1;
+
+  return "<div class=\"info_tos\"><a target=\"_blank\" href=\""
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(depth0 != null ? depth0 : {},((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.termsOfServiceUrl : stack1),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "\" data-sw-translate>Terms of service</a></div>";
+},"6":function(container,depth0,helpers,partials,data) {
+    var stack1;
+
+  return "<div><div class='info_name' style=\"display: inline\" data-sw-translate>Created by </div> "
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(depth0 != null ? depth0 : {},((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.name : stack1),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "</div>";
+},"8":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
+
+  return "<div class='info_url' data-sw-translate>See more at <a href=\""
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.url : stack1),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "\">"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.url : stack1),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "</a></div>";
+},"10":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
+
+  return "<div class='info_email'><a target=\"_parent\" href=\"mailto:"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.contact : stack1)) != null ? stack1.email : stack1),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "?subject="
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.title : stack1),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "\" data-sw-translate>Contact the developer</a></div>";
+},"12":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
+
+  return "<div class='info_license'><a target=\"_blank\" href='"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.license : stack1)) != null ? stack1.url : stack1),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "'>"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,((stack1 = ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.license : stack1)) != null ? stack1.name : stack1),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "</a></div>";
+},"14":function(container,depth0,helpers,partials,data) {
+    var stack1;
+
+  return "  , <span style=\"font-variant: small-caps\" data-sw-translate>api version</span>: "
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(depth0 != null ? depth0 : {},((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.version : stack1),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "\n    ";
+},"16":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
+
+  return "    <span style=\"float:right\"><a target=\"_blank\" href=\""
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.validatorUrl : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "/debug?url="
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.url : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "\"><img id=\"validator\" src=\""
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.validatorUrl : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "?url="
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.url : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "\"></a>\n    </span>\n";
+},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {};
+
+  return "<div class='info' id='api_info'>\n"
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.info : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "</div>\n<div class='container' id='resources_container'>\n  <div class='authorize-wrapper'></div>\n\n  <ul id='resources'></ul>\n\n  <div class=\"footer\">\n    <h4 style=\"color: #999\">[ <span style=\"font-variant: small-caps\">base url</span>: "
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(alias1,(depth0 != null ? depth0.basePath : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "\n"
+    + ((stack1 = helpers["if"].call(alias1,((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.version : stack1),{"name":"if","hash":{},"fn":container.program(14, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "]\n"
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.validatorUrl : depth0),{"name":"if","hash":{},"fn":container.program(16, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "    </h4>\n    </div>\n</div>\n";
+},"useData":true});
+templates['oauth2'] = template({"1":function(container,depth0,helpers,partials,data) {
+    var stack1;
+
+  return "<p>Authorization URL: "
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.authorizationUrl : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "</p>";
+},"3":function(container,depth0,helpers,partials,data) {
+    var stack1;
+
+  return "<p>Token URL: "
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.tokenUrl : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "</p>";
+},"5":function(container,depth0,helpers,partials,data) {
+    return "        <p>Please input username and password for password flow authorization</p>\n        <fieldset>\n            <div><label>Username: <input class=\"oauth-username\" type=\"text\" name=\"username\"></label></div>\n            <div><label>Password: <input class=\"oauth-password\" type=\"password\" name=\"password\"></label></div>\n        </fieldset>\n";
+},"7":function(container,depth0,helpers,partials,data) {
+    var stack1;
+
+  return "        <p>Setup client authentication."
+    + ((stack1 = helpers["if"].call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.requireClientAuthenticaiton : depth0),{"name":"if","hash":{},"fn":container.program(8, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "</p>\n        <fieldset>\n            <div><label>Type:\n                <select class=\"oauth-client-authentication-type\" name=\"client-authentication-type\">\n                    <option value=\"none\" selected>None or other</option>\n                    <option value=\"basic\">Basic auth</option>\n                    <option value=\"request-body\">Request body</option>\n                </select>\n            </label></div>\n            <div class=\"oauth-client-authentication\" hidden>\n                <div><label>ClientId: <input class=\"oauth-client-id\" type=\"text\" name=\"client-id\"></label></div>\n                <div><label>Secret: <input class=\"oauth-client-secret\" type=\"text\" name=\"client-secret\"></label></div>\n            </div>\n        </fieldset>\n";
+},"8":function(container,depth0,helpers,partials,data) {
+    return "(Required)";
+},"10":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
+
+  return "            <li>\n                <input class=\"oauth-scope\" type=\"checkbox\" data-scope=\""
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.scope : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "\" oauthtype=\""
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.OAuthSchemeKey : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "\"/>\n                <label>"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.scope : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "</label><br/>\n                <span class=\"api-scope-desc\">"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "\n"
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.OAuthSchemeKey : depth0),{"name":"if","hash":{},"fn":container.program(11, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "                </span>\n            </li>\n";
+},"11":function(container,depth0,helpers,partials,data) {
+    var stack1;
+
+  return "                        ("
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.OAuthSchemeKey : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + ")\n";
+},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
+
+  return "<div>\n    <h3 class=\"auth__title\">OAuth2.0</h3>\n    <p>"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "</p>\n    "
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.authorizationUrl : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "\n    "
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.tokenUrl : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "\n    <p>flow: "
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.flow : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "</p>\n"
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isPasswordFlow : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.clientAuthentication : depth0),{"name":"if","hash":{},"fn":container.program(7, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "    <p><strong> "
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.appName : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + " </strong> API requires the following scopes. Select which ones you want to grant to Swagger UI.</p>\n    <p>Scopes are used to grant an application different levels of access to data on behalf of the end user. Each API may declare one or more scopes.\n        <a href=\"#\">Learn how to use</a>\n    </p>\n    <ul class=\"api-popup-scopes\">\n"
+    + ((stack1 = helpers.each.call(alias1,(depth0 != null ? depth0.scopes : depth0),{"name":"each","hash":{},"fn":container.program(10, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "    </ul>\n</div>";
+},"useData":true});
+templates['operation'] = template({"1":function(container,depth0,helpers,partials,data) {
+    return "deprecated";
+},"3":function(container,depth0,helpers,partials,data) {
+    return "            <h4><span data-sw-translate>Warning: Deprecated</span></h4>\n";
+},"5":function(container,depth0,helpers,partials,data) {
+    var stack1;
+
+  return "        <h4><span data-sw-translate>Implementation Notes</span></h4>\n        <div class=\"markdown\">"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "</div>\n";
+},"7":function(container,depth0,helpers,partials,data) {
+    return "            <div class='authorize-wrapper authorize-wrapper_operation'></div>\n";
+},"9":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {};
+
+  return "          <div class=\"response-class\">\n            <h4><span data-sw-translate>Response Class</span> (<span data-sw-translate>Status</span> "
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(alias1,(depth0 != null ? depth0.successCode : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + ")</h4>\n              "
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.successDescription : depth0),{"name":"if","hash":{},"fn":container.program(10, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "\n            <p><span class=\"model-signature\" /></p>\n            <br/>\n            <div class=\"response-content-type\" />\n            </div>\n";
+},"10":function(container,depth0,helpers,partials,data) {
+    var stack1;
+
+  return "<div class=\"markdown\">"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.successDescription : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "</div>";
+},"12":function(container,depth0,helpers,partials,data) {
+    var stack1;
+
+  return "          <h4 data-sw-translate>Headers</h4>\n          <table class=\"headers\">\n            <thead>\n              <tr>\n                <th style=\"width: 100px; max-width: 100px\" data-sw-translate>Header</th>\n                <th style=\"width: 310px; max-width: 310px\" data-sw-translate>Description</th>\n                <th style=\"width: 200px; max-width: 200px\" data-sw-translate>Type</th>\n                <th style=\"width: 320px; max-width: 320px\" data-sw-translate>Other</th>\n              </tr>\n            </thead>\n            <tbody>\n"
+    + ((stack1 = helpers.each.call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.headers : depth0),{"name":"each","hash":{},"fn":container.program(13, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "            </tbody>\n          </table>\n";
+},"13":function(container,depth0,helpers,partials,data) {
+    var stack1, helper, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
+
+  return "              <tr>\n                <td>"
+    + container.escapeExpression(((helper = (helper = helpers.key || (data && data.key)) != null ? helper : alias2),(typeof helper === "function" ? helper.call(alias1,{"name":"key","hash":{},"data":data}) : helper)))
+    + "</td>\n                <td>"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "</td>\n                <td>"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.type : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "</td>\n                <td>"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.other : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "</td>\n              </tr>\n";
+},"15":function(container,depth0,helpers,partials,data) {
+    return "          <h4 data-sw-translate>Parameters</h4>\n          <table class='fullwidth parameters'>\n          <thead>\n            <tr>\n            <th style=\"width: 100px; max-width: 100px\" data-sw-translate>Parameter</th>\n            <th style=\"width: 310px; max-width: 310px\" data-sw-translate>Value</th>\n            <th style=\"width: 200px; max-width: 200px\" data-sw-translate>Description</th>\n            <th style=\"width: 100px; max-width: 100px\" data-sw-translate>Parameter Type</th>\n            <th style=\"width: 220px; max-width: 230px\" data-sw-translate>Data Type</th>\n            </tr>\n          </thead>\n          <tbody class=\"operation-params\">\n\n          </tbody>\n          </table>\n";
+},"17":function(container,depth0,helpers,partials,data) {
+    return "          <div style='margin:0;padding:0;display:inline'></div>\n          <h4 data-sw-translate>Response Messages</h4>\n          <table class='fullwidth response-messages'>\n            <thead>\n            <tr>\n              <th data-sw-translate>HTTP Status Code</th>\n              <th data-sw-translate>Reason</th>\n              <th data-sw-translate>Response Model</th>\n              <th data-sw-translate>Headers</th>\n            </tr>\n            </thead>\n            <tbody class=\"operation-status\">\n            </tbody>\n          </table>\n";
+},"19":function(container,depth0,helpers,partials,data) {
+    return "";
+},"21":function(container,depth0,helpers,partials,data) {
+    return "          <div class='sandbox_header'>\n            <input class='submit' type='submit' value='Try it out!' data-sw-translate/>\n            <a href='#' class='response_hider' style='display:none' data-sw-translate>Hide Response</a>\n            <span class='response_throbber' style='display:none'></span>\n          </div>\n";
+},"23":function(container,depth0,helpers,partials,data) {
+    return "          <h4 data-sw-translate>Request Headers</h4>\n          <div class='block request_headers'></div>\n";
+},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing, alias3=container.escapeExpression;
+
+  return "  <ul class='operations' >\n    <li class='"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.method : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + " operation' id='"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.parentId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "_"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.nickname : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "'>\n      <div class='heading'>\n        <h3>\n          <span class='http_method'>\n          <a href='#!/"
+    + alias3((helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.encodedParentId : depth0),{"name":"sanitize","hash":{},"data":data}))
+    + "/"
+    + alias3((helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.nickname : depth0),{"name":"sanitize","hash":{},"data":data}))
+    + "' class=\"toggleOperation\">"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.method : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "</a>\n          </span>\n          <span class='path'>\n          <a href='#!/"
+    + alias3((helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.encodedParentId : depth0),{"name":"sanitize","hash":{},"data":data}))
+    + "/"
+    + alias3((helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.nickname : depth0),{"name":"sanitize","hash":{},"data":data}))
+    + "' class=\"toggleOperation "
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.deprecated : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "\">"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.path : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "</a>\n          </span>\n        </h3>\n        <ul class='options'>\n          <li>\n          <a href='#!/"
+    + alias3((helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.encodedParentId : depth0),{"name":"sanitize","hash":{},"data":data}))
+    + "/"
+    + alias3((helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.nickname : depth0),{"name":"sanitize","hash":{},"data":data}))
+    + "' class=\"toggleOperation\"><span class=\"markdown\">"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.summary : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "</span></a>\n          </li>\n        </ul>\n      </div>\n      <div class='content' id='"
+    + alias3((helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.encodedParentId : depth0),{"name":"sanitize","hash":{},"data":data}))
+    + "_"
+    + alias3((helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.nickname : depth0),{"name":"sanitize","hash":{},"data":data}))
+    + "_content' style='display:none'>\n"
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.deprecated : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.security : depth0),{"name":"if","hash":{},"fn":container.program(7, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.type : depth0),{"name":"if","hash":{},"fn":container.program(9, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "\n"
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.headers : depth0),{"name":"if","hash":{},"fn":container.program(12, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "\n        <form accept-charset='UTF-8' class='sandbox'>\n          <div style='margin:0;padding:0;display:inline'></div>\n"
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.parameters : depth0),{"name":"if","hash":{},"fn":container.program(15, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.responseMessages : depth0),{"name":"if","hash":{},"fn":container.program(17, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isReadOnly : depth0),{"name":"if","hash":{},"fn":container.program(19, data, 0),"inverse":container.program(21, data, 0),"data":data})) != null ? stack1 : "")
+    + "        </form>\n        <div class='response' style='display:none'>\n          <h4 class='curl'>Curl</h4>\n          <div class='block curl'></div>\n          <h4 data-sw-translate>Request URL</h4>\n          <div class='block request_url'></div>\n"
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.showRequestHeaders : depth0),{"name":"if","hash":{},"fn":container.program(23, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "          <h4 data-sw-translate>Response Body</h4>\n          <div class='block response_body'></div>\n          <h4 data-sw-translate>Response Code</h4>\n          <div class='block response_code'></div>\n          <h4 data-sw-translate>Response Headers</h4>\n          <div class='block response_headers'></div>\n        </div>\n      </div>\n    </li>\n  </ul>\n";
+},"useData":true});
+templates['param'] = template({"1":function(container,depth0,helpers,partials,data) {
+    var stack1;
+
+  return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.isFile : depth0),{"name":"if","hash":{},"fn":container.program(2, data, 0),"inverse":container.program(4, data, 0),"data":data})) != null ? stack1 : "");
+},"2":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
+
+  return "                     <input type=\"file\" name='"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "' id='"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "'/>\n                   <div class=\"parameter-content-type\" />\n";
+},"4":function(container,depth0,helpers,partials,data) {
+    var stack1;
+
+  return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : {},(depth0 != null ? depth0["default"] : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.program(7, data, 0),"data":data})) != null ? stack1 : "");
+},"5":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
+
+  return "                             <div class=\"editor_holder\"></div>\n                           <textarea class='body-textarea' name='"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "' id='"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "'>"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0["default"] : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "</textarea>\n        <br />\n        <div class=\"parameter-content-type\" />\n";
+},"7":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
+
+  return "                             <textarea class='body-textarea' name='"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "' id='"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "'></textarea>\n                         <div class=\"editor_holder\"></div>\n                           <br />\n                                <div class=\"parameter-content-type\" />\n";
+},"9":function(container,depth0,helpers,partials,data) {
+    var stack1;
+
+  return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.isFile : depth0),{"name":"if","hash":{},"fn":container.program(2, data, 0),"inverse":container.program(10, data, 0),"data":data})) != null ? stack1 : "");
+},"10":function(container,depth0,helpers,partials,data) {
+    var stack1;
+
+  return ((stack1 = (helpers.renderTextParam || (depth0 && depth0.renderTextParam) || helpers.helperMissing).call(depth0 != null ? depth0 : {},depth0,{"name":"renderTextParam","hash":{},"fn":container.program(11, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "");
+},"11":function(container,depth0,helpers,partials,data) {
+    return "";
+},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
+
+  return "<td class='code'><label for='"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "'>"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "</label></td>\n<td>\n\n"
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isBody : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(9, data, 0),"data":data})) != null ? stack1 : "")
+    + "\n</td>\n<td class=\"markdown\">"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "</td>\n<td>"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.paramType : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "</td>\n<td>\n   <span class=\"model-signature\"></span>\n</td>\n";
+},"useData":true});
+templates['param_list'] = template({"1":function(container,depth0,helpers,partials,data) {
+    return " required";
+},"3":function(container,depth0,helpers,partials,data) {
+    return " multiple=\"multiple\"";
+},"5":function(container,depth0,helpers,partials,data) {
+    return " required ";
+},"7":function(container,depth0,helpers,partials,data) {
+    var stack1;
+
+  return "      <option "
+    + ((stack1 = helpers.unless.call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.hasDefault : depth0),{"name":"unless","hash":{},"fn":container.program(8, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + " value=''></option>\n";
+},"8":function(container,depth0,helpers,partials,data) {
+    return "  selected=\"\" ";
+},"10":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
+
+  return "\n      <option "
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isDefault : depth0),{"name":"if","hash":{},"fn":container.program(11, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "  value='"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.value : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "'> "
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.value : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + " "
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isDefault : depth0),{"name":"if","hash":{},"fn":container.program(13, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + " </option>\n\n";
+},"11":function(container,depth0,helpers,partials,data) {
+    return " selected=\"\"  ";
+},"13":function(container,depth0,helpers,partials,data) {
+    return " (default) ";
+},"15":function(container,depth0,helpers,partials,data) {
+    return "<strong>";
+},"17":function(container,depth0,helpers,partials,data) {
+    return "</strong>";
+},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+    var stack1, helper, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
+
+  return "<td class='code"
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.required : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "'><label for='"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "'>"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "</label></td>\n<td>\n  <select "
+    + ((stack1 = (helpers.isArray || (depth0 && depth0.isArray) || alias2).call(alias1,depth0,{"name":"isArray","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + " class=\"parameter "
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.required : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "\" name=\""
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "\" id=\""
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "\">\n\n"
+    + ((stack1 = helpers.unless.call(alias1,(depth0 != null ? depth0.required : depth0),{"name":"unless","hash":{},"fn":container.program(7, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "\n"
+    + ((stack1 = helpers.each.call(alias1,((stack1 = (depth0 != null ? depth0.allowableValues : depth0)) != null ? stack1.descriptiveValues : stack1),{"name":"each","hash":{},"fn":container.program(10, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "\n  </select>\n</td>\n<td class=\"markdown\">"
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.required : depth0),{"name":"if","hash":{},"fn":container.program(15, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + ((stack1 = ((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : alias2),(typeof helper === "function" ? helper.call(alias1,{"name":"description","hash":{},"data":data}) : helper))) != null ? stack1 : "")
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.required : depth0),{"name":"if","hash":{},"fn":container.program(17, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "</td>\n<td>"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.paramType : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "</td>\n<td><span class=\"model-signature\"></span></td>\n";
+},"useData":true});
+templates['param_readonly'] = template({"1":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
+
+  return "        <textarea class='body-textarea' readonly='readonly' name='"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "' id='"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "'>"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0["default"] : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "</textarea>\n        <div class=\"parameter-content-type\" />\n";
+},"3":function(container,depth0,helpers,partials,data) {
+    var stack1;
+
+  return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : {},(depth0 != null ? depth0["default"] : depth0),{"name":"if","hash":{},"fn":container.program(4, data, 0),"inverse":container.program(6, data, 0),"data":data})) != null ? stack1 : "");
+},"4":function(container,depth0,helpers,partials,data) {
+    var stack1;
+
+  return "            "
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0["default"] : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "\n";
+},"6":function(container,depth0,helpers,partials,data) {
+    return "            (empty)\n";
+},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
+
+  return "<td class='code'><label for='"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "'>"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "</label></td>\n<td>\n"
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isBody : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(3, data, 0),"data":data})) != null ? stack1 : "")
+    + "</td>\n<td class=\"markdown\">"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "</td>\n<td>"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.paramType : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "</td>\n<td><span class=\"model-signature\"></span></td>\n";
+},"useData":true});
+templates['param_readonly_required'] = template({"1":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
+
+  return "        <textarea class='body-textarea' readonly='readonly' placeholder='(required)' name='"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "' id='"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "'>"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0["default"] : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "</textarea>\n";
+},"3":function(container,depth0,helpers,partials,data) {
+    var stack1;
+
+  return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : {},(depth0 != null ? depth0["default"] : depth0),{"name":"if","hash":{},"fn":container.program(4, data, 0),"inverse":container.program(6, data, 0),"data":data})) != null ? stack1 : "");
+},"4":function(container,depth0,helpers,partials,data) {
+    var stack1;
+
+  return "            "
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0["default"] : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "\n";
+},"6":function(container,depth0,helpers,partials,data) {
+    return "            (empty)\n";
+},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
+
+  return "<td class='code required'><label for='"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "'>"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "</label></td>\n<td>\n"
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isBody : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(3, data, 0),"data":data})) != null ? stack1 : "")
+    + "</td>\n<td class=\"markdown\">"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "</td>\n<td>"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.paramType : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "</td>\n<td><span class=\"model-signature\"></span></td>\n";
+},"useData":true});
+templates['param_required'] = template({"1":function(container,depth0,helpers,partials,data) {
+    var stack1;
+
+  return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.isFile : depth0),{"name":"if","hash":{},"fn":container.program(2, data, 0),"inverse":container.program(4, data, 0),"data":data})) != null ? stack1 : "");
+},"2":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
+
+  return "                     <input type=\"file\" name='"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "' id='"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "'/>\n";
+},"4":function(container,depth0,helpers,partials,data) {
+    var stack1;
+
+  return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : {},(depth0 != null ? depth0["default"] : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.program(7, data, 0),"data":data})) != null ? stack1 : "");
+},"5":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
+
+  return "                             <div class=\"editor_holder\"></div>\n                           <textarea class='body-textarea required' placeholder='(required)' name='"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "' id=\""
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "\">"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0["default"] : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "</textarea>\n        <br />\n        <div class=\"parameter-content-type\" />\n";
+},"7":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
+
+  return "                             <textarea class='body-textarea required' placeholder='(required)' name='"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "' id='"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "'></textarea>\n                         <div class=\"editor_holder\"></div>\n                           <br />\n                                <div class=\"parameter-content-type\" />\n";
+},"9":function(container,depth0,helpers,partials,data) {
+    var stack1;
+
+  return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.isFile : depth0),{"name":"if","hash":{},"fn":container.program(10, data, 0),"inverse":container.program(12, data, 0),"data":data})) != null ? stack1 : "");
+},"10":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
+
+  return "                     <input class='parameter required' type='file' name='"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "' id='"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "'/>\n";
+},"12":function(container,depth0,helpers,partials,data) {
+    var stack1;
+
+  return ((stack1 = (helpers.renderTextParam || (depth0 && depth0.renderTextParam) || helpers.helperMissing).call(depth0 != null ? depth0 : {},depth0,{"name":"renderTextParam","hash":{},"fn":container.program(13, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "");
+},"13":function(container,depth0,helpers,partials,data) {
+    return "";
+},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
+
+  return "<td class='code required'><label for='"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.valueId : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "'>"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "</label></td>\n<td>\n"
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isBody : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(9, data, 0),"data":data})) != null ? stack1 : "")
+    + "</td>\n<td>\n   <strong><span class=\"markdown\">"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "</span></strong>\n</td>\n<td>"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.paramType : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "</td>\n<td><span class=\"model-signature\"></span></td>\n";
+},"useData":true});
+templates['parameter_content_type'] = template({"1":function(container,depth0,helpers,partials,data) {
+    var stack1;
+
+  return ((stack1 = helpers.each.call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.consumes : depth0),{"name":"each","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "");
+},"2":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
+
+  return "  <option value=\""
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,depth0,{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "\">"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,depth0,{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "</option>\n";
+},"4":function(container,depth0,helpers,partials,data) {
+    return "  <option value=\"application/json\">application/json</option>\n";
+},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+    var stack1, helper, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
+
+  return "<label for=\""
+    + container.escapeExpression(((helper = (helper = helpers.parameterContentTypeId || (depth0 != null ? depth0.parameterContentTypeId : depth0)) != null ? helper : alias2),(typeof helper === "function" ? helper.call(alias1,{"name":"parameterContentTypeId","hash":{},"data":data}) : helper)))
+    + "\" data-sw-translate>Parameter content type:</label>\n<select name=\"parameterContentType\" id=\""
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.parameterContentTypeId : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "\">\n"
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.consumes : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(4, data, 0),"data":data})) != null ? stack1 : "")
+    + "</select>\n";
+},"useData":true});
+templates['popup'] = template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+    var helper;
+
+  return "<div class=\"api-popup-dialog-wrapper\">\n    <div class=\"api-popup-title\">"
+    + container.escapeExpression(((helper = (helper = helpers.title || (depth0 != null ? depth0.title : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : {},{"name":"title","hash":{},"data":data}) : helper)))
+    + "</div>\n    <div class=\"api-popup-content\"></div>\n    <p class=\"error-msg\"></p>\n    <div class=\"api-popup-actions\">\n        <button class=\"api-popup-cancel api-button gray\" type=\"button\">Cancel</button>\n    </div>\n</div>\n<div class=\"api-popup-dialog-shadow\"></div>";
+},"useData":true});
+templates['resource'] = template({"1":function(container,depth0,helpers,partials,data) {
+    return " : ";
+},"3":function(container,depth0,helpers,partials,data) {
+    var stack1;
+
+  return "    <li>\n      <a href='"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.url : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "' data-sw-translate>Raw</a>\n    </li>\n";
+},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+    var stack1, helper, options, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing, buffer =
+  "<div class='heading'>\n  <h2>\n    <a href='#!/"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.id : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "' class=\"toggleEndpointList\" data-id=\""
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.id : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "\">"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.name : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "</a> ";
+  stack1 = ((helper = (helper = helpers.summary || (depth0 != null ? depth0.summary : depth0)) != null ? helper : alias2),(options={"name":"summary","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data}),(typeof helper === "function" ? helper.call(alias1,options) : helper));
+  if (!helpers.summary) { stack1 = helpers.blockHelperMissing.call(depth0,stack1,options)}
+  if (stack1 != null) { buffer += stack1; }
+  return buffer + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.summary : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "\n  </h2>\n  <ul class='options'>\n    <li>\n      <a href='#!/"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.id : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "' id='endpointListTogger_"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.id : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "' class=\"toggleEndpointList\" data-id=\""
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.id : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "\" data-sw-translate>Show/Hide</a>\n    </li>\n    <li>\n      <a href='#' class=\"collapseResource\" data-id=\""
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.id : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "\" data-sw-translate>\n        List Operations\n      </a>\n    </li>\n    <li>\n      <a href='#' class=\"expandResource\" data-id=\""
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.id : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "\" data-sw-translate>\n        Expand Operations\n      </a>\n    </li>\n"
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.url : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "  </ul>\n</div>\n<ul class='endpoints' id='"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.id : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "_endpoint_list' style='display:none'>\n\n</ul>\n";
+},"useData":true});
+templates['response_content_type'] = template({"1":function(container,depth0,helpers,partials,data) {
+    var stack1;
+
+  return ((stack1 = helpers.each.call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.produces : depth0),{"name":"each","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "");
+},"2":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
+
+  return "  <option value=\""
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,depth0,{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "\">"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,depth0,{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "</option>\n";
+},"4":function(container,depth0,helpers,partials,data) {
+    return "  <option value=\"application/json\">application/json</option>\n";
+},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+    var stack1, helper, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
+
+  return "<label data-sw-translate for=\""
+    + alias4(((helper = (helper = helpers.responseContentTypeId || (depth0 != null ? depth0.responseContentTypeId : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"responseContentTypeId","hash":{},"data":data}) : helper)))
+    + "\">Response Content Type</label>\n<select name=\"responseContentType\" id=\""
+    + alias4(((helper = (helper = helpers.responseContentTypeId || (depth0 != null ? depth0.responseContentTypeId : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"responseContentTypeId","hash":{},"data":data}) : helper)))
+    + "\">\n"
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.produces : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(4, data, 0),"data":data})) != null ? stack1 : "")
+    + "</select>\n";
+},"useData":true});
+templates['signature'] = template({"1":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {};
+
+  return "\n<div>\n<ul class=\"signature-nav\">\n  <li><a class=\"description-link\" href=\"#\" data-sw-translate>Model</a></li>\n  <li><a class=\"snippet-link\" href=\"#\" data-sw-translate>Example Value</a></li>\n</ul>\n<div>\n\n<div class=\"signature-container\">\n  <div class=\"description\">\n      "
+    + container.escapeExpression((helpers.sanitize || (depth0 && depth0.sanitize) || helpers.helperMissing).call(alias1,(depth0 != null ? depth0.signature : depth0),{"name":"sanitize","hash":{},"data":data}))
+    + "\n  </div>\n\n  <div class=\"snippet\">\n"
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.sampleJSON : depth0),{"name":"if","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.sampleXML : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "  </div>\n</div>\n";
+},"2":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {};
+
+  return "      <div class=\"snippet_json\">\n        <pre><code>"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(alias1,(depth0 != null ? depth0.sampleJSON : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "</code></pre>\n        "
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isParam : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "\n      </div>\n";
+},"3":function(container,depth0,helpers,partials,data) {
+    return "<small class=\"notice\" data-sw-translate></small>";
+},"5":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {};
+
+  return "    <div class=\"snippet_xml\">\n      <pre><code>"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(alias1,(depth0 != null ? depth0.sampleXML : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "</code></pre>\n      "
+    + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isParam : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "\n    </div>\n";
+},"7":function(container,depth0,helpers,partials,data) {
+    var stack1;
+
+  return "    "
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.signature : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "\n";
+},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+    var stack1;
+
+  return ((stack1 = (helpers.ifCond || (depth0 && depth0.ifCond) || helpers.helperMissing).call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.sampleJSON : depth0),"||",(depth0 != null ? depth0.sampleXML : depth0),{"name":"ifCond","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(7, data, 0),"data":data})) != null ? stack1 : "");
+},"useData":true});
+templates['status_code'] = template({"1":function(container,depth0,helpers,partials,data) {
+    var stack1, helper, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
+
+  return "      <tr>\n        <td>"
+    + container.escapeExpression(((helper = (helper = helpers.key || (data && data.key)) != null ? helper : alias2),(typeof helper === "function" ? helper.call(alias1,{"name":"key","hash":{},"data":data}) : helper)))
+    + "</td>\n        <td>"
+    + ((stack1 = (helpers.sanitize || (depth0 && depth0.sanitize) || alias2).call(alias1,(depth0 != null ? depth0.description : depth0),{"name":"sanitize","hash":{},"data":data})) != null ? stack1 : "")
+    + "</td>\n        <td>"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.type : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "</td>\n      </tr>\n";
+},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+    var stack1, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing;
+
+  return "<td width='15%' class='code'>"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.code : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "</td>\n<td class=\"markdown\">"
+    + ((stack1 = (helpers.escape || (depth0 && depth0.escape) || alias2).call(alias1,(depth0 != null ? depth0.message : depth0),{"name":"escape","hash":{},"data":data})) != null ? stack1 : "")
+    + "</td>\n<td width='50%'><span class=\"model-signature\" /></td>\n<td class=\"headers\">\n  <table>\n    <tbody>\n"
+    + ((stack1 = helpers.each.call(alias1,(depth0 != null ? depth0.headers : depth0),{"name":"each","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+    + "    </tbody>\n  </table>\n</td>";
+},"useData":true});
+})();}
+ /* jshint ignore:end */
+'use strict';
+
+
+$(function() {
+
+       // Helper function for vertically aligning DOM elements
+       // http://www.seodenver.com/simple-vertical-align-plugin-for-jquery/
+       $.fn.vAlign = function() {
+               return this.each(function(){
+                       var ah = $(this).height();
+                       var ph = $(this).parent().height();
+                       var mh = (ph - ah) / 2;
+                       $(this).css('margin-top', mh);
+               });
+       };
+
+       $.fn.stretchFormtasticInputWidthToParent = function() {
+               return this.each(function(){
+                       var p_width = $(this).closest("form").innerWidth();
+                       var p_padding = parseInt($(this).closest("form").css('padding-left') ,10) + parseInt($(this).closest('form').css('padding-right'), 10);
+                       var this_padding = parseInt($(this).css('padding-left'), 10) + parseInt($(this).css('padding-right'), 10);
+                       $(this).css('width', p_width - p_padding - this_padding);
+               });
+       };
+
+       $('form.formtastic li.string input, form.formtastic textarea').stretchFormtasticInputWidthToParent();
+
+       // Vertically center these paragraphs
+       // Parent may need a min-height for this to work..
+       $('ul.downplayed li div.content p').vAlign();
+
+       // When a sandbox form is submitted..
+       $("form.sandbox").submit(function(){
+
+               var error_free = true;
+
+               // Cycle through the forms required inputs
+               $(this).find("input.required").each(function() {
+
+                       // Remove any existing error styles from the input
+                       $(this).removeClass('error');
+
+                       // Tack the error style on if the input is empty..
+                       if ($(this).val() === '') {
+                               $(this).addClass('error');
+                               $(this).wiggle();
+                               error_free = false;
+                       }
+
+               });
+
+               return error_free;
+       });
+
+});
+
+function clippyCopiedCallback() {
+  $('#api_key_copied').fadeIn().delay(1000).fadeOut();
+
+  // var b = $("#clippy_tooltip_" + a);
+  // b.length != 0 && (b.attr("title", "copied!").trigger("tipsy.reload"), setTimeout(function() {
+  //   b.attr("title", "copy to clipboard")
+  // },
+  // 500))
+}
+
+// Logging function that accounts for browsers that don't have window.console
+function log(){
+  log.history = log.history || [];
+  log.history.push(arguments);
+  if(this.console){
+    console.log( Array.prototype.slice.call(arguments)[0] );
+  }
+}
+
+// Handle browsers that do console incorrectly (IE9 and below, see http://stackoverflow.com/a/5539378/7913)
+if (Function.prototype.bind && console && typeof console.log === "object") {
+    [
+      "log","info","warn","error","assert","dir","clear","profile","profileEnd"
+    ].forEach(function (method) {
+        console[method] = this.bind(console[method], console);
+    }, Function.prototype.call);
+}
+
+window.Docs = {
+
+       shebang: function() {
+
+               // If shebang has an operation nickname in it..
+               // e.g. /docs/#!/words/get_search
+               var fragments = $.param.fragment().split('/');
+               fragments.shift(); // get rid of the bang
+
+               switch (fragments.length) {
+                       case 1:
+        if (fragments[0].length > 0) { // prevent matching "#/"
+          // Expand all operations for the resource and scroll to it
+          var dom_id = 'resource_' + fragments[0];
+
+          Docs.expandEndpointListForResource(fragments[0]);
+          $("#"+dom_id).slideto({highlight: false});
+        }
+                               break;
+                       case 2:
+                               // Refer to the endpoint DOM element, e.g. #words_get_search
+
+        // Expand Resource
+        Docs.expandEndpointListForResource(fragments[0]);
+        $("#"+dom_id).slideto({highlight: false});
+
+            // Expand operation
+            var li_dom_id = fragments.join('_');
+            var li_content_dom_id = li_dom_id + "_content";
+
+
+            Docs.expandOperation($('#'+li_content_dom_id));
+            $('#'+li_dom_id).slideto({highlight: false});
+            break;
+               }
+       },
+
+       toggleEndpointListForResource: function(resource) {
+               var elem = $('li#resource_' + Docs.escapeResourceName(resource) + ' ul.endpoints');
+               if (elem.is(':visible')) {
+                       $.bbq.pushState('#/', 2);
+                       Docs.collapseEndpointListForResource(resource);
+               } else {
+            $.bbq.pushState('#/' + resource, 2);
+                       Docs.expandEndpointListForResource(resource);
+               }
+       },
+
+       // Expand resource
+       expandEndpointListForResource: function(resource) {
+               var resource = Docs.escapeResourceName(resource);
+               if (resource == '') {
+                       $('.resource ul.endpoints').slideDown();
+                       return;
+               }
+
+               $('li#resource_' + resource).addClass('active');
+
+               var elem = $('li#resource_' + resource + ' ul.endpoints');
+               elem.slideDown();
+       },
+
+       // Collapse resource and mark as explicitly closed
+       collapseEndpointListForResource: function(resource) {
+               var resource = Docs.escapeResourceName(resource);
+               if (resource == '') {
+                       $('.resource ul.endpoints').slideUp();
+                       return;
+               }
+
+               $('li#resource_' + resource).removeClass('active');
+
+               var elem = $('li#resource_' + resource + ' ul.endpoints');
+               elem.slideUp();
+       },
+
+       expandOperationsForResource: function(resource) {
+               // Make sure the resource container is open..
+               Docs.expandEndpointListForResource(resource);
+
+               if (resource == '') {
+                       $('.resource ul.endpoints li.operation div.content').slideDown();
+                       return;
+               }
+
+               $('li#resource_' + Docs.escapeResourceName(resource) + ' li.operation div.content').each(function() {
+                       Docs.expandOperation($(this));
+               });
+       },
+
+       collapseOperationsForResource: function(resource) {
+               // Make sure the resource container is open..
+               Docs.expandEndpointListForResource(resource);
+
+               if (resource == '') {
+                       $('.resource ul.endpoints li.operation div.content').slideUp();
+                       return;
+               }
+
+               $('li#resource_' + Docs.escapeResourceName(resource) + ' li.operation div.content').each(function() {
+                       Docs.collapseOperation($(this));
+               });
+       },
+
+       escapeResourceName: function(resource) {
+               return resource.replace(/[!"#$%&'()*+,.\/:;<=>?@\[\\\]\^`{|}~]/g, "\\$&");
+       },
+
+       expandOperation: function(elem) {
+               elem.slideDown();
+       },
+
+       collapseOperation: function(elem) {
+               elem.slideUp();
+       }
+};
+
+/*!
+ * https://github.com/es-shims/es5-shim
+ * @license es5-shim Copyright 2009-2015 by contributors, MIT License
+ * see https://github.com/es-shims/es5-shim/blob/master/LICENSE
+ */
+
+// vim: ts=4 sts=4 sw=4 expandtab
+
+// Add semicolon to prevent IIFE from being passed as argument to concatenated code.
+;
+
+// UMD (Universal Module Definition)
+// see https://github.com/umdjs/umd/blob/master/templates/returnExports.js
+(function (root, factory) {
+    'use strict';
+
+    /* global define, exports, module */
+    if (typeof define === 'function' && define.amd) {
+        // AMD. Register as an anonymous module.
+        define(factory);
+    } else if (typeof exports === 'object') {
+        // Node. Does not work with strict CommonJS, but
+        // only CommonJS-like enviroments that support module.exports,
+        // like Node.
+        module.exports = factory();
+    } else {
+        // Browser globals (root is window)
+        root.returnExports = factory();
+    }
+}(this, function () {
+    /**
+     * Brings an environment as close to ECMAScript 5 compliance
+     * as is possible with the facilities of erstwhile engines.
+     *
+     * Annotated ES5: http://es5.github.com/ (specific links below)
+     * ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
+     * Required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/
+     */
+
+    // Shortcut to an often accessed properties, in order to avoid multiple
+    // dereference that costs universally. This also holds a reference to known-good
+    // functions.
+    var $Array = Array;
+    var ArrayPrototype = $Array.prototype;
+    var $Object = Object;
+    var ObjectPrototype = $Object.prototype;
+    var $Function = Function;
+    var FunctionPrototype = $Function.prototype;
+    var $String = String;
+    var StringPrototype = $String.prototype;
+    var $Number = Number;
+    var NumberPrototype = $Number.prototype;
+    var array_slice = ArrayPrototype.slice;
+    var array_splice = ArrayPrototype.splice;
+    var array_push = ArrayPrototype.push;
+    var array_unshift = ArrayPrototype.unshift;
+    var array_concat = ArrayPrototype.concat;
+    var array_join = ArrayPrototype.join;
+    var call = FunctionPrototype.call;
+    var apply = FunctionPrototype.apply;
+    var max = Math.max;
+    var min = Math.min;
+
+    // Having a toString local variable name breaks in Opera so use to_string.
+    var to_string = ObjectPrototype.toString;
+
+    /* global Symbol */
+    /* eslint-disable one-var-declaration-per-line, no-redeclare, max-statements-per-line */
+    var hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol';
+    var isCallable; /* inlined from https://npmjs.com/is-callable */ var fnToStr = Function.prototype.toString, constructorRegex = /^\s*class /, isES6ClassFn = function isES6ClassFn(value) { try { var fnStr = fnToStr.call(value); var singleStripped = fnStr.replace(/\/\/.*\n/g, ''); var multiStripped = singleStripped.replace(/\/\*[.\s\S]*\*\//g, ''); var spaceStripped = multiStripped.replace(/\n/mg, ' ').replace(/ {2}/g, ' '); return constructorRegex.test(spaceStripped); } catch (e) { return false; /* not a function */ } }, tryFunctionObject = function tryFunctionObject(value) { try { if (isES6ClassFn(value)) { return false; } fnToStr.call(value); return true; } catch (e) { return false; } }, fnClass = '[object Function]', genClass = '[object GeneratorFunction]', isCallable = function isCallable(value) { if (!value) { return false; } if (typeof value !== 'function' && typeof value !== 'object') { return false; } if (hasToStringTag) { return tryFunctionObject(value); } if (isES6ClassFn(value)) { return false; } var strClass = to_string.call(value); return strClass === fnClass || strClass === genClass; };
+
+    var isRegex; /* inlined from https://npmjs.com/is-regex */ var regexExec = RegExp.prototype.exec, tryRegexExec = function tryRegexExec(value) { try { regexExec.call(value); return true; } catch (e) { return false; } }, regexClass = '[object RegExp]'; isRegex = function isRegex(value) { if (typeof value !== 'object') { return false; } return hasToStringTag ? tryRegexExec(value) : to_string.call(value) === regexClass; };
+    var isString; /* inlined from https://npmjs.com/is-string */ var strValue = String.prototype.valueOf, tryStringObject = function tryStringObject(value) { try { strValue.call(value); return true; } catch (e) { return false; } }, stringClass = '[object String]'; isString = function isString(value) { if (typeof value === 'string') { return true; } if (typeof value !== 'object') { return false; } return hasToStringTag ? tryStringObject(value) : to_string.call(value) === stringClass; };
+    /* eslint-enable one-var-declaration-per-line, no-redeclare, max-statements-per-line */
+
+    /* inlined from http://npmjs.com/define-properties */
+    var supportsDescriptors = $Object.defineProperty && (function () {
+        try {
+            var obj = {};
+            $Object.defineProperty(obj, 'x', { enumerable: false, value: obj });
+            for (var _ in obj) { // jscs:ignore disallowUnusedVariables
+                return false;
+            }
+            return obj.x === obj;
+        } catch (e) { /* this is ES3 */
+            return false;
+        }
+    }());
+    var defineProperties = (function (has) {
+        // Define configurable, writable, and non-enumerable props
+        // if they don't exist.
+        var defineProperty;
+        if (supportsDescriptors) {
+            defineProperty = function (object, name, method, forceAssign) {
+                if (!forceAssign && (name in object)) {
+                    return;
+                }
+                $Object.defineProperty(object, name, {
+                    configurable: true,
+                    enumerable: false,
+                    writable: true,
+                    value: method
+                });
+            };
+        } else {
+            defineProperty = function (object, name, method, forceAssign) {
+                if (!forceAssign && (name in object)) {
+                    return;
+                }
+                object[name] = method;
+            };
+        }
+        return function defineProperties(object, map, forceAssign) {
+            for (var name in map) {
+                if (has.call(map, name)) {
+                    defineProperty(object, name, map[name], forceAssign);
+                }
+            }
+        };
+    }(ObjectPrototype.hasOwnProperty));
+
+    //
+    // Util
+    // ======
+    //
+
+    /* replaceable with https://npmjs.com/package/es-abstract /helpers/isPrimitive */
+    var isPrimitive = function isPrimitive(input) {
+        var type = typeof input;
+        return input === null || (type !== 'object' && type !== 'function');
+    };
+
+    var isActualNaN = $Number.isNaN || function isActualNaN(x) {
+        return x !== x;
+    };
+
+    var ES = {
+        // ES5 9.4
+        // http://es5.github.com/#x9.4
+        // http://jsperf.com/to-integer
+        /* replaceable with https://npmjs.com/package/es-abstract ES5.ToInteger */
+        ToInteger: function ToInteger(num) {
+            var n = +num;
+            if (isActualNaN(n)) {
+                n = 0;
+            } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) {
+                n = (n > 0 || -1) * Math.floor(Math.abs(n));
+            }
+            return n;
+        },
+
+        /* replaceable with https://npmjs.com/package/es-abstract ES5.ToPrimitive */
+        ToPrimitive: function ToPrimitive(input) {
+            var val, valueOf, toStr;
+            if (isPrimitive(input)) {
+                return input;
+            }
+            valueOf = input.valueOf;
+            if (isCallable(valueOf)) {
+                val = valueOf.call(input);
+                if (isPrimitive(val)) {
+                    return val;
+                }
+            }
+            toStr = input.toString;
+            if (isCallable(toStr)) {
+                val = toStr.call(input);
+                if (isPrimitive(val)) {
+                    return val;
+                }
+            }
+            throw new TypeError();
+        },
+
+        // ES5 9.9
+        // http://es5.github.com/#x9.9
+        /* replaceable with https://npmjs.com/package/es-abstract ES5.ToObject */
+        ToObject: function (o) {
+            if (o == null) { // this matches both null and undefined
+                throw new TypeError("can't convert " + o + ' to object');
+            }
+            return $Object(o);
+        },
+
+        /* replaceable with https://npmjs.com/package/es-abstract ES5.ToUint32 */
+        ToUint32: function ToUint32(x) {
+            return x >>> 0;
+        }
+    };
+
+    //
+    // Function
+    // ========
+    //
+
+    // ES-5 15.3.4.5
+    // http://es5.github.com/#x15.3.4.5
+
+    var Empty = function Empty() {};
+
+    defineProperties(FunctionPrototype, {
+        bind: function bind(that) { // .length is 1
+            // 1. Let Target be the this value.
+            var target = this;
+            // 2. If IsCallable(Target) is false, throw a TypeError exception.
+            if (!isCallable(target)) {
+                throw new TypeError('Function.prototype.bind called on incompatible ' + target);
+            }
+            // 3. Let A be a new (possibly empty) internal list of all of the
+            //   argument values provided after thisArg (arg1, arg2 etc), in order.
+            // XXX slicedArgs will stand in for "A" if used
+            var args = array_slice.call(arguments, 1); // for normal call
+            // 4. Let F be a new native ECMAScript object.
+            // 11. Set the [[Prototype]] internal property of F to the standard
+            //   built-in Function prototype object as specified in 15.3.3.1.
+            // 12. Set the [[Call]] internal property of F as described in
+            //   15.3.4.5.1.
+            // 13. Set the [[Construct]] internal property of F as described in
+            //   15.3.4.5.2.
+            // 14. Set the [[HasInstance]] internal property of F as described in
+            //   15.3.4.5.3.
+            var bound;
+            var binder = function () {
+
+                if (this instanceof bound) {
+                    // 15.3.4.5.2 [[Construct]]
+                    // When the [[Construct]] internal method of a function object,
+                    // F that was created using the bind function is called with a
+                    // list of arguments ExtraArgs, the following steps are taken:
+                    // 1. Let target be the value of F's [[TargetFunction]]
+                    //   internal property.
+                    // 2. If target has no [[Construct]] internal method, a
+                    //   TypeError exception is thrown.
+                    // 3. Let boundArgs be the value of F's [[BoundArgs]] internal
+                    //   property.
+                    // 4. Let args be a new list containing the same values as the
+                    //   list boundArgs in the same order followed by the same
+                    //   values as the list ExtraArgs in the same order.
+                    // 5. Return the result of calling the [[Construct]] internal
+                    //   method of target providing args as the arguments.
+
+                    var result = apply.call(
+                        target,
+                        this,
+                        array_concat.call(args, array_slice.call(arguments))
+                    );
+                    if ($Object(result) === result) {
+                        return result;
+                    }
+                    return this;
+
+                } else {
+                    // 15.3.4.5.1 [[Call]]
+                    // When the [[Call]] internal method of a function object, F,
+                    // which was created using the bind function is called with a
+                    // this value and a list of arguments ExtraArgs, the following
+                    // steps are taken:
+                    // 1. Let boundArgs be the value of F's [[BoundArgs]] internal
+                    //   property.
+                    // 2. Let boundThis be the value of F's [[BoundThis]] internal
+                    //   property.
+                    // 3. Let target be the value of F's [[TargetFunction]] internal
+                    //   property.
+                    // 4. Let args be a new list containing the same values as the
+                    //   list boundArgs in the same order followed by the same
+                    //   values as the list ExtraArgs in the same order.
+                    // 5. Return the result of calling the [[Call]] internal method
+                    //   of target providing boundThis as the this value and
+                    //   providing args as the arguments.
+
+                    // equiv: target.call(this, ...boundArgs, ...args)
+                    return apply.call(
+                        target,
+                        that,
+                        array_concat.call(args, array_slice.call(arguments))
+                    );
+
+                }
+
+            };
+
+            // 15. If the [[Class]] internal property of Target is "Function", then
+            //     a. Let L be the length property of Target minus the length of A.
+            //     b. Set the length own property of F to either 0 or L, whichever is
+            //       larger.
+            // 16. Else set the length own property of F to 0.
+
+            var boundLength = max(0, target.length - args.length);
+
+            // 17. Set the attributes of the length own property of F to the values
+            //   specified in 15.3.5.1.
+            var boundArgs = [];
+            for (var i = 0; i < boundLength; i++) {
+                array_push.call(boundArgs, '$' + i);
+            }
+
+            // XXX Build a dynamic function with desired amount of arguments is the only
+            // way to set the length property of a function.
+            // In environments where Content Security Policies enabled (Chrome extensions,
+            // for ex.) all use of eval or Function costructor throws an exception.
+            // However in all of these environments Function.prototype.bind exists
+            // and so this code will never be executed.
+            bound = $Function('binder', 'return function (' + array_join.call(boundArgs, ',') + '){ return binder.apply(this, arguments); }')(binder);
+
+            if (target.prototype) {
+                Empty.prototype = target.prototype;
+                bound.prototype = new Empty();
+                // Clean up dangling references.
+                Empty.prototype = null;
+            }
+
+            // TODO
+            // 18. Set the [[Extensible]] internal property of F to true.
+
+            // TODO
+            // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).
+            // 20. Call the [[DefineOwnProperty]] internal method of F with
+            //   arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]:
+            //   thrower, [[Enumerable]]: false, [[Configurable]]: false}, and
+            //   false.
+            // 21. Call the [[DefineOwnProperty]] internal method of F with
+            //   arguments "arguments", PropertyDescriptor {[[Get]]: thrower,
+            //   [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false},
+            //   and false.
+
+            // TODO
+            // NOTE Function objects created using Function.prototype.bind do not
+            // have a prototype property or the [[Code]], [[FormalParameters]], and
+            // [[Scope]] internal properties.
+            // XXX can't delete prototype in pure-js.
+
+            // 22. Return F.
+            return bound;
+        }
+    });
+
+    // _Please note: Shortcuts are defined after `Function.prototype.bind` as we
+    // use it in defining shortcuts.
+    var owns = call.bind(ObjectPrototype.hasOwnProperty);
+    var toStr = call.bind(ObjectPrototype.toString);
+    var arraySlice = call.bind(array_slice);
+    var arraySliceApply = apply.bind(array_slice);
+    var strSlice = call.bind(StringPrototype.slice);
+    var strSplit = call.bind(StringPrototype.split);
+    var strIndexOf = call.bind(StringPrototype.indexOf);
+    var pushCall = call.bind(array_push);
+    var isEnum = call.bind(ObjectPrototype.propertyIsEnumerable);
+    var arraySort = call.bind(ArrayPrototype.sort);
+
+    //
+    // Array
+    // =====
+    //
+
+    var isArray = $Array.isArray || function isArray(obj) {
+        return toStr(obj) === '[object Array]';
+    };
+
+    // ES5 15.4.4.12
+    // http://es5.github.com/#x15.4.4.13
+    // Return len+argCount.
+    // [bugfix, ielt8]
+    // IE < 8 bug: [].unshift(0) === undefined but should be "1"
+    var hasUnshiftReturnValueBug = [].unshift(0) !== 1;
+    defineProperties(ArrayPrototype, {
+        unshift: function () {
+            array_unshift.apply(this, arguments);
+            return this.length;
+        }
+    }, hasUnshiftReturnValueBug);
+
+    // ES5 15.4.3.2
+    // http://es5.github.com/#x15.4.3.2
+    // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
+    defineProperties($Array, { isArray: isArray });
+
+    // The IsCallable() check in the Array functions
+    // has been replaced with a strict check on the
+    // internal class of the object to trap cases where
+    // the provided function was actually a regular
+    // expression literal, which in V8 and
+    // JavaScriptCore is a typeof "function".  Only in
+    // V8 are regular expression literals permitted as
+    // reduce parameters, so it is desirable in the
+    // general case for the shim to match the more
+    // strict and common behavior of rejecting regular
+    // expressions.
+
+    // ES5 15.4.4.18
+    // http://es5.github.com/#x15.4.4.18
+    // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach
+
+    // Check failure of by-index access of string characters (IE < 9)
+    // and failure of `0 in boxedString` (Rhino)
+    var boxedString = $Object('a');
+    var splitString = boxedString[0] !== 'a' || !(0 in boxedString);
+
+    var properlyBoxesContext = function properlyBoxed(method) {
+        // Check node 0.6.21 bug where third parameter is not boxed
+        var properlyBoxesNonStrict = true;
+        var properlyBoxesStrict = true;
+        var threwException = false;
+        if (method) {
+            try {
+                method.call('foo', function (_, __, context) {
+                    if (typeof context !== 'object') {
+                        properlyBoxesNonStrict = false;
+                    }
+                });
+
+                method.call([1], function () {
+                    'use strict';
+
+                    properlyBoxesStrict = typeof this === 'string';
+                }, 'x');
+            } catch (e) {
+                threwException = true;
+            }
+        }
+        return !!method && !threwException && properlyBoxesNonStrict && properlyBoxesStrict;
+    };
+
+    defineProperties(ArrayPrototype, {
+        forEach: function forEach(callbackfn/*, thisArg*/) {
+            var object = ES.ToObject(this);
+            var self = splitString && isString(this) ? strSplit(this, '') : object;
+            var i = -1;
+            var length = ES.ToUint32(self.length);
+            var T;
+            if (arguments.length > 1) {
+                T = arguments[1];
+            }
+
+            // If no callback function or if callback is not a callable function
+            if (!isCallable(callbackfn)) {
+                throw new TypeError('Array.prototype.forEach callback must be a function');
+            }
+
+            while (++i < length) {
+                if (i in self) {
+                    // Invoke the callback function with call, passing arguments:
+                    // context, property value, property key, thisArg object
+                    if (typeof T === 'undefined') {
+                        callbackfn(self[i], i, object);
+                    } else {
+                        callbackfn.call(T, self[i], i, object);
+                    }
+                }
+            }
+        }
+    }, !properlyBoxesContext(ArrayPrototype.forEach));
+
+    // ES5 15.4.4.19
+    // http://es5.github.com/#x15.4.4.19
+    // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
+    defineProperties(ArrayPrototype, {
+        map: function map(callbackfn/*, thisArg*/) {
+            var object = ES.ToObject(this);
+            var self = splitString && isString(this) ? strSplit(this, '') : object;
+            var length = ES.ToUint32(self.length);
+            var result = $Array(length);
+            var T;
+            if (arguments.length > 1) {
+                T = arguments[1];
+            }
+
+            // If no callback function or if callback is not a callable function
+            if (!isCallable(callbackfn)) {
+                throw new TypeError('Array.prototype.map callback must be a function');
+            }
+
+            for (var i = 0; i < length; i++) {
+                if (i in self) {
+                    if (typeof T === 'undefined') {
+                        result[i] = callbackfn(self[i], i, object);
+                    } else {
+                        result[i] = callbackfn.call(T, self[i], i, object);
+                    }
+                }
+            }
+            return result;
+        }
+    }, !properlyBoxesContext(ArrayPrototype.map));
+
+    // ES5 15.4.4.20
+    // http://es5.github.com/#x15.4.4.20
+    // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
+    defineProperties(ArrayPrototype, {
+        filter: function filter(callbackfn/*, thisArg*/) {
+            var object = ES.ToObject(this);
+            var self = splitString && isString(this) ? strSplit(this, '') : object;
+            var length = ES.ToUint32(self.length);
+            var result = [];
+            var value;
+            var T;
+            if (arguments.length > 1) {
+                T = arguments[1];
+            }
+
+            // If no callback function or if callback is not a callable function
+            if (!isCallable(callbackfn)) {
+                throw new TypeError('Array.prototype.filter callback must be a function');
+            }
+
+            for (var i = 0; i < length; i++) {
+                if (i in self) {
+                    value = self[i];
+                    if (typeof T === 'undefined' ? callbackfn(value, i, object) : callbackfn.call(T, value, i, object)) {
+                        pushCall(result, value);
+                    }
+                }
+            }
+            return result;
+        }
+    }, !properlyBoxesContext(ArrayPrototype.filter));
+
+    // ES5 15.4.4.16
+    // http://es5.github.com/#x15.4.4.16
+    // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every
+    defineProperties(ArrayPrototype, {
+        every: function every(callbackfn/*, thisArg*/) {
+            var object = ES.ToObject(this);
+            var self = splitString && isString(this) ? strSplit(this, '') : object;
+            var length = ES.ToUint32(self.length);
+            var T;
+            if (arguments.length > 1) {
+                T = arguments[1];
+            }
+
+            // If no callback function or if callback is not a callable function
+            if (!isCallable(callbackfn)) {
+                throw new TypeError('Array.prototype.every callback must be a function');
+            }
+
+            for (var i = 0; i < length; i++) {
+                if (i in self && !(typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }, !properlyBoxesContext(ArrayPrototype.every));
+
+    // ES5 15.4.4.17
+    // http://es5.github.com/#x15.4.4.17
+    // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
+    defineProperties(ArrayPrototype, {
+        some: function some(callbackfn/*, thisArg */) {
+            var object = ES.ToObject(this);
+            var self = splitString && isString(this) ? strSplit(this, '') : object;
+            var length = ES.ToUint32(self.length);
+            var T;
+            if (arguments.length > 1) {
+                T = arguments[1];
+            }
+
+            // If no callback function or if callback is not a callable function
+            if (!isCallable(callbackfn)) {
+                throw new TypeError('Array.prototype.some callback must be a function');
+            }
+
+            for (var i = 0; i < length; i++) {
+                if (i in self && (typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }, !properlyBoxesContext(ArrayPrototype.some));
+
+    // ES5 15.4.4.21
+    // http://es5.github.com/#x15.4.4.21
+    // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
+    var reduceCoercesToObject = false;
+    if (ArrayPrototype.reduce) {
+        reduceCoercesToObject = typeof ArrayPrototype.reduce.call('es5', function (_, __, ___, list) {
+            return list;
+        }) === 'object';
+    }
+    defineProperties(ArrayPrototype, {
+        reduce: function reduce(callbackfn/*, initialValue*/) {
+            var object = ES.ToObject(this);
+            var self = splitString && isString(this) ? strSplit(this, '') : object;
+            var length = ES.ToUint32(self.length);
+
+            // If no callback function or if callback is not a callable function
+            if (!isCallable(callbackfn)) {
+                throw new TypeError('Array.prototype.reduce callback must be a function');
+            }
+
+            // no value to return if no initial value and an empty array
+            if (length === 0 && arguments.length === 1) {
+                throw new TypeError('reduce of empty array with no initial value');
+            }
+
+            var i = 0;
+            var result;
+            if (arguments.length >= 2) {
+                result = arguments[1];
+            } else {
+                do {
+                    if (i in self) {
+                        result = self[i++];
+                        break;
+                    }
+
+                    // if array contains no values, no initial value to return
+                    if (++i >= length) {
+                        throw new TypeError('reduce of empty array with no initial value');
+                    }
+                } while (true);
+            }
+
+            for (; i < length; i++) {
+                if (i in self) {
+                    result = callbackfn(result, self[i], i, object);
+                }
+            }
+
+            return result;
+        }
+    }, !reduceCoercesToObject);
+
+    // ES5 15.4.4.22
+    // http://es5.github.com/#x15.4.4.22
+    // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight
+    var reduceRightCoercesToObject = false;
+    if (ArrayPrototype.reduceRight) {
+        reduceRightCoercesToObject = typeof ArrayPrototype.reduceRight.call('es5', function (_, __, ___, list) {
+            return list;
+        }) === 'object';
+    }
+    defineProperties(ArrayPrototype, {
+        reduceRight: function reduceRight(callbackfn/*, initial*/) {
+            var object = ES.ToObject(this);
+            var self = splitString && isString(this) ? strSplit(this, '') : object;
+            var length = ES.ToUint32(self.length);
+
+            // If no callback function or if callback is not a callable function
+            if (!isCallable(callbackfn)) {
+                throw new TypeError('Array.prototype.reduceRight callback must be a function');
+            }
+
+            // no value to return if no initial value, empty array
+            if (length === 0 && arguments.length === 1) {
+                throw new TypeError('reduceRight of empty array with no initial value');
+            }
+
+            var result;
+            var i = length - 1;
+            if (arguments.length >= 2) {
+                result = arguments[1];
+            } else {
+                do {
+                    if (i in self) {
+                        result = self[i--];
+                        break;
+                    }
+
+                    // if array contains no values, no initial value to return
+                    if (--i < 0) {
+                        throw new TypeError('reduceRight of empty array with no initial value');
+                    }
+                } while (true);
+            }
+
+            if (i < 0) {
+                return result;
+            }
+
+            do {
+                if (i in self) {
+                    result = callbackfn(result, self[i], i, object);
+                }
+            } while (i--);
+
+            return result;
+        }
+    }, !reduceRightCoercesToObject);
+
+    // ES5 15.4.4.14
+    // http://es5.github.com/#x15.4.4.14
+    // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
+    var hasFirefox2IndexOfBug = ArrayPrototype.indexOf && [0, 1].indexOf(1, 2) !== -1;
+    defineProperties(ArrayPrototype, {
+        indexOf: function indexOf(searchElement/*, fromIndex */) {
+            var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this);
+            var length = ES.ToUint32(self.length);
+
+            if (length === 0) {
+                return -1;
+            }
+
+            var i = 0;
+            if (arguments.length > 1) {
+                i = ES.ToInteger(arguments[1]);
+            }
+
+            // handle negative indices
+            i = i >= 0 ? i : max(0, length + i);
+            for (; i < length; i++) {
+                if (i in self && self[i] === searchElement) {
+                    return i;
+                }
+            }
+            return -1;
+        }
+    }, hasFirefox2IndexOfBug);
+
+    // ES5 15.4.4.15
+    // http://es5.github.com/#x15.4.4.15
+    // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf
+    var hasFirefox2LastIndexOfBug = ArrayPrototype.lastIndexOf && [0, 1].lastIndexOf(0, -3) !== -1;
+    defineProperties(ArrayPrototype, {
+        lastIndexOf: function lastIndexOf(searchElement/*, fromIndex */) {
+            var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this);
+            var length = ES.ToUint32(self.length);
+
+            if (length === 0) {
+                return -1;
+            }
+            var i = length - 1;
+            if (arguments.length > 1) {
+                i = min(i, ES.ToInteger(arguments[1]));
+            }
+            // handle negative indices
+            i = i >= 0 ? i : length - Math.abs(i);
+            for (; i >= 0; i--) {
+                if (i in self && searchElement === self[i]) {
+                    return i;
+                }
+            }
+            return -1;
+        }
+    }, hasFirefox2LastIndexOfBug);
+
+    // ES5 15.4.4.12
+    // http://es5.github.com/#x15.4.4.12
+    var spliceNoopReturnsEmptyArray = (function () {
+        var a = [1, 2];
+        var result = a.splice();
+        return a.length === 2 && isArray(result) && result.length === 0;
+    }());
+    defineProperties(ArrayPrototype, {
+        // Safari 5.0 bug where .splice() returns undefined
+        splice: function splice(start, deleteCount) {
+            if (arguments.length === 0) {
+                return [];
+            } else {
+                return array_splice.apply(this, arguments);
+            }
+        }
+    }, !spliceNoopReturnsEmptyArray);
+
+    var spliceWorksWithEmptyObject = (function () {
+        var obj = {};
+        ArrayPrototype.splice.call(obj, 0, 0, 1);
+        return obj.length === 1;
+    }());
+    defineProperties(ArrayPrototype, {
+        splice: function splice(start, deleteCount) {
+            if (arguments.length === 0) {
+                return [];
+            }
+            var args = arguments;
+            this.length = max(ES.ToInteger(this.length), 0);
+            if (arguments.length > 0 && typeof deleteCount !== 'number') {
+                args = arraySlice(arguments);
+                if (args.length < 2) {
+                    pushCall(args, this.length - start);
+                } else {
+                    args[1] = ES.ToInteger(deleteCount);
+                }
+            }
+            return array_splice.apply(this, args);
+        }
+    }, !spliceWorksWithEmptyObject);
+    var spliceWorksWithLargeSparseArrays = (function () {
+        // Per https://github.com/es-shims/es5-shim/issues/295
+        // Safari 7/8 breaks with sparse arrays of size 1e5 or greater
+        var arr = new $Array(1e5);
+        // note: the index MUST be 8 or larger or the test will false pass
+        arr[8] = 'x';
+        arr.splice(1, 1);
+        // note: this test must be defined *after* the indexOf shim
+        // per https://github.com/es-shims/es5-shim/issues/313
+        return arr.indexOf('x') === 7;
+    }());
+    var spliceWorksWithSmallSparseArrays = (function () {
+        // Per https://github.com/es-shims/es5-shim/issues/295
+        // Opera 12.15 breaks on this, no idea why.
+        var n = 256;
+        var arr = [];
+        arr[n] = 'a';
+        arr.splice(n + 1, 0, 'b');
+        return arr[n] === 'a';
+    }());
+    defineProperties(ArrayPrototype, {
+        splice: function splice(start, deleteCount) {
+            var O = ES.ToObject(this);
+            var A = [];
+            var len = ES.ToUint32(O.length);
+            var relativeStart = ES.ToInteger(start);
+            var actualStart = relativeStart < 0 ? max((len + relativeStart), 0) : min(relativeStart, len);
+            var actualDeleteCount = min(max(ES.ToInteger(deleteCount), 0), len - actualStart);
+
+            var k = 0;
+            var from;
+            while (k < actualDeleteCount) {
+                from = $String(actualStart + k);
+                if (owns(O, from)) {
+                    A[k] = O[from];
+                }
+                k += 1;
+            }
+
+            var items = arraySlice(arguments, 2);
+            var itemCount = items.length;
+            var to;
+            if (itemCount < actualDeleteCount) {
+                k = actualStart;
+                var maxK = len - actualDeleteCount;
+                while (k < maxK) {
+                    from = $String(k + actualDeleteCount);
+                    to = $String(k + itemCount);
+                    if (owns(O, from)) {
+                        O[to] = O[from];
+                    } else {
+                        delete O[to];
+                    }
+                    k += 1;
+                }
+                k = len;
+                var minK = len - actualDeleteCount + itemCount;
+                while (k > minK) {
+                    delete O[k - 1];
+                    k -= 1;
+                }
+            } else if (itemCount > actualDeleteCount) {
+                k = len - actualDeleteCount;
+                while (k > actualStart) {
+                    from = $String(k + actualDeleteCount - 1);
+                    to = $String(k + itemCount - 1);
+                    if (owns(O, from)) {
+                        O[to] = O[from];
+                    } else {
+                        delete O[to];
+                    }
+                    k -= 1;
+                }
+            }
+            k = actualStart;
+            for (var i = 0; i < items.length; ++i) {
+                O[k] = items[i];
+                k += 1;
+            }
+            O.length = len - actualDeleteCount + itemCount;
+
+            return A;
+        }
+    }, !spliceWorksWithLargeSparseArrays || !spliceWorksWithSmallSparseArrays);
+
+    var originalJoin = ArrayPrototype.join;
+    var hasStringJoinBug;
+    try {
+        hasStringJoinBug = Array.prototype.join.call('123', ',') !== '1,2,3';
+    } catch (e) {
+        hasStringJoinBug = true;
+    }
+    if (hasStringJoinBug) {
+        defineProperties(ArrayPrototype, {
+            join: function join(separator) {
+                var sep = typeof separator === 'undefined' ? ',' : separator;
+                return originalJoin.call(isString(this) ? strSplit(this, '') : this, sep);
+            }
+        }, hasStringJoinBug);
+    }
+
+    var hasJoinUndefinedBug = [1, 2].join(undefined) !== '1,2';
+    if (hasJoinUndefinedBug) {
+        defineProperties(ArrayPrototype, {
+            join: function join(separator) {
+                var sep = typeof separator === 'undefined' ? ',' : separator;
+                return originalJoin.call(this, sep);
+            }
+        }, hasJoinUndefinedBug);
+    }
+
+    var pushShim = function push(item) {
+        var O = ES.ToObject(this);
+        var n = ES.ToUint32(O.length);
+        var i = 0;
+        while (i < arguments.length) {
+            O[n + i] = arguments[i];
+            i += 1;
+        }
+        O.length = n + i;
+        return n + i;
+    };
+
+    var pushIsNotGeneric = (function () {
+        var obj = {};
+        var result = Array.prototype.push.call(obj, undefined);
+        return result !== 1 || obj.length !== 1 || typeof obj[0] !== 'undefined' || !owns(obj, 0);
+    }());
+    defineProperties(ArrayPrototype, {
+        push: function push(item) {
+            if (isArray(this)) {
+                return array_push.apply(this, arguments);
+            }
+            return pushShim.apply(this, arguments);
+        }
+    }, pushIsNotGeneric);
+
+    // This fixes a very weird bug in Opera 10.6 when pushing `undefined
+    var pushUndefinedIsWeird = (function () {
+        var arr = [];
+        var result = arr.push(undefined);
+        return result !== 1 || arr.length !== 1 || typeof arr[0] !== 'undefined' || !owns(arr, 0);
+    }());
+    defineProperties(ArrayPrototype, { push: pushShim }, pushUndefinedIsWeird);
+
+    // ES5 15.2.3.14
+    // http://es5.github.io/#x15.4.4.10
+    // Fix boxed string bug
+    defineProperties(ArrayPrototype, {
+        slice: function (start, end) {
+            var arr = isString(this) ? strSplit(this, '') : this;
+            return arraySliceApply(arr, arguments);
+        }
+    }, splitString);
+
+    var sortIgnoresNonFunctions = (function () {
+        try {
+            [1, 2].sort(null);
+            [1, 2].sort({});
+            return true;
+        } catch (e) {}
+        return false;
+    }());
+    var sortThrowsOnRegex = (function () {
+        // this is a problem in Firefox 4, in which `typeof /a/ === 'function'`
+        try {
+            [1, 2].sort(/a/);
+            return false;
+        } catch (e) {}
+        return true;
+    }());
+    var sortIgnoresUndefined = (function () {
+        // applies in IE 8, for one.
+        try {
+            [1, 2].sort(undefined);
+            return true;
+        } catch (e) {}
+        return false;
+    }());
+    defineProperties(ArrayPrototype, {
+        sort: function sort(compareFn) {
+            if (typeof compareFn === 'undefined') {
+                return arraySort(this);
+            }
+            if (!isCallable(compareFn)) {
+                throw new TypeError('Array.prototype.sort callback must be a function');
+            }
+            return arraySort(this, compareFn);
+        }
+    }, sortIgnoresNonFunctions || !sortIgnoresUndefined || !sortThrowsOnRegex);
+
+    //
+    // Object
+    // ======
+    //
+
+    // ES5 15.2.3.14
+    // http://es5.github.com/#x15.2.3.14
+
+    // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
+    var hasDontEnumBug = !isEnum({ 'toString': null }, 'toString');
+    var hasProtoEnumBug = isEnum(function () {}, 'prototype');
+    var hasStringEnumBug = !owns('x', '0');
+    var equalsConstructorPrototype = function (o) {
+        var ctor = o.constructor;
+        return ctor && ctor.prototype === o;
+    };
+    var blacklistedKeys = {
+        $window: true,
+        $console: true,
+        $parent: true,
+        $self: true,
+        $frame: true,
+        $frames: true,
+        $frameElement: true,
+        $webkitIndexedDB: true,
+        $webkitStorageInfo: true,
+        $external: true
+    };
+    var hasAutomationEqualityBug = (function () {
+        /* globals window */
+        if (typeof window === 'undefined') {
+            return false;
+        }
+        for (var k in window) {
+            try {
+                if (!blacklistedKeys['$' + k] && owns(window, k) && window[k] !== null && typeof window[k] === 'object') {
+                    equalsConstructorPrototype(window[k]);
+                }
+            } catch (e) {
+                return true;
+            }
+        }
+        return false;
+    }());
+    var equalsConstructorPrototypeIfNotBuggy = function (object) {
+        if (typeof window === 'undefined' || !hasAutomationEqualityBug) {
+            return equalsConstructorPrototype(object);
+        }
+        try {
+            return equalsConstructorPrototype(object);
+        } catch (e) {
+            return false;
+        }
+    };
+    var dontEnums = [
+        'toString',
+        'toLocaleString',
+        'valueOf',
+        'hasOwnProperty',
+        'isPrototypeOf',
+        'propertyIsEnumerable',
+        'constructor'
+    ];
+    var dontEnumsLength = dontEnums.length;
+
+    // taken directly from https://github.com/ljharb/is-arguments/blob/master/index.js
+    // can be replaced with require('is-arguments') if we ever use a build process instead
+    var isStandardArguments = function isArguments(value) {
+        return toStr(value) === '[object Arguments]';
+    };
+    var isLegacyArguments = function isArguments(value) {
+        return value !== null &&
+            typeof value === 'object' &&
+            typeof value.length === 'number' &&
+            value.length >= 0 &&
+            !isArray(value) &&
+            isCallable(value.callee);
+    };
+    var isArguments = isStandardArguments(arguments) ? isStandardArguments : isLegacyArguments;
+
+    defineProperties($Object, {
+        keys: function keys(object) {
+            var isFn = isCallable(object);
+            var isArgs = isArguments(object);
+            var isObject = object !== null && typeof object === 'object';
+            var isStr = isObject && isString(object);
+
+            if (!isObject && !isFn && !isArgs) {
+                throw new TypeError('Object.keys called on a non-object');
+            }
+
+            var theKeys = [];
+            var skipProto = hasProtoEnumBug && isFn;
+            if ((isStr && hasStringEnumBug) || isArgs) {
+                for (var i = 0; i < object.length; ++i) {
+                    pushCall(theKeys, $String(i));
+                }
+            }
+
+            if (!isArgs) {
+                for (var name in object) {
+                    if (!(skipProto && name === 'prototype') && owns(object, name)) {
+                        pushCall(theKeys, $String(name));
+                    }
+                }
+            }
+
+            if (hasDontEnumBug) {
+                var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);
+                for (var j = 0; j < dontEnumsLength; j++) {
+                    var dontEnum = dontEnums[j];
+                    if (!(skipConstructor && dontEnum === 'constructor') && owns(object, dontEnum)) {
+                        pushCall(theKeys, dontEnum);
+                    }
+                }
+            }
+            return theKeys;
+        }
+    });
+
+    var keysWorksWithArguments = $Object.keys && (function () {
+        // Safari 5.0 bug
+        return $Object.keys(arguments).length === 2;
+    }(1, 2));
+    var keysHasArgumentsLengthBug = $Object.keys && (function () {
+        var argKeys = $Object.keys(arguments);
+        return arguments.length !== 1 || argKeys.length !== 1 || argKeys[0] !== 1;
+    }(1));
+    var originalKeys = $Object.keys;
+    defineProperties($Object, {
+        keys: function keys(object) {
+            if (isArguments(object)) {
+                return originalKeys(arraySlice(object));
+            } else {
+                return originalKeys(object);
+            }
+        }
+    }, !keysWorksWithArguments || keysHasArgumentsLengthBug);
+
+    //
+    // Date
+    // ====
+    //
+
+    var hasNegativeMonthYearBug = new Date(-3509827329600292).getUTCMonth() !== 0;
+    var aNegativeTestDate = new Date(-1509842289600292);
+    var aPositiveTestDate = new Date(1449662400000);
+    var hasToUTCStringFormatBug = aNegativeTestDate.toUTCString() !== 'Mon, 01 Jan -45875 11:59:59 GMT';
+    var hasToDateStringFormatBug;
+    var hasToStringFormatBug;
+    var timeZoneOffset = aNegativeTestDate.getTimezoneOffset();
+    if (timeZoneOffset < -720) {
+        hasToDateStringFormatBug = aNegativeTestDate.toDateString() !== 'Tue Jan 02 -45875';
+        hasToStringFormatBug = !(/^Thu Dec 10 2015 \d\d:\d\d:\d\d GMT[-\+]\d\d\d\d(?: |$)/).test(aPositiveTestDate.toString());
+    } else {
+        hasToDateStringFormatBug = aNegativeTestDate.toDateString() !== 'Mon Jan 01 -45875';
+        hasToStringFormatBug = !(/^Wed Dec 09 2015 \d\d:\d\d:\d\d GMT[-\+]\d\d\d\d(?: |$)/).test(aPositiveTestDate.toString());
+    }
+
+    var originalGetFullYear = call.bind(Date.prototype.getFullYear);
+    var originalGetMonth = call.bind(Date.prototype.getMonth);
+    var originalGetDate = call.bind(Date.prototype.getDate);
+    var originalGetUTCFullYear = call.bind(Date.prototype.getUTCFullYear);
+    var originalGetUTCMonth = call.bind(Date.prototype.getUTCMonth);
+    var originalGetUTCDate = call.bind(Date.prototype.getUTCDate);
+    var originalGetUTCDay = call.bind(Date.prototype.getUTCDay);
+    var originalGetUTCHours = call.bind(Date.prototype.getUTCHours);
+    var originalGetUTCMinutes = call.bind(Date.prototype.getUTCMinutes);
+    var originalGetUTCSeconds = call.bind(Date.prototype.getUTCSeconds);
+    var originalGetUTCMilliseconds = call.bind(Date.prototype.getUTCMilliseconds);
+    var dayName = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
+    var monthName = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
+    var daysInMonth = function daysInMonth(month, year) {
+        return originalGetDate(new Date(year, month, 0));
+    };
+
+    defineProperties(Date.prototype, {
+        getFullYear: function getFullYear() {
+            if (!this || !(this instanceof Date)) {
+                throw new TypeError('this is not a Date object.');
+            }
+            var year = originalGetFullYear(this);
+            if (year < 0 && originalGetMonth(this) > 11) {
+                return year + 1;
+            }
+            return year;
+        },
+        getMonth: function getMonth() {
+            if (!this || !(this instanceof Date)) {
+                throw new TypeError('this is not a Date object.');
+            }
+            var year = originalGetFullYear(this);
+            var month = originalGetMonth(this);
+            if (year < 0 && month > 11) {
+                return 0;
+            }
+            return month;
+        },
+        getDate: function getDate() {
+            if (!this || !(this instanceof Date)) {
+                throw new TypeError('this is not a Date object.');
+            }
+            var year = originalGetFullYear(this);
+            var month = originalGetMonth(this);
+            var date = originalGetDate(this);
+            if (year < 0 && month > 11) {
+                if (month === 12) {
+                    return date;
+                }
+                var days = daysInMonth(0, year + 1);
+                return (days - date) + 1;
+            }
+            return date;
+        },
+        getUTCFullYear: function getUTCFullYear() {
+            if (!this || !(this instanceof Date)) {
+                throw new TypeError('this is not a Date object.');
+            }
+            var year = originalGetUTCFullYear(this);
+            if (year < 0 && originalGetUTCMonth(this) > 11) {
+                return year + 1;
+            }
+            return year;
+        },
+        getUTCMonth: function getUTCMonth() {
+            if (!this || !(this instanceof Date)) {
+                throw new TypeError('this is not a Date object.');
+            }
+            var year = originalGetUTCFullYear(this);
+            var month = originalGetUTCMonth(this);
+            if (year < 0 && month > 11) {
+                return 0;
+            }
+            return month;
+        },
+        getUTCDate: function getUTCDate() {
+            if (!this || !(this instanceof Date)) {
+                throw new TypeError('this is not a Date object.');
+            }
+            var year = originalGetUTCFullYear(this);
+            var month = originalGetUTCMonth(this);
+            var date = originalGetUTCDate(this);
+            if (year < 0 && month > 11) {
+                if (month === 12) {
+                    return date;
+                }
+                var days = daysInMonth(0, year + 1);
+                return (days - date) + 1;
+            }
+            return date;
+        }
+    }, hasNegativeMonthYearBug);
+
+    defineProperties(Date.prototype, {
+        toUTCString: function toUTCString() {
+            if (!this || !(this instanceof Date)) {
+                throw new TypeError('this is not a Date object.');
+            }
+            var day = originalGetUTCDay(this);
+            var date = originalGetUTCDate(this);
+            var month = originalGetUTCMonth(this);
+            var year = originalGetUTCFullYear(this);
+            var hour = originalGetUTCHours(this);
+            var minute = originalGetUTCMinutes(this);
+            var second = originalGetUTCSeconds(this);
+            return dayName[day] + ', ' +
+                (date < 10 ? '0' + date : date) + ' ' +
+                monthName[month] + ' ' +
+                year + ' ' +
+                (hour < 10 ? '0' + hour : hour) + ':' +
+                (minute < 10 ? '0' + minute : minute) + ':' +
+                (second < 10 ? '0' + second : second) + ' GMT';
+        }
+    }, hasNegativeMonthYearBug || hasToUTCStringFormatBug);
+
+    // Opera 12 has `,`
+    defineProperties(Date.prototype, {
+        toDateString: function toDateString() {
+            if (!this || !(this instanceof Date)) {
+                throw new TypeError('this is not a Date object.');
+            }
+            var day = this.getDay();
+            var date = this.getDate();
+            var month = this.getMonth();
+            var year = this.getFullYear();
+            return dayName[day] + ' ' +
+                monthName[month] + ' ' +
+                (date < 10 ? '0' + date : date) + ' ' +
+                year;
+        }
+    }, hasNegativeMonthYearBug || hasToDateStringFormatBug);
+
+    // can't use defineProperties here because of toString enumeration issue in IE <= 8
+    if (hasNegativeMonthYearBug || hasToStringFormatBug) {
+        Date.prototype.toString = function toString() {
+            if (!this || !(this instanceof Date)) {
+                throw new TypeError('this is not a Date object.');
+            }
+            var day = this.getDay();
+            var date = this.getDate();
+            var month = this.getMonth();
+            var year = this.getFullYear();
+            var hour = this.getHours();
+            var minute = this.getMinutes();
+            var second = this.getSeconds();
+            var timezoneOffset = this.getTimezoneOffset();
+            var hoursOffset = Math.floor(Math.abs(timezoneOffset) / 60);
+            var minutesOffset = Math.floor(Math.abs(timezoneOffset) % 60);
+            return dayName[day] + ' ' +
+                monthName[month] + ' ' +
+                (date < 10 ? '0' + date : date) + ' ' +
+                year + ' ' +
+                (hour < 10 ? '0' + hour : hour) + ':' +
+                (minute < 10 ? '0' + minute : minute) + ':' +
+                (second < 10 ? '0' + second : second) + ' GMT' +
+                (timezoneOffset > 0 ? '-' : '+') +
+                (hoursOffset < 10 ? '0' + hoursOffset : hoursOffset) +
+                (minutesOffset < 10 ? '0' + minutesOffset : minutesOffset);
+        };
+        if (supportsDescriptors) {
+            $Object.defineProperty(Date.prototype, 'toString', {
+                configurable: true,
+                enumerable: false,
+                writable: true
+            });
+        }
+    }
+
+    // ES5 15.9.5.43
+    // http://es5.github.com/#x15.9.5.43
+    // This function returns a String value represent the instance in time
+    // represented by this Date object. The format of the String is the Date Time
+    // string format defined in 15.9.1.15. All fields are present in the String.
+    // The time zone is always UTC, denoted by the suffix Z. If the time value of
+    // this object is not a finite Number a RangeError exception is thrown.
+    var negativeDate = -62198755200000;
+    var negativeYearString = '-000001';
+    var hasNegativeDateBug = Date.prototype.toISOString && new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1;
+    var hasSafari51DateBug = Date.prototype.toISOString && new Date(-1).toISOString() !== '1969-12-31T23:59:59.999Z';
+
+    var getTime = call.bind(Date.prototype.getTime);
+
+    defineProperties(Date.prototype, {
+        toISOString: function toISOString() {
+            if (!isFinite(this) || !isFinite(getTime(this))) {
+                // Adope Photoshop requires the second check.
+                throw new RangeError('Date.prototype.toISOString called on non-finite value.');
+            }
+
+            var year = originalGetUTCFullYear(this);
+
+            var month = originalGetUTCMonth(this);
+            // see https://github.com/es-shims/es5-shim/issues/111
+            year += Math.floor(month / 12);
+            month = (month % 12 + 12) % 12;
+
+            // the date time string format is specified in 15.9.1.15.
+            var result = [month + 1, originalGetUTCDate(this), originalGetUTCHours(this), originalGetUTCMinutes(this), originalGetUTCSeconds(this)];
+            year = (
+                (year < 0 ? '-' : (year > 9999 ? '+' : '')) +
+                strSlice('00000' + Math.abs(year), (0 <= year && year <= 9999) ? -4 : -6)
+            );
+
+            for (var i = 0; i < result.length; ++i) {
+                // pad months, days, hours, minutes, and seconds to have two digits.
+                result[i] = strSlice('00' + result[i], -2);
+            }
+            // pad milliseconds to have three digits.
+            return (
+                year + '-' + arraySlice(result, 0, 2).join('-') +
+                'T' + arraySlice(result, 2).join(':') + '.' +
+                strSlice('000' + originalGetUTCMilliseconds(this), -3) + 'Z'
+            );
+        }
+    }, hasNegativeDateBug || hasSafari51DateBug);
+
+    // ES5 15.9.5.44
+    // http://es5.github.com/#x15.9.5.44
+    // This function provides a String representation of a Date object for use by
+    // JSON.stringify (15.12.3).
+    var dateToJSONIsSupported = (function () {
+        try {
+            return Date.prototype.toJSON &&
+                new Date(NaN).toJSON() === null &&
+                new Date(negativeDate).toJSON().indexOf(negativeYearString) !== -1 &&
+                Date.prototype.toJSON.call({ // generic
+                    toISOString: function () { return true; }
+                });
+        } catch (e) {
+            return false;
+        }
+    }());
+    if (!dateToJSONIsSupported) {
+        Date.prototype.toJSON = function toJSON(key) {
+            // When the toJSON method is called with argument key, the following
+            // steps are taken:
+
+            // 1.  Let O be the result of calling ToObject, giving it the this
+            // value as its argument.
+            // 2. Let tv be ES.ToPrimitive(O, hint Number).
+            var O = $Object(this);
+            var tv = ES.ToPrimitive(O);
+            // 3. If tv is a Number and is not finite, return null.
+            if (typeof tv === 'number' && !isFinite(tv)) {
+                return null;
+            }
+            // 4. Let toISO be the result of calling the [[Get]] internal method of
+            // O with argument "toISOString".
+            var toISO = O.toISOString;
+            // 5. If IsCallable(toISO) is false, throw a TypeError exception.
+            if (!isCallable(toISO)) {
+                throw new TypeError('toISOString property is not callable');
+            }
+            // 6. Return the result of calling the [[Call]] internal method of
+            //  toISO with O as the this value and an empty argument list.
+            return toISO.call(O);
+
+            // NOTE 1 The argument is ignored.
+
+            // NOTE 2 The toJSON function is intentionally generic; it does not
+            // require that its this value be a Date object. Therefore, it can be
+            // transferred to other kinds of objects for use as a method. However,
+            // it does require that any such object have a toISOString method. An
+            // object is free to use the argument key to filter its
+            // stringification.
+        };
+    }
+
+    // ES5 15.9.4.2
+    // http://es5.github.com/#x15.9.4.2
+    // based on work shared by Daniel Friesen (dantman)
+    // http://gist.github.com/303249
+    var supportsExtendedYears = Date.parse('+033658-09-27T01:46:40.000Z') === 1e15;
+    var acceptsInvalidDates = !isNaN(Date.parse('2012-04-04T24:00:00.500Z')) || !isNaN(Date.parse('2012-11-31T23:59:59.000Z')) || !isNaN(Date.parse('2012-12-31T23:59:60.000Z'));
+    var doesNotParseY2KNewYear = isNaN(Date.parse('2000-01-01T00:00:00.000Z'));
+    if (doesNotParseY2KNewYear || acceptsInvalidDates || !supportsExtendedYears) {
+        // XXX global assignment won't work in embeddings that use
+        // an alternate object for the context.
+        /* global Date: true */
+        /* eslint-disable no-undef */
+        var maxSafeUnsigned32Bit = Math.pow(2, 31) - 1;
+        var hasSafariSignedIntBug = isActualNaN(new Date(1970, 0, 1, 0, 0, 0, maxSafeUnsigned32Bit + 1).getTime());
+        /* eslint-disable no-implicit-globals */
+        Date = (function (NativeDate) {
+        /* eslint-enable no-implicit-globals */
+        /* eslint-enable no-undef */
+            // Date.length === 7
+            var DateShim = function Date(Y, M, D, h, m, s, ms) {
+                var length = arguments.length;
+                var date;
+                if (this instanceof NativeDate) {
+                    var seconds = s;
+                    var millis = ms;
+                    if (hasSafariSignedIntBug && length >= 7 && ms > maxSafeUnsigned32Bit) {
+                        // work around a Safari 8/9 bug where it treats the seconds as signed
+                        var msToShift = Math.floor(ms / maxSafeUnsigned32Bit) * maxSafeUnsigned32Bit;
+                        var sToShift = Math.floor(msToShift / 1e3);
+                        seconds += sToShift;
+                        millis -= sToShift * 1e3;
+                    }
+                    date = length === 1 && $String(Y) === Y ? // isString(Y)
+                        // We explicitly pass it through parse:
+                        new NativeDate(DateShim.parse(Y)) :
+                        // We have to manually make calls depending on argument
+                        // length here
+                        length >= 7 ? new NativeDate(Y, M, D, h, m, seconds, millis) :
+                        length >= 6 ? new NativeDate(Y, M, D, h, m, seconds) :
+                        length >= 5 ? new NativeDate(Y, M, D, h, m) :
+                        length >= 4 ? new NativeDate(Y, M, D, h) :
+                        length >= 3 ? new NativeDate(Y, M, D) :
+                        length >= 2 ? new NativeDate(Y, M) :
+                        length >= 1 ? new NativeDate(Y instanceof NativeDate ? +Y : Y) :
+                                      new NativeDate();
+                } else {
+                    date = NativeDate.apply(this, arguments);
+                }
+                if (!isPrimitive(date)) {
+                    // Prevent mixups with unfixed Date object
+                    defineProperties(date, { constructor: DateShim }, true);
+                }
+                return date;
+            };
+
+            // 15.9.1.15 Date Time String Format.
+            var isoDateExpression = new RegExp('^' +
+                '(\\d{4}|[+-]\\d{6})' + // four-digit year capture or sign +
+                                          // 6-digit extended year
+                '(?:-(\\d{2})' + // optional month capture
+                '(?:-(\\d{2})' + // optional day capture
+                '(?:' + // capture hours:minutes:seconds.milliseconds
+                    'T(\\d{2})' + // hours capture
+                    ':(\\d{2})' + // minutes capture
+                    '(?:' + // optional :seconds.milliseconds
+                        ':(\\d{2})' + // seconds capture
+                        '(?:(\\.\\d{1,}))?' + // milliseconds capture
+                    ')?' +
+                '(' + // capture UTC offset component
+                    'Z|' + // UTC capture
+                    '(?:' + // offset specifier +/-hours:minutes
+                        '([-+])' + // sign capture
+                        '(\\d{2})' + // hours offset capture
+                        ':(\\d{2})' + // minutes offset capture
+                    ')' +
+                ')?)?)?)?' +
+            '$');
+
+            var months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365];
+
+            var dayFromMonth = function dayFromMonth(year, month) {
+                var t = month > 1 ? 1 : 0;
+                return (
+                    months[month] +
+                    Math.floor((year - 1969 + t) / 4) -
+                    Math.floor((year - 1901 + t) / 100) +
+                    Math.floor((year - 1601 + t) / 400) +
+                    365 * (year - 1970)
+                );
+            };
+
+            var toUTC = function toUTC(t) {
+                var s = 0;
+                var ms = t;
+                if (hasSafariSignedIntBug && ms > maxSafeUnsigned32Bit) {
+                    // work around a Safari 8/9 bug where it treats the seconds as signed
+                    var msToShift = Math.floor(ms / maxSafeUnsigned32Bit) * maxSafeUnsigned32Bit;
+                    var sToShift = Math.floor(msToShift / 1e3);
+                    s += sToShift;
+                    ms -= sToShift * 1e3;
+                }
+                return $Number(new NativeDate(1970, 0, 1, 0, 0, s, ms));
+            };
+
+            // Copy any custom methods a 3rd party library may have added
+            for (var key in NativeDate) {
+                if (owns(NativeDate, key)) {
+                    DateShim[key] = NativeDate[key];
+                }
+            }
+
+            // Copy "native" methods explicitly; they may be non-enumerable
+            defineProperties(DateShim, {
+                now: NativeDate.now,
+                UTC: NativeDate.UTC
+            }, true);
+            DateShim.prototype = NativeDate.prototype;
+            defineProperties(DateShim.prototype, {
+                constructor: DateShim
+            }, true);
+
+            // Upgrade Date.parse to handle simplified ISO 8601 strings
+            var parseShim = function parse(string) {
+                var match = isoDateExpression.exec(string);
+                if (match) {
+                    // parse months, days, hours, minutes, seconds, and milliseconds
+                    // provide default values if necessary
+                    // parse the UTC offset component
+                    var year = $Number(match[1]),
+                        month = $Number(match[2] || 1) - 1,
+                        day = $Number(match[3] || 1) - 1,
+                        hour = $Number(match[4] || 0),
+                        minute = $Number(match[5] || 0),
+                        second = $Number(match[6] || 0),
+                        millisecond = Math.floor($Number(match[7] || 0) * 1000),
+                        // When time zone is missed, local offset should be used
+                        // (ES 5.1 bug)
+                        // see https://bugs.ecmascript.org/show_bug.cgi?id=112
+                        isLocalTime = Boolean(match[4] && !match[8]),
+                        signOffset = match[9] === '-' ? 1 : -1,
+                        hourOffset = $Number(match[10] || 0),
+                        minuteOffset = $Number(match[11] || 0),
+                        result;
+                    var hasMinutesOrSecondsOrMilliseconds = minute > 0 || second > 0 || millisecond > 0;
+                    if (
+                        hour < (hasMinutesOrSecondsOrMilliseconds ? 24 : 25) &&
+                        minute < 60 && second < 60 && millisecond < 1000 &&
+                        month > -1 && month < 12 && hourOffset < 24 &&
+                        minuteOffset < 60 && // detect invalid offsets
+                        day > -1 &&
+                        day < (dayFromMonth(year, month + 1) - dayFromMonth(year, month))
+                    ) {
+                        result = (
+                            (dayFromMonth(year, month) + day) * 24 +
+                            hour +
+                            hourOffset * signOffset
+                        ) * 60;
+                        result = (
+                            (result + minute + minuteOffset * signOffset) * 60 +
+                            second
+                        ) * 1000 + millisecond;
+                        if (isLocalTime) {
+                            result = toUTC(result);
+                        }
+                        if (-8.64e15 <= result && result <= 8.64e15) {
+                            return result;
+                        }
+                    }
+                    return NaN;
+                }
+                return NativeDate.parse.apply(this, arguments);
+            };
+            defineProperties(DateShim, { parse: parseShim });
+
+            return DateShim;
+        }(Date));
+        /* global Date: false */
+    }
+
+    // ES5 15.9.4.4
+    // http://es5.github.com/#x15.9.4.4
+    if (!Date.now) {
+        Date.now = function now() {
+            return new Date().getTime();
+        };
+    }
+
+    //
+    // Number
+    // ======
+    //
+
+    // ES5.1 15.7.4.5
+    // http://es5.github.com/#x15.7.4.5
+    var hasToFixedBugs = NumberPrototype.toFixed && (
+      (0.00008).toFixed(3) !== '0.000' ||
+      (0.9).toFixed(0) !== '1' ||
+      (1.255).toFixed(2) !== '1.25' ||
+      (1000000000000000128).toFixed(0) !== '1000000000000000128'
+    );
+
+    var toFixedHelpers = {
+        base: 1e7,
+        size: 6,
+        data: [0, 0, 0, 0, 0, 0],
+        multiply: function multiply(n, c) {
+            var i = -1;
+            var c2 = c;
+            while (++i < toFixedHelpers.size) {
+                c2 += n * toFixedHelpers.data[i];
+                toFixedHelpers.data[i] = c2 % toFixedHelpers.base;
+                c2 = Math.floor(c2 / toFixedHelpers.base);
+            }
+        },
+        divide: function divide(n) {
+            var i = toFixedHelpers.size;
+            var c = 0;
+            while (--i >= 0) {
+                c += toFixedHelpers.data[i];
+                toFixedHelpers.data[i] = Math.floor(c / n);
+                c = (c % n) * toFixedHelpers.base;
+            }
+        },
+        numToString: function numToString() {
+            var i = toFixedHelpers.size;
+            var s = '';
+            while (--i >= 0) {
+                if (s !== '' || i === 0 || toFixedHelpers.data[i] !== 0) {
+                    var t = $String(toFixedHelpers.data[i]);
+                    if (s === '') {
+                        s = t;
+                    } else {
+                        s += strSlice('0000000', 0, 7 - t.length) + t;
+                    }
+                }
+            }
+            return s;
+        },
+        pow: function pow(x, n, acc) {
+            return (n === 0 ? acc : (n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc)));
+        },
+        log: function log(x) {
+            var n = 0;
+            var x2 = x;
+            while (x2 >= 4096) {
+                n += 12;
+                x2 /= 4096;
+            }
+            while (x2 >= 2) {
+                n += 1;
+                x2 /= 2;
+            }
+            return n;
+        }
+    };
+
+    var toFixedShim = function toFixed(fractionDigits) {
+        var f, x, s, m, e, z, j, k;
+
+        // Test for NaN and round fractionDigits down
+        f = $Number(fractionDigits);
+        f = isActualNaN(f) ? 0 : Math.floor(f);
+
+        if (f < 0 || f > 20) {
+            throw new RangeError('Number.toFixed called with invalid number of decimals');
+        }
+
+        x = $Number(this);
+
+        if (isActualNaN(x)) {
+            return 'NaN';
+        }
+
+        // If it is too big or small, return the string value of the number
+        if (x <= -1e21 || x >= 1e21) {
+            return $String(x);
+        }
+
+        s = '';
+
+        if (x < 0) {
+            s = '-';
+            x = -x;
+        }
+
+        m = '0';
+
+        if (x > 1e-21) {
+            // 1e-21 < x < 1e21
+            // -70 < log2(x) < 70
+            e = toFixedHelpers.log(x * toFixedHelpers.pow(2, 69, 1)) - 69;
+            z = (e < 0 ? x * toFixedHelpers.pow(2, -e, 1) : x / toFixedHelpers.pow(2, e, 1));
+            z *= 0x10000000000000; // Math.pow(2, 52);
+            e = 52 - e;
+
+            // -18 < e < 122
+            // x = z / 2 ^ e
+            if (e > 0) {
+                toFixedHelpers.multiply(0, z);
+                j = f;
+
+                while (j >= 7) {
+                    toFixedHelpers.multiply(1e7, 0);
+                    j -= 7;
+                }
+
+                toFixedHelpers.multiply(toFixedHelpers.pow(10, j, 1), 0);
+                j = e - 1;
+
+                while (j >= 23) {
+                    toFixedHelpers.divide(1 << 23);
+                    j -= 23;
+                }
+
+                toFixedHelpers.divide(1 << j);
+                toFixedHelpers.multiply(1, 1);
+                toFixedHelpers.divide(2);
+                m = toFixedHelpers.numToString();
+            } else {
+                toFixedHelpers.multiply(0, z);
+                toFixedHelpers.multiply(1 << (-e), 0);
+                m = toFixedHelpers.numToString() + strSlice('0.00000000000000000000', 2, 2 + f);
+            }
+        }
+
+        if (f > 0) {
+            k = m.length;
+
+            if (k <= f) {
+                m = s + strSlice('0.0000000000000000000', 0, f - k + 2) + m;
+            } else {
+                m = s + strSlice(m, 0, k - f) + '.' + strSlice(m, k - f);
+            }
+        } else {
+            m = s + m;
+        }
+
+        return m;
+    };
+    defineProperties(NumberPrototype, { toFixed: toFixedShim }, hasToFixedBugs);
+
+    var hasToPrecisionUndefinedBug = (function () {
+        try {
+            return 1.0.toPrecision(undefined) === '1';
+        } catch (e) {
+            return true;
+        }
+    }());
+    var originalToPrecision = NumberPrototype.toPrecision;
+    defineProperties(NumberPrototype, {
+        toPrecision: function toPrecision(precision) {
+            return typeof precision === 'undefined' ? originalToPrecision.call(this) : originalToPrecision.call(this, precision);
+        }
+    }, hasToPrecisionUndefinedBug);
+
+    //
+    // String
+    // ======
+    //
+
+    // ES5 15.5.4.14
+    // http://es5.github.com/#x15.5.4.14
+
+    // [bugfix, IE lt 9, firefox 4, Konqueror, Opera, obscure browsers]
+    // Many browsers do not split properly with regular expressions or they
+    // do not perform the split correctly under obscure conditions.
+    // See http://blog.stevenlevithan.com/archives/cross-browser-split
+    // I've tested in many browsers and this seems to cover the deviant ones:
+    //    'ab'.split(/(?:ab)*/) should be ["", ""], not [""]
+    //    '.'.split(/(.?)(.?)/) should be ["", ".", "", ""], not ["", ""]
+    //    'tesst'.split(/(s)*/) should be ["t", undefined, "e", "s", "t"], not
+    //       [undefined, "t", undefined, "e", ...]
+    //    ''.split(/.?/) should be [], not [""]
+    //    '.'.split(/()()/) should be ["."], not ["", "", "."]
+
+    if (
+        'ab'.split(/(?:ab)*/).length !== 2 ||
+        '.'.split(/(.?)(.?)/).length !== 4 ||
+        'tesst'.split(/(s)*/)[1] === 't' ||
+        'test'.split(/(?:)/, -1).length !== 4 ||
+        ''.split(/.?/).length ||
+        '.'.split(/()()/).length > 1
+    ) {
+        (function () {
+            var compliantExecNpcg = typeof (/()??/).exec('')[1] === 'undefined'; // NPCG: nonparticipating capturing group
+            var maxSafe32BitInt = Math.pow(2, 32) - 1;
+
+            StringPrototype.split = function (separator, limit) {
+                var string = String(this);
+                if (typeof separator === 'undefined' && limit === 0) {
+                    return [];
+                }
+
+                // If `separator` is not a regex, use native split
+                if (!isRegex(separator)) {
+                    return strSplit(this, separator, limit);
+                }
+
+                var output = [];
+                var flags = (separator.ignoreCase ? 'i' : '') +
+                            (separator.multiline ? 'm' : '') +
+                            (separator.unicode ? 'u' : '') + // in ES6
+                            (separator.sticky ? 'y' : ''), // Firefox 3+ and ES6
+                    lastLastIndex = 0,
+                    // Make `global` and avoid `lastIndex` issues by working with a copy
+                    separator2, match, lastIndex, lastLength;
+                var separatorCopy = new RegExp(separator.source, flags + 'g');
+                if (!compliantExecNpcg) {
+                    // Doesn't need flags gy, but they don't hurt
+                    separator2 = new RegExp('^' + separatorCopy.source + '$(?!\\s)', flags);
+                }
+                /* Values for `limit`, per the spec:
+                 * If undefined: 4294967295 // maxSafe32BitInt
+                 * If 0, Infinity, or NaN: 0
+                 * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
+                 * If negative number: 4294967296 - Math.floor(Math.abs(limit))
+                 * If other: Type-convert, then use the above rules
+                 */
+                var splitLimit = typeof limit === 'undefined' ? maxSafe32BitInt : ES.ToUint32(limit);
+                match = separatorCopy.exec(string);
+                while (match) {
+                    // `separatorCopy.lastIndex` is not reliable cross-browser
+                    lastIndex = match.index + match[0].length;
+                    if (lastIndex > lastLastIndex) {
+                        pushCall(output, strSlice(string, lastLastIndex, match.index));
+                        // Fix browsers whose `exec` methods don't consistently return `undefined` for
+                        // nonparticipating capturing groups
+                        if (!compliantExecNpcg && match.length > 1) {
+                            /* eslint-disable no-loop-func */
+                            match[0].replace(separator2, function () {
+                                for (var i = 1; i < arguments.length - 2; i++) {
+                                    if (typeof arguments[i] === 'undefined') {
+                                        match[i] = void 0;
+                                    }
+                                }
+                            });
+                            /* eslint-enable no-loop-func */
+                        }
+                        if (match.length > 1 && match.index < string.length) {
+                            array_push.apply(output, arraySlice(match, 1));
+                        }
+                        lastLength = match[0].length;
+                        lastLastIndex = lastIndex;
+                        if (output.length >= splitLimit) {
+                            break;
+                        }
+                    }
+                    if (separatorCopy.lastIndex === match.index) {
+                        separatorCopy.lastIndex++; // Avoid an infinite loop
+                    }
+                    match = separatorCopy.exec(string);
+                }
+                if (lastLastIndex === string.length) {
+                    if (lastLength || !separatorCopy.test('')) {
+                        pushCall(output, '');
+                    }
+                } else {
+                    pushCall(output, strSlice(string, lastLastIndex));
+                }
+                return output.length > splitLimit ? arraySlice(output, 0, splitLimit) : output;
+            };
+        }());
+
+    // [bugfix, chrome]
+    // If separator is undefined, then the result array contains just one String,
+    // which is the this value (converted to a String). If limit is not undefined,
+    // then the output array is truncated so that it contains no more than limit
+    // elements.
+    // "0".split(undefined, 0) -> []
+    } else if ('0'.split(void 0, 0).length) {
+        StringPrototype.split = function split(separator, limit) {
+            if (typeof separator === 'undefined' && limit === 0) {
+                return [];
+            }
+            return strSplit(this, separator, limit);
+        };
+    }
+
+    var str_replace = StringPrototype.replace;
+    var replaceReportsGroupsCorrectly = (function () {
+        var groups = [];
+        'x'.replace(/x(.)?/g, function (match, group) {
+            pushCall(groups, group);
+        });
+        return groups.length === 1 && typeof groups[0] === 'undefined';
+    }());
+
+    if (!replaceReportsGroupsCorrectly) {
+        StringPrototype.replace = function replace(searchValue, replaceValue) {
+            var isFn = isCallable(replaceValue);
+            var hasCapturingGroups = isRegex(searchValue) && (/\)[*?]/).test(searchValue.source);
+            if (!isFn || !hasCapturingGroups) {
+                return str_replace.call(this, searchValue, replaceValue);
+            } else {
+                var wrappedReplaceValue = function (match) {
+                    var length = arguments.length;
+                    var originalLastIndex = searchValue.lastIndex;
+                    searchValue.lastIndex = 0;
+                    var args = searchValue.exec(match) || [];
+                    searchValue.lastIndex = originalLastIndex;
+                    pushCall(args, arguments[length - 2], arguments[length - 1]);
+                    return replaceValue.apply(this, args);
+                };
+                return str_replace.call(this, searchValue, wrappedReplaceValue);
+            }
+        };
+    }
+
+    // ECMA-262, 3rd B.2.3
+    // Not an ECMAScript standard, although ECMAScript 3rd Edition has a
+    // non-normative section suggesting uniform semantics and it should be
+    // normalized across all browsers
+    // [bugfix, IE lt 9] IE < 9 substr() with negative value not working in IE
+    var string_substr = StringPrototype.substr;
+    var hasNegativeSubstrBug = ''.substr && '0b'.substr(-1) !== 'b';
+    defineProperties(StringPrototype, {
+        substr: function substr(start, length) {
+            var normalizedStart = start;
+            if (start < 0) {
+                normalizedStart = max(this.length + start, 0);
+            }
+            return string_substr.call(this, normalizedStart, length);
+        }
+    }, hasNegativeSubstrBug);
+
+    // ES5 15.5.4.20
+    // whitespace from: http://es5.github.io/#x15.5.4.20
+    var ws = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' +
+        '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028' +
+        '\u2029\uFEFF';
+    var zeroWidth = '\u200b';
+    var wsRegexChars = '[' + ws + ']';
+    var trimBeginRegexp = new RegExp('^' + wsRegexChars + wsRegexChars + '*');
+    var trimEndRegexp = new RegExp(wsRegexChars + wsRegexChars + '*$');
+    var hasTrimWhitespaceBug = StringPrototype.trim && (ws.trim() || !zeroWidth.trim());
+    defineProperties(StringPrototype, {
+        // http://blog.stevenlevithan.com/archives/faster-trim-javascript
+        // http://perfectionkills.com/whitespace-deviations/
+        trim: function trim() {
+            if (typeof this === 'undefined' || this === null) {
+                throw new TypeError("can't convert " + this + ' to object');
+            }
+            return $String(this).replace(trimBeginRegexp, '').replace(trimEndRegexp, '');
+        }
+    }, hasTrimWhitespaceBug);
+    var trim = call.bind(String.prototype.trim);
+
+    var hasLastIndexBug = StringPrototype.lastIndexOf && 'abcあい'.lastIndexOf('あい', 2) !== -1;
+    defineProperties(StringPrototype, {
+        lastIndexOf: function lastIndexOf(searchString) {
+            if (typeof this === 'undefined' || this === null) {
+                throw new TypeError("can't convert " + this + ' to object');
+            }
+            var S = $String(this);
+            var searchStr = $String(searchString);
+            var numPos = arguments.length > 1 ? $Number(arguments[1]) : NaN;
+            var pos = isActualNaN(numPos) ? Infinity : ES.ToInteger(numPos);
+            var start = min(max(pos, 0), S.length);
+            var searchLen = searchStr.length;
+            var k = start + searchLen;
+            while (k > 0) {
+                k = max(0, k - searchLen);
+                var index = strIndexOf(strSlice(S, k, start + searchLen), searchStr);
+                if (index !== -1) {
+                    return k + index;
+                }
+            }
+            return -1;
+        }
+    }, hasLastIndexBug);
+
+    var originalLastIndexOf = StringPrototype.lastIndexOf;
+    defineProperties(StringPrototype, {
+        lastIndexOf: function lastIndexOf(searchString) {
+            return originalLastIndexOf.apply(this, arguments);
+        }
+    }, StringPrototype.lastIndexOf.length !== 1);
+
+    // ES-5 15.1.2.2
+    /* eslint-disable radix */
+    if (parseInt(ws + '08') !== 8 || parseInt(ws + '0x16') !== 22) {
+    /* eslint-enable radix */
+        /* global parseInt: true */
+        parseInt = (function (origParseInt) {
+            var hexRegex = /^[\-+]?0[xX]/;
+            return function parseInt(str, radix) {
+                var string = trim(String(str));
+                var defaultedRadix = $Number(radix) || (hexRegex.test(string) ? 16 : 10);
+                return origParseInt(string, defaultedRadix);
+            };
+        }(parseInt));
+    }
+
+    // https://es5.github.io/#x15.1.2.3
+    if (1 / parseFloat('-0') !== -Infinity) {
+        /* global parseFloat: true */
+        parseFloat = (function (origParseFloat) {
+            return function parseFloat(string) {
+                var inputString = trim(String(string));
+                var result = origParseFloat(inputString);
+                return result === 0 && strSlice(inputString, 0, 1) === '-' ? -0 : result;
+            };
+        }(parseFloat));
+    }
+
+    if (String(new RangeError('test')) !== 'RangeError: test') {
+        var errorToStringShim = function toString() {
+            if (typeof this === 'undefined' || this === null) {
+                throw new TypeError("can't convert " + this + ' to object');
+            }
+            var name = this.name;
+            if (typeof name === 'undefined') {
+                name = 'Error';
+            } else if (typeof name !== 'string') {
+                name = $String(name);
+            }
+            var msg = this.message;
+            if (typeof msg === 'undefined') {
+                msg = '';
+            } else if (typeof msg !== 'string') {
+                msg = $String(msg);
+            }
+            if (!name) {
+                return msg;
+            }
+            if (!msg) {
+                return name;
+            }
+            return name + ': ' + msg;
+        };
+        // can't use defineProperties here because of toString enumeration issue in IE <= 8
+        Error.prototype.toString = errorToStringShim;
+    }
+
+    if (supportsDescriptors) {
+        var ensureNonEnumerable = function (obj, prop) {
+            if (isEnum(obj, prop)) {
+                var desc = Object.getOwnPropertyDescriptor(obj, prop);
+                if (desc.configurable) {
+                    desc.enumerable = false;
+                    Object.defineProperty(obj, prop, desc);
+                }
+            }
+        };
+        ensureNonEnumerable(Error.prototype, 'message');
+        if (Error.prototype.message !== '') {
+            Error.prototype.message = '';
+        }
+        ensureNonEnumerable(Error.prototype, 'name');
+    }
+
+    if (String(/a/mig) !== '/a/gim') {
+        var regexToString = function toString() {
+            var str = '/' + this.source + '/';
+            if (this.global) {
+                str += 'g';
+            }
+            if (this.ignoreCase) {
+                str += 'i';
+            }
+            if (this.multiline) {
+                str += 'm';
+            }
+            return str;
+        };
+        // can't use defineProperties here because of toString enumeration issue in IE <= 8
+        RegExp.prototype.toString = regexToString;
+    }
+}));
+
+'use strict';
+/*jslint eqeq: true*/
+
+Handlebars.registerHelper('sanitize', function (text) {
+    var result;
+
+    if (text === undefined) { return ''; }
+
+    result = sanitizeHtml(text, {
+        allowedTags: [ 'div', 'span', 'b', 'i', 'em', 'strong', 'a', 'br', 'table', 'tbody', 'tr', 'th', 'td' ],
+        allowedAttributes: {
+            'div': [ 'class' ],
+            'span': [ 'class' ],
+            'table': [ 'class' ],
+            'td': [ 'class' ],
+            'th': [ 'colspan' ],
+            'a': [ 'href' ]
+        }
+    });
+
+    return new Handlebars.SafeString(result);
+});
+
+Handlebars.registerHelper('renderTextParam', function(param) {
+    var result, type = 'text', idAtt = '';
+       var paramType = (param.schema) ? param.type || param.schema.type || '' : param.type || '';
+    var isArray = paramType.toLowerCase() === 'array' || param.allowMultiple;
+    var defaultValue = isArray && Array.isArray(param.default) ? param.default.join('\n') : param.default;
+    var name = Handlebars.Utils.escapeExpression(param.name);
+    var valueId = Handlebars.Utils.escapeExpression(param.valueId);
+    paramType = Handlebars.Utils.escapeExpression(paramType);
+
+    var dataVendorExtensions = Object.keys(param).filter(function(property) {
+        // filter X-data- properties
+        return property.match(/^X-data-/i) !== null;
+    }).reduce(function(result, property) {
+        // remove X- from property name, so it results in html attributes like data-foo='bar'
+        return result += ' ' + property.substring(2, property.length) + '=\'' + param[property] + '\'';
+    }, '');
+
+    if(param.format && param.format === 'password') {
+        type = 'password';
+    }
+
+    if(valueId) {
+        idAtt = ' id=\'' + valueId + '\'';
+    }
+
+    if (defaultValue) {
+      defaultValue = sanitizeHtml(defaultValue);
+    } else {
+      defaultValue = '';
+    }
+
+    if(isArray) {
+        result = '<textarea class=\'body-textarea' + (param.required ? ' required' : '') + '\' name=\'' + name + '\'' + idAtt + dataVendorExtensions;
+        result += ' placeholder=\'Provide multiple values in new lines' + (param.required ? ' (at least one required).' : '.') + '\'>';
+        result += defaultValue + '</textarea>';
+    } else {
+        var parameterClass = 'parameter';
+        if(param.required) {
+          parameterClass += ' required';
+        }
+        result = '<input class=\'' + parameterClass + '\' minlength=\'' + (param.required ? 1 : 0) + '\'';
+        result += ' name=\'' + name +'\' placeholder=\'' + (param.required ? '(required)' : '') + '\'' + idAtt + dataVendorExtensions;
+        result += ' type=\'' + type + '\' value=\'' + defaultValue + '\'/>';
+    }
+    return new Handlebars.SafeString(result);
+});
+
+Handlebars.registerHelper('ifCond', function (v1, operator, v2, options) {
+
+    switch (operator) {
+        case '==':
+            return (v1 == v2) ? options.fn(this) : options.inverse(this);
+        case '===':
+            return (v1 === v2) ? options.fn(this) : options.inverse(this);
+        case '<':
+            return (v1 < v2) ? options.fn(this) : options.inverse(this);
+        case '<=':
+            return (v1 <= v2) ? options.fn(this) : options.inverse(this);
+        case '>':
+            return (v1 > v2) ? options.fn(this) : options.inverse(this);
+        case '>=':
+            return (v1 >= v2) ? options.fn(this) : options.inverse(this);
+        case '&&':
+            return (v1 && v2) ? options.fn(this) : options.inverse(this);
+        case '||':
+            return (v1 || v2) ? options.fn(this) : options.inverse(this);
+        default:
+            return options.inverse(this);
+    }
+});
+
+Handlebars.registerHelper('escape', function (value) {
+    var text = Handlebars.Utils.escapeExpression(value);
+
+    return new Handlebars.SafeString(text);
+});
+
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.sanitizeHtml=f()}})(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){var htmlparser=require("htmlparser2");var extend=require("xtend");var quoteRegexp=require("regexp-quote");function each(obj,cb){if(obj)Object.keys(obj).forEach(function(key){cb(obj[key],key)})}function has(obj,key){return{}.hasOwnProperty.call(obj,key)}module.exports=sanitizeHtml;function sanitizeHtml(html,options,_recursing){var result="";function Frame(tag,attribs){var that=this;this.tag=tag;this.attribs=attribs||{};this.tagPosition=result.length;this.text="";this.updateParentNodeText=function(){if(stack.length){var parentFrame=stack[stack.length-1];parentFrame.text+=that.text}}}if(!options){options=sanitizeHtml.defaults;options.parser=htmlParserDefaults}else{options=extend(sanitizeHtml.defaults,options);if(options.parser){options.parser=extend(htmlParserDefaults,options.parser)}else{options.parser=htmlParserDefaults}}var nonTextTagsArray=options.nonTextTags||["script","style","textarea"];var allowedAttributesMap;var allowedAttributesGlobMap;if(options.allowedAttributes){allowedAttributesMap={};allowedAttributesGlobMap={};each(options.allowedAttributes,function(attributes,tag){allowedAttributesMap[tag]=[];var globRegex=[];attributes.forEach(function(name){if(name.indexOf("*")>=0){globRegex.push(quoteRegexp(name).replace(/\\\*/g,".*"))}else{allowedAttributesMap[tag].push(name)}});allowedAttributesGlobMap[tag]=new RegExp("^("+globRegex.join("|")+")$")})}var allowedClassesMap={};each(options.allowedClasses,function(classes,tag){if(allowedAttributesMap){if(!has(allowedAttributesMap,tag)){allowedAttributesMap[tag]=[]}allowedAttributesMap[tag].push("class")}allowedClassesMap[tag]=classes});var transformTagsMap={};var transformTagsAll;each(options.transformTags,function(transform,tag){var transFun;if(typeof transform==="function"){transFun=transform}else if(typeof transform==="string"){transFun=sanitizeHtml.simpleTransform(transform)}if(tag==="*"){transformTagsAll=transFun}else{transformTagsMap[tag]=transFun}});var depth=0;var stack=[];var skipMap={};var transformMap={};var skipText=false;var skipTextDepth=0;var parser=new htmlparser.Parser({onopentag:function(name,attribs){if(skipText){skipTextDepth++;return}var frame=new Frame(name,attribs);stack.push(frame);var skip=false;var hasText=frame.text?true:false;var transformedTag;if(has(transformTagsMap,name)){transformedTag=transformTagsMap[name](name,attribs);frame.attribs=attribs=transformedTag.attribs;if(transformedTag.text!==undefined){frame.innerText=transformedTag.text}if(name!==transformedTag.tagName){frame.name=name=transformedTag.tagName;transformMap[depth]=transformedTag.tagName}}if(transformTagsAll){transformedTag=transformTagsAll(name,attribs);frame.attribs=attribs=transformedTag.attribs;if(name!==transformedTag.tagName){frame.name=name=transformedTag.tagName;transformMap[depth]=transformedTag.tagName}}if(options.allowedTags&&options.allowedTags.indexOf(name)===-1){skip=true;if(nonTextTagsArray.indexOf(name)!==-1){skipText=true;skipTextDepth=1}skipMap[depth]=true}depth++;if(skip){return}result+="<"+name;if(!allowedAttributesMap||has(allowedAttributesMap,name)||allowedAttributesMap["*"]){each(attribs,function(value,a){if(!allowedAttributesMap||has(allowedAttributesMap,name)&&allowedAttributesMap[name].indexOf(a)!==-1||allowedAttributesMap["*"]&&allowedAttributesMap["*"].indexOf(a)!==-1||has(allowedAttributesGlobMap,name)&&allowedAttributesGlobMap[name].test(a)||allowedAttributesGlobMap["*"]&&allowedAttributesGlobMap["*"].test(a)){if(a==="href"||a==="src"){if(naughtyHref(name,value)){delete frame.attribs[a];return}}if(a==="class"){value=filterClasses(value,allowedClassesMap[name]);if(!value.length){delete frame.attribs[a];return}}result+=" "+a;if(value.length){result+='="'+escapeHtml(value)+'"'}}else{delete frame.attribs[a]}})}if(options.selfClosing.indexOf(name)!==-1){result+=" />"}else{result+=">";if(frame.innerText&&!hasText&&!options.textFilter){result+=frame.innerText}}},ontext:function(text){if(skipText){return}var lastFrame=stack[stack.length-1];var tag;if(lastFrame){tag=lastFrame.tag;text=lastFrame.innerText!==undefined?lastFrame.innerText:text}if(tag==="script"||tag==="style"){result+=text}else{var escaped=escapeHtml(text);if(options.textFilter){result+=options.textFilter(escaped)}else{result+=escaped}}if(stack.length){var frame=stack[stack.length-1];frame.text+=text}},onclosetag:function(name){if(skipText){skipTextDepth--;if(!skipTextDepth){skipText=false}else{return}}var frame=stack.pop();if(!frame){return}skipText=false;depth--;if(skipMap[depth]){delete skipMap[depth];frame.updateParentNodeText();return}if(transformMap[depth]){name=transformMap[depth];delete transformMap[depth]}if(options.exclusiveFilter&&options.exclusiveFilter(frame)){result=result.substr(0,frame.tagPosition);return}frame.updateParentNodeText();if(options.selfClosing.indexOf(name)!==-1){return}result+="</"+name+">"}},options.parser);parser.write(html);parser.end();return result;function escapeHtml(s){if(typeof s!=="string"){s=s+""}return s.replace(/\&/g,"&amp;").replace(/</g,"&lt;").replace(/\>/g,"&gt;").replace(/\"/g,"&quot;")}function naughtyHref(name,href){href=href.replace(/[\x00-\x20]+/g,"");href=href.replace(/<\!\-\-.*?\-\-\>/g,"");var matches=href.match(/^([a-zA-Z]+)\:/);if(!matches){return false}var scheme=matches[1].toLowerCase();if(has(options.allowedSchemesByTag,name)){return options.allowedSchemesByTag[name].indexOf(scheme)===-1}return!options.allowedSchemes||options.allowedSchemes.indexOf(scheme)===-1}function filterClasses(classes,allowed){if(!allowed){return classes}classes=classes.split(/\s+/);return classes.filter(function(clss){return allowed.indexOf(clss)!==-1}).join(" ")}}var htmlParserDefaults={decodeEntities:true};sanitizeHtml.defaults={allowedTags:["h3","h4","h5","h6","blockquote","p","a","ul","ol","nl","li","b","i","strong","em","strike","code","hr","br","div","table","thead","caption","tbody","tr","th","td","pre"],allowedAttributes:{a:["href","name","target"],img:["src"]},selfClosing:["img","br","hr","area","base","basefont","input","link","meta"],allowedSchemes:["http","https","ftp","mailto"],allowedSchemesByTag:{}};sanitizeHtml.simpleTransform=function(newTagName,newAttribs,merge){merge=merge===undefined?true:merge;newAttribs=newAttribs||{};return function(tagName,attribs){var attrib;if(merge){for(attrib in newAttribs){attribs[attrib]=newAttribs[attrib]}}else{attribs=newAttribs}return{tagName:newTagName,attribs:attribs}}}},{htmlparser2:36,"regexp-quote":54,xtend:58}],2:[function(require,module,exports){"use strict";exports.toByteArray=toByteArray;exports.fromByteArray=fromByteArray;var lookup=[];var revLookup=[];var Arr=typeof Uint8Array!=="undefined"?Uint8Array:Array;function init(){var code="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";for(var i=0,len=code.length;i<len;++i){lookup[i]=code[i];revLookup[code.charCodeAt(i)]=i}revLookup["-".charCodeAt(0)]=62;revLookup["_".charCodeAt(0)]=63}init();function toByteArray(b64){var i,j,l,tmp,placeHolders,arr;var len=b64.length;if(len%4>0){throw new Error("Invalid string. Length must be a multiple of 4")}placeHolders=b64[len-2]==="="?2:b64[len-1]==="="?1:0;arr=new Arr(len*3/4-placeHolders);l=placeHolders>0?len-4:len;var L=0;for(i=0,j=0;i<l;i+=4,j+=3){tmp=revLookup[b64.charCodeAt(i)]<<18|revLookup[b64.charCodeAt(i+1)]<<12|revLookup[b64.charCodeAt(i+2)]<<6|revLookup[b64.charCodeAt(i+3)];arr[L++]=tmp>>16&255;arr[L++]=tmp>>8&255;arr[L++]=tmp&255}if(placeHolders===2){tmp=revLookup[b64.charCodeAt(i)]<<2|revLookup[b64.charCodeAt(i+1)]>>4;arr[L++]=tmp&255}else if(placeHolders===1){tmp=revLookup[b64.charCodeAt(i)]<<10|revLookup[b64.charCodeAt(i+1)]<<4|revLookup[b64.charCodeAt(i+2)]>>2;arr[L++]=tmp>>8&255;arr[L++]=tmp&255}return arr}function tripletToBase64(num){return lookup[num>>18&63]+lookup[num>>12&63]+lookup[num>>6&63]+lookup[num&63]}function encodeChunk(uint8,start,end){var tmp;var output=[];for(var i=start;i<end;i+=3){tmp=(uint8[i]<<16)+(uint8[i+1]<<8)+uint8[i+2];output.push(tripletToBase64(tmp))}return output.join("")}function fromByteArray(uint8){var tmp;var len=uint8.length;var extraBytes=len%3;var output="";var parts=[];var maxChunkLength=16383;for(var i=0,len2=len-extraBytes;i<len2;i+=maxChunkLength){parts.push(encodeChunk(uint8,i,i+maxChunkLength>len2?len2:i+maxChunkLength))}if(extraBytes===1){tmp=uint8[len-1];output+=lookup[tmp>>2];output+=lookup[tmp<<4&63];output+="=="}else if(extraBytes===2){tmp=(uint8[len-2]<<8)+uint8[len-1];output+=lookup[tmp>>10];output+=lookup[tmp>>4&63];output+=lookup[tmp<<2&63];output+="="}parts.push(output);return parts.join("")}},{}],3:[function(require,module,exports){},{}],4:[function(require,module,exports){(function(global){"use strict";var buffer=require("buffer");var Buffer=buffer.Buffer;var SlowBuffer=buffer.SlowBuffer;var MAX_LEN=buffer.kMaxLength||2147483647;exports.alloc=function alloc(size,fill,encoding){if(typeof Buffer.alloc==="function"){return Buffer.alloc(size,fill,encoding)}if(typeof encoding==="number"){throw new TypeError("encoding must not be number")}if(typeof size!=="number"){throw new TypeError("size must be a number")}if(size>MAX_LEN){throw new RangeError("size is too large")}var enc=encoding;var _fill=fill;if(_fill===undefined){enc=undefined;_fill=0}var buf=new Buffer(size);if(typeof _fill==="string"){var fillBuf=new Buffer(_fill,enc);var flen=fillBuf.length;var i=-1;while(++i<size){buf[i]=fillBuf[i%flen]}}else{buf.fill(_fill)}return buf};exports.allocUnsafe=function allocUnsafe(size){if(typeof Buffer.allocUnsafe==="function"){return Buffer.allocUnsafe(size)}if(typeof size!=="number"){throw new TypeError("size must be a number")}if(size>MAX_LEN){throw new RangeError("size is too large")}return new Buffer(size)};exports.from=function from(value,encodingOrOffset,length){if(typeof Buffer.from==="function"&&(!global.Uint8Array||Uint8Array.from!==Buffer.from)){return Buffer.from(value,encodingOrOffset,length)}if(typeof value==="number"){throw new TypeError('"value" argument must not be a number')}if(typeof value==="string"){return new Buffer(value,encodingOrOffset)}if(typeof ArrayBuffer!=="undefined"&&value instanceof ArrayBuffer){var offset=encodingOrOffset;if(arguments.length===1){return new Buffer(value)}if(typeof offset==="undefined"){offset=0}var len=length;if(typeof len==="undefined"){len=value.byteLength-offset}if(offset>=value.byteLength){throw new RangeError("'offset' is out of bounds")}if(len>value.byteLength-offset){throw new RangeError("'length' is out of bounds")}return new Buffer(value.slice(offset,offset+len))}if(Buffer.isBuffer(value)){var out=new Buffer(value.length);value.copy(out,0,0,value.length);return out}if(value){if(Array.isArray(value)||typeof ArrayBuffer!=="undefined"&&value.buffer instanceof ArrayBuffer||"length"in value){return new Buffer(value)}if(value.type==="Buffer"&&Array.isArray(value.data)){return new Buffer(value.data)}}throw new TypeError("First argument must be a string, Buffer, "+"ArrayBuffer, Array, or array-like object.")};exports.allocUnsafeSlow=function allocUnsafeSlow(size){if(typeof Buffer.allocUnsafeSlow==="function"){return Buffer.allocUnsafeSlow(size)}if(typeof size!=="number"){throw new TypeError("size must be a number")}if(size>=MAX_LEN){throw new RangeError("size is too large")}return new SlowBuffer(size)}}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{buffer:5}],5:[function(require,module,exports){(function(global){"use strict";var base64=require("base64-js");var ieee754=require("ieee754");var isArray=require("isarray");exports.Buffer=Buffer;exports.SlowBuffer=SlowBuffer;exports.INSPECT_MAX_BYTES=50;Buffer.TYPED_ARRAY_SUPPORT=global.TYPED_ARRAY_SUPPORT!==undefined?global.TYPED_ARRAY_SUPPORT:typedArraySupport();exports.kMaxLength=kMaxLength();function typedArraySupport(){try{var arr=new Uint8Array(1);arr.__proto__={__proto__:Uint8Array.prototype,foo:function(){return 42}};return arr.foo()===42&&typeof arr.subarray==="function"&&arr.subarray(1,1).byteLength===0}catch(e){return false}}function kMaxLength(){return Buffer.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function createBuffer(that,length){if(kMaxLength()<length){throw new RangeError("Invalid typed array length")}if(Buffer.TYPED_ARRAY_SUPPORT){that=new Uint8Array(length);that.__proto__=Buffer.prototype}else{if(that===null){that=new Buffer(length)}that.length=length}return that}function Buffer(arg,encodingOrOffset,length){if(!Buffer.TYPED_ARRAY_SUPPORT&&!(this instanceof Buffer)){return new Buffer(arg,encodingOrOffset,length)}if(typeof arg==="number"){if(typeof encodingOrOffset==="string"){throw new Error("If encoding is specified then the first argument must be a string")}return allocUnsafe(this,arg)}return from(this,arg,encodingOrOffset,length)}Buffer.poolSize=8192;Buffer._augment=function(arr){arr.__proto__=Buffer.prototype;return arr};function from(that,value,encodingOrOffset,length){if(typeof value==="number"){throw new TypeError('"value" argument must not be a number')}if(typeof ArrayBuffer!=="undefined"&&value instanceof ArrayBuffer){return fromArrayBuffer(that,value,encodingOrOffset,length)}if(typeof value==="string"){return fromString(that,value,encodingOrOffset)}return fromObject(that,value)}Buffer.from=function(value,encodingOrOffset,length){return from(null,value,encodingOrOffset,length)};if(Buffer.TYPED_ARRAY_SUPPORT){Buffer.prototype.__proto__=Uint8Array.prototype;Buffer.__proto__=Uint8Array;if(typeof Symbol!=="undefined"&&Symbol.species&&Buffer[Symbol.species]===Buffer){Object.defineProperty(Buffer,Symbol.species,{value:null,configurable:true})}}function assertSize(size){if(typeof size!=="number"){throw new TypeError('"size" argument must be a number')}else if(size<0){throw new RangeError('"size" argument must not be negative')}}function alloc(that,size,fill,encoding){assertSize(size);if(size<=0){return createBuffer(that,size)}if(fill!==undefined){return typeof encoding==="string"?createBuffer(that,size).fill(fill,encoding):createBuffer(that,size).fill(fill)}return createBuffer(that,size)}Buffer.alloc=function(size,fill,encoding){return alloc(null,size,fill,encoding)};function allocUnsafe(that,size){assertSize(size);that=createBuffer(that,size<0?0:checked(size)|0);if(!Buffer.TYPED_ARRAY_SUPPORT){for(var i=0;i<size;++i){that[i]=0}}return that}Buffer.allocUnsafe=function(size){return allocUnsafe(null,size)};Buffer.allocUnsafeSlow=function(size){return allocUnsafe(null,size)};function fromString(that,string,encoding){if(typeof encoding!=="string"||encoding===""){encoding="utf8"}if(!Buffer.isEncoding(encoding)){throw new TypeError('"encoding" must be a valid string encoding')}var length=byteLength(string,encoding)|0;that=createBuffer(that,length);var actual=that.write(string,encoding);if(actual!==length){that=that.slice(0,actual)}return that}function fromArrayLike(that,array){var length=array.length<0?0:checked(array.length)|0;that=createBuffer(that,length);for(var i=0;i<length;i+=1){that[i]=array[i]&255}return that}function fromArrayBuffer(that,array,byteOffset,length){array.byteLength;if(byteOffset<0||array.byteLength<byteOffset){throw new RangeError("'offset' is out of bounds")}if(array.byteLength<byteOffset+(length||0)){throw new RangeError("'length' is out of bounds")}if(byteOffset===undefined&&length===undefined){array=new Uint8Array(array)}else if(length===undefined){array=new Uint8Array(array,byteOffset)}else{array=new Uint8Array(array,byteOffset,length)}if(Buffer.TYPED_ARRAY_SUPPORT){that=array;that.__proto__=Buffer.prototype}else{that=fromArrayLike(that,array)}return that}function fromObject(that,obj){if(Buffer.isBuffer(obj)){var len=checked(obj.length)|0;that=createBuffer(that,len);if(that.length===0){return that}obj.copy(that,0,0,len);return that}if(obj){if(typeof ArrayBuffer!=="undefined"&&obj.buffer instanceof ArrayBuffer||"length"in obj){if(typeof obj.length!=="number"||isnan(obj.length)){return createBuffer(that,0)}return fromArrayLike(that,obj)}if(obj.type==="Buffer"&&isArray(obj.data)){return fromArrayLike(that,obj.data)}}throw new TypeError("First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.")}function checked(length){if(length>=kMaxLength()){throw new RangeError("Attempt to allocate Buffer larger than maximum "+"size: 0x"+kMaxLength().toString(16)+" bytes")}return length|0}function SlowBuffer(length){if(+length!=length){length=0}return Buffer.alloc(+length)}Buffer.isBuffer=function isBuffer(b){return!!(b!=null&&b._isBuffer)};Buffer.compare=function compare(a,b){if(!Buffer.isBuffer(a)||!Buffer.isBuffer(b)){throw new TypeError("Arguments must be Buffers")}if(a===b)return 0;var x=a.length;var y=b.length;for(var i=0,len=Math.min(x,y);i<len;++i){if(a[i]!==b[i]){x=a[i];y=b[i];break}}if(x<y)return-1;if(y<x)return 1;return 0};Buffer.isEncoding=function isEncoding(encoding){switch(String(encoding).toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"latin1":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return true;default:return false}};Buffer.concat=function concat(list,length){if(!isArray(list)){throw new TypeError('"list" argument must be an Array of Buffers')}if(list.length===0){return Buffer.alloc(0)}var i;if(length===undefined){length=0;for(i=0;i<list.length;++i){length+=list[i].length}}var buffer=Buffer.allocUnsafe(length);var pos=0;for(i=0;i<list.length;++i){var buf=list[i];if(!Buffer.isBuffer(buf)){throw new TypeError('"list" argument must be an Array of Buffers')}buf.copy(buffer,pos);pos+=buf.length}return buffer};function byteLength(string,encoding){if(Buffer.isBuffer(string)){return string.length}if(typeof ArrayBuffer!=="undefined"&&typeof ArrayBuffer.isView==="function"&&(ArrayBuffer.isView(string)||string instanceof ArrayBuffer)){return string.byteLength}if(typeof string!=="string"){string=""+string}var len=string.length;if(len===0)return 0;var loweredCase=false;for(;;){switch(encoding){case"ascii":case"latin1":case"binary":return len;case"utf8":case"utf-8":case undefined:return utf8ToBytes(string).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return len*2;case"hex":return len>>>1;case"base64":return base64ToBytes(string).length;default:if(loweredCase)return utf8ToBytes(string).length;encoding=(""+encoding).toLowerCase();loweredCase=true}}}Buffer.byteLength=byteLength;function slowToString(encoding,start,end){var loweredCase=false;if(start===undefined||start<0){start=0}if(start>this.length){return""}if(end===undefined||end>this.length){end=this.length}if(end<=0){return""}end>>>=0;start>>>=0;if(end<=start){return""}if(!encoding)encoding="utf8";while(true){switch(encoding){case"hex":return hexSlice(this,start,end);case"utf8":case"utf-8":return utf8Slice(this,start,end);case"ascii":return asciiSlice(this,start,end);case"latin1":case"binary":return latin1Slice(this,start,end);case"base64":return base64Slice(this,start,end);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return utf16leSlice(this,start,end);default:if(loweredCase)throw new TypeError("Unknown encoding: "+encoding);encoding=(encoding+"").toLowerCase();loweredCase=true}}}Buffer.prototype._isBuffer=true;function swap(b,n,m){var i=b[n];b[n]=b[m];b[m]=i}Buffer.prototype.swap16=function swap16(){var len=this.length;if(len%2!==0){throw new RangeError("Buffer size must be a multiple of 16-bits")}for(var i=0;i<len;i+=2){swap(this,i,i+1)}return this};Buffer.prototype.swap32=function swap32(){var len=this.length;if(len%4!==0){throw new RangeError("Buffer size must be a multiple of 32-bits")}for(var i=0;i<len;i+=4){swap(this,i,i+3);swap(this,i+1,i+2)}return this};Buffer.prototype.swap64=function swap64(){var len=this.length;if(len%8!==0){throw new RangeError("Buffer size must be a multiple of 64-bits")}for(var i=0;i<len;i+=8){swap(this,i,i+7);swap(this,i+1,i+6);swap(this,i+2,i+5);swap(this,i+3,i+4)}return this};Buffer.prototype.toString=function toString(){var length=this.length|0;if(length===0)return"";if(arguments.length===0)return utf8Slice(this,0,length);return slowToString.apply(this,arguments)};Buffer.prototype.equals=function equals(b){if(!Buffer.isBuffer(b))throw new TypeError("Argument must be a Buffer");if(this===b)return true;return Buffer.compare(this,b)===0};Buffer.prototype.inspect=function inspect(){var str="";var max=exports.INSPECT_MAX_BYTES;if(this.length>0){str=this.toString("hex",0,max).match(/.{2}/g).join(" ");if(this.length>max)str+=" ... "}return"<Buffer "+str+">"};Buffer.prototype.compare=function compare(target,start,end,thisStart,thisEnd){if(!Buffer.isBuffer(target)){throw new TypeError("Argument must be a Buffer")}if(start===undefined){start=0}if(end===undefined){end=target?target.length:0}if(thisStart===undefined){thisStart=0}if(thisEnd===undefined){thisEnd=this.length}if(start<0||end>target.length||thisStart<0||thisEnd>this.length){throw new RangeError("out of range index")}if(thisStart>=thisEnd&&start>=end){return 0}if(thisStart>=thisEnd){return-1}if(start>=end){return 1}start>>>=0;end>>>=0;thisStart>>>=0;thisEnd>>>=0;if(this===target)return 0;var x=thisEnd-thisStart;var y=end-start;var len=Math.min(x,y);var thisCopy=this.slice(thisStart,thisEnd);var targetCopy=target.slice(start,end);for(var i=0;i<len;++i){if(thisCopy[i]!==targetCopy[i]){x=thisCopy[i];y=targetCopy[i];break}}if(x<y)return-1;if(y<x)return 1;return 0};function bidirectionalIndexOf(buffer,val,byteOffset,encoding,dir){if(buffer.length===0)return-1;if(typeof byteOffset==="string"){encoding=byteOffset;byteOffset=0}else if(byteOffset>2147483647){byteOffset=2147483647}else if(byteOffset<-2147483648){byteOffset=-2147483648}byteOffset=+byteOffset;if(isNaN(byteOffset)){byteOffset=dir?0:buffer.length-1}if(byteOffset<0)byteOffset=buffer.length+byteOffset;if(byteOffset>=buffer.length){if(dir)return-1;else byteOffset=buffer.length-1}else if(byteOffset<0){if(dir)byteOffset=0;else return-1}if(typeof val==="string"){val=Buffer.from(val,encoding)}if(Buffer.isBuffer(val)){if(val.length===0){return-1}return arrayIndexOf(buffer,val,byteOffset,encoding,dir)}else if(typeof val==="number"){val=val&255;if(Buffer.TYPED_ARRAY_SUPPORT&&typeof Uint8Array.prototype.indexOf==="function"){if(dir){return Uint8Array.prototype.indexOf.call(buffer,val,byteOffset)}else{return Uint8Array.prototype.lastIndexOf.call(buffer,val,byteOffset)}}return arrayIndexOf(buffer,[val],byteOffset,encoding,dir)}throw new TypeError("val must be string, number or Buffer")}function arrayIndexOf(arr,val,byteOffset,encoding,dir){var indexSize=1;var arrLength=arr.length;var valLength=val.length;if(encoding!==undefined){encoding=String(encoding).toLowerCase();if(encoding==="ucs2"||encoding==="ucs-2"||encoding==="utf16le"||encoding==="utf-16le"){if(arr.length<2||val.length<2){return-1}indexSize=2;arrLength/=2;valLength/=2;byteOffset/=2}}function read(buf,i){if(indexSize===1){return buf[i]}else{return buf.readUInt16BE(i*indexSize)}}var i;if(dir){var foundIndex=-1;for(i=byteOffset;i<arrLength;i++){if(read(arr,i)===read(val,foundIndex===-1?0:i-foundIndex)){if(foundIndex===-1)foundIndex=i;if(i-foundIndex+1===valLength)return foundIndex*indexSize}else{if(foundIndex!==-1)i-=i-foundIndex;foundIndex=-1}}}else{if(byteOffset+valLength>arrLength)byteOffset=arrLength-valLength;for(i=byteOffset;i>=0;i--){var found=true;for(var j=0;j<valLength;j++){if(read(arr,i+j)!==read(val,j)){found=false;break}}if(found)return i}}return-1}Buffer.prototype.includes=function includes(val,byteOffset,encoding){return this.indexOf(val,byteOffset,encoding)!==-1};Buffer.prototype.indexOf=function indexOf(val,byteOffset,encoding){return bidirectionalIndexOf(this,val,byteOffset,encoding,true)};Buffer.prototype.lastIndexOf=function lastIndexOf(val,byteOffset,encoding){return bidirectionalIndexOf(this,val,byteOffset,encoding,false)};function hexWrite(buf,string,offset,length){offset=Number(offset)||0;var remaining=buf.length-offset;if(!length){length=remaining}else{length=Number(length);if(length>remaining){length=remaining}}var strLen=string.length;if(strLen%2!==0)throw new TypeError("Invalid hex string");if(length>strLen/2){length=strLen/2}for(var i=0;i<length;++i){var parsed=parseInt(string.substr(i*2,2),16);if(isNaN(parsed))return i;buf[offset+i]=parsed}return i}function utf8Write(buf,string,offset,length){return blitBuffer(utf8ToBytes(string,buf.length-offset),buf,offset,length)}function asciiWrite(buf,string,offset,length){return blitBuffer(asciiToBytes(string),buf,offset,length)}function latin1Write(buf,string,offset,length){return asciiWrite(buf,string,offset,length)}function base64Write(buf,string,offset,length){return blitBuffer(base64ToBytes(string),buf,offset,length)}function ucs2Write(buf,string,offset,length){return blitBuffer(utf16leToBytes(string,buf.length-offset),buf,offset,length)}Buffer.prototype.write=function write(string,offset,length,encoding){if(offset===undefined){encoding="utf8";length=this.length;offset=0}else if(length===undefined&&typeof offset==="string"){encoding=offset;length=this.length;offset=0}else if(isFinite(offset)){offset=offset|0;if(isFinite(length)){length=length|0;if(encoding===undefined)encoding="utf8"}else{encoding=length;length=undefined}}else{throw new Error("Buffer.write(string, encoding, offset[, length]) is no longer supported")}var remaining=this.length-offset;if(length===undefined||length>remaining)length=remaining;if(string.length>0&&(length<0||offset<0)||offset>this.length){throw new RangeError("Attempt to write outside buffer bounds")}if(!encoding)encoding="utf8";var loweredCase=false;for(;;){switch(encoding){case"hex":return hexWrite(this,string,offset,length);case"utf8":case"utf-8":return utf8Write(this,string,offset,length);case"ascii":return asciiWrite(this,string,offset,length);case"latin1":case"binary":return latin1Write(this,string,offset,length);case"base64":return base64Write(this,string,offset,length);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return ucs2Write(this,string,offset,length);default:if(loweredCase)throw new TypeError("Unknown encoding: "+encoding);encoding=(""+encoding).toLowerCase();loweredCase=true}}};Buffer.prototype.toJSON=function toJSON(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};function base64Slice(buf,start,end){if(start===0&&end===buf.length){return base64.fromByteArray(buf)}else{return base64.fromByteArray(buf.slice(start,end))}}function utf8Slice(buf,start,end){end=Math.min(buf.length,end);var res=[];var i=start;while(i<end){var firstByte=buf[i];var codePoint=null;var bytesPerSequence=firstByte>239?4:firstByte>223?3:firstByte>191?2:1;if(i+bytesPerSequence<=end){var secondByte,thirdByte,fourthByte,tempCodePoint;switch(bytesPerSequence){case 1:if(firstByte<128){codePoint=firstByte}break;case 2:secondByte=buf[i+1];if((secondByte&192)===128){tempCodePoint=(firstByte&31)<<6|secondByte&63;if(tempCodePoint>127){codePoint=tempCodePoint}}break;case 3:secondByte=buf[i+1];thirdByte=buf[i+2];if((secondByte&192)===128&&(thirdByte&192)===128){tempCodePoint=(firstByte&15)<<12|(secondByte&63)<<6|thirdByte&63;if(tempCodePoint>2047&&(tempCodePoint<55296||tempCodePoint>57343)){codePoint=tempCodePoint}}break;case 4:secondByte=buf[i+1];thirdByte=buf[i+2];fourthByte=buf[i+3];if((secondByte&192)===128&&(thirdByte&192)===128&&(fourthByte&192)===128){tempCodePoint=(firstByte&15)<<18|(secondByte&63)<<12|(thirdByte&63)<<6|fourthByte&63;if(tempCodePoint>65535&&tempCodePoint<1114112){codePoint=tempCodePoint}}}}if(codePoint===null){codePoint=65533;bytesPerSequence=1}else if(codePoint>65535){codePoint-=65536;res.push(codePoint>>>10&1023|55296);codePoint=56320|codePoint&1023}res.push(codePoint);i+=bytesPerSequence}return decodeCodePointsArray(res)}var MAX_ARGUMENTS_LENGTH=4096;function decodeCodePointsArray(codePoints){var len=codePoints.length;if(len<=MAX_ARGUMENTS_LENGTH){return String.fromCharCode.apply(String,codePoints)}var res="";var i=0;while(i<len){res+=String.fromCharCode.apply(String,codePoints.slice(i,i+=MAX_ARGUMENTS_LENGTH))}return res}function asciiSlice(buf,start,end){var ret="";end=Math.min(buf.length,end);for(var i=start;i<end;++i){ret+=String.fromCharCode(buf[i]&127)}return ret}function latin1Slice(buf,start,end){var ret="";end=Math.min(buf.length,end);for(var i=start;i<end;++i){ret+=String.fromCharCode(buf[i])}return ret}function hexSlice(buf,start,end){var len=buf.length;if(!start||start<0)start=0;if(!end||end<0||end>len)end=len;var out="";for(var i=start;i<end;++i){out+=toHex(buf[i])}return out}function utf16leSlice(buf,start,end){var bytes=buf.slice(start,end);var res="";for(var i=0;i<bytes.length;i+=2){res+=String.fromCharCode(bytes[i]+bytes[i+1]*256)}return res}Buffer.prototype.slice=function slice(start,end){var len=this.length;start=~~start;end=end===undefined?len:~~end;if(start<0){start+=len;if(start<0)start=0}else if(start>len){start=len}if(end<0){end+=len;if(end<0)end=0}else if(end>len){end=len}if(end<start)end=start;var newBuf;if(Buffer.TYPED_ARRAY_SUPPORT){newBuf=this.subarray(start,end);newBuf.__proto__=Buffer.prototype}else{var sliceLen=end-start;newBuf=new Buffer(sliceLen,undefined);for(var i=0;i<sliceLen;++i){newBuf[i]=this[i+start]}}return newBuf};function checkOffset(offset,ext,length){if(offset%1!==0||offset<0)throw new RangeError("offset is not uint");if(offset+ext>length)throw new RangeError("Trying to access beyond buffer length")}Buffer.prototype.readUIntLE=function readUIntLE(offset,byteLength,noAssert){offset=offset|0;byteLength=byteLength|0;if(!noAssert)checkOffset(offset,byteLength,this.length);var val=this[offset];var mul=1;var i=0;while(++i<byteLength&&(mul*=256)){val+=this[offset+i]*mul}return val};Buffer.prototype.readUIntBE=function readUIntBE(offset,byteLength,noAssert){offset=offset|0;byteLength=byteLength|0;if(!noAssert){checkOffset(offset,byteLength,this.length)}var val=this[offset+--byteLength];var mul=1;while(byteLength>0&&(mul*=256)){val+=this[offset+--byteLength]*mul}return val};Buffer.prototype.readUInt8=function readUInt8(offset,noAssert){if(!noAssert)checkOffset(offset,1,this.length);return this[offset]};Buffer.prototype.readUInt16LE=function readUInt16LE(offset,noAssert){if(!noAssert)checkOffset(offset,2,this.length);return this[offset]|this[offset+1]<<8};Buffer.prototype.readUInt16BE=function readUInt16BE(offset,noAssert){if(!noAssert)checkOffset(offset,2,this.length);return this[offset]<<8|this[offset+1]};Buffer.prototype.readUInt32LE=function readUInt32LE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return(this[offset]|this[offset+1]<<8|this[offset+2]<<16)+this[offset+3]*16777216};Buffer.prototype.readUInt32BE=function readUInt32BE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return this[offset]*16777216+(this[offset+1]<<16|this[offset+2]<<8|this[offset+3])};Buffer.prototype.readIntLE=function readIntLE(offset,byteLength,noAssert){offset=offset|0;byteLength=byteLength|0;if(!noAssert)checkOffset(offset,byteLength,this.length);var val=this[offset];var mul=1;var i=0;while(++i<byteLength&&(mul*=256)){val+=this[offset+i]*mul}mul*=128;if(val>=mul)val-=Math.pow(2,8*byteLength);return val};Buffer.prototype.readIntBE=function readIntBE(offset,byteLength,noAssert){offset=offset|0;byteLength=byteLength|0;if(!noAssert)checkOffset(offset,byteLength,this.length);
+var i=byteLength;var mul=1;var val=this[offset+--i];while(i>0&&(mul*=256)){val+=this[offset+--i]*mul}mul*=128;if(val>=mul)val-=Math.pow(2,8*byteLength);return val};Buffer.prototype.readInt8=function readInt8(offset,noAssert){if(!noAssert)checkOffset(offset,1,this.length);if(!(this[offset]&128))return this[offset];return(255-this[offset]+1)*-1};Buffer.prototype.readInt16LE=function readInt16LE(offset,noAssert){if(!noAssert)checkOffset(offset,2,this.length);var val=this[offset]|this[offset+1]<<8;return val&32768?val|4294901760:val};Buffer.prototype.readInt16BE=function readInt16BE(offset,noAssert){if(!noAssert)checkOffset(offset,2,this.length);var val=this[offset+1]|this[offset]<<8;return val&32768?val|4294901760:val};Buffer.prototype.readInt32LE=function readInt32LE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return this[offset]|this[offset+1]<<8|this[offset+2]<<16|this[offset+3]<<24};Buffer.prototype.readInt32BE=function readInt32BE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return this[offset]<<24|this[offset+1]<<16|this[offset+2]<<8|this[offset+3]};Buffer.prototype.readFloatLE=function readFloatLE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return ieee754.read(this,offset,true,23,4)};Buffer.prototype.readFloatBE=function readFloatBE(offset,noAssert){if(!noAssert)checkOffset(offset,4,this.length);return ieee754.read(this,offset,false,23,4)};Buffer.prototype.readDoubleLE=function readDoubleLE(offset,noAssert){if(!noAssert)checkOffset(offset,8,this.length);return ieee754.read(this,offset,true,52,8)};Buffer.prototype.readDoubleBE=function readDoubleBE(offset,noAssert){if(!noAssert)checkOffset(offset,8,this.length);return ieee754.read(this,offset,false,52,8)};function checkInt(buf,value,offset,ext,max,min){if(!Buffer.isBuffer(buf))throw new TypeError('"buffer" argument must be a Buffer instance');if(value>max||value<min)throw new RangeError('"value" argument is out of bounds');if(offset+ext>buf.length)throw new RangeError("Index out of range")}Buffer.prototype.writeUIntLE=function writeUIntLE(value,offset,byteLength,noAssert){value=+value;offset=offset|0;byteLength=byteLength|0;if(!noAssert){var maxBytes=Math.pow(2,8*byteLength)-1;checkInt(this,value,offset,byteLength,maxBytes,0)}var mul=1;var i=0;this[offset]=value&255;while(++i<byteLength&&(mul*=256)){this[offset+i]=value/mul&255}return offset+byteLength};Buffer.prototype.writeUIntBE=function writeUIntBE(value,offset,byteLength,noAssert){value=+value;offset=offset|0;byteLength=byteLength|0;if(!noAssert){var maxBytes=Math.pow(2,8*byteLength)-1;checkInt(this,value,offset,byteLength,maxBytes,0)}var i=byteLength-1;var mul=1;this[offset+i]=value&255;while(--i>=0&&(mul*=256)){this[offset+i]=value/mul&255}return offset+byteLength};Buffer.prototype.writeUInt8=function writeUInt8(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,1,255,0);if(!Buffer.TYPED_ARRAY_SUPPORT)value=Math.floor(value);this[offset]=value&255;return offset+1};function objectWriteUInt16(buf,value,offset,littleEndian){if(value<0)value=65535+value+1;for(var i=0,j=Math.min(buf.length-offset,2);i<j;++i){buf[offset+i]=(value&255<<8*(littleEndian?i:1-i))>>>(littleEndian?i:1-i)*8}}Buffer.prototype.writeUInt16LE=function writeUInt16LE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,2,65535,0);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value&255;this[offset+1]=value>>>8}else{objectWriteUInt16(this,value,offset,true)}return offset+2};Buffer.prototype.writeUInt16BE=function writeUInt16BE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,2,65535,0);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value>>>8;this[offset+1]=value&255}else{objectWriteUInt16(this,value,offset,false)}return offset+2};function objectWriteUInt32(buf,value,offset,littleEndian){if(value<0)value=4294967295+value+1;for(var i=0,j=Math.min(buf.length-offset,4);i<j;++i){buf[offset+i]=value>>>(littleEndian?i:3-i)*8&255}}Buffer.prototype.writeUInt32LE=function writeUInt32LE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,4,4294967295,0);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset+3]=value>>>24;this[offset+2]=value>>>16;this[offset+1]=value>>>8;this[offset]=value&255}else{objectWriteUInt32(this,value,offset,true)}return offset+4};Buffer.prototype.writeUInt32BE=function writeUInt32BE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,4,4294967295,0);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value>>>24;this[offset+1]=value>>>16;this[offset+2]=value>>>8;this[offset+3]=value&255}else{objectWriteUInt32(this,value,offset,false)}return offset+4};Buffer.prototype.writeIntLE=function writeIntLE(value,offset,byteLength,noAssert){value=+value;offset=offset|0;if(!noAssert){var limit=Math.pow(2,8*byteLength-1);checkInt(this,value,offset,byteLength,limit-1,-limit)}var i=0;var mul=1;var sub=0;this[offset]=value&255;while(++i<byteLength&&(mul*=256)){if(value<0&&sub===0&&this[offset+i-1]!==0){sub=1}this[offset+i]=(value/mul>>0)-sub&255}return offset+byteLength};Buffer.prototype.writeIntBE=function writeIntBE(value,offset,byteLength,noAssert){value=+value;offset=offset|0;if(!noAssert){var limit=Math.pow(2,8*byteLength-1);checkInt(this,value,offset,byteLength,limit-1,-limit)}var i=byteLength-1;var mul=1;var sub=0;this[offset+i]=value&255;while(--i>=0&&(mul*=256)){if(value<0&&sub===0&&this[offset+i+1]!==0){sub=1}this[offset+i]=(value/mul>>0)-sub&255}return offset+byteLength};Buffer.prototype.writeInt8=function writeInt8(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,1,127,-128);if(!Buffer.TYPED_ARRAY_SUPPORT)value=Math.floor(value);if(value<0)value=255+value+1;this[offset]=value&255;return offset+1};Buffer.prototype.writeInt16LE=function writeInt16LE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,2,32767,-32768);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value&255;this[offset+1]=value>>>8}else{objectWriteUInt16(this,value,offset,true)}return offset+2};Buffer.prototype.writeInt16BE=function writeInt16BE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,2,32767,-32768);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value>>>8;this[offset+1]=value&255}else{objectWriteUInt16(this,value,offset,false)}return offset+2};Buffer.prototype.writeInt32LE=function writeInt32LE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,4,2147483647,-2147483648);if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value&255;this[offset+1]=value>>>8;this[offset+2]=value>>>16;this[offset+3]=value>>>24}else{objectWriteUInt32(this,value,offset,true)}return offset+4};Buffer.prototype.writeInt32BE=function writeInt32BE(value,offset,noAssert){value=+value;offset=offset|0;if(!noAssert)checkInt(this,value,offset,4,2147483647,-2147483648);if(value<0)value=4294967295+value+1;if(Buffer.TYPED_ARRAY_SUPPORT){this[offset]=value>>>24;this[offset+1]=value>>>16;this[offset+2]=value>>>8;this[offset+3]=value&255}else{objectWriteUInt32(this,value,offset,false)}return offset+4};function checkIEEE754(buf,value,offset,ext,max,min){if(offset+ext>buf.length)throw new RangeError("Index out of range");if(offset<0)throw new RangeError("Index out of range")}function writeFloat(buf,value,offset,littleEndian,noAssert){if(!noAssert){checkIEEE754(buf,value,offset,4,3.4028234663852886e38,-3.4028234663852886e38)}ieee754.write(buf,value,offset,littleEndian,23,4);return offset+4}Buffer.prototype.writeFloatLE=function writeFloatLE(value,offset,noAssert){return writeFloat(this,value,offset,true,noAssert)};Buffer.prototype.writeFloatBE=function writeFloatBE(value,offset,noAssert){return writeFloat(this,value,offset,false,noAssert)};function writeDouble(buf,value,offset,littleEndian,noAssert){if(!noAssert){checkIEEE754(buf,value,offset,8,1.7976931348623157e308,-1.7976931348623157e308)}ieee754.write(buf,value,offset,littleEndian,52,8);return offset+8}Buffer.prototype.writeDoubleLE=function writeDoubleLE(value,offset,noAssert){return writeDouble(this,value,offset,true,noAssert)};Buffer.prototype.writeDoubleBE=function writeDoubleBE(value,offset,noAssert){return writeDouble(this,value,offset,false,noAssert)};Buffer.prototype.copy=function copy(target,targetStart,start,end){if(!start)start=0;if(!end&&end!==0)end=this.length;if(targetStart>=target.length)targetStart=target.length;if(!targetStart)targetStart=0;if(end>0&&end<start)end=start;if(end===start)return 0;if(target.length===0||this.length===0)return 0;if(targetStart<0){throw new RangeError("targetStart out of bounds")}if(start<0||start>=this.length)throw new RangeError("sourceStart out of bounds");if(end<0)throw new RangeError("sourceEnd out of bounds");if(end>this.length)end=this.length;if(target.length-targetStart<end-start){end=target.length-targetStart+start}var len=end-start;var i;if(this===target&&start<targetStart&&targetStart<end){for(i=len-1;i>=0;--i){target[i+targetStart]=this[i+start]}}else if(len<1e3||!Buffer.TYPED_ARRAY_SUPPORT){for(i=0;i<len;++i){target[i+targetStart]=this[i+start]}}else{Uint8Array.prototype.set.call(target,this.subarray(start,start+len),targetStart)}return len};Buffer.prototype.fill=function fill(val,start,end,encoding){if(typeof val==="string"){if(typeof start==="string"){encoding=start;start=0;end=this.length}else if(typeof end==="string"){encoding=end;end=this.length}if(val.length===1){var code=val.charCodeAt(0);if(code<256){val=code}}if(encoding!==undefined&&typeof encoding!=="string"){throw new TypeError("encoding must be a string")}if(typeof encoding==="string"&&!Buffer.isEncoding(encoding)){throw new TypeError("Unknown encoding: "+encoding)}}else if(typeof val==="number"){val=val&255}if(start<0||this.length<start||this.length<end){throw new RangeError("Out of range index")}if(end<=start){return this}start=start>>>0;end=end===undefined?this.length:end>>>0;if(!val)val=0;var i;if(typeof val==="number"){for(i=start;i<end;++i){this[i]=val}}else{var bytes=Buffer.isBuffer(val)?val:utf8ToBytes(new Buffer(val,encoding).toString());var len=bytes.length;for(i=0;i<end-start;++i){this[i+start]=bytes[i%len]}}return this};var INVALID_BASE64_RE=/[^+\/0-9A-Za-z-_]/g;function base64clean(str){str=stringtrim(str).replace(INVALID_BASE64_RE,"");if(str.length<2)return"";while(str.length%4!==0){str=str+"="}return str}function stringtrim(str){if(str.trim)return str.trim();return str.replace(/^\s+|\s+$/g,"")}function toHex(n){if(n<16)return"0"+n.toString(16);return n.toString(16)}function utf8ToBytes(string,units){units=units||Infinity;var codePoint;var length=string.length;var leadSurrogate=null;var bytes=[];for(var i=0;i<length;++i){codePoint=string.charCodeAt(i);if(codePoint>55295&&codePoint<57344){if(!leadSurrogate){if(codePoint>56319){if((units-=3)>-1)bytes.push(239,191,189);continue}else if(i+1===length){if((units-=3)>-1)bytes.push(239,191,189);continue}leadSurrogate=codePoint;continue}if(codePoint<56320){if((units-=3)>-1)bytes.push(239,191,189);leadSurrogate=codePoint;continue}codePoint=(leadSurrogate-55296<<10|codePoint-56320)+65536}else if(leadSurrogate){if((units-=3)>-1)bytes.push(239,191,189)}leadSurrogate=null;if(codePoint<128){if((units-=1)<0)break;bytes.push(codePoint)}else if(codePoint<2048){if((units-=2)<0)break;bytes.push(codePoint>>6|192,codePoint&63|128)}else if(codePoint<65536){if((units-=3)<0)break;bytes.push(codePoint>>12|224,codePoint>>6&63|128,codePoint&63|128)}else if(codePoint<1114112){if((units-=4)<0)break;bytes.push(codePoint>>18|240,codePoint>>12&63|128,codePoint>>6&63|128,codePoint&63|128)}else{throw new Error("Invalid code point")}}return bytes}function asciiToBytes(str){var byteArray=[];for(var i=0;i<str.length;++i){byteArray.push(str.charCodeAt(i)&255)}return byteArray}function utf16leToBytes(str,units){var c,hi,lo;var byteArray=[];for(var i=0;i<str.length;++i){if((units-=2)<0)break;c=str.charCodeAt(i);hi=c>>8;lo=c%256;byteArray.push(lo);byteArray.push(hi)}return byteArray}function base64ToBytes(str){return base64.toByteArray(base64clean(str))}function blitBuffer(src,dst,offset,length){for(var i=0;i<length;++i){if(i+offset>=dst.length||i>=src.length)break;dst[i+offset]=src[i]}return i}function isnan(val){return val!==val}}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{"base64-js":2,ieee754:37,isarray:40}],6:[function(require,module,exports){(function(Buffer){function isArray(arg){if(Array.isArray){return Array.isArray(arg)}return objectToString(arg)==="[object Array]"}exports.isArray=isArray;function isBoolean(arg){return typeof arg==="boolean"}exports.isBoolean=isBoolean;function isNull(arg){return arg===null}exports.isNull=isNull;function isNullOrUndefined(arg){return arg==null}exports.isNullOrUndefined=isNullOrUndefined;function isNumber(arg){return typeof arg==="number"}exports.isNumber=isNumber;function isString(arg){return typeof arg==="string"}exports.isString=isString;function isSymbol(arg){return typeof arg==="symbol"}exports.isSymbol=isSymbol;function isUndefined(arg){return arg===void 0}exports.isUndefined=isUndefined;function isRegExp(re){return objectToString(re)==="[object RegExp]"}exports.isRegExp=isRegExp;function isObject(arg){return typeof arg==="object"&&arg!==null}exports.isObject=isObject;function isDate(d){return objectToString(d)==="[object Date]"}exports.isDate=isDate;function isError(e){return objectToString(e)==="[object Error]"||e instanceof Error}exports.isError=isError;function isFunction(arg){return typeof arg==="function"}exports.isFunction=isFunction;function isPrimitive(arg){return arg===null||typeof arg==="boolean"||typeof arg==="number"||typeof arg==="string"||typeof arg==="symbol"||typeof arg==="undefined"}exports.isPrimitive=isPrimitive;exports.isBuffer=Buffer.isBuffer;function objectToString(o){return Object.prototype.toString.call(o)}}).call(this,{isBuffer:require("../../is-buffer/index.js")})},{"../../is-buffer/index.js":39}],7:[function(require,module,exports){var ElementType=require("domelementtype");var entities=require("entities");var booleanAttributes={__proto__:null,allowfullscreen:true,async:true,autofocus:true,autoplay:true,checked:true,controls:true,default:true,defer:true,disabled:true,hidden:true,ismap:true,loop:true,multiple:true,muted:true,open:true,readonly:true,required:true,reversed:true,scoped:true,seamless:true,selected:true,typemustmatch:true};var unencodedElements={__proto__:null,style:true,script:true,xmp:true,iframe:true,noembed:true,noframes:true,plaintext:true,noscript:true};function formatAttrs(attributes,opts){if(!attributes)return;var output="",value;for(var key in attributes){value=attributes[key];if(output){output+=" "}if(!value&&booleanAttributes[key]){output+=key}else{output+=key+'="'+(opts.decodeEntities?entities.encodeXML(value):value)+'"'}}return output}var singleTag={__proto__:null,area:true,base:true,basefont:true,br:true,col:true,command:true,embed:true,frame:true,hr:true,img:true,input:true,isindex:true,keygen:true,link:true,meta:true,param:true,source:true,track:true,wbr:true};var render=module.exports=function(dom,opts){if(!Array.isArray(dom)&&!dom.cheerio)dom=[dom];opts=opts||{};var output="";for(var i=0;i<dom.length;i++){var elem=dom[i];if(elem.type==="root")output+=render(elem.children,opts);else if(ElementType.isTag(elem))output+=renderTag(elem,opts);else if(elem.type===ElementType.Directive)output+=renderDirective(elem);else if(elem.type===ElementType.Comment)output+=renderComment(elem);else if(elem.type===ElementType.CDATA)output+=renderCdata(elem);else output+=renderText(elem,opts)}return output};function renderTag(elem,opts){if(elem.name==="svg")opts={decodeEntities:opts.decodeEntities,xmlMode:true};var tag="<"+elem.name,attribs=formatAttrs(elem.attribs,opts);if(attribs){tag+=" "+attribs}if(opts.xmlMode&&(!elem.children||elem.children.length===0)){tag+="/>"}else{tag+=">";if(elem.children){tag+=render(elem.children,opts)}if(!singleTag[elem.name]||opts.xmlMode){tag+="</"+elem.name+">"}}return tag}function renderDirective(elem){return"<"+elem.data+">"}function renderText(elem,opts){var data=elem.data||"";if(opts.decodeEntities&&!(elem.parent&&elem.parent.name in unencodedElements)){data=entities.encodeXML(data)}return data}function renderCdata(elem){return"<![CDATA["+elem.children[0].data+"]]>"}function renderComment(elem){return"<!--"+elem.data+"-->"}},{domelementtype:8,entities:20}],8:[function(require,module,exports){module.exports={Text:"text",Directive:"directive",Comment:"comment",Script:"script",Style:"style",Tag:"tag",CDATA:"cdata",isTag:function(elem){return elem.type==="tag"||elem.type==="script"||elem.type==="style"}}},{}],9:[function(require,module,exports){module.exports={Text:"text",Directive:"directive",Comment:"comment",Script:"script",Style:"style",Tag:"tag",CDATA:"cdata",Doctype:"doctype",isTag:function(elem){return elem.type==="tag"||elem.type==="script"||elem.type==="style"}}},{}],10:[function(require,module,exports){var ElementType=require("domelementtype");var re_whitespace=/\s+/g;var NodePrototype=require("./lib/node");var ElementPrototype=require("./lib/element");function DomHandler(callback,options,elementCB){if(typeof callback==="object"){elementCB=options;options=callback;callback=null}else if(typeof options==="function"){elementCB=options;options=defaultOpts}this._callback=callback;this._options=options||defaultOpts;this._elementCB=elementCB;this.dom=[];this._done=false;this._tagStack=[];this._parser=this._parser||null}var defaultOpts={normalizeWhitespace:false,withStartIndices:false};DomHandler.prototype.onparserinit=function(parser){this._parser=parser};DomHandler.prototype.onreset=function(){DomHandler.call(this,this._callback,this._options,this._elementCB)};DomHandler.prototype.onend=function(){if(this._done)return;this._done=true;this._parser=null;this._handleCallback(null)};DomHandler.prototype._handleCallback=DomHandler.prototype.onerror=function(error){if(typeof this._callback==="function"){this._callback(error,this.dom)}else{if(error)throw error}};DomHandler.prototype.onclosetag=function(){var elem=this._tagStack.pop();if(this._elementCB)this._elementCB(elem)};DomHandler.prototype._addDomElement=function(element){var parent=this._tagStack[this._tagStack.length-1];var siblings=parent?parent.children:this.dom;var previousSibling=siblings[siblings.length-1];element.next=null;if(this._options.withStartIndices){element.startIndex=this._parser.startIndex}if(this._options.withDomLvl1){element.__proto__=element.type==="tag"?ElementPrototype:NodePrototype}if(previousSibling){element.prev=previousSibling;previousSibling.next=element}else{element.prev=null}siblings.push(element);element.parent=parent||null};DomHandler.prototype.onopentag=function(name,attribs){var element={type:name==="script"?ElementType.Script:name==="style"?ElementType.Style:ElementType.Tag,name:name,attribs:attribs,children:[]};this._addDomElement(element);this._tagStack.push(element)};DomHandler.prototype.ontext=function(data){var normalize=this._options.normalizeWhitespace||this._options.ignoreWhitespace;var lastTag;if(!this._tagStack.length&&this.dom.length&&(lastTag=this.dom[this.dom.length-1]).type===ElementType.Text){if(normalize){lastTag.data=(lastTag.data+data).replace(re_whitespace," ")}else{lastTag.data+=data}}else{if(this._tagStack.length&&(lastTag=this._tagStack[this._tagStack.length-1])&&(lastTag=lastTag.children[lastTag.children.length-1])&&lastTag.type===ElementType.Text){if(normalize){lastTag.data=(lastTag.data+data).replace(re_whitespace," ")}else{lastTag.data+=data}}else{if(normalize){data=data.replace(re_whitespace," ")}this._addDomElement({data:data,type:ElementType.Text})}}};DomHandler.prototype.oncomment=function(data){var lastTag=this._tagStack[this._tagStack.length-1];if(lastTag&&lastTag.type===ElementType.Comment){lastTag.data+=data;return}var element={data:data,type:ElementType.Comment};this._addDomElement(element);this._tagStack.push(element)};DomHandler.prototype.oncdatastart=function(){var element={children:[{data:"",type:ElementType.Text}],type:ElementType.CDATA};this._addDomElement(element);this._tagStack.push(element)};DomHandler.prototype.oncommentend=DomHandler.prototype.oncdataend=function(){this._tagStack.pop()};DomHandler.prototype.onprocessinginstruction=function(name,data){this._addDomElement({name:name,data:data,type:ElementType.Directive})};module.exports=DomHandler},{"./lib/element":11,"./lib/node":12,domelementtype:9}],11:[function(require,module,exports){var NodePrototype=require("./node");var ElementPrototype=module.exports=Object.create(NodePrototype);var domLvl1={tagName:"name"};Object.keys(domLvl1).forEach(function(key){var shorthand=domLvl1[key];Object.defineProperty(ElementPrototype,key,{get:function(){return this[shorthand]||null},set:function(val){this[shorthand]=val;return val}})})},{"./node":12}],12:[function(require,module,exports){var NodePrototype=module.exports={get firstChild(){var children=this.children;return children&&children[0]||null},get lastChild(){var children=this.children;return children&&children[children.length-1]||null},get nodeType(){return nodeTypes[this.type]||nodeTypes.element}};var domLvl1={tagName:"name",childNodes:"children",parentNode:"parent",previousSibling:"prev",nextSibling:"next",nodeValue:"data"};var nodeTypes={element:1,text:3,cdata:4,comment:8};Object.keys(domLvl1).forEach(function(key){var shorthand=domLvl1[key];Object.defineProperty(NodePrototype,key,{get:function(){return this[shorthand]||null},set:function(val){this[shorthand]=val;return val}})})},{}],13:[function(require,module,exports){var DomUtils=module.exports;[require("./lib/stringify"),require("./lib/traversal"),require("./lib/manipulation"),require("./lib/querying"),require("./lib/legacy"),require("./lib/helpers")].forEach(function(ext){Object.keys(ext).forEach(function(key){DomUtils[key]=ext[key].bind(DomUtils)})})},{"./lib/helpers":14,"./lib/legacy":15,"./lib/manipulation":16,"./lib/querying":17,"./lib/stringify":18,"./lib/traversal":19}],14:[function(require,module,exports){exports.removeSubsets=function(nodes){var idx=nodes.length,node,ancestor,replace;while(--idx>-1){node=ancestor=nodes[idx];nodes[idx]=null;replace=true;while(ancestor){if(nodes.indexOf(ancestor)>-1){replace=false;nodes.splice(idx,1);break}ancestor=ancestor.parent}if(replace){nodes[idx]=node}}return nodes};var POSITION={DISCONNECTED:1,PRECEDING:2,FOLLOWING:4,CONTAINS:8,CONTAINED_BY:16};var comparePos=exports.compareDocumentPosition=function(nodeA,nodeB){var aParents=[];var bParents=[];var current,sharedParent,siblings,aSibling,bSibling,idx;if(nodeA===nodeB){return 0}current=nodeA;while(current){aParents.unshift(current);current=current.parent}current=nodeB;while(current){bParents.unshift(current);current=current.parent}idx=0;while(aParents[idx]===bParents[idx]){idx++}if(idx===0){return POSITION.DISCONNECTED}sharedParent=aParents[idx-1];siblings=sharedParent.children;aSibling=aParents[idx];bSibling=bParents[idx];if(siblings.indexOf(aSibling)>siblings.indexOf(bSibling)){if(sharedParent===nodeB){return POSITION.FOLLOWING|POSITION.CONTAINED_BY}return POSITION.FOLLOWING}else{if(sharedParent===nodeA){return POSITION.PRECEDING|POSITION.CONTAINS}return POSITION.PRECEDING}};exports.uniqueSort=function(nodes){var idx=nodes.length,node,position;nodes=nodes.slice();while(--idx>-1){node=nodes[idx];position=nodes.indexOf(node);if(position>-1&&position<idx){nodes.splice(idx,1)}}nodes.sort(function(a,b){var relative=comparePos(a,b);if(relative&POSITION.PRECEDING){return-1}else if(relative&POSITION.FOLLOWING){return 1}return 0});return nodes}},{}],15:[function(require,module,exports){var ElementType=require("domelementtype");var isTag=exports.isTag=ElementType.isTag;exports.testElement=function(options,element){for(var key in options){if(!options.hasOwnProperty(key));else if(key==="tag_name"){if(!isTag(element)||!options.tag_name(element.name)){return false}}else if(key==="tag_type"){if(!options.tag_type(element.type))return false}else if(key==="tag_contains"){if(isTag(element)||!options.tag_contains(element.data)){return false}}else if(!element.attribs||!options[key](element.attribs[key])){return false}}return true};var Checks={tag_name:function(name){if(typeof name==="function"){return function(elem){return isTag(elem)&&name(elem.name)}}else if(name==="*"){return isTag}else{return function(elem){return isTag(elem)&&elem.name===name}}},tag_type:function(type){if(typeof type==="function"){return function(elem){return type(elem.type)}}else{return function(elem){return elem.type===type}}},tag_contains:function(data){if(typeof data==="function"){return function(elem){return!isTag(elem)&&data(elem.data)}}else{return function(elem){return!isTag(elem)&&elem.data===data}}}};function getAttribCheck(attrib,value){if(typeof value==="function"){return function(elem){return elem.attribs&&value(elem.attribs[attrib])}}else{return function(elem){return elem.attribs&&elem.attribs[attrib]===value}}}function combineFuncs(a,b){return function(elem){return a(elem)||b(elem)}}exports.getElements=function(options,element,recurse,limit){var funcs=Object.keys(options).map(function(key){var value=options[key];return key in Checks?Checks[key](value):getAttribCheck(key,value)});return funcs.length===0?[]:this.filter(funcs.reduce(combineFuncs),element,recurse,limit)};exports.getElementById=function(id,element,recurse){if(!Array.isArray(element))element=[element];return this.findOne(getAttribCheck("id",id),element,recurse!==false)};exports.getElementsByTagName=function(name,element,recurse,limit){return this.filter(Checks.tag_name(name),element,recurse,limit)};exports.getElementsByTagType=function(type,element,recurse,limit){return this.filter(Checks.tag_type(type),element,recurse,limit)}},{domelementtype:9}],16:[function(require,module,exports){exports.removeElement=function(elem){if(elem.prev)elem.prev.next=elem.next;if(elem.next)elem.next.prev=elem.prev;if(elem.parent){var childs=elem.parent.children;childs.splice(childs.lastIndexOf(elem),1)}};exports.replaceElement=function(elem,replacement){var prev=replacement.prev=elem.prev;if(prev){prev.next=replacement}var next=replacement.next=elem.next;if(next){next.prev=replacement}var parent=replacement.parent=elem.parent;if(parent){var childs=parent.children;childs[childs.lastIndexOf(elem)]=replacement}};exports.appendChild=function(elem,child){child.parent=elem;if(elem.children.push(child)!==1){var sibling=elem.children[elem.children.length-2];sibling.next=child;child.prev=sibling;child.next=null}};exports.append=function(elem,next){var parent=elem.parent,currNext=elem.next;next.next=currNext;next.prev=elem;elem.next=next;next.parent=parent;if(currNext){currNext.prev=next;if(parent){var childs=parent.children;childs.splice(childs.lastIndexOf(currNext),0,next)}}else if(parent){parent.children.push(next)}};exports.prepend=function(elem,prev){var parent=elem.parent;if(parent){var childs=parent.children;childs.splice(childs.lastIndexOf(elem),0,prev)}if(elem.prev){elem.prev.next=prev}prev.parent=parent;prev.prev=elem.prev;prev.next=elem;elem.prev=prev}},{}],17:[function(require,module,exports){var isTag=require("domelementtype").isTag;module.exports={filter:filter,find:find,findOneChild:findOneChild,findOne:findOne,existsOne:existsOne,findAll:findAll};function filter(test,element,recurse,limit){if(!Array.isArray(element))element=[element];if(typeof limit!=="number"||!isFinite(limit)){limit=Infinity}return find(test,element,recurse!==false,limit)}function find(test,elems,recurse,limit){var result=[],childs;for(var i=0,j=elems.length;i<j;i++){if(test(elems[i])){result.push(elems[i]);if(--limit<=0)break}childs=elems[i].children;if(recurse&&childs&&childs.length>0){childs=find(test,childs,recurse,limit);result=result.concat(childs);limit-=childs.length;if(limit<=0)break}}return result}function findOneChild(test,elems){for(var i=0,l=elems.length;i<l;i++){if(test(elems[i]))return elems[i]}return null}function findOne(test,elems){var elem=null;for(var i=0,l=elems.length;i<l&&!elem;i++){if(!isTag(elems[i])){continue}else if(test(elems[i])){elem=elems[i]}else if(elems[i].children.length>0){elem=findOne(test,elems[i].children)}}return elem}function existsOne(test,elems){for(var i=0,l=elems.length;i<l;i++){if(isTag(elems[i])&&(test(elems[i])||elems[i].children.length>0&&existsOne(test,elems[i].children))){return true}}return false}function findAll(test,elems){var result=[];for(var i=0,j=elems.length;i<j;i++){if(!isTag(elems[i]))continue;if(test(elems[i]))result.push(elems[i]);if(elems[i].children.length>0){result=result.concat(findAll(test,elems[i].children))}}return result}},{domelementtype:9}],18:[function(require,module,exports){var ElementType=require("domelementtype"),getOuterHTML=require("dom-serializer"),isTag=ElementType.isTag;module.exports={getInnerHTML:getInnerHTML,getOuterHTML:getOuterHTML,getText:getText};function getInnerHTML(elem,opts){return elem.children?elem.children.map(function(elem){return getOuterHTML(elem,opts)}).join(""):""}function getText(elem){if(Array.isArray(elem))return elem.map(getText).join("");if(isTag(elem)||elem.type===ElementType.CDATA)return getText(elem.children);if(elem.type===ElementType.Text)return elem.data;return""}},{"dom-serializer":7,domelementtype:9}],19:[function(require,module,exports){var getChildren=exports.getChildren=function(elem){return elem.children};var getParent=exports.getParent=function(elem){return elem.parent};exports.getSiblings=function(elem){var parent=getParent(elem);return parent?getChildren(parent):[elem]};exports.getAttributeValue=function(elem,name){return elem.attribs&&elem.attribs[name]};exports.hasAttrib=function(elem,name){return!!elem.attribs&&hasOwnProperty.call(elem.attribs,name)};exports.getName=function(elem){return elem.name}},{}],20:[function(require,module,exports){var encode=require("./lib/encode.js"),decode=require("./lib/decode.js");exports.decode=function(data,level){return(!level||level<=0?decode.XML:decode.HTML)(data)};exports.decodeStrict=function(data,level){return(!level||level<=0?decode.XML:decode.HTMLStrict)(data)};exports.encode=function(data,level){return(!level||level<=0?encode.XML:encode.HTML)(data)};exports.encodeXML=encode.XML;exports.encodeHTML4=exports.encodeHTML5=exports.encodeHTML=encode.HTML;exports.decodeXML=exports.decodeXMLStrict=decode.XML;exports.decodeHTML4=exports.decodeHTML5=exports.decodeHTML=decode.HTML;exports.decodeHTML4Strict=exports.decodeHTML5Strict=exports.decodeHTMLStrict=decode.HTMLStrict;exports.escape=encode.escape},{"./lib/decode.js":21,"./lib/encode.js":23}],21:[function(require,module,exports){var entityMap=require("../maps/entities.json"),legacyMap=require("../maps/legacy.json"),xmlMap=require("../maps/xml.json"),decodeCodePoint=require("./decode_codepoint.js");var decodeXMLStrict=getStrictDecoder(xmlMap),decodeHTMLStrict=getStrictDecoder(entityMap);function getStrictDecoder(map){var keys=Object.keys(map).join("|"),replace=getReplacer(map);keys+="|#[xX][\\da-fA-F]+|#\\d+";var re=new RegExp("&(?:"+keys+");","g");return function(str){return String(str).replace(re,replace)}}var decodeHTML=function(){var legacy=Object.keys(legacyMap).sort(sorter);var keys=Object.keys(entityMap).sort(sorter);for(var i=0,j=0;i<keys.length;i++){if(legacy[j]===keys[i]){keys[i]+=";?";j++}else{keys[i]+=";"}}var re=new RegExp("&(?:"+keys.join("|")+"|#[xX][\\da-fA-F]+;?|#\\d+;?)","g"),replace=getReplacer(entityMap);function replacer(str){if(str.substr(-1)!==";")str+=";";return replace(str)}return function(str){return String(str).replace(re,replacer)}}();function sorter(a,b){return a<b?1:-1}function getReplacer(map){return function replace(str){if(str.charAt(1)==="#"){if(str.charAt(2)==="X"||str.charAt(2)==="x"){return decodeCodePoint(parseInt(str.substr(3),16))}return decodeCodePoint(parseInt(str.substr(2),10))}return map[str.slice(1,-1)];
+}}module.exports={XML:decodeXMLStrict,HTML:decodeHTML,HTMLStrict:decodeHTMLStrict}},{"../maps/entities.json":25,"../maps/legacy.json":26,"../maps/xml.json":27,"./decode_codepoint.js":22}],22:[function(require,module,exports){var decodeMap=require("../maps/decode.json");module.exports=decodeCodePoint;function decodeCodePoint(codePoint){if(codePoint>=55296&&codePoint<=57343||codePoint>1114111){return"�"}if(codePoint in decodeMap){codePoint=decodeMap[codePoint]}var output="";if(codePoint>65535){codePoint-=65536;output+=String.fromCharCode(codePoint>>>10&1023|55296);codePoint=56320|codePoint&1023}output+=String.fromCharCode(codePoint);return output}},{"../maps/decode.json":24}],23:[function(require,module,exports){var inverseXML=getInverseObj(require("../maps/xml.json")),xmlReplacer=getInverseReplacer(inverseXML);exports.XML=getInverse(inverseXML,xmlReplacer);var inverseHTML=getInverseObj(require("../maps/entities.json")),htmlReplacer=getInverseReplacer(inverseHTML);exports.HTML=getInverse(inverseHTML,htmlReplacer);function getInverseObj(obj){return Object.keys(obj).sort().reduce(function(inverse,name){inverse[obj[name]]="&"+name+";";return inverse},{})}function getInverseReplacer(inverse){var single=[],multiple=[];Object.keys(inverse).forEach(function(k){if(k.length===1){single.push("\\"+k)}else{multiple.push(k)}});multiple.unshift("["+single.join("")+"]");return new RegExp(multiple.join("|"),"g")}var re_nonASCII=/[^\0-\x7F]/g,re_astralSymbols=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g;function singleCharReplacer(c){return"&#x"+c.charCodeAt(0).toString(16).toUpperCase()+";"}function astralReplacer(c){var high=c.charCodeAt(0);var low=c.charCodeAt(1);var codePoint=(high-55296)*1024+low-56320+65536;return"&#x"+codePoint.toString(16).toUpperCase()+";"}function getInverse(inverse,re){function func(name){return inverse[name]}return function(data){return data.replace(re,func).replace(re_astralSymbols,astralReplacer).replace(re_nonASCII,singleCharReplacer)}}var re_xmlChars=getInverseReplacer(inverseXML);function escapeXML(data){return data.replace(re_xmlChars,singleCharReplacer).replace(re_astralSymbols,astralReplacer).replace(re_nonASCII,singleCharReplacer)}exports.escape=escapeXML},{"../maps/entities.json":25,"../maps/xml.json":27}],24:[function(require,module,exports){module.exports={0:65533,128:8364,130:8218,131:402,132:8222,133:8230,134:8224,135:8225,136:710,137:8240,138:352,139:8249,140:338,142:381,145:8216,146:8217,147:8220,148:8221,149:8226,150:8211,151:8212,152:732,153:8482,154:353,155:8250,156:339,158:382,159:376}},{}],25:[function(require,module,exports){module.exports={Aacute:"Á",aacute:"á",Abreve:"Ă",abreve:"ă",ac:"∾",acd:"∿",acE:"∾̳",Acirc:"Â",acirc:"â",acute:"´",Acy:"А",acy:"а",AElig:"Æ",aelig:"æ",af:"⁡",Afr:"𝔄",afr:"𝔞",Agrave:"À",agrave:"à",alefsym:"ℵ",aleph:"ℵ",Alpha:"Α",alpha:"α",Amacr:"Ā",amacr:"ā",amalg:"⨿",amp:"&",AMP:"&",andand:"⩕",And:"⩓",and:"∧",andd:"⩜",andslope:"⩘",andv:"⩚",ang:"∠",ange:"⦤",angle:"∠",angmsdaa:"⦨",angmsdab:"⦩",angmsdac:"⦪",angmsdad:"⦫",angmsdae:"⦬",angmsdaf:"⦭",angmsdag:"⦮",angmsdah:"⦯",angmsd:"∡",angrt:"∟",angrtvb:"⊾",angrtvbd:"⦝",angsph:"∢",angst:"Å",angzarr:"⍼",Aogon:"Ą",aogon:"ą",Aopf:"𝔸",aopf:"𝕒",apacir:"⩯",ap:"≈",apE:"⩰",ape:"≊",apid:"≋",apos:"'",ApplyFunction:"⁡",approx:"≈",approxeq:"≊",Aring:"Å",aring:"å",Ascr:"𝒜",ascr:"𝒶",Assign:"≔",ast:"*",asymp:"≈",asympeq:"≍",Atilde:"Ã",atilde:"ã",Auml:"Ä",auml:"ä",awconint:"∳",awint:"⨑",backcong:"≌",backepsilon:"϶",backprime:"‵",backsim:"∽",backsimeq:"⋍",Backslash:"∖",Barv:"⫧",barvee:"⊽",barwed:"⌅",Barwed:"⌆",barwedge:"⌅",bbrk:"⎵",bbrktbrk:"⎶",bcong:"≌",Bcy:"Б",bcy:"б",bdquo:"„",becaus:"∵",because:"∵",Because:"∵",bemptyv:"⦰",bepsi:"϶",bernou:"ℬ",Bernoullis:"ℬ",Beta:"Β",beta:"β",beth:"ℶ",between:"≬",Bfr:"𝔅",bfr:"𝔟",bigcap:"⋂",bigcirc:"◯",bigcup:"⋃",bigodot:"⨀",bigoplus:"⨁",bigotimes:"⨂",bigsqcup:"⨆",bigstar:"★",bigtriangledown:"▽",bigtriangleup:"△",biguplus:"⨄",bigvee:"⋁",bigwedge:"⋀",bkarow:"⤍",blacklozenge:"⧫",blacksquare:"▪",blacktriangle:"▴",blacktriangledown:"▾",blacktriangleleft:"◂",blacktriangleright:"▸",blank:"␣",blk12:"▒",blk14:"░",blk34:"▓",block:"█",bne:"=⃥",bnequiv:"≡⃥",bNot:"⫭",bnot:"⌐",Bopf:"𝔹",bopf:"𝕓",bot:"⊥",bottom:"⊥",bowtie:"⋈",boxbox:"⧉",boxdl:"┐",boxdL:"╕",boxDl:"╖",boxDL:"╗",boxdr:"┌",boxdR:"╒",boxDr:"╓",boxDR:"╔",boxh:"─",boxH:"═",boxhd:"┬",boxHd:"╤",boxhD:"╥",boxHD:"╦",boxhu:"┴",boxHu:"╧",boxhU:"╨",boxHU:"╩",boxminus:"⊟",boxplus:"⊞",boxtimes:"⊠",boxul:"┘",boxuL:"╛",boxUl:"╜",boxUL:"╝",boxur:"└",boxuR:"╘",boxUr:"╙",boxUR:"╚",boxv:"│",boxV:"║",boxvh:"┼",boxvH:"╪",boxVh:"╫",boxVH:"╬",boxvl:"┤",boxvL:"╡",boxVl:"╢",boxVL:"╣",boxvr:"├",boxvR:"╞",boxVr:"╟",boxVR:"╠",bprime:"‵",breve:"˘",Breve:"˘",brvbar:"¦",bscr:"𝒷",Bscr:"ℬ",bsemi:"⁏",bsim:"∽",bsime:"⋍",bsolb:"⧅",bsol:"\\",bsolhsub:"⟈",bull:"•",bullet:"•",bump:"≎",bumpE:"⪮",bumpe:"≏",Bumpeq:"≎",bumpeq:"≏",Cacute:"Ć",cacute:"ć",capand:"⩄",capbrcup:"⩉",capcap:"⩋",cap:"∩",Cap:"⋒",capcup:"⩇",capdot:"⩀",CapitalDifferentialD:"ⅅ",caps:"∩︀",caret:"⁁",caron:"ˇ",Cayleys:"ℭ",ccaps:"⩍",Ccaron:"Č",ccaron:"č",Ccedil:"Ç",ccedil:"ç",Ccirc:"Ĉ",ccirc:"ĉ",Cconint:"∰",ccups:"⩌",ccupssm:"⩐",Cdot:"Ċ",cdot:"ċ",cedil:"¸",Cedilla:"¸",cemptyv:"⦲",cent:"¢",centerdot:"·",CenterDot:"·",cfr:"𝔠",Cfr:"ℭ",CHcy:"Ч",chcy:"ч",check:"✓",checkmark:"✓",Chi:"Χ",chi:"χ",circ:"ˆ",circeq:"≗",circlearrowleft:"↺",circlearrowright:"↻",circledast:"⊛",circledcirc:"⊚",circleddash:"⊝",CircleDot:"⊙",circledR:"®",circledS:"Ⓢ",CircleMinus:"⊖",CirclePlus:"⊕",CircleTimes:"⊗",cir:"○",cirE:"⧃",cire:"≗",cirfnint:"⨐",cirmid:"⫯",cirscir:"⧂",ClockwiseContourIntegral:"∲",CloseCurlyDoubleQuote:"”",CloseCurlyQuote:"’",clubs:"♣",clubsuit:"♣",colon:":",Colon:"∷",Colone:"⩴",colone:"≔",coloneq:"≔",comma:",",commat:"@",comp:"∁",compfn:"∘",complement:"∁",complexes:"ℂ",cong:"≅",congdot:"⩭",Congruent:"≡",conint:"∮",Conint:"∯",ContourIntegral:"∮",copf:"𝕔",Copf:"ℂ",coprod:"∐",Coproduct:"∐",copy:"©",COPY:"©",copysr:"℗",CounterClockwiseContourIntegral:"∳",crarr:"↵",cross:"✗",Cross:"⨯",Cscr:"𝒞",cscr:"𝒸",csub:"⫏",csube:"⫑",csup:"⫐",csupe:"⫒",ctdot:"⋯",cudarrl:"⤸",cudarrr:"⤵",cuepr:"⋞",cuesc:"⋟",cularr:"↶",cularrp:"⤽",cupbrcap:"⩈",cupcap:"⩆",CupCap:"≍",cup:"∪",Cup:"⋓",cupcup:"⩊",cupdot:"⊍",cupor:"⩅",cups:"∪︀",curarr:"↷",curarrm:"⤼",curlyeqprec:"⋞",curlyeqsucc:"⋟",curlyvee:"⋎",curlywedge:"⋏",curren:"¤",curvearrowleft:"↶",curvearrowright:"↷",cuvee:"⋎",cuwed:"⋏",cwconint:"∲",cwint:"∱",cylcty:"⌭",dagger:"†",Dagger:"‡",daleth:"ℸ",darr:"↓",Darr:"↡",dArr:"⇓",dash:"‐",Dashv:"⫤",dashv:"⊣",dbkarow:"⤏",dblac:"˝",Dcaron:"Ď",dcaron:"ď",Dcy:"Д",dcy:"д",ddagger:"‡",ddarr:"⇊",DD:"ⅅ",dd:"ⅆ",DDotrahd:"⤑",ddotseq:"⩷",deg:"°",Del:"∇",Delta:"Δ",delta:"δ",demptyv:"⦱",dfisht:"⥿",Dfr:"𝔇",dfr:"𝔡",dHar:"⥥",dharl:"⇃",dharr:"⇂",DiacriticalAcute:"´",DiacriticalDot:"˙",DiacriticalDoubleAcute:"˝",DiacriticalGrave:"`",DiacriticalTilde:"˜",diam:"⋄",diamond:"⋄",Diamond:"⋄",diamondsuit:"♦",diams:"♦",die:"¨",DifferentialD:"ⅆ",digamma:"ϝ",disin:"⋲",div:"÷",divide:"÷",divideontimes:"⋇",divonx:"⋇",DJcy:"Ђ",djcy:"ђ",dlcorn:"⌞",dlcrop:"⌍",dollar:"$",Dopf:"𝔻",dopf:"𝕕",Dot:"¨",dot:"˙",DotDot:"⃜",doteq:"≐",doteqdot:"≑",DotEqual:"≐",dotminus:"∸",dotplus:"∔",dotsquare:"⊡",doublebarwedge:"⌆",DoubleContourIntegral:"∯",DoubleDot:"¨",DoubleDownArrow:"⇓",DoubleLeftArrow:"⇐",DoubleLeftRightArrow:"⇔",DoubleLeftTee:"⫤",DoubleLongLeftArrow:"⟸",DoubleLongLeftRightArrow:"⟺",DoubleLongRightArrow:"⟹",DoubleRightArrow:"⇒",DoubleRightTee:"⊨",DoubleUpArrow:"⇑",DoubleUpDownArrow:"⇕",DoubleVerticalBar:"∥",DownArrowBar:"⤓",downarrow:"↓",DownArrow:"↓",Downarrow:"⇓",DownArrowUpArrow:"⇵",DownBreve:"̑",downdownarrows:"⇊",downharpoonleft:"⇃",downharpoonright:"⇂",DownLeftRightVector:"⥐",DownLeftTeeVector:"⥞",DownLeftVectorBar:"⥖",DownLeftVector:"↽",DownRightTeeVector:"⥟",DownRightVectorBar:"⥗",DownRightVector:"⇁",DownTeeArrow:"↧",DownTee:"⊤",drbkarow:"⤐",drcorn:"⌟",drcrop:"⌌",Dscr:"𝒟",dscr:"𝒹",DScy:"Ѕ",dscy:"ѕ",dsol:"⧶",Dstrok:"Đ",dstrok:"đ",dtdot:"⋱",dtri:"▿",dtrif:"▾",duarr:"⇵",duhar:"⥯",dwangle:"⦦",DZcy:"Џ",dzcy:"џ",dzigrarr:"⟿",Eacute:"É",eacute:"é",easter:"⩮",Ecaron:"Ě",ecaron:"ě",Ecirc:"Ê",ecirc:"ê",ecir:"≖",ecolon:"≕",Ecy:"Э",ecy:"э",eDDot:"⩷",Edot:"Ė",edot:"ė",eDot:"≑",ee:"ⅇ",efDot:"≒",Efr:"𝔈",efr:"𝔢",eg:"⪚",Egrave:"È",egrave:"è",egs:"⪖",egsdot:"⪘",el:"⪙",Element:"∈",elinters:"⏧",ell:"ℓ",els:"⪕",elsdot:"⪗",Emacr:"Ē",emacr:"ē",empty:"∅",emptyset:"∅",EmptySmallSquare:"◻",emptyv:"∅",EmptyVerySmallSquare:"▫",emsp13:" ",emsp14:" ",emsp:" ",ENG:"Ŋ",eng:"ŋ",ensp:" ",Eogon:"Ę",eogon:"ę",Eopf:"𝔼",eopf:"𝕖",epar:"⋕",eparsl:"⧣",eplus:"⩱",epsi:"ε",Epsilon:"Ε",epsilon:"ε",epsiv:"ϵ",eqcirc:"≖",eqcolon:"≕",eqsim:"≂",eqslantgtr:"⪖",eqslantless:"⪕",Equal:"⩵",equals:"=",EqualTilde:"≂",equest:"≟",Equilibrium:"⇌",equiv:"≡",equivDD:"⩸",eqvparsl:"⧥",erarr:"⥱",erDot:"≓",escr:"ℯ",Escr:"ℰ",esdot:"≐",Esim:"⩳",esim:"≂",Eta:"Η",eta:"η",ETH:"Ð",eth:"ð",Euml:"Ë",euml:"ë",euro:"€",excl:"!",exist:"∃",Exists:"∃",expectation:"ℰ",exponentiale:"ⅇ",ExponentialE:"ⅇ",fallingdotseq:"≒",Fcy:"Ф",fcy:"ф",female:"♀",ffilig:"ffi",fflig:"ff",ffllig:"ffl",Ffr:"𝔉",ffr:"𝔣",filig:"fi",FilledSmallSquare:"◼",FilledVerySmallSquare:"▪",fjlig:"fj",flat:"♭",fllig:"fl",fltns:"▱",fnof:"ƒ",Fopf:"𝔽",fopf:"𝕗",forall:"∀",ForAll:"∀",fork:"⋔",forkv:"⫙",Fouriertrf:"ℱ",fpartint:"⨍",frac12:"½",frac13:"⅓",frac14:"¼",frac15:"⅕",frac16:"⅙",frac18:"⅛",frac23:"⅔",frac25:"⅖",frac34:"¾",frac35:"⅗",frac38:"⅜",frac45:"⅘",frac56:"⅚",frac58:"⅝",frac78:"⅞",frasl:"⁄",frown:"⌢",fscr:"𝒻",Fscr:"ℱ",gacute:"ǵ",Gamma:"Γ",gamma:"γ",Gammad:"Ϝ",gammad:"ϝ",gap:"⪆",Gbreve:"Ğ",gbreve:"ğ",Gcedil:"Ģ",Gcirc:"Ĝ",gcirc:"ĝ",Gcy:"Г",gcy:"г",Gdot:"Ġ",gdot:"ġ",ge:"≥",gE:"≧",gEl:"⪌",gel:"⋛",geq:"≥",geqq:"≧",geqslant:"⩾",gescc:"⪩",ges:"⩾",gesdot:"⪀",gesdoto:"⪂",gesdotol:"⪄",gesl:"⋛︀",gesles:"⪔",Gfr:"𝔊",gfr:"𝔤",gg:"≫",Gg:"⋙",ggg:"⋙",gimel:"ℷ",GJcy:"Ѓ",gjcy:"ѓ",gla:"⪥",gl:"≷",glE:"⪒",glj:"⪤",gnap:"⪊",gnapprox:"⪊",gne:"⪈",gnE:"≩",gneq:"⪈",gneqq:"≩",gnsim:"⋧",Gopf:"𝔾",gopf:"𝕘",grave:"`",GreaterEqual:"≥",GreaterEqualLess:"⋛",GreaterFullEqual:"≧",GreaterGreater:"⪢",GreaterLess:"≷",GreaterSlantEqual:"⩾",GreaterTilde:"≳",Gscr:"𝒢",gscr:"ℊ",gsim:"≳",gsime:"⪎",gsiml:"⪐",gtcc:"⪧",gtcir:"⩺",gt:">",GT:">",Gt:"≫",gtdot:"⋗",gtlPar:"⦕",gtquest:"⩼",gtrapprox:"⪆",gtrarr:"⥸",gtrdot:"⋗",gtreqless:"⋛",gtreqqless:"⪌",gtrless:"≷",gtrsim:"≳",gvertneqq:"≩︀",gvnE:"≩︀",Hacek:"ˇ",hairsp:" ",half:"½",hamilt:"ℋ",HARDcy:"Ъ",hardcy:"ъ",harrcir:"⥈",harr:"↔",hArr:"⇔",harrw:"↭",Hat:"^",hbar:"ℏ",Hcirc:"Ĥ",hcirc:"ĥ",hearts:"♥",heartsuit:"♥",hellip:"…",hercon:"⊹",hfr:"𝔥",Hfr:"ℌ",HilbertSpace:"ℋ",hksearow:"⤥",hkswarow:"⤦",hoarr:"⇿",homtht:"∻",hookleftarrow:"↩",hookrightarrow:"↪",hopf:"𝕙",Hopf:"ℍ",horbar:"―",HorizontalLine:"─",hscr:"𝒽",Hscr:"ℋ",hslash:"ℏ",Hstrok:"Ħ",hstrok:"ħ",HumpDownHump:"≎",HumpEqual:"≏",hybull:"⁃",hyphen:"‐",Iacute:"Í",iacute:"í",ic:"⁣",Icirc:"Î",icirc:"î",Icy:"И",icy:"и",Idot:"İ",IEcy:"Е",iecy:"е",iexcl:"¡",iff:"⇔",ifr:"𝔦",Ifr:"ℑ",Igrave:"Ì",igrave:"ì",ii:"ⅈ",iiiint:"⨌",iiint:"∭",iinfin:"⧜",iiota:"℩",IJlig:"IJ",ijlig:"ij",Imacr:"Ī",imacr:"ī",image:"ℑ",ImaginaryI:"ⅈ",imagline:"ℐ",imagpart:"ℑ",imath:"ı",Im:"ℑ",imof:"⊷",imped:"Ƶ",Implies:"⇒",incare:"℅",in:"∈",infin:"∞",infintie:"⧝",inodot:"ı",intcal:"⊺",int:"∫",Int:"∬",integers:"ℤ",Integral:"∫",intercal:"⊺",Intersection:"⋂",intlarhk:"⨗",intprod:"⨼",InvisibleComma:"⁣",InvisibleTimes:"⁢",IOcy:"Ё",iocy:"ё",Iogon:"Į",iogon:"į",Iopf:"𝕀",iopf:"𝕚",Iota:"Ι",iota:"ι",iprod:"⨼",iquest:"¿",iscr:"𝒾",Iscr:"ℐ",isin:"∈",isindot:"⋵",isinE:"⋹",isins:"⋴",isinsv:"⋳",isinv:"∈",it:"⁢",Itilde:"Ĩ",itilde:"ĩ",Iukcy:"І",iukcy:"і",Iuml:"Ï",iuml:"ï",Jcirc:"Ĵ",jcirc:"ĵ",Jcy:"Й",jcy:"й",Jfr:"𝔍",jfr:"𝔧",jmath:"ȷ",Jopf:"𝕁",jopf:"𝕛",Jscr:"𝒥",jscr:"𝒿",Jsercy:"Ј",jsercy:"ј",Jukcy:"Є",jukcy:"є",Kappa:"Κ",kappa:"κ",kappav:"ϰ",Kcedil:"Ķ",kcedil:"ķ",Kcy:"К",kcy:"к",Kfr:"𝔎",kfr:"𝔨",kgreen:"ĸ",KHcy:"Х",khcy:"х",KJcy:"Ќ",kjcy:"ќ",Kopf:"𝕂",kopf:"𝕜",Kscr:"𝒦",kscr:"𝓀",lAarr:"⇚",Lacute:"Ĺ",lacute:"ĺ",laemptyv:"⦴",lagran:"ℒ",Lambda:"Λ",lambda:"λ",lang:"⟨",Lang:"⟪",langd:"⦑",langle:"⟨",lap:"⪅",Laplacetrf:"ℒ",laquo:"«",larrb:"⇤",larrbfs:"⤟",larr:"←",Larr:"↞",lArr:"⇐",larrfs:"⤝",larrhk:"↩",larrlp:"↫",larrpl:"⤹",larrsim:"⥳",larrtl:"↢",latail:"⤙",lAtail:"⤛",lat:"⪫",late:"⪭",lates:"⪭︀",lbarr:"⤌",lBarr:"⤎",lbbrk:"❲",lbrace:"{",lbrack:"[",lbrke:"⦋",lbrksld:"⦏",lbrkslu:"⦍",Lcaron:"Ľ",lcaron:"ľ",Lcedil:"Ļ",lcedil:"ļ",lceil:"⌈",lcub:"{",Lcy:"Л",lcy:"л",ldca:"⤶",ldquo:"“",ldquor:"„",ldrdhar:"⥧",ldrushar:"⥋",ldsh:"↲",le:"≤",lE:"≦",LeftAngleBracket:"⟨",LeftArrowBar:"⇤",leftarrow:"←",LeftArrow:"←",Leftarrow:"⇐",LeftArrowRightArrow:"⇆",leftarrowtail:"↢",LeftCeiling:"⌈",LeftDoubleBracket:"⟦",LeftDownTeeVector:"⥡",LeftDownVectorBar:"⥙",LeftDownVector:"⇃",LeftFloor:"⌊",leftharpoondown:"↽",leftharpoonup:"↼",leftleftarrows:"⇇",leftrightarrow:"↔",LeftRightArrow:"↔",Leftrightarrow:"⇔",leftrightarrows:"⇆",leftrightharpoons:"⇋",leftrightsquigarrow:"↭",LeftRightVector:"⥎",LeftTeeArrow:"↤",LeftTee:"⊣",LeftTeeVector:"⥚",leftthreetimes:"⋋",LeftTriangleBar:"⧏",LeftTriangle:"⊲",LeftTriangleEqual:"⊴",LeftUpDownVector:"⥑",LeftUpTeeVector:"⥠",LeftUpVectorBar:"⥘",LeftUpVector:"↿",LeftVectorBar:"⥒",LeftVector:"↼",lEg:"⪋",leg:"⋚",leq:"≤",leqq:"≦",leqslant:"⩽",lescc:"⪨",les:"⩽",lesdot:"⩿",lesdoto:"⪁",lesdotor:"⪃",lesg:"⋚︀",lesges:"⪓",lessapprox:"⪅",lessdot:"⋖",lesseqgtr:"⋚",lesseqqgtr:"⪋",LessEqualGreater:"⋚",LessFullEqual:"≦",LessGreater:"≶",lessgtr:"≶",LessLess:"⪡",lesssim:"≲",LessSlantEqual:"⩽",LessTilde:"≲",lfisht:"⥼",lfloor:"⌊",Lfr:"𝔏",lfr:"𝔩",lg:"≶",lgE:"⪑",lHar:"⥢",lhard:"↽",lharu:"↼",lharul:"⥪",lhblk:"▄",LJcy:"Љ",ljcy:"љ",llarr:"⇇",ll:"≪",Ll:"⋘",llcorner:"⌞",Lleftarrow:"⇚",llhard:"⥫",lltri:"◺",Lmidot:"Ŀ",lmidot:"ŀ",lmoustache:"⎰",lmoust:"⎰",lnap:"⪉",lnapprox:"⪉",lne:"⪇",lnE:"≨",lneq:"⪇",lneqq:"≨",lnsim:"⋦",loang:"⟬",loarr:"⇽",lobrk:"⟦",longleftarrow:"⟵",LongLeftArrow:"⟵",Longleftarrow:"⟸",longleftrightarrow:"⟷",LongLeftRightArrow:"⟷",Longleftrightarrow:"⟺",longmapsto:"⟼",longrightarrow:"⟶",LongRightArrow:"⟶",Longrightarrow:"⟹",looparrowleft:"↫",looparrowright:"↬",lopar:"⦅",Lopf:"𝕃",lopf:"𝕝",loplus:"⨭",lotimes:"⨴",lowast:"∗",lowbar:"_",LowerLeftArrow:"↙",LowerRightArrow:"↘",loz:"◊",lozenge:"◊",lozf:"⧫",lpar:"(",lparlt:"⦓",lrarr:"⇆",lrcorner:"⌟",lrhar:"⇋",lrhard:"⥭",lrm:"‎",lrtri:"⊿",lsaquo:"‹",lscr:"𝓁",Lscr:"ℒ",lsh:"↰",Lsh:"↰",lsim:"≲",lsime:"⪍",lsimg:"⪏",lsqb:"[",lsquo:"‘",lsquor:"‚",Lstrok:"Ł",lstrok:"ł",ltcc:"⪦",ltcir:"⩹",lt:"<",LT:"<",Lt:"≪",ltdot:"⋖",lthree:"⋋",ltimes:"⋉",ltlarr:"⥶",ltquest:"⩻",ltri:"◃",ltrie:"⊴",ltrif:"◂",ltrPar:"⦖",lurdshar:"⥊",luruhar:"⥦",lvertneqq:"≨︀",lvnE:"≨︀",macr:"¯",male:"♂",malt:"✠",maltese:"✠",Map:"⤅",map:"↦",mapsto:"↦",mapstodown:"↧",mapstoleft:"↤",mapstoup:"↥",marker:"▮",mcomma:"⨩",Mcy:"М",mcy:"м",mdash:"—",mDDot:"∺",measuredangle:"∡",MediumSpace:" ",Mellintrf:"ℳ",Mfr:"𝔐",mfr:"𝔪",mho:"℧",micro:"µ",midast:"*",midcir:"⫰",mid:"∣",middot:"·",minusb:"⊟",minus:"−",minusd:"∸",minusdu:"⨪",MinusPlus:"∓",mlcp:"⫛",mldr:"…",mnplus:"∓",models:"⊧",Mopf:"𝕄",mopf:"𝕞",mp:"∓",mscr:"𝓂",Mscr:"ℳ",mstpos:"∾",Mu:"Μ",mu:"μ",multimap:"⊸",mumap:"⊸",nabla:"∇",Nacute:"Ń",nacute:"ń",nang:"∠⃒",nap:"≉",napE:"⩰̸",napid:"≋̸",napos:"ʼn",napprox:"≉",natural:"♮",naturals:"ℕ",natur:"♮",nbsp:" ",nbump:"≎̸",nbumpe:"≏̸",ncap:"⩃",Ncaron:"Ň",ncaron:"ň",Ncedil:"Ņ",ncedil:"ņ",ncong:"≇",ncongdot:"⩭̸",ncup:"⩂",Ncy:"Н",ncy:"н",ndash:"–",nearhk:"⤤",nearr:"↗",neArr:"⇗",nearrow:"↗",ne:"≠",nedot:"≐̸",NegativeMediumSpace:"​",NegativeThickSpace:"​",NegativeThinSpace:"​",NegativeVeryThinSpace:"​",nequiv:"≢",nesear:"⤨",nesim:"≂̸",NestedGreaterGreater:"≫",NestedLessLess:"≪",NewLine:"\n",nexist:"∄",nexists:"∄",Nfr:"𝔑",nfr:"𝔫",ngE:"≧̸",nge:"≱",ngeq:"≱",ngeqq:"≧̸",ngeqslant:"⩾̸",nges:"⩾̸",nGg:"⋙̸",ngsim:"≵",nGt:"≫⃒",ngt:"≯",ngtr:"≯",nGtv:"≫̸",nharr:"↮",nhArr:"⇎",nhpar:"⫲",ni:"∋",nis:"⋼",nisd:"⋺",niv:"∋",NJcy:"Њ",njcy:"њ",nlarr:"↚",nlArr:"⇍",nldr:"‥",nlE:"≦̸",nle:"≰",nleftarrow:"↚",nLeftarrow:"⇍",nleftrightarrow:"↮",nLeftrightarrow:"⇎",nleq:"≰",nleqq:"≦̸",nleqslant:"⩽̸",nles:"⩽̸",nless:"≮",nLl:"⋘̸",nlsim:"≴",nLt:"≪⃒",nlt:"≮",nltri:"⋪",nltrie:"⋬",nLtv:"≪̸",nmid:"∤",NoBreak:"⁠",NonBreakingSpace:" ",nopf:"𝕟",Nopf:"ℕ",Not:"⫬",not:"¬",NotCongruent:"≢",NotCupCap:"≭",NotDoubleVerticalBar:"∦",NotElement:"∉",NotEqual:"≠",NotEqualTilde:"≂̸",NotExists:"∄",NotGreater:"≯",NotGreaterEqual:"≱",NotGreaterFullEqual:"≧̸",NotGreaterGreater:"≫̸",NotGreaterLess:"≹",NotGreaterSlantEqual:"⩾̸",NotGreaterTilde:"≵",NotHumpDownHump:"≎̸",NotHumpEqual:"≏̸",notin:"∉",notindot:"⋵̸",notinE:"⋹̸",notinva:"∉",notinvb:"⋷",notinvc:"⋶",NotLeftTriangleBar:"⧏̸",NotLeftTriangle:"⋪",NotLeftTriangleEqual:"⋬",NotLess:"≮",NotLessEqual:"≰",NotLessGreater:"≸",NotLessLess:"≪̸",NotLessSlantEqual:"⩽̸",NotLessTilde:"≴",NotNestedGreaterGreater:"⪢̸",NotNestedLessLess:"⪡̸",notni:"∌",notniva:"∌",notnivb:"⋾",notnivc:"⋽",NotPrecedes:"⊀",NotPrecedesEqual:"⪯̸",NotPrecedesSlantEqual:"⋠",NotReverseElement:"∌",NotRightTriangleBar:"⧐̸",NotRightTriangle:"⋫",NotRightTriangleEqual:"⋭",NotSquareSubset:"⊏̸",NotSquareSubsetEqual:"⋢",NotSquareSuperset:"⊐̸",NotSquareSupersetEqual:"⋣",NotSubset:"⊂⃒",NotSubsetEqual:"⊈",NotSucceeds:"⊁",NotSucceedsEqual:"⪰̸",NotSucceedsSlantEqual:"⋡",NotSucceedsTilde:"≿̸",NotSuperset:"⊃⃒",NotSupersetEqual:"⊉",NotTilde:"≁",NotTildeEqual:"≄",NotTildeFullEqual:"≇",NotTildeTilde:"≉",NotVerticalBar:"∤",nparallel:"∦",npar:"∦",nparsl:"⫽⃥",npart:"∂̸",npolint:"⨔",npr:"⊀",nprcue:"⋠",nprec:"⊀",npreceq:"⪯̸",npre:"⪯̸",nrarrc:"⤳̸",nrarr:"↛",nrArr:"⇏",nrarrw:"↝̸",nrightarrow:"↛",nRightarrow:"⇏",nrtri:"⋫",nrtrie:"⋭",nsc:"⊁",nsccue:"⋡",nsce:"⪰̸",Nscr:"𝒩",nscr:"𝓃",nshortmid:"∤",nshortparallel:"∦",nsim:"≁",nsime:"≄",nsimeq:"≄",nsmid:"∤",nspar:"∦",nsqsube:"⋢",nsqsupe:"⋣",nsub:"⊄",nsubE:"⫅̸",nsube:"⊈",nsubset:"⊂⃒",nsubseteq:"⊈",nsubseteqq:"⫅̸",nsucc:"⊁",nsucceq:"⪰̸",nsup:"⊅",nsupE:"⫆̸",nsupe:"⊉",nsupset:"⊃⃒",nsupseteq:"⊉",nsupseteqq:"⫆̸",ntgl:"≹",Ntilde:"Ñ",ntilde:"ñ",ntlg:"≸",ntriangleleft:"⋪",ntrianglelefteq:"⋬",ntriangleright:"⋫",ntrianglerighteq:"⋭",Nu:"Ν",nu:"ν",num:"#",numero:"№",numsp:" ",nvap:"≍⃒",nvdash:"⊬",nvDash:"⊭",nVdash:"⊮",nVDash:"⊯",nvge:"≥⃒",nvgt:">⃒",nvHarr:"⤄",nvinfin:"⧞",nvlArr:"⤂",nvle:"≤⃒",nvlt:"<⃒",nvltrie:"⊴⃒",nvrArr:"⤃",nvrtrie:"⊵⃒",nvsim:"∼⃒",nwarhk:"⤣",nwarr:"↖",nwArr:"⇖",nwarrow:"↖",nwnear:"⤧",Oacute:"Ó",oacute:"ó",oast:"⊛",Ocirc:"Ô",ocirc:"ô",ocir:"⊚",Ocy:"О",ocy:"о",odash:"⊝",Odblac:"Ő",odblac:"ő",odiv:"⨸",odot:"⊙",odsold:"⦼",OElig:"Œ",oelig:"œ",ofcir:"⦿",Ofr:"𝔒",ofr:"𝔬",ogon:"˛",Ograve:"Ò",ograve:"ò",ogt:"⧁",ohbar:"⦵",ohm:"Ω",oint:"∮",olarr:"↺",olcir:"⦾",olcross:"⦻",oline:"‾",olt:"⧀",Omacr:"Ō",omacr:"ō",Omega:"Ω",omega:"ω",Omicron:"Ο",omicron:"ο",omid:"⦶",ominus:"⊖",Oopf:"𝕆",oopf:"𝕠",opar:"⦷",OpenCurlyDoubleQuote:"“",OpenCurlyQuote:"‘",operp:"⦹",oplus:"⊕",orarr:"↻",Or:"⩔",or:"∨",ord:"⩝",order:"ℴ",orderof:"ℴ",ordf:"ª",ordm:"º",origof:"⊶",oror:"⩖",orslope:"⩗",orv:"⩛",oS:"Ⓢ",Oscr:"𝒪",oscr:"ℴ",Oslash:"Ø",oslash:"ø",osol:"⊘",Otilde:"Õ",otilde:"õ",otimesas:"⨶",Otimes:"⨷",otimes:"⊗",Ouml:"Ö",ouml:"ö",ovbar:"⌽",OverBar:"‾",OverBrace:"⏞",OverBracket:"⎴",OverParenthesis:"⏜",para:"¶",parallel:"∥",par:"∥",parsim:"⫳",parsl:"⫽",part:"∂",PartialD:"∂",Pcy:"П",pcy:"п",percnt:"%",period:".",permil:"‰",perp:"⊥",pertenk:"‱",Pfr:"𝔓",pfr:"𝔭",Phi:"Φ",phi:"φ",phiv:"ϕ",phmmat:"ℳ",phone:"☎",Pi:"Π",pi:"π",pitchfork:"⋔",piv:"ϖ",planck:"ℏ",planckh:"ℎ",plankv:"ℏ",plusacir:"⨣",plusb:"⊞",pluscir:"⨢",plus:"+",plusdo:"∔",plusdu:"⨥",pluse:"⩲",PlusMinus:"±",plusmn:"±",plussim:"⨦",plustwo:"⨧",pm:"±",Poincareplane:"ℌ",pointint:"⨕",popf:"𝕡",Popf:"ℙ",pound:"£",prap:"⪷",Pr:"⪻",pr:"≺",prcue:"≼",precapprox:"⪷",prec:"≺",preccurlyeq:"≼",Precedes:"≺",PrecedesEqual:"⪯",PrecedesSlantEqual:"≼",PrecedesTilde:"≾",preceq:"⪯",precnapprox:"⪹",precneqq:"⪵",precnsim:"⋨",pre:"⪯",prE:"⪳",precsim:"≾",prime:"′",Prime:"″",primes:"ℙ",prnap:"⪹",prnE:"⪵",prnsim:"⋨",prod:"∏",Product:"∏",profalar:"⌮",profline:"⌒",profsurf:"⌓",prop:"∝",Proportional:"∝",Proportion:"∷",propto:"∝",prsim:"≾",prurel:"⊰",Pscr:"𝒫",pscr:"𝓅",Psi:"Ψ",psi:"ψ",puncsp:" ",Qfr:"𝔔",qfr:"𝔮",qint:"⨌",qopf:"𝕢",Qopf:"ℚ",qprime:"⁗",Qscr:"𝒬",qscr:"𝓆",quaternions:"ℍ",quatint:"⨖",quest:"?",questeq:"≟",quot:'"',QUOT:'"',rAarr:"⇛",race:"∽̱",Racute:"Ŕ",racute:"ŕ",radic:"√",raemptyv:"⦳",rang:"⟩",Rang:"⟫",rangd:"⦒",range:"⦥",rangle:"⟩",raquo:"»",rarrap:"⥵",rarrb:"⇥",rarrbfs:"⤠",rarrc:"⤳",rarr:"→",Rarr:"↠",rArr:"⇒",rarrfs:"⤞",rarrhk:"↪",rarrlp:"↬",rarrpl:"⥅",rarrsim:"⥴",Rarrtl:"⤖",rarrtl:"↣",rarrw:"↝",ratail:"⤚",rAtail:"⤜",ratio:"∶",rationals:"ℚ",rbarr:"⤍",rBarr:"⤏",RBarr:"⤐",rbbrk:"❳",rbrace:"}",rbrack:"]",rbrke:"⦌",rbrksld:"⦎",rbrkslu:"⦐",Rcaron:"Ř",rcaron:"ř",Rcedil:"Ŗ",rcedil:"ŗ",rceil:"⌉",rcub:"}",Rcy:"Р",rcy:"р",rdca:"⤷",rdldhar:"⥩",rdquo:"”",rdquor:"”",rdsh:"↳",real:"ℜ",realine:"ℛ",realpart:"ℜ",reals:"ℝ",Re:"ℜ",rect:"▭",reg:"®",REG:"®",ReverseElement:"∋",ReverseEquilibrium:"⇋",ReverseUpEquilibrium:"⥯",rfisht:"⥽",rfloor:"⌋",rfr:"𝔯",Rfr:"ℜ",rHar:"⥤",rhard:"⇁",rharu:"⇀",rharul:"⥬",Rho:"Ρ",rho:"ρ",rhov:"ϱ",RightAngleBracket:"⟩",RightArrowBar:"⇥",rightarrow:"→",RightArrow:"→",Rightarrow:"⇒",RightArrowLeftArrow:"⇄",rightarrowtail:"↣",RightCeiling:"⌉",RightDoubleBracket:"⟧",RightDownTeeVector:"⥝",RightDownVectorBar:"⥕",RightDownVector:"⇂",RightFloor:"⌋",rightharpoondown:"⇁",rightharpoonup:"⇀",rightleftarrows:"⇄",rightleftharpoons:"⇌",rightrightarrows:"⇉",rightsquigarrow:"↝",RightTeeArrow:"↦",RightTee:"⊢",RightTeeVector:"⥛",rightthreetimes:"⋌",RightTriangleBar:"⧐",RightTriangle:"⊳",RightTriangleEqual:"⊵",RightUpDownVector:"⥏",RightUpTeeVector:"⥜",RightUpVectorBar:"⥔",RightUpVector:"↾",RightVectorBar:"⥓",RightVector:"⇀",ring:"˚",risingdotseq:"≓",rlarr:"⇄",rlhar:"⇌",rlm:"‏",rmoustache:"⎱",rmoust:"⎱",rnmid:"⫮",roang:"⟭",roarr:"⇾",robrk:"⟧",ropar:"⦆",ropf:"𝕣",Ropf:"ℝ",roplus:"⨮",rotimes:"⨵",RoundImplies:"⥰",rpar:")",rpargt:"⦔",rppolint:"⨒",rrarr:"⇉",Rrightarrow:"⇛",rsaquo:"›",rscr:"𝓇",Rscr:"ℛ",rsh:"↱",Rsh:"↱",rsqb:"]",rsquo:"’",rsquor:"’",rthree:"⋌",rtimes:"⋊",rtri:"▹",rtrie:"⊵",rtrif:"▸",rtriltri:"⧎",RuleDelayed:"⧴",ruluhar:"⥨",rx:"℞",Sacute:"Ś",sacute:"ś",sbquo:"‚",scap:"⪸",Scaron:"Š",scaron:"š",Sc:"⪼",sc:"≻",sccue:"≽",sce:"⪰",scE:"⪴",Scedil:"Ş",scedil:"ş",Scirc:"Ŝ",scirc:"ŝ",scnap:"⪺",scnE:"⪶",scnsim:"⋩",scpolint:"⨓",scsim:"≿",Scy:"С",scy:"с",sdotb:"⊡",sdot:"⋅",sdote:"⩦",searhk:"⤥",searr:"↘",seArr:"⇘",searrow:"↘",sect:"§",semi:";",seswar:"⤩",setminus:"∖",setmn:"∖",sext:"✶",Sfr:"𝔖",sfr:"𝔰",sfrown:"⌢",sharp:"♯",SHCHcy:"Щ",shchcy:"щ",SHcy:"Ш",shcy:"ш",ShortDownArrow:"↓",ShortLeftArrow:"←",shortmid:"∣",shortparallel:"∥",ShortRightArrow:"→",ShortUpArrow:"↑",shy:"­",Sigma:"Σ",sigma:"σ",sigmaf:"ς",sigmav:"ς",sim:"∼",simdot:"⩪",sime:"≃",simeq:"≃",simg:"⪞",simgE:"⪠",siml:"⪝",simlE:"⪟",simne:"≆",simplus:"⨤",simrarr:"⥲",slarr:"←",SmallCircle:"∘",smallsetminus:"∖",smashp:"⨳",smeparsl:"⧤",smid:"∣",smile:"⌣",smt:"⪪",smte:"⪬",smtes:"⪬︀",SOFTcy:"Ь",softcy:"ь",solbar:"⌿",solb:"⧄",sol:"/",Sopf:"𝕊",sopf:"𝕤",spades:"♠",spadesuit:"♠",spar:"∥",sqcap:"⊓",sqcaps:"⊓︀",sqcup:"⊔",sqcups:"⊔︀",Sqrt:"√",sqsub:"⊏",sqsube:"⊑",sqsubset:"⊏",sqsubseteq:"⊑",sqsup:"⊐",sqsupe:"⊒",sqsupset:"⊐",sqsupseteq:"⊒",square:"□",Square:"□",SquareIntersection:"⊓",SquareSubset:"⊏",SquareSubsetEqual:"⊑",SquareSuperset:"⊐",SquareSupersetEqual:"⊒",SquareUnion:"⊔",squarf:"▪",squ:"□",squf:"▪",srarr:"→",Sscr:"𝒮",sscr:"𝓈",ssetmn:"∖",ssmile:"⌣",sstarf:"⋆",Star:"⋆",star:"☆",starf:"★",straightepsilon:"ϵ",straightphi:"ϕ",strns:"¯",sub:"⊂",Sub:"⋐",subdot:"⪽",subE:"⫅",sube:"⊆",subedot:"⫃",submult:"⫁",subnE:"⫋",subne:"⊊",subplus:"⪿",subrarr:"⥹",subset:"⊂",Subset:"⋐",subseteq:"⊆",subseteqq:"⫅",SubsetEqual:"⊆",subsetneq:"⊊",subsetneqq:"⫋",subsim:"⫇",subsub:"⫕",subsup:"⫓",succapprox:"⪸",succ:"≻",succcurlyeq:"≽",Succeeds:"≻",SucceedsEqual:"⪰",SucceedsSlantEqual:"≽",SucceedsTilde:"≿",succeq:"⪰",succnapprox:"⪺",succneqq:"⪶",succnsim:"⋩",succsim:"≿",SuchThat:"∋",sum:"∑",Sum:"∑",sung:"♪",sup1:"¹",sup2:"²",sup3:"³",sup:"⊃",Sup:"⋑",supdot:"⪾",supdsub:"⫘",supE:"⫆",supe:"⊇",supedot:"⫄",Superset:"⊃",SupersetEqual:"⊇",suphsol:"⟉",suphsub:"⫗",suplarr:"⥻",supmult:"⫂",supnE:"⫌",supne:"⊋",supplus:"⫀",supset:"⊃",Supset:"⋑",supseteq:"⊇",supseteqq:"⫆",supsetneq:"⊋",supsetneqq:"⫌",supsim:"⫈",supsub:"⫔",supsup:"⫖",swarhk:"⤦",swarr:"↙",swArr:"⇙",swarrow:"↙",swnwar:"⤪",szlig:"ß",Tab:"\t",target:"⌖",Tau:"Τ",tau:"τ",tbrk:"⎴",Tcaron:"Ť",tcaron:"ť",Tcedil:"Ţ",tcedil:"ţ",Tcy:"Т",tcy:"т",tdot:"⃛",telrec:"⌕",Tfr:"𝔗",tfr:"𝔱",there4:"∴",therefore:"∴",Therefore:"∴",Theta:"Θ",theta:"θ",thetasym:"ϑ",thetav:"ϑ",thickapprox:"≈",thicksim:"∼",ThickSpace:"  ",ThinSpace:" ",thinsp:" ",thkap:"≈",thksim:"∼",THORN:"Þ",thorn:"þ",tilde:"˜",Tilde:"∼",TildeEqual:"≃",TildeFullEqual:"≅",TildeTilde:"≈",timesbar:"⨱",timesb:"⊠",times:"×",timesd:"⨰",tint:"∭",toea:"⤨",topbot:"⌶",topcir:"⫱",top:"⊤",Topf:"𝕋",topf:"𝕥",topfork:"⫚",tosa:"⤩",tprime:"‴",trade:"™",TRADE:"™",triangle:"▵",triangledown:"▿",triangleleft:"◃",trianglelefteq:"⊴",triangleq:"≜",triangleright:"▹",trianglerighteq:"⊵",tridot:"◬",trie:"≜",triminus:"⨺",TripleDot:"⃛",triplus:"⨹",trisb:"⧍",tritime:"⨻",trpezium:"⏢",Tscr:"𝒯",tscr:"𝓉",TScy:"Ц",tscy:"ц",TSHcy:"Ћ",tshcy:"ћ",Tstrok:"Ŧ",tstrok:"ŧ",twixt:"≬",twoheadleftarrow:"↞",twoheadrightarrow:"↠",Uacute:"Ú",uacute:"ú",uarr:"↑",Uarr:"↟",uArr:"⇑",Uarrocir:"⥉",Ubrcy:"Ў",ubrcy:"ў",Ubreve:"Ŭ",ubreve:"ŭ",Ucirc:"Û",ucirc:"û",Ucy:"У",ucy:"у",udarr:"⇅",Udblac:"Ű",udblac:"ű",udhar:"⥮",ufisht:"⥾",Ufr:"𝔘",ufr:"𝔲",Ugrave:"Ù",ugrave:"ù",uHar:"⥣",uharl:"↿",uharr:"↾",uhblk:"▀",ulcorn:"⌜",ulcorner:"⌜",ulcrop:"⌏",ultri:"◸",Umacr:"Ū",umacr:"ū",uml:"¨",UnderBar:"_",UnderBrace:"⏟",UnderBracket:"⎵",UnderParenthesis:"⏝",Union:"⋃",UnionPlus:"⊎",Uogon:"Ų",uogon:"ų",Uopf:"𝕌",uopf:"𝕦",UpArrowBar:"⤒",uparrow:"↑",UpArrow:"↑",Uparrow:"⇑",UpArrowDownArrow:"⇅",updownarrow:"↕",UpDownArrow:"↕",Updownarrow:"⇕",UpEquilibrium:"⥮",upharpoonleft:"↿",upharpoonright:"↾",uplus:"⊎",UpperLeftArrow:"↖",UpperRightArrow:"↗",upsi:"υ",Upsi:"ϒ",upsih:"ϒ",Upsilon:"Υ",upsilon:"υ",UpTeeArrow:"↥",UpTee:"⊥",upuparrows:"⇈",urcorn:"⌝",urcorner:"⌝",urcrop:"⌎",Uring:"Ů",uring:"ů",urtri:"◹",Uscr:"𝒰",uscr:"𝓊",utdot:"⋰",Utilde:"Ũ",utilde:"ũ",utri:"▵",utrif:"▴",uuarr:"⇈",Uuml:"Ü",uuml:"ü",uwangle:"⦧",vangrt:"⦜",varepsilon:"ϵ",varkappa:"ϰ",varnothing:"∅",varphi:"ϕ",varpi:"ϖ",varpropto:"∝",varr:"↕",vArr:"⇕",varrho:"ϱ",varsigma:"ς",varsubsetneq:"⊊︀",varsubsetneqq:"⫋︀",varsupsetneq:"⊋︀",varsupsetneqq:"⫌︀",vartheta:"ϑ",vartriangleleft:"⊲",vartriangleright:"⊳",vBar:"⫨",Vbar:"⫫",vBarv:"⫩",Vcy:"В",vcy:"в",vdash:"⊢",vDash:"⊨",Vdash:"⊩",VDash:"⊫",Vdashl:"⫦",veebar:"⊻",vee:"∨",Vee:"⋁",veeeq:"≚",vellip:"⋮",verbar:"|",Verbar:"‖",vert:"|",Vert:"‖",VerticalBar:"∣",VerticalLine:"|",VerticalSeparator:"❘",VerticalTilde:"≀",VeryThinSpace:" ",Vfr:"𝔙",vfr:"𝔳",vltri:"⊲",vnsub:"⊂⃒",vnsup:"⊃⃒",Vopf:"𝕍",vopf:"𝕧",vprop:"∝",vrtri:"⊳",Vscr:"𝒱",vscr:"𝓋",vsubnE:"⫋︀",vsubne:"⊊︀",vsupnE:"⫌︀",vsupne:"⊋︀",Vvdash:"⊪",vzigzag:"⦚",Wcirc:"Ŵ",wcirc:"ŵ",wedbar:"⩟",wedge:"∧",Wedge:"⋀",wedgeq:"≙",weierp:"℘",Wfr:"𝔚",wfr:"𝔴",Wopf:"𝕎",wopf:"𝕨",wp:"℘",wr:"≀",wreath:"≀",Wscr:"𝒲",wscr:"𝓌",xcap:"⋂",xcirc:"◯",xcup:"⋃",xdtri:"▽",Xfr:"𝔛",xfr:"𝔵",xharr:"⟷",xhArr:"⟺",Xi:"Ξ",xi:"ξ",xlarr:"⟵",xlArr:"⟸",xmap:"⟼",xnis:"⋻",xodot:"⨀",Xopf:"𝕏",xopf:"𝕩",xoplus:"⨁",xotime:"⨂",xrarr:"⟶",xrArr:"⟹",Xscr:"𝒳",xscr:"𝓍",xsqcup:"⨆",xuplus:"⨄",xutri:"△",xvee:"⋁",xwedge:"⋀",Yacute:"Ý",yacute:"ý",YAcy:"Я",yacy:"я",Ycirc:"Ŷ",ycirc:"ŷ",Ycy:"Ы",ycy:"ы",yen:"¥",Yfr:"𝔜",yfr:"𝔶",YIcy:"Ї",yicy:"ї",Yopf:"𝕐",yopf:"𝕪",Yscr:"𝒴",yscr:"𝓎",YUcy:"Ю",yucy:"ю",yuml:"ÿ",Yuml:"Ÿ",Zacute:"Ź",zacute:"ź",Zcaron:"Ž",zcaron:"ž",Zcy:"З",zcy:"з",Zdot:"Ż",zdot:"ż",zeetrf:"ℨ",ZeroWidthSpace:"​",Zeta:"Ζ",zeta:"ζ",zfr:"𝔷",Zfr:"ℨ",ZHcy:"Ж",zhcy:"ж",zigrarr:"⇝",zopf:"𝕫",Zopf:"ℤ",Zscr:"𝒵",zscr:"𝓏",zwj:"‍",zwnj:"‌"}},{}],26:[function(require,module,exports){module.exports={Aacute:"Á",aacute:"á",Acirc:"Â",acirc:"â",acute:"´",AElig:"Æ",aelig:"æ",Agrave:"À",agrave:"à",amp:"&",AMP:"&",Aring:"Å",aring:"å",Atilde:"Ã",atilde:"ã",Auml:"Ä",auml:"ä",brvbar:"¦",Ccedil:"Ç",ccedil:"ç",cedil:"¸",cent:"¢",copy:"©",COPY:"©",curren:"¤",deg:"°",divide:"÷",Eacute:"É",eacute:"é",Ecirc:"Ê",ecirc:"ê",Egrave:"È",egrave:"è",ETH:"Ð",eth:"ð",Euml:"Ë",euml:"ë",frac12:"½",frac14:"¼",frac34:"¾",gt:">",GT:">",Iacute:"Í",iacute:"í",Icirc:"Î",icirc:"î",iexcl:"¡",Igrave:"Ì",igrave:"ì",iquest:"¿",Iuml:"Ï",iuml:"ï",laquo:"«",lt:"<",LT:"<",macr:"¯",micro:"µ",middot:"·",nbsp:" ",not:"¬",Ntilde:"Ñ",ntilde:"ñ",Oacute:"Ó",oacute:"ó",Ocirc:"Ô",ocirc:"ô",Ograve:"Ò",ograve:"ò",ordf:"ª",ordm:"º",Oslash:"Ø",oslash:"ø",Otilde:"Õ",otilde:"õ",Ouml:"Ö",ouml:"ö",para:"¶",plusmn:"±",pound:"£",quot:'"',QUOT:'"',raquo:"»",reg:"®",REG:"®",sect:"§",shy:"­",sup1:"¹",sup2:"²",sup3:"³",szlig:"ß",THORN:"Þ",thorn:"þ",times:"×",Uacute:"Ú",uacute:"ú",Ucirc:"Û",ucirc:"û",Ugrave:"Ù",ugrave:"ù",uml:"¨",Uuml:"Ü",uuml:"ü",Yacute:"Ý",yacute:"ý",yen:"¥",yuml:"ÿ"}},{}],27:[function(require,module,exports){module.exports={amp:"&",apos:"'",gt:">",lt:"<",quot:'"'}},{}],28:[function(require,module,exports){function EventEmitter(){this._events=this._events||{};this._maxListeners=this._maxListeners||undefined}module.exports=EventEmitter;EventEmitter.EventEmitter=EventEmitter;EventEmitter.prototype._events=undefined;EventEmitter.prototype._maxListeners=undefined;EventEmitter.defaultMaxListeners=10;EventEmitter.prototype.setMaxListeners=function(n){if(!isNumber(n)||n<0||isNaN(n))throw TypeError("n must be a positive number");this._maxListeners=n;return this};EventEmitter.prototype.emit=function(type){var er,handler,len,args,i,listeners;if(!this._events)this._events={};if(type==="error"){if(!this._events.error||isObject(this._events.error)&&!this._events.error.length){er=arguments[1];if(er instanceof Error){throw er}else{var err=new Error('Uncaught, unspecified "error" event. ('+er+")");err.context=er;throw err}}}handler=this._events[type];if(isUndefined(handler))return false;if(isFunction(handler)){switch(arguments.length){case 1:handler.call(this);break;case 2:handler.call(this,arguments[1]);break;case 3:handler.call(this,arguments[1],arguments[2]);break;default:args=Array.prototype.slice.call(arguments,1);handler.apply(this,args)}}else if(isObject(handler)){args=Array.prototype.slice.call(arguments,1);listeners=handler.slice();len=listeners.length;for(i=0;i<len;i++)listeners[i].apply(this,args)}return true};EventEmitter.prototype.addListener=function(type,listener){var m;if(!isFunction(listener))throw TypeError("listener must be a function");if(!this._events)this._events={};if(this._events.newListener)this.emit("newListener",type,isFunction(listener.listener)?listener.listener:listener);if(!this._events[type])this._events[type]=listener;else if(isObject(this._events[type]))this._events[type].push(listener);else this._events[type]=[this._events[type],listener];if(isObject(this._events[type])&&!this._events[type].warned){if(!isUndefined(this._maxListeners)){m=this._maxListeners}else{m=EventEmitter.defaultMaxListeners}if(m&&m>0&&this._events[type].length>m){this._events[type].warned=true;console.error("(node) warning: possible EventEmitter memory "+"leak detected. %d listeners added. "+"Use emitter.setMaxListeners() to increase limit.",this._events[type].length);if(typeof console.trace==="function"){console.trace()}}}return this};EventEmitter.prototype.on=EventEmitter.prototype.addListener;EventEmitter.prototype.once=function(type,listener){if(!isFunction(listener))throw TypeError("listener must be a function");var fired=false;function g(){this.removeListener(type,g);if(!fired){fired=true;listener.apply(this,arguments)}}g.listener=listener;this.on(type,g);return this};EventEmitter.prototype.removeListener=function(type,listener){var list,position,length,i;if(!isFunction(listener))throw TypeError("listener must be a function");if(!this._events||!this._events[type])return this;list=this._events[type];length=list.length;position=-1;if(list===listener||isFunction(list.listener)&&list.listener===listener){delete this._events[type];if(this._events.removeListener)this.emit("removeListener",type,listener)}else if(isObject(list)){for(i=length;i-- >0;){if(list[i]===listener||list[i].listener&&list[i].listener===listener){position=i;break}}if(position<0)return this;if(list.length===1){list.length=0;delete this._events[type]}else{list.splice(position,1);
+}if(this._events.removeListener)this.emit("removeListener",type,listener)}return this};EventEmitter.prototype.removeAllListeners=function(type){var key,listeners;if(!this._events)return this;if(!this._events.removeListener){if(arguments.length===0)this._events={};else if(this._events[type])delete this._events[type];return this}if(arguments.length===0){for(key in this._events){if(key==="removeListener")continue;this.removeAllListeners(key)}this.removeAllListeners("removeListener");this._events={};return this}listeners=this._events[type];if(isFunction(listeners)){this.removeListener(type,listeners)}else if(listeners){while(listeners.length)this.removeListener(type,listeners[listeners.length-1])}delete this._events[type];return this};EventEmitter.prototype.listeners=function(type){var ret;if(!this._events||!this._events[type])ret=[];else if(isFunction(this._events[type]))ret=[this._events[type]];else ret=this._events[type].slice();return ret};EventEmitter.prototype.listenerCount=function(type){if(this._events){var evlistener=this._events[type];if(isFunction(evlistener))return 1;else if(evlistener)return evlistener.length}return 0};EventEmitter.listenerCount=function(emitter,type){return emitter.listenerCount(type)};function isFunction(arg){return typeof arg==="function"}function isNumber(arg){return typeof arg==="number"}function isObject(arg){return typeof arg==="object"&&arg!==null}function isUndefined(arg){return arg===void 0}},{}],29:[function(require,module,exports){module.exports=CollectingHandler;function CollectingHandler(cbs){this._cbs=cbs||{};this.events=[]}var EVENTS=require("./").EVENTS;Object.keys(EVENTS).forEach(function(name){if(EVENTS[name]===0){name="on"+name;CollectingHandler.prototype[name]=function(){this.events.push([name]);if(this._cbs[name])this._cbs[name]()}}else if(EVENTS[name]===1){name="on"+name;CollectingHandler.prototype[name]=function(a){this.events.push([name,a]);if(this._cbs[name])this._cbs[name](a)}}else if(EVENTS[name]===2){name="on"+name;CollectingHandler.prototype[name]=function(a,b){this.events.push([name,a,b]);if(this._cbs[name])this._cbs[name](a,b)}}else{throw Error("wrong number of arguments")}});CollectingHandler.prototype.onreset=function(){this.events=[];if(this._cbs.onreset)this._cbs.onreset()};CollectingHandler.prototype.restart=function(){if(this._cbs.onreset)this._cbs.onreset();for(var i=0,len=this.events.length;i<len;i++){if(this._cbs[this.events[i][0]]){var num=this.events[i].length;if(num===1){this._cbs[this.events[i][0]]()}else if(num===2){this._cbs[this.events[i][0]](this.events[i][1])}else{this._cbs[this.events[i][0]](this.events[i][1],this.events[i][2])}}}}},{"./":36}],30:[function(require,module,exports){var index=require("./index.js"),DomHandler=index.DomHandler,DomUtils=index.DomUtils;function FeedHandler(callback,options){this.init(callback,options)}require("inherits")(FeedHandler,DomHandler);FeedHandler.prototype.init=DomHandler;function getElements(what,where){return DomUtils.getElementsByTagName(what,where,true)}function getOneElement(what,where){return DomUtils.getElementsByTagName(what,where,true,1)[0]}function fetch(what,where,recurse){return DomUtils.getText(DomUtils.getElementsByTagName(what,where,recurse,1)).trim()}function addConditionally(obj,prop,what,where,recurse){var tmp=fetch(what,where,recurse);if(tmp)obj[prop]=tmp}var isValidFeed=function(value){return value==="rss"||value==="feed"||value==="rdf:RDF"};FeedHandler.prototype.onend=function(){var feed={},feedRoot=getOneElement(isValidFeed,this.dom),tmp,childs;if(feedRoot){if(feedRoot.name==="feed"){childs=feedRoot.children;feed.type="atom";addConditionally(feed,"id","id",childs);addConditionally(feed,"title","title",childs);if((tmp=getOneElement("link",childs))&&(tmp=tmp.attribs)&&(tmp=tmp.href))feed.link=tmp;addConditionally(feed,"description","subtitle",childs);if(tmp=fetch("updated",childs))feed.updated=new Date(tmp);addConditionally(feed,"author","email",childs,true);feed.items=getElements("entry",childs).map(function(item){var entry={},tmp;item=item.children;addConditionally(entry,"id","id",item);addConditionally(entry,"title","title",item);if((tmp=getOneElement("link",item))&&(tmp=tmp.attribs)&&(tmp=tmp.href))entry.link=tmp;if(tmp=fetch("summary",item)||fetch("content",item))entry.description=tmp;if(tmp=fetch("updated",item))entry.pubDate=new Date(tmp);return entry})}else{childs=getOneElement("channel",feedRoot.children).children;feed.type=feedRoot.name.substr(0,3);feed.id="";addConditionally(feed,"title","title",childs);addConditionally(feed,"link","link",childs);addConditionally(feed,"description","description",childs);if(tmp=fetch("lastBuildDate",childs))feed.updated=new Date(tmp);addConditionally(feed,"author","managingEditor",childs,true);feed.items=getElements("item",feedRoot.children).map(function(item){var entry={},tmp;item=item.children;addConditionally(entry,"id","guid",item);addConditionally(entry,"title","title",item);addConditionally(entry,"link","link",item);addConditionally(entry,"description","description",item);if(tmp=fetch("pubDate",item))entry.pubDate=new Date(tmp);return entry})}}this.dom=feed;DomHandler.prototype._handleCallback.call(this,feedRoot?null:Error("couldn't find root of feed"))};module.exports=FeedHandler},{"./index.js":36,inherits:38}],31:[function(require,module,exports){var Tokenizer=require("./Tokenizer.js");var formTags={input:true,option:true,optgroup:true,select:true,button:true,datalist:true,textarea:true};var openImpliesClose={tr:{tr:true,th:true,td:true},th:{th:true},td:{thead:true,th:true,td:true},body:{head:true,link:true,script:true},li:{li:true},p:{p:true},h1:{p:true},h2:{p:true},h3:{p:true},h4:{p:true},h5:{p:true},h6:{p:true},select:formTags,input:formTags,output:formTags,button:formTags,datalist:formTags,textarea:formTags,option:{option:true},optgroup:{optgroup:true}};var voidElements={__proto__:null,area:true,base:true,basefont:true,br:true,col:true,command:true,embed:true,frame:true,hr:true,img:true,input:true,isindex:true,keygen:true,link:true,meta:true,param:true,source:true,track:true,wbr:true,path:true,circle:true,ellipse:true,line:true,rect:true,use:true,stop:true,polyline:true,polygon:true};var re_nameEnd=/\s|\//;function Parser(cbs,options){this._options=options||{};this._cbs=cbs||{};this._tagname="";this._attribname="";this._attribvalue="";this._attribs=null;this._stack=[];this.startIndex=0;this.endIndex=null;this._lowerCaseTagNames="lowerCaseTags"in this._options?!!this._options.lowerCaseTags:!this._options.xmlMode;this._lowerCaseAttributeNames="lowerCaseAttributeNames"in this._options?!!this._options.lowerCaseAttributeNames:!this._options.xmlMode;if(this._options.Tokenizer){Tokenizer=this._options.Tokenizer}this._tokenizer=new Tokenizer(this._options,this);if(this._cbs.onparserinit)this._cbs.onparserinit(this)}require("inherits")(Parser,require("events").EventEmitter);Parser.prototype._updatePosition=function(initialOffset){if(this.endIndex===null){if(this._tokenizer._sectionStart<=initialOffset){this.startIndex=0}else{this.startIndex=this._tokenizer._sectionStart-initialOffset}}else this.startIndex=this.endIndex+1;this.endIndex=this._tokenizer.getAbsoluteIndex()};Parser.prototype.ontext=function(data){this._updatePosition(1);this.endIndex--;if(this._cbs.ontext)this._cbs.ontext(data)};Parser.prototype.onopentagname=function(name){if(this._lowerCaseTagNames){name=name.toLowerCase()}this._tagname=name;if(!this._options.xmlMode&&name in openImpliesClose){for(var el;(el=this._stack[this._stack.length-1])in openImpliesClose[name];this.onclosetag(el));}if(this._options.xmlMode||!(name in voidElements)){this._stack.push(name)}if(this._cbs.onopentagname)this._cbs.onopentagname(name);if(this._cbs.onopentag)this._attribs={}};Parser.prototype.onopentagend=function(){this._updatePosition(1);if(this._attribs){if(this._cbs.onopentag)this._cbs.onopentag(this._tagname,this._attribs);this._attribs=null}if(!this._options.xmlMode&&this._cbs.onclosetag&&this._tagname in voidElements){this._cbs.onclosetag(this._tagname)}this._tagname=""};Parser.prototype.onclosetag=function(name){this._updatePosition(1);if(this._lowerCaseTagNames){name=name.toLowerCase()}if(this._stack.length&&(!(name in voidElements)||this._options.xmlMode)){var pos=this._stack.lastIndexOf(name);if(pos!==-1){if(this._cbs.onclosetag){pos=this._stack.length-pos;while(pos--)this._cbs.onclosetag(this._stack.pop())}else this._stack.length=pos}else if(name==="p"&&!this._options.xmlMode){this.onopentagname(name);this._closeCurrentTag()}}else if(!this._options.xmlMode&&(name==="br"||name==="p")){this.onopentagname(name);this._closeCurrentTag()}};Parser.prototype.onselfclosingtag=function(){if(this._options.xmlMode||this._options.recognizeSelfClosing){this._closeCurrentTag()}else{this.onopentagend()}};Parser.prototype._closeCurrentTag=function(){var name=this._tagname;this.onopentagend();if(this._stack[this._stack.length-1]===name){if(this._cbs.onclosetag){this._cbs.onclosetag(name)}this._stack.pop()}};Parser.prototype.onattribname=function(name){if(this._lowerCaseAttributeNames){name=name.toLowerCase()}this._attribname=name};Parser.prototype.onattribdata=function(value){this._attribvalue+=value};Parser.prototype.onattribend=function(){if(this._cbs.onattribute)this._cbs.onattribute(this._attribname,this._attribvalue);if(this._attribs&&!Object.prototype.hasOwnProperty.call(this._attribs,this._attribname)){this._attribs[this._attribname]=this._attribvalue}this._attribname="";this._attribvalue=""};Parser.prototype._getInstructionName=function(value){var idx=value.search(re_nameEnd),name=idx<0?value:value.substr(0,idx);if(this._lowerCaseTagNames){name=name.toLowerCase()}return name};Parser.prototype.ondeclaration=function(value){if(this._cbs.onprocessinginstruction){var name=this._getInstructionName(value);this._cbs.onprocessinginstruction("!"+name,"!"+value)}};Parser.prototype.onprocessinginstruction=function(value){if(this._cbs.onprocessinginstruction){var name=this._getInstructionName(value);this._cbs.onprocessinginstruction("?"+name,"?"+value)}};Parser.prototype.oncomment=function(value){this._updatePosition(4);if(this._cbs.oncomment)this._cbs.oncomment(value);if(this._cbs.oncommentend)this._cbs.oncommentend()};Parser.prototype.oncdata=function(value){this._updatePosition(1);if(this._options.xmlMode||this._options.recognizeCDATA){if(this._cbs.oncdatastart)this._cbs.oncdatastart();if(this._cbs.ontext)this._cbs.ontext(value);if(this._cbs.oncdataend)this._cbs.oncdataend()}else{this.oncomment("[CDATA["+value+"]]")}};Parser.prototype.onerror=function(err){if(this._cbs.onerror)this._cbs.onerror(err)};Parser.prototype.onend=function(){if(this._cbs.onclosetag){for(var i=this._stack.length;i>0;this._cbs.onclosetag(this._stack[--i]));}if(this._cbs.onend)this._cbs.onend()};Parser.prototype.reset=function(){if(this._cbs.onreset)this._cbs.onreset();this._tokenizer.reset();this._tagname="";this._attribname="";this._attribs=null;this._stack=[];if(this._cbs.onparserinit)this._cbs.onparserinit(this)};Parser.prototype.parseComplete=function(data){this.reset();this.end(data)};Parser.prototype.write=function(chunk){this._tokenizer.write(chunk)};Parser.prototype.end=function(chunk){this._tokenizer.end(chunk)};Parser.prototype.pause=function(){this._tokenizer.pause()};Parser.prototype.resume=function(){this._tokenizer.resume()};Parser.prototype.parseChunk=Parser.prototype.write;Parser.prototype.done=Parser.prototype.end;module.exports=Parser},{"./Tokenizer.js":34,events:28,inherits:38}],32:[function(require,module,exports){module.exports=ProxyHandler;function ProxyHandler(cbs){this._cbs=cbs||{}}var EVENTS=require("./").EVENTS;Object.keys(EVENTS).forEach(function(name){if(EVENTS[name]===0){name="on"+name;ProxyHandler.prototype[name]=function(){if(this._cbs[name])this._cbs[name]()}}else if(EVENTS[name]===1){name="on"+name;ProxyHandler.prototype[name]=function(a){if(this._cbs[name])this._cbs[name](a)}}else if(EVENTS[name]===2){name="on"+name;ProxyHandler.prototype[name]=function(a,b){if(this._cbs[name])this._cbs[name](a,b)}}else{throw Error("wrong number of arguments")}})},{"./":36}],33:[function(require,module,exports){module.exports=Stream;var Parser=require("./WritableStream.js");function Stream(options){Parser.call(this,new Cbs(this),options)}require("inherits")(Stream,Parser);Stream.prototype.readable=true;function Cbs(scope){this.scope=scope}var EVENTS=require("../").EVENTS;Object.keys(EVENTS).forEach(function(name){if(EVENTS[name]===0){Cbs.prototype["on"+name]=function(){this.scope.emit(name)}}else if(EVENTS[name]===1){Cbs.prototype["on"+name]=function(a){this.scope.emit(name,a)}}else if(EVENTS[name]===2){Cbs.prototype["on"+name]=function(a,b){this.scope.emit(name,a,b)}}else{throw Error("wrong number of arguments!")}})},{"../":36,"./WritableStream.js":35,inherits:38}],34:[function(require,module,exports){module.exports=Tokenizer;var decodeCodePoint=require("entities/lib/decode_codepoint.js"),entityMap=require("entities/maps/entities.json"),legacyMap=require("entities/maps/legacy.json"),xmlMap=require("entities/maps/xml.json"),i=0,TEXT=i++,BEFORE_TAG_NAME=i++,IN_TAG_NAME=i++,IN_SELF_CLOSING_TAG=i++,BEFORE_CLOSING_TAG_NAME=i++,IN_CLOSING_TAG_NAME=i++,AFTER_CLOSING_TAG_NAME=i++,BEFORE_ATTRIBUTE_NAME=i++,IN_ATTRIBUTE_NAME=i++,AFTER_ATTRIBUTE_NAME=i++,BEFORE_ATTRIBUTE_VALUE=i++,IN_ATTRIBUTE_VALUE_DQ=i++,IN_ATTRIBUTE_VALUE_SQ=i++,IN_ATTRIBUTE_VALUE_NQ=i++,BEFORE_DECLARATION=i++,IN_DECLARATION=i++,IN_PROCESSING_INSTRUCTION=i++,BEFORE_COMMENT=i++,IN_COMMENT=i++,AFTER_COMMENT_1=i++,AFTER_COMMENT_2=i++,BEFORE_CDATA_1=i++,BEFORE_CDATA_2=i++,BEFORE_CDATA_3=i++,BEFORE_CDATA_4=i++,BEFORE_CDATA_5=i++,BEFORE_CDATA_6=i++,IN_CDATA=i++,AFTER_CDATA_1=i++,AFTER_CDATA_2=i++,BEFORE_SPECIAL=i++,BEFORE_SPECIAL_END=i++,BEFORE_SCRIPT_1=i++,BEFORE_SCRIPT_2=i++,BEFORE_SCRIPT_3=i++,BEFORE_SCRIPT_4=i++,BEFORE_SCRIPT_5=i++,AFTER_SCRIPT_1=i++,AFTER_SCRIPT_2=i++,AFTER_SCRIPT_3=i++,AFTER_SCRIPT_4=i++,AFTER_SCRIPT_5=i++,BEFORE_STYLE_1=i++,BEFORE_STYLE_2=i++,BEFORE_STYLE_3=i++,BEFORE_STYLE_4=i++,AFTER_STYLE_1=i++,AFTER_STYLE_2=i++,AFTER_STYLE_3=i++,AFTER_STYLE_4=i++,BEFORE_ENTITY=i++,BEFORE_NUMERIC_ENTITY=i++,IN_NAMED_ENTITY=i++,IN_NUMERIC_ENTITY=i++,IN_HEX_ENTITY=i++,j=0,SPECIAL_NONE=j++,SPECIAL_SCRIPT=j++,SPECIAL_STYLE=j++;function whitespace(c){return c===" "||c==="\n"||c==="\t"||c==="\f"||c==="\r"}function characterState(char,SUCCESS){return function(c){if(c===char)this._state=SUCCESS}}function ifElseState(upper,SUCCESS,FAILURE){var lower=upper.toLowerCase();if(upper===lower){return function(c){if(c===lower){this._state=SUCCESS}else{this._state=FAILURE;this._index--}}}else{return function(c){if(c===lower||c===upper){this._state=SUCCESS}else{this._state=FAILURE;this._index--}}}}function consumeSpecialNameChar(upper,NEXT_STATE){var lower=upper.toLowerCase();return function(c){if(c===lower||c===upper){this._state=NEXT_STATE}else{this._state=IN_TAG_NAME;this._index--}}}function Tokenizer(options,cbs){this._state=TEXT;this._buffer="";this._sectionStart=0;this._index=0;this._bufferOffset=0;this._baseState=TEXT;this._special=SPECIAL_NONE;this._cbs=cbs;this._running=true;this._ended=false;this._xmlMode=!!(options&&options.xmlMode);this._decodeEntities=!!(options&&options.decodeEntities)}Tokenizer.prototype._stateText=function(c){if(c==="<"){if(this._index>this._sectionStart){this._cbs.ontext(this._getSection())}this._state=BEFORE_TAG_NAME;this._sectionStart=this._index}else if(this._decodeEntities&&this._special===SPECIAL_NONE&&c==="&"){if(this._index>this._sectionStart){this._cbs.ontext(this._getSection())}this._baseState=TEXT;this._state=BEFORE_ENTITY;this._sectionStart=this._index}};Tokenizer.prototype._stateBeforeTagName=function(c){if(c==="/"){this._state=BEFORE_CLOSING_TAG_NAME}else if(c==="<"){this._cbs.ontext(this._getSection());this._sectionStart=this._index}else if(c===">"||this._special!==SPECIAL_NONE||whitespace(c)){this._state=TEXT}else if(c==="!"){this._state=BEFORE_DECLARATION;this._sectionStart=this._index+1}else if(c==="?"){this._state=IN_PROCESSING_INSTRUCTION;this._sectionStart=this._index+1}else{this._state=!this._xmlMode&&(c==="s"||c==="S")?BEFORE_SPECIAL:IN_TAG_NAME;this._sectionStart=this._index}};Tokenizer.prototype._stateInTagName=function(c){if(c==="/"||c===">"||whitespace(c)){this._emitToken("onopentagname");this._state=BEFORE_ATTRIBUTE_NAME;this._index--}};Tokenizer.prototype._stateBeforeCloseingTagName=function(c){if(whitespace(c));else if(c===">"){this._state=TEXT}else if(this._special!==SPECIAL_NONE){if(c==="s"||c==="S"){this._state=BEFORE_SPECIAL_END}else{this._state=TEXT;this._index--}}else{this._state=IN_CLOSING_TAG_NAME;this._sectionStart=this._index}};Tokenizer.prototype._stateInCloseingTagName=function(c){if(c===">"||whitespace(c)){this._emitToken("onclosetag");this._state=AFTER_CLOSING_TAG_NAME;this._index--}};Tokenizer.prototype._stateAfterCloseingTagName=function(c){if(c===">"){this._state=TEXT;this._sectionStart=this._index+1}};Tokenizer.prototype._stateBeforeAttributeName=function(c){if(c===">"){this._cbs.onopentagend();this._state=TEXT;this._sectionStart=this._index+1}else if(c==="/"){this._state=IN_SELF_CLOSING_TAG}else if(!whitespace(c)){this._state=IN_ATTRIBUTE_NAME;this._sectionStart=this._index}};Tokenizer.prototype._stateInSelfClosingTag=function(c){if(c===">"){this._cbs.onselfclosingtag();this._state=TEXT;this._sectionStart=this._index+1}else if(!whitespace(c)){this._state=BEFORE_ATTRIBUTE_NAME;this._index--}};Tokenizer.prototype._stateInAttributeName=function(c){if(c==="="||c==="/"||c===">"||whitespace(c)){this._cbs.onattribname(this._getSection());this._sectionStart=-1;this._state=AFTER_ATTRIBUTE_NAME;this._index--}};Tokenizer.prototype._stateAfterAttributeName=function(c){if(c==="="){this._state=BEFORE_ATTRIBUTE_VALUE}else if(c==="/"||c===">"){this._cbs.onattribend();this._state=BEFORE_ATTRIBUTE_NAME;this._index--}else if(!whitespace(c)){this._cbs.onattribend();this._state=IN_ATTRIBUTE_NAME;this._sectionStart=this._index}};Tokenizer.prototype._stateBeforeAttributeValue=function(c){if(c==='"'){this._state=IN_ATTRIBUTE_VALUE_DQ;this._sectionStart=this._index+1}else if(c==="'"){this._state=IN_ATTRIBUTE_VALUE_SQ;this._sectionStart=this._index+1}else if(!whitespace(c)){this._state=IN_ATTRIBUTE_VALUE_NQ;this._sectionStart=this._index;this._index--}};Tokenizer.prototype._stateInAttributeValueDoubleQuotes=function(c){if(c==='"'){this._emitToken("onattribdata");this._cbs.onattribend();this._state=BEFORE_ATTRIBUTE_NAME}else if(this._decodeEntities&&c==="&"){this._emitToken("onattribdata");this._baseState=this._state;this._state=BEFORE_ENTITY;this._sectionStart=this._index}};Tokenizer.prototype._stateInAttributeValueSingleQuotes=function(c){if(c==="'"){this._emitToken("onattribdata");this._cbs.onattribend();this._state=BEFORE_ATTRIBUTE_NAME}else if(this._decodeEntities&&c==="&"){this._emitToken("onattribdata");this._baseState=this._state;this._state=BEFORE_ENTITY;this._sectionStart=this._index}};Tokenizer.prototype._stateInAttributeValueNoQuotes=function(c){if(whitespace(c)||c===">"){this._emitToken("onattribdata");this._cbs.onattribend();this._state=BEFORE_ATTRIBUTE_NAME;this._index--}else if(this._decodeEntities&&c==="&"){this._emitToken("onattribdata");this._baseState=this._state;this._state=BEFORE_ENTITY;this._sectionStart=this._index}};Tokenizer.prototype._stateBeforeDeclaration=function(c){this._state=c==="["?BEFORE_CDATA_1:c==="-"?BEFORE_COMMENT:IN_DECLARATION};Tokenizer.prototype._stateInDeclaration=function(c){if(c===">"){this._cbs.ondeclaration(this._getSection());this._state=TEXT;this._sectionStart=this._index+1}};Tokenizer.prototype._stateInProcessingInstruction=function(c){if(c===">"){this._cbs.onprocessinginstruction(this._getSection());this._state=TEXT;this._sectionStart=this._index+1}};Tokenizer.prototype._stateBeforeComment=function(c){if(c==="-"){this._state=IN_COMMENT;this._sectionStart=this._index+1}else{this._state=IN_DECLARATION}};Tokenizer.prototype._stateInComment=function(c){if(c==="-")this._state=AFTER_COMMENT_1};Tokenizer.prototype._stateAfterComment1=function(c){if(c==="-"){this._state=AFTER_COMMENT_2}else{this._state=IN_COMMENT}};Tokenizer.prototype._stateAfterComment2=function(c){if(c===">"){this._cbs.oncomment(this._buffer.substring(this._sectionStart,this._index-2));this._state=TEXT;this._sectionStart=this._index+1}else if(c!=="-"){this._state=IN_COMMENT}};Tokenizer.prototype._stateBeforeCdata1=ifElseState("C",BEFORE_CDATA_2,IN_DECLARATION);Tokenizer.prototype._stateBeforeCdata2=ifElseState("D",BEFORE_CDATA_3,IN_DECLARATION);Tokenizer.prototype._stateBeforeCdata3=ifElseState("A",BEFORE_CDATA_4,IN_DECLARATION);Tokenizer.prototype._stateBeforeCdata4=ifElseState("T",BEFORE_CDATA_5,IN_DECLARATION);Tokenizer.prototype._stateBeforeCdata5=ifElseState("A",BEFORE_CDATA_6,IN_DECLARATION);Tokenizer.prototype._stateBeforeCdata6=function(c){if(c==="["){this._state=IN_CDATA;this._sectionStart=this._index+1}else{this._state=IN_DECLARATION;this._index--}};Tokenizer.prototype._stateInCdata=function(c){if(c==="]")this._state=AFTER_CDATA_1};Tokenizer.prototype._stateAfterCdata1=characterState("]",AFTER_CDATA_2);Tokenizer.prototype._stateAfterCdata2=function(c){if(c===">"){this._cbs.oncdata(this._buffer.substring(this._sectionStart,this._index-2));this._state=TEXT;this._sectionStart=this._index+1}else if(c!=="]"){this._state=IN_CDATA}};Tokenizer.prototype._stateBeforeSpecial=function(c){if(c==="c"||c==="C"){this._state=BEFORE_SCRIPT_1}else if(c==="t"||c==="T"){this._state=BEFORE_STYLE_1}else{this._state=IN_TAG_NAME;this._index--}};Tokenizer.prototype._stateBeforeSpecialEnd=function(c){if(this._special===SPECIAL_SCRIPT&&(c==="c"||c==="C")){this._state=AFTER_SCRIPT_1}else if(this._special===SPECIAL_STYLE&&(c==="t"||c==="T")){this._state=AFTER_STYLE_1}else this._state=TEXT};Tokenizer.prototype._stateBeforeScript1=consumeSpecialNameChar("R",BEFORE_SCRIPT_2);Tokenizer.prototype._stateBeforeScript2=consumeSpecialNameChar("I",BEFORE_SCRIPT_3);Tokenizer.prototype._stateBeforeScript3=consumeSpecialNameChar("P",BEFORE_SCRIPT_4);Tokenizer.prototype._stateBeforeScript4=consumeSpecialNameChar("T",BEFORE_SCRIPT_5);Tokenizer.prototype._stateBeforeScript5=function(c){if(c==="/"||c===">"||whitespace(c)){this._special=SPECIAL_SCRIPT}this._state=IN_TAG_NAME;this._index--};Tokenizer.prototype._stateAfterScript1=ifElseState("R",AFTER_SCRIPT_2,TEXT);Tokenizer.prototype._stateAfterScript2=ifElseState("I",AFTER_SCRIPT_3,TEXT);Tokenizer.prototype._stateAfterScript3=ifElseState("P",AFTER_SCRIPT_4,TEXT);Tokenizer.prototype._stateAfterScript4=ifElseState("T",AFTER_SCRIPT_5,TEXT);Tokenizer.prototype._stateAfterScript5=function(c){if(c===">"||whitespace(c)){this._special=SPECIAL_NONE;this._state=IN_CLOSING_TAG_NAME;this._sectionStart=this._index-6;this._index--}else this._state=TEXT};Tokenizer.prototype._stateBeforeStyle1=consumeSpecialNameChar("Y",BEFORE_STYLE_2);Tokenizer.prototype._stateBeforeStyle2=consumeSpecialNameChar("L",BEFORE_STYLE_3);Tokenizer.prototype._stateBeforeStyle3=consumeSpecialNameChar("E",BEFORE_STYLE_4);Tokenizer.prototype._stateBeforeStyle4=function(c){if(c==="/"||c===">"||whitespace(c)){this._special=SPECIAL_STYLE}this._state=IN_TAG_NAME;this._index--};Tokenizer.prototype._stateAfterStyle1=ifElseState("Y",AFTER_STYLE_2,TEXT);Tokenizer.prototype._stateAfterStyle2=ifElseState("L",AFTER_STYLE_3,TEXT);Tokenizer.prototype._stateAfterStyle3=ifElseState("E",AFTER_STYLE_4,TEXT);Tokenizer.prototype._stateAfterStyle4=function(c){if(c===">"||whitespace(c)){this._special=SPECIAL_NONE;this._state=IN_CLOSING_TAG_NAME;this._sectionStart=this._index-5;this._index--}else this._state=TEXT};Tokenizer.prototype._stateBeforeEntity=ifElseState("#",BEFORE_NUMERIC_ENTITY,IN_NAMED_ENTITY);Tokenizer.prototype._stateBeforeNumericEntity=ifElseState("X",IN_HEX_ENTITY,IN_NUMERIC_ENTITY);Tokenizer.prototype._parseNamedEntityStrict=function(){if(this._sectionStart+1<this._index){var entity=this._buffer.substring(this._sectionStart+1,this._index),map=this._xmlMode?xmlMap:entityMap;if(map.hasOwnProperty(entity)){this._emitPartial(map[entity]);this._sectionStart=this._index+1}}};Tokenizer.prototype._parseLegacyEntity=function(){var start=this._sectionStart+1,limit=this._index-start;if(limit>6)limit=6;while(limit>=2){var entity=this._buffer.substr(start,limit);if(legacyMap.hasOwnProperty(entity)){this._emitPartial(legacyMap[entity]);this._sectionStart+=limit+1;return}else{limit--}}};Tokenizer.prototype._stateInNamedEntity=function(c){if(c===";"){this._parseNamedEntityStrict();if(this._sectionStart+1<this._index&&!this._xmlMode){this._parseLegacyEntity()}this._state=this._baseState}else if((c<"a"||c>"z")&&(c<"A"||c>"Z")&&(c<"0"||c>"9")){if(this._xmlMode);else if(this._sectionStart+1===this._index);else if(this._baseState!==TEXT){if(c!=="="){this._parseNamedEntityStrict()}}else{this._parseLegacyEntity()}this._state=this._baseState;this._index--}};Tokenizer.prototype._decodeNumericEntity=function(offset,base){var sectionStart=this._sectionStart+offset;if(sectionStart!==this._index){var entity=this._buffer.substring(sectionStart,this._index);var parsed=parseInt(entity,base);this._emitPartial(decodeCodePoint(parsed));this._sectionStart=this._index}else{this._sectionStart--}this._state=this._baseState};Tokenizer.prototype._stateInNumericEntity=function(c){if(c===";"){this._decodeNumericEntity(2,10);this._sectionStart++}else if(c<"0"||c>"9"){if(!this._xmlMode){this._decodeNumericEntity(2,10)}else{this._state=this._baseState}this._index--}};Tokenizer.prototype._stateInHexEntity=function(c){if(c===";"){this._decodeNumericEntity(3,16);this._sectionStart++}else if((c<"a"||c>"f")&&(c<"A"||c>"F")&&(c<"0"||c>"9")){if(!this._xmlMode){this._decodeNumericEntity(3,16)}else{this._state=this._baseState}this._index--}};Tokenizer.prototype._cleanup=function(){if(this._sectionStart<0){this._buffer="";this._index=0;this._bufferOffset+=this._index}else if(this._running){if(this._state===TEXT){if(this._sectionStart!==this._index){this._cbs.ontext(this._buffer.substr(this._sectionStart))}this._buffer="";this._bufferOffset+=this._index;this._index=0}else if(this._sectionStart===this._index){this._buffer="";this._bufferOffset+=this._index;this._index=0}else{this._buffer=this._buffer.substr(this._sectionStart);this._index-=this._sectionStart;this._bufferOffset+=this._sectionStart}this._sectionStart=0}};Tokenizer.prototype.write=function(chunk){if(this._ended)this._cbs.onerror(Error(".write() after done!"));this._buffer+=chunk;this._parse()};Tokenizer.prototype._parse=function(){while(this._index<this._buffer.length&&this._running){var c=this._buffer.charAt(this._index);if(this._state===TEXT){this._stateText(c)}else if(this._state===BEFORE_TAG_NAME){this._stateBeforeTagName(c)}else if(this._state===IN_TAG_NAME){this._stateInTagName(c)}else if(this._state===BEFORE_CLOSING_TAG_NAME){this._stateBeforeCloseingTagName(c)}else if(this._state===IN_CLOSING_TAG_NAME){this._stateInCloseingTagName(c)}else if(this._state===AFTER_CLOSING_TAG_NAME){this._stateAfterCloseingTagName(c)}else if(this._state===IN_SELF_CLOSING_TAG){this._stateInSelfClosingTag(c)}else if(this._state===BEFORE_ATTRIBUTE_NAME){this._stateBeforeAttributeName(c)}else if(this._state===IN_ATTRIBUTE_NAME){this._stateInAttributeName(c)}else if(this._state===AFTER_ATTRIBUTE_NAME){this._stateAfterAttributeName(c)}else if(this._state===BEFORE_ATTRIBUTE_VALUE){this._stateBeforeAttributeValue(c)}else if(this._state===IN_ATTRIBUTE_VALUE_DQ){this._stateInAttributeValueDoubleQuotes(c)}else if(this._state===IN_ATTRIBUTE_VALUE_SQ){this._stateInAttributeValueSingleQuotes(c)}else if(this._state===IN_ATTRIBUTE_VALUE_NQ){this._stateInAttributeValueNoQuotes(c)}else if(this._state===BEFORE_DECLARATION){this._stateBeforeDeclaration(c)}else if(this._state===IN_DECLARATION){this._stateInDeclaration(c)}else if(this._state===IN_PROCESSING_INSTRUCTION){this._stateInProcessingInstruction(c)}else if(this._state===BEFORE_COMMENT){this._stateBeforeComment(c)}else if(this._state===IN_COMMENT){this._stateInComment(c)}else if(this._state===AFTER_COMMENT_1){this._stateAfterComment1(c)}else if(this._state===AFTER_COMMENT_2){this._stateAfterComment2(c)}else if(this._state===BEFORE_CDATA_1){this._stateBeforeCdata1(c)}else if(this._state===BEFORE_CDATA_2){this._stateBeforeCdata2(c)}else if(this._state===BEFORE_CDATA_3){this._stateBeforeCdata3(c)}else if(this._state===BEFORE_CDATA_4){this._stateBeforeCdata4(c)}else if(this._state===BEFORE_CDATA_5){this._stateBeforeCdata5(c)}else if(this._state===BEFORE_CDATA_6){this._stateBeforeCdata6(c)}else if(this._state===IN_CDATA){this._stateInCdata(c)}else if(this._state===AFTER_CDATA_1){this._stateAfterCdata1(c)}else if(this._state===AFTER_CDATA_2){this._stateAfterCdata2(c)}else if(this._state===BEFORE_SPECIAL){this._stateBeforeSpecial(c)}else if(this._state===BEFORE_SPECIAL_END){this._stateBeforeSpecialEnd(c)}else if(this._state===BEFORE_SCRIPT_1){this._stateBeforeScript1(c)}else if(this._state===BEFORE_SCRIPT_2){this._stateBeforeScript2(c)}else if(this._state===BEFORE_SCRIPT_3){this._stateBeforeScript3(c)}else if(this._state===BEFORE_SCRIPT_4){this._stateBeforeScript4(c)}else if(this._state===BEFORE_SCRIPT_5){this._stateBeforeScript5(c)}else if(this._state===AFTER_SCRIPT_1){this._stateAfterScript1(c)}else if(this._state===AFTER_SCRIPT_2){this._stateAfterScript2(c)}else if(this._state===AFTER_SCRIPT_3){this._stateAfterScript3(c)}else if(this._state===AFTER_SCRIPT_4){this._stateAfterScript4(c)}else if(this._state===AFTER_SCRIPT_5){this._stateAfterScript5(c)}else if(this._state===BEFORE_STYLE_1){this._stateBeforeStyle1(c)}else if(this._state===BEFORE_STYLE_2){this._stateBeforeStyle2(c)}else if(this._state===BEFORE_STYLE_3){this._stateBeforeStyle3(c)}else if(this._state===BEFORE_STYLE_4){this._stateBeforeStyle4(c)}else if(this._state===AFTER_STYLE_1){this._stateAfterStyle1(c)}else if(this._state===AFTER_STYLE_2){this._stateAfterStyle2(c)}else if(this._state===AFTER_STYLE_3){this._stateAfterStyle3(c)}else if(this._state===AFTER_STYLE_4){this._stateAfterStyle4(c)}else if(this._state===BEFORE_ENTITY){this._stateBeforeEntity(c)}else if(this._state===BEFORE_NUMERIC_ENTITY){this._stateBeforeNumericEntity(c)}else if(this._state===IN_NAMED_ENTITY){this._stateInNamedEntity(c)}else if(this._state===IN_NUMERIC_ENTITY){this._stateInNumericEntity(c)}else if(this._state===IN_HEX_ENTITY){this._stateInHexEntity(c)}else{this._cbs.onerror(Error("unknown _state"),this._state)}this._index++}this._cleanup()};Tokenizer.prototype.pause=function(){this._running=false};Tokenizer.prototype.resume=function(){this._running=true;if(this._index<this._buffer.length){this._parse()}if(this._ended){this._finish()}};Tokenizer.prototype.end=function(chunk){if(this._ended)this._cbs.onerror(Error(".end() after done!"));if(chunk)this.write(chunk);this._ended=true;if(this._running)this._finish()};Tokenizer.prototype._finish=function(){if(this._sectionStart<this._index){this._handleTrailingData()}this._cbs.onend()};Tokenizer.prototype._handleTrailingData=function(){var data=this._buffer.substr(this._sectionStart);if(this._state===IN_CDATA||this._state===AFTER_CDATA_1||this._state===AFTER_CDATA_2){this._cbs.oncdata(data)}else if(this._state===IN_COMMENT||this._state===AFTER_COMMENT_1||this._state===AFTER_COMMENT_2){this._cbs.oncomment(data)}else if(this._state===IN_NAMED_ENTITY&&!this._xmlMode){this._parseLegacyEntity();if(this._sectionStart<this._index){this._state=this._baseState;this._handleTrailingData()}}else if(this._state===IN_NUMERIC_ENTITY&&!this._xmlMode){this._decodeNumericEntity(2,10);if(this._sectionStart<this._index){this._state=this._baseState;this._handleTrailingData()}}else if(this._state===IN_HEX_ENTITY&&!this._xmlMode){this._decodeNumericEntity(3,16);if(this._sectionStart<this._index){this._state=this._baseState;this._handleTrailingData()}}else if(this._state!==IN_TAG_NAME&&this._state!==BEFORE_ATTRIBUTE_NAME&&this._state!==BEFORE_ATTRIBUTE_VALUE&&this._state!==AFTER_ATTRIBUTE_NAME&&this._state!==IN_ATTRIBUTE_NAME&&this._state!==IN_ATTRIBUTE_VALUE_SQ&&this._state!==IN_ATTRIBUTE_VALUE_DQ&&this._state!==IN_ATTRIBUTE_VALUE_NQ&&this._state!==IN_CLOSING_TAG_NAME){
+this._cbs.ontext(data)}};Tokenizer.prototype.reset=function(){Tokenizer.call(this,{xmlMode:this._xmlMode,decodeEntities:this._decodeEntities},this._cbs)};Tokenizer.prototype.getAbsoluteIndex=function(){return this._bufferOffset+this._index};Tokenizer.prototype._getSection=function(){return this._buffer.substring(this._sectionStart,this._index)};Tokenizer.prototype._emitToken=function(name){this._cbs[name](this._getSection());this._sectionStart=-1};Tokenizer.prototype._emitPartial=function(value){if(this._baseState!==TEXT){this._cbs.onattribdata(value)}else{this._cbs.ontext(value)}}},{"entities/lib/decode_codepoint.js":22,"entities/maps/entities.json":25,"entities/maps/legacy.json":26,"entities/maps/xml.json":27}],35:[function(require,module,exports){module.exports=Stream;var Parser=require("./Parser.js"),WritableStream=require("stream").Writable||require("readable-stream").Writable,StringDecoder=require("string_decoder").StringDecoder,Buffer=require("buffer").Buffer;function Stream(cbs,options){var parser=this._parser=new Parser(cbs,options);var decoder=this._decoder=new StringDecoder;WritableStream.call(this,{decodeStrings:false});this.once("finish",function(){parser.end(decoder.end())})}require("inherits")(Stream,WritableStream);WritableStream.prototype._write=function(chunk,encoding,cb){if(chunk instanceof Buffer)chunk=this._decoder.write(chunk);this._parser.write(chunk);cb()}},{"./Parser.js":31,buffer:5,inherits:38,"readable-stream":3,stream:55,string_decoder:56}],36:[function(require,module,exports){var Parser=require("./Parser.js"),DomHandler=require("domhandler");function defineProp(name,value){delete module.exports[name];module.exports[name]=value;return value}module.exports={Parser:Parser,Tokenizer:require("./Tokenizer.js"),ElementType:require("domelementtype"),DomHandler:DomHandler,get FeedHandler(){return defineProp("FeedHandler",require("./FeedHandler.js"))},get Stream(){return defineProp("Stream",require("./Stream.js"))},get WritableStream(){return defineProp("WritableStream",require("./WritableStream.js"))},get ProxyHandler(){return defineProp("ProxyHandler",require("./ProxyHandler.js"))},get DomUtils(){return defineProp("DomUtils",require("domutils"))},get CollectingHandler(){return defineProp("CollectingHandler",require("./CollectingHandler.js"))},DefaultHandler:DomHandler,get RssHandler(){return defineProp("RssHandler",this.FeedHandler)},parseDOM:function(data,options){var handler=new DomHandler(options);new Parser(handler,options).end(data);return handler.dom},parseFeed:function(feed,options){var handler=new module.exports.FeedHandler(options);new Parser(handler,options).end(feed);return handler.dom},createDomStream:function(cb,options,elementCb){var handler=new DomHandler(cb,options,elementCb);return new Parser(handler,options)},EVENTS:{attribute:2,cdatastart:0,cdataend:0,text:1,processinginstruction:2,comment:1,commentend:0,closetag:1,opentag:2,opentagname:1,error:1,end:0}}},{"./CollectingHandler.js":29,"./FeedHandler.js":30,"./Parser.js":31,"./ProxyHandler.js":32,"./Stream.js":33,"./Tokenizer.js":34,"./WritableStream.js":35,domelementtype:9,domhandler:10,domutils:13}],37:[function(require,module,exports){exports.read=function(buffer,offset,isLE,mLen,nBytes){var e,m;var eLen=nBytes*8-mLen-1;var eMax=(1<<eLen)-1;var eBias=eMax>>1;var nBits=-7;var i=isLE?nBytes-1:0;var d=isLE?-1:1;var s=buffer[offset+i];i+=d;e=s&(1<<-nBits)-1;s>>=-nBits;nBits+=eLen;for(;nBits>0;e=e*256+buffer[offset+i],i+=d,nBits-=8){}m=e&(1<<-nBits)-1;e>>=-nBits;nBits+=mLen;for(;nBits>0;m=m*256+buffer[offset+i],i+=d,nBits-=8){}if(e===0){e=1-eBias}else if(e===eMax){return m?NaN:(s?-1:1)*Infinity}else{m=m+Math.pow(2,mLen);e=e-eBias}return(s?-1:1)*m*Math.pow(2,e-mLen)};exports.write=function(buffer,value,offset,isLE,mLen,nBytes){var e,m,c;var eLen=nBytes*8-mLen-1;var eMax=(1<<eLen)-1;var eBias=eMax>>1;var rt=mLen===23?Math.pow(2,-24)-Math.pow(2,-77):0;var i=isLE?0:nBytes-1;var d=isLE?1:-1;var s=value<0||value===0&&1/value<0?1:0;value=Math.abs(value);if(isNaN(value)||value===Infinity){m=isNaN(value)?1:0;e=eMax}else{e=Math.floor(Math.log(value)/Math.LN2);if(value*(c=Math.pow(2,-e))<1){e--;c*=2}if(e+eBias>=1){value+=rt/c}else{value+=rt*Math.pow(2,1-eBias)}if(value*c>=2){e++;c/=2}if(e+eBias>=eMax){m=0;e=eMax}else if(e+eBias>=1){m=(value*c-1)*Math.pow(2,mLen);e=e+eBias}else{m=value*Math.pow(2,eBias-1)*Math.pow(2,mLen);e=0}}for(;mLen>=8;buffer[offset+i]=m&255,i+=d,m/=256,mLen-=8){}e=e<<mLen|m;eLen+=mLen;for(;eLen>0;buffer[offset+i]=e&255,i+=d,e/=256,eLen-=8){}buffer[offset+i-d]|=s*128}},{}],38:[function(require,module,exports){if(typeof Object.create==="function"){module.exports=function inherits(ctor,superCtor){ctor.super_=superCtor;ctor.prototype=Object.create(superCtor.prototype,{constructor:{value:ctor,enumerable:false,writable:true,configurable:true}})}}else{module.exports=function inherits(ctor,superCtor){ctor.super_=superCtor;var TempCtor=function(){};TempCtor.prototype=superCtor.prototype;ctor.prototype=new TempCtor;ctor.prototype.constructor=ctor}}},{}],39:[function(require,module,exports){module.exports=function(obj){return obj!=null&&(isBuffer(obj)||isSlowBuffer(obj)||!!obj._isBuffer)};function isBuffer(obj){return!!obj.constructor&&typeof obj.constructor.isBuffer==="function"&&obj.constructor.isBuffer(obj)}function isSlowBuffer(obj){return typeof obj.readFloatLE==="function"&&typeof obj.slice==="function"&&isBuffer(obj.slice(0,0))}},{}],40:[function(require,module,exports){var toString={}.toString;module.exports=Array.isArray||function(arr){return toString.call(arr)=="[object Array]"}},{}],41:[function(require,module,exports){(function(process){"use strict";if(!process.version||process.version.indexOf("v0.")===0||process.version.indexOf("v1.")===0&&process.version.indexOf("v1.8.")!==0){module.exports=nextTick}else{module.exports=process.nextTick}function nextTick(fn,arg1,arg2,arg3){if(typeof fn!=="function"){throw new TypeError('"callback" argument must be a function')}var len=arguments.length;var args,i;switch(len){case 0:case 1:return process.nextTick(fn);case 2:return process.nextTick(function afterTickOne(){fn.call(null,arg1)});case 3:return process.nextTick(function afterTickTwo(){fn.call(null,arg1,arg2)});case 4:return process.nextTick(function afterTickThree(){fn.call(null,arg1,arg2,arg3)});default:args=new Array(len-1);i=0;while(i<args.length){args[i++]=arguments[i]}return process.nextTick(function afterTick(){fn.apply(null,args)})}}}).call(this,require("_process"))},{_process:42}],42:[function(require,module,exports){var process=module.exports={};var cachedSetTimeout;var cachedClearTimeout;function defaultSetTimout(){throw new Error("setTimeout has not been defined")}function defaultClearTimeout(){throw new Error("clearTimeout has not been defined")}(function(){try{if(typeof setTimeout==="function"){cachedSetTimeout=setTimeout}else{cachedSetTimeout=defaultSetTimout}}catch(e){cachedSetTimeout=defaultSetTimout}try{if(typeof clearTimeout==="function"){cachedClearTimeout=clearTimeout}else{cachedClearTimeout=defaultClearTimeout}}catch(e){cachedClearTimeout=defaultClearTimeout}})();function runTimeout(fun){if(cachedSetTimeout===setTimeout){return setTimeout(fun,0)}if((cachedSetTimeout===defaultSetTimout||!cachedSetTimeout)&&setTimeout){cachedSetTimeout=setTimeout;return setTimeout(fun,0)}try{return cachedSetTimeout(fun,0)}catch(e){try{return cachedSetTimeout.call(null,fun,0)}catch(e){return cachedSetTimeout.call(this,fun,0)}}}function runClearTimeout(marker){if(cachedClearTimeout===clearTimeout){return clearTimeout(marker)}if((cachedClearTimeout===defaultClearTimeout||!cachedClearTimeout)&&clearTimeout){cachedClearTimeout=clearTimeout;return clearTimeout(marker)}try{return cachedClearTimeout(marker)}catch(e){try{return cachedClearTimeout.call(null,marker)}catch(e){return cachedClearTimeout.call(this,marker)}}}var queue=[];var draining=false;var currentQueue;var queueIndex=-1;function cleanUpNextTick(){if(!draining||!currentQueue){return}draining=false;if(currentQueue.length){queue=currentQueue.concat(queue)}else{queueIndex=-1}if(queue.length){drainQueue()}}function drainQueue(){if(draining){return}var timeout=runTimeout(cleanUpNextTick);draining=true;var len=queue.length;while(len){currentQueue=queue;queue=[];while(++queueIndex<len){if(currentQueue){currentQueue[queueIndex].run()}}queueIndex=-1;len=queue.length}currentQueue=null;draining=false;runClearTimeout(timeout)}process.nextTick=function(fun){var args=new Array(arguments.length-1);if(arguments.length>1){for(var i=1;i<arguments.length;i++){args[i-1]=arguments[i]}}queue.push(new Item(fun,args));if(queue.length===1&&!draining){runTimeout(drainQueue)}};function Item(fun,array){this.fun=fun;this.array=array}Item.prototype.run=function(){this.fun.apply(null,this.array)};process.title="browser";process.browser=true;process.env={};process.argv=[];process.version="";process.versions={};function noop(){}process.on=noop;process.addListener=noop;process.once=noop;process.off=noop;process.removeListener=noop;process.removeAllListeners=noop;process.emit=noop;process.binding=function(name){throw new Error("process.binding is not supported")};process.cwd=function(){return"/"};process.chdir=function(dir){throw new Error("process.chdir is not supported")};process.umask=function(){return 0}},{}],43:[function(require,module,exports){module.exports=require("./lib/_stream_duplex.js")},{"./lib/_stream_duplex.js":44}],44:[function(require,module,exports){"use strict";var objectKeys=Object.keys||function(obj){var keys=[];for(var key in obj){keys.push(key)}return keys};module.exports=Duplex;var processNextTick=require("process-nextick-args");var util=require("core-util-is");util.inherits=require("inherits");var Readable=require("./_stream_readable");var Writable=require("./_stream_writable");util.inherits(Duplex,Readable);var keys=objectKeys(Writable.prototype);for(var v=0;v<keys.length;v++){var method=keys[v];if(!Duplex.prototype[method])Duplex.prototype[method]=Writable.prototype[method]}function Duplex(options){if(!(this instanceof Duplex))return new Duplex(options);Readable.call(this,options);Writable.call(this,options);if(options&&options.readable===false)this.readable=false;if(options&&options.writable===false)this.writable=false;this.allowHalfOpen=true;if(options&&options.allowHalfOpen===false)this.allowHalfOpen=false;this.once("end",onend)}function onend(){if(this.allowHalfOpen||this._writableState.ended)return;processNextTick(onEndNT,this)}function onEndNT(self){self.end()}function forEach(xs,f){for(var i=0,l=xs.length;i<l;i++){f(xs[i],i)}}},{"./_stream_readable":46,"./_stream_writable":48,"core-util-is":6,inherits:38,"process-nextick-args":41}],45:[function(require,module,exports){"use strict";module.exports=PassThrough;var Transform=require("./_stream_transform");var util=require("core-util-is");util.inherits=require("inherits");util.inherits(PassThrough,Transform);function PassThrough(options){if(!(this instanceof PassThrough))return new PassThrough(options);Transform.call(this,options)}PassThrough.prototype._transform=function(chunk,encoding,cb){cb(null,chunk)}},{"./_stream_transform":47,"core-util-is":6,inherits:38}],46:[function(require,module,exports){(function(process){"use strict";module.exports=Readable;var processNextTick=require("process-nextick-args");var isArray=require("isarray");Readable.ReadableState=ReadableState;var EE=require("events").EventEmitter;var EElistenerCount=function(emitter,type){return emitter.listeners(type).length};var Stream;(function(){try{Stream=require("st"+"ream")}catch(_){}finally{if(!Stream)Stream=require("events").EventEmitter}})();var Buffer=require("buffer").Buffer;var bufferShim=require("buffer-shims");var util=require("core-util-is");util.inherits=require("inherits");var debugUtil=require("util");var debug=void 0;if(debugUtil&&debugUtil.debuglog){debug=debugUtil.debuglog("stream")}else{debug=function(){}}var BufferList=require("./internal/streams/BufferList");var StringDecoder;util.inherits(Readable,Stream);function prependListener(emitter,event,fn){if(typeof emitter.prependListener==="function"){return emitter.prependListener(event,fn)}else{if(!emitter._events||!emitter._events[event])emitter.on(event,fn);else if(isArray(emitter._events[event]))emitter._events[event].unshift(fn);else emitter._events[event]=[fn,emitter._events[event]]}}var Duplex;function ReadableState(options,stream){Duplex=Duplex||require("./_stream_duplex");options=options||{};this.objectMode=!!options.objectMode;if(stream instanceof Duplex)this.objectMode=this.objectMode||!!options.readableObjectMode;var hwm=options.highWaterMark;var defaultHwm=this.objectMode?16:16*1024;this.highWaterMark=hwm||hwm===0?hwm:defaultHwm;this.highWaterMark=~~this.highWaterMark;this.buffer=new BufferList;this.length=0;this.pipes=null;this.pipesCount=0;this.flowing=null;this.ended=false;this.endEmitted=false;this.reading=false;this.sync=true;this.needReadable=false;this.emittedReadable=false;this.readableListening=false;this.resumeScheduled=false;this.defaultEncoding=options.defaultEncoding||"utf8";this.ranOut=false;this.awaitDrain=0;this.readingMore=false;this.decoder=null;this.encoding=null;if(options.encoding){if(!StringDecoder)StringDecoder=require("string_decoder/").StringDecoder;this.decoder=new StringDecoder(options.encoding);this.encoding=options.encoding}}var Duplex;function Readable(options){Duplex=Duplex||require("./_stream_duplex");if(!(this instanceof Readable))return new Readable(options);this._readableState=new ReadableState(options,this);this.readable=true;if(options&&typeof options.read==="function")this._read=options.read;Stream.call(this)}Readable.prototype.push=function(chunk,encoding){var state=this._readableState;if(!state.objectMode&&typeof chunk==="string"){encoding=encoding||state.defaultEncoding;if(encoding!==state.encoding){chunk=bufferShim.from(chunk,encoding);encoding=""}}return readableAddChunk(this,state,chunk,encoding,false)};Readable.prototype.unshift=function(chunk){var state=this._readableState;return readableAddChunk(this,state,chunk,"",true)};Readable.prototype.isPaused=function(){return this._readableState.flowing===false};function readableAddChunk(stream,state,chunk,encoding,addToFront){var er=chunkInvalid(state,chunk);if(er){stream.emit("error",er)}else if(chunk===null){state.reading=false;onEofChunk(stream,state)}else if(state.objectMode||chunk&&chunk.length>0){if(state.ended&&!addToFront){var e=new Error("stream.push() after EOF");stream.emit("error",e)}else if(state.endEmitted&&addToFront){var _e=new Error("stream.unshift() after end event");stream.emit("error",_e)}else{var skipAdd;if(state.decoder&&!addToFront&&!encoding){chunk=state.decoder.write(chunk);skipAdd=!state.objectMode&&chunk.length===0}if(!addToFront)state.reading=false;if(!skipAdd){if(state.flowing&&state.length===0&&!state.sync){stream.emit("data",chunk);stream.read(0)}else{state.length+=state.objectMode?1:chunk.length;if(addToFront)state.buffer.unshift(chunk);else state.buffer.push(chunk);if(state.needReadable)emitReadable(stream)}}maybeReadMore(stream,state)}}else if(!addToFront){state.reading=false}return needMoreData(state)}function needMoreData(state){return!state.ended&&(state.needReadable||state.length<state.highWaterMark||state.length===0)}Readable.prototype.setEncoding=function(enc){if(!StringDecoder)StringDecoder=require("string_decoder/").StringDecoder;this._readableState.decoder=new StringDecoder(enc);this._readableState.encoding=enc;return this};var MAX_HWM=8388608;function computeNewHighWaterMark(n){if(n>=MAX_HWM){n=MAX_HWM}else{n--;n|=n>>>1;n|=n>>>2;n|=n>>>4;n|=n>>>8;n|=n>>>16;n++}return n}function howMuchToRead(n,state){if(n<=0||state.length===0&&state.ended)return 0;if(state.objectMode)return 1;if(n!==n){if(state.flowing&&state.length)return state.buffer.head.data.length;else return state.length}if(n>state.highWaterMark)state.highWaterMark=computeNewHighWaterMark(n);if(n<=state.length)return n;if(!state.ended){state.needReadable=true;return 0}return state.length}Readable.prototype.read=function(n){debug("read",n);n=parseInt(n,10);var state=this._readableState;var nOrig=n;if(n!==0)state.emittedReadable=false;if(n===0&&state.needReadable&&(state.length>=state.highWaterMark||state.ended)){debug("read: emitReadable",state.length,state.ended);if(state.length===0&&state.ended)endReadable(this);else emitReadable(this);return null}n=howMuchToRead(n,state);if(n===0&&state.ended){if(state.length===0)endReadable(this);return null}var doRead=state.needReadable;debug("need readable",doRead);if(state.length===0||state.length-n<state.highWaterMark){doRead=true;debug("length less than watermark",doRead)}if(state.ended||state.reading){doRead=false;debug("reading or ended",doRead)}else if(doRead){debug("do read");state.reading=true;state.sync=true;if(state.length===0)state.needReadable=true;this._read(state.highWaterMark);state.sync=false;if(!state.reading)n=howMuchToRead(nOrig,state)}var ret;if(n>0)ret=fromList(n,state);else ret=null;if(ret===null){state.needReadable=true;n=0}else{state.length-=n}if(state.length===0){if(!state.ended)state.needReadable=true;if(nOrig!==n&&state.ended)endReadable(this)}if(ret!==null)this.emit("data",ret);return ret};function chunkInvalid(state,chunk){var er=null;if(!Buffer.isBuffer(chunk)&&typeof chunk!=="string"&&chunk!==null&&chunk!==undefined&&!state.objectMode){er=new TypeError("Invalid non-string/buffer chunk")}return er}function onEofChunk(stream,state){if(state.ended)return;if(state.decoder){var chunk=state.decoder.end();if(chunk&&chunk.length){state.buffer.push(chunk);state.length+=state.objectMode?1:chunk.length}}state.ended=true;emitReadable(stream)}function emitReadable(stream){var state=stream._readableState;state.needReadable=false;if(!state.emittedReadable){debug("emitReadable",state.flowing);state.emittedReadable=true;if(state.sync)processNextTick(emitReadable_,stream);else emitReadable_(stream)}}function emitReadable_(stream){debug("emit readable");stream.emit("readable");flow(stream)}function maybeReadMore(stream,state){if(!state.readingMore){state.readingMore=true;processNextTick(maybeReadMore_,stream,state)}}function maybeReadMore_(stream,state){var len=state.length;while(!state.reading&&!state.flowing&&!state.ended&&state.length<state.highWaterMark){debug("maybeReadMore read 0");stream.read(0);if(len===state.length)break;else len=state.length}state.readingMore=false}Readable.prototype._read=function(n){this.emit("error",new Error("not implemented"))};Readable.prototype.pipe=function(dest,pipeOpts){var src=this;var state=this._readableState;switch(state.pipesCount){case 0:state.pipes=dest;break;case 1:state.pipes=[state.pipes,dest];break;default:state.pipes.push(dest);break}state.pipesCount+=1;debug("pipe count=%d opts=%j",state.pipesCount,pipeOpts);var doEnd=(!pipeOpts||pipeOpts.end!==false)&&dest!==process.stdout&&dest!==process.stderr;var endFn=doEnd?onend:cleanup;if(state.endEmitted)processNextTick(endFn);else src.once("end",endFn);dest.on("unpipe",onunpipe);function onunpipe(readable){debug("onunpipe");if(readable===src){cleanup()}}function onend(){debug("onend");dest.end()}var ondrain=pipeOnDrain(src);dest.on("drain",ondrain);var cleanedUp=false;function cleanup(){debug("cleanup");dest.removeListener("close",onclose);dest.removeListener("finish",onfinish);dest.removeListener("drain",ondrain);dest.removeListener("error",onerror);dest.removeListener("unpipe",onunpipe);src.removeListener("end",onend);src.removeListener("end",cleanup);src.removeListener("data",ondata);cleanedUp=true;if(state.awaitDrain&&(!dest._writableState||dest._writableState.needDrain))ondrain()}var increasedAwaitDrain=false;src.on("data",ondata);function ondata(chunk){debug("ondata");increasedAwaitDrain=false;var ret=dest.write(chunk);if(false===ret&&!increasedAwaitDrain){if((state.pipesCount===1&&state.pipes===dest||state.pipesCount>1&&indexOf(state.pipes,dest)!==-1)&&!cleanedUp){debug("false write response, pause",src._readableState.awaitDrain);src._readableState.awaitDrain++;increasedAwaitDrain=true}src.pause()}}function onerror(er){debug("onerror",er);unpipe();dest.removeListener("error",onerror);if(EElistenerCount(dest,"error")===0)dest.emit("error",er)}prependListener(dest,"error",onerror);function onclose(){dest.removeListener("finish",onfinish);unpipe()}dest.once("close",onclose);function onfinish(){debug("onfinish");dest.removeListener("close",onclose);unpipe()}dest.once("finish",onfinish);function unpipe(){debug("unpipe");src.unpipe(dest)}dest.emit("pipe",src);if(!state.flowing){debug("pipe resume");src.resume()}return dest};function pipeOnDrain(src){return function(){var state=src._readableState;debug("pipeOnDrain",state.awaitDrain);if(state.awaitDrain)state.awaitDrain--;if(state.awaitDrain===0&&EElistenerCount(src,"data")){state.flowing=true;flow(src)}}}Readable.prototype.unpipe=function(dest){var state=this._readableState;if(state.pipesCount===0)return this;if(state.pipesCount===1){if(dest&&dest!==state.pipes)return this;if(!dest)dest=state.pipes;state.pipes=null;state.pipesCount=0;state.flowing=false;if(dest)dest.emit("unpipe",this);return this}if(!dest){var dests=state.pipes;var len=state.pipesCount;state.pipes=null;state.pipesCount=0;state.flowing=false;for(var _i=0;_i<len;_i++){dests[_i].emit("unpipe",this)}return this}var i=indexOf(state.pipes,dest);if(i===-1)return this;state.pipes.splice(i,1);state.pipesCount-=1;if(state.pipesCount===1)state.pipes=state.pipes[0];dest.emit("unpipe",this);return this};Readable.prototype.on=function(ev,fn){var res=Stream.prototype.on.call(this,ev,fn);if(ev==="data"){if(this._readableState.flowing!==false)this.resume()}else if(ev==="readable"){var state=this._readableState;if(!state.endEmitted&&!state.readableListening){state.readableListening=state.needReadable=true;state.emittedReadable=false;if(!state.reading){processNextTick(nReadingNextTick,this)}else if(state.length){emitReadable(this,state)}}}return res};Readable.prototype.addListener=Readable.prototype.on;function nReadingNextTick(self){debug("readable nexttick read 0");self.read(0)}Readable.prototype.resume=function(){var state=this._readableState;if(!state.flowing){debug("resume");state.flowing=true;resume(this,state)}return this};function resume(stream,state){if(!state.resumeScheduled){state.resumeScheduled=true;processNextTick(resume_,stream,state)}}function resume_(stream,state){if(!state.reading){debug("resume read 0");stream.read(0)}state.resumeScheduled=false;state.awaitDrain=0;stream.emit("resume");flow(stream);if(state.flowing&&!state.reading)stream.read(0)}Readable.prototype.pause=function(){debug("call pause flowing=%j",this._readableState.flowing);if(false!==this._readableState.flowing){debug("pause");this._readableState.flowing=false;this.emit("pause")}return this};function flow(stream){var state=stream._readableState;debug("flow",state.flowing);while(state.flowing&&stream.read()!==null){}}Readable.prototype.wrap=function(stream){var state=this._readableState;var paused=false;var self=this;stream.on("end",function(){debug("wrapped end");if(state.decoder&&!state.ended){var chunk=state.decoder.end();if(chunk&&chunk.length)self.push(chunk)}self.push(null)});stream.on("data",function(chunk){debug("wrapped data");if(state.decoder)chunk=state.decoder.write(chunk);if(state.objectMode&&(chunk===null||chunk===undefined))return;else if(!state.objectMode&&(!chunk||!chunk.length))return;var ret=self.push(chunk);if(!ret){paused=true;stream.pause()}});for(var i in stream){if(this[i]===undefined&&typeof stream[i]==="function"){this[i]=function(method){return function(){return stream[method].apply(stream,arguments)}}(i)}}var events=["error","close","destroy","pause","resume"];forEach(events,function(ev){stream.on(ev,self.emit.bind(self,ev))});self._read=function(n){debug("wrapped _read",n);if(paused){paused=false;stream.resume()}};return self};Readable._fromList=fromList;function fromList(n,state){if(state.length===0)return null;var ret;if(state.objectMode)ret=state.buffer.shift();else if(!n||n>=state.length){if(state.decoder)ret=state.buffer.join("");else if(state.buffer.length===1)ret=state.buffer.head.data;else ret=state.buffer.concat(state.length);state.buffer.clear()}else{ret=fromListPartial(n,state.buffer,state.decoder)}return ret}function fromListPartial(n,list,hasStrings){var ret;if(n<list.head.data.length){ret=list.head.data.slice(0,n);list.head.data=list.head.data.slice(n)}else if(n===list.head.data.length){ret=list.shift()}else{ret=hasStrings?copyFromBufferString(n,list):copyFromBuffer(n,list)}return ret}function copyFromBufferString(n,list){var p=list.head;var c=1;var ret=p.data;n-=ret.length;while(p=p.next){var str=p.data;var nb=n>str.length?str.length:n;if(nb===str.length)ret+=str;else ret+=str.slice(0,n);n-=nb;if(n===0){if(nb===str.length){++c;if(p.next)list.head=p.next;else list.head=list.tail=null}else{list.head=p;p.data=str.slice(nb)}break}++c}list.length-=c;return ret}function copyFromBuffer(n,list){var ret=bufferShim.allocUnsafe(n);var p=list.head;var c=1;p.data.copy(ret);n-=p.data.length;while(p=p.next){var buf=p.data;var nb=n>buf.length?buf.length:n;buf.copy(ret,ret.length-n,0,nb);n-=nb;if(n===0){if(nb===buf.length){++c;if(p.next)list.head=p.next;else list.head=list.tail=null}else{list.head=p;p.data=buf.slice(nb)}break}++c}list.length-=c;return ret}function endReadable(stream){var state=stream._readableState;if(state.length>0)throw new Error('"endReadable()" called on non-empty stream');if(!state.endEmitted){state.ended=true;processNextTick(endReadableNT,state,stream)}}function endReadableNT(state,stream){if(!state.endEmitted&&state.length===0){state.endEmitted=true;stream.readable=false;stream.emit("end")}}function forEach(xs,f){for(var i=0,l=xs.length;i<l;i++){f(xs[i],i)}}function indexOf(xs,x){for(var i=0,l=xs.length;i<l;i++){if(xs[i]===x)return i}return-1}}).call(this,require("_process"))},{"./_stream_duplex":44,"./internal/streams/BufferList":49,_process:42,buffer:5,"buffer-shims":4,"core-util-is":6,events:28,inherits:38,isarray:40,"process-nextick-args":41,"string_decoder/":56,util:3}],47:[function(require,module,exports){"use strict";module.exports=Transform;var Duplex=require("./_stream_duplex");var util=require("core-util-is");util.inherits=require("inherits");util.inherits(Transform,Duplex);function TransformState(stream){this.afterTransform=function(er,data){return afterTransform(stream,er,data)};this.needTransform=false;this.transforming=false;this.writecb=null;this.writechunk=null;this.writeencoding=null}function afterTransform(stream,er,data){var ts=stream._transformState;ts.transforming=false;var cb=ts.writecb;if(!cb)return stream.emit("error",new Error("no writecb in Transform class"));ts.writechunk=null;ts.writecb=null;if(data!==null&&data!==undefined)stream.push(data);cb(er);var rs=stream._readableState;rs.reading=false;if(rs.needReadable||rs.length<rs.highWaterMark){stream._read(rs.highWaterMark)}}function Transform(options){if(!(this instanceof Transform))return new Transform(options);Duplex.call(this,options);this._transformState=new TransformState(this);var stream=this;this._readableState.needReadable=true;this._readableState.sync=false;if(options){if(typeof options.transform==="function")this._transform=options.transform;if(typeof options.flush==="function")this._flush=options.flush}this.once("prefinish",function(){if(typeof this._flush==="function")this._flush(function(er){done(stream,er)});else done(stream)})}Transform.prototype.push=function(chunk,encoding){this._transformState.needTransform=false;return Duplex.prototype.push.call(this,chunk,encoding)};Transform.prototype._transform=function(chunk,encoding,cb){throw new Error("Not implemented")};Transform.prototype._write=function(chunk,encoding,cb){var ts=this._transformState;ts.writecb=cb;ts.writechunk=chunk;ts.writeencoding=encoding;if(!ts.transforming){var rs=this._readableState;if(ts.needTransform||rs.needReadable||rs.length<rs.highWaterMark)this._read(rs.highWaterMark)}};Transform.prototype._read=function(n){var ts=this._transformState;if(ts.writechunk!==null&&ts.writecb&&!ts.transforming){ts.transforming=true;this._transform(ts.writechunk,ts.writeencoding,ts.afterTransform)}else{ts.needTransform=true}};function done(stream,er){if(er)return stream.emit("error",er);var ws=stream._writableState;var ts=stream._transformState;if(ws.length)throw new Error("Calling transform done when ws.length != 0");if(ts.transforming)throw new Error("Calling transform done when still transforming");return stream.push(null)}},{"./_stream_duplex":44,"core-util-is":6,inherits:38}],48:[function(require,module,exports){(function(process){"use strict";module.exports=Writable;var processNextTick=require("process-nextick-args");var asyncWrite=!process.browser&&["v0.10","v0.9."].indexOf(process.version.slice(0,5))>-1?setImmediate:processNextTick;Writable.WritableState=WritableState;var util=require("core-util-is");util.inherits=require("inherits");var internalUtil={deprecate:require("util-deprecate")};var Stream;(function(){try{Stream=require("st"+"ream")}catch(_){}finally{if(!Stream)Stream=require("events").EventEmitter}})();var Buffer=require("buffer").Buffer;var bufferShim=require("buffer-shims");util.inherits(Writable,Stream);function nop(){}function WriteReq(chunk,encoding,cb){this.chunk=chunk;this.encoding=encoding;this.callback=cb;this.next=null}var Duplex;function WritableState(options,stream){Duplex=Duplex||require("./_stream_duplex");options=options||{};this.objectMode=!!options.objectMode;if(stream instanceof Duplex)this.objectMode=this.objectMode||!!options.writableObjectMode;var hwm=options.highWaterMark;var defaultHwm=this.objectMode?16:16*1024;this.highWaterMark=hwm||hwm===0?hwm:defaultHwm;this.highWaterMark=~~this.highWaterMark;this.needDrain=false;this.ending=false;this.ended=false;this.finished=false;var noDecode=options.decodeStrings===false;this.decodeStrings=!noDecode;this.defaultEncoding=options.defaultEncoding||"utf8";this.length=0;this.writing=false;this.corked=0;this.sync=true;this.bufferProcessing=false;this.onwrite=function(er){onwrite(stream,er)};this.writecb=null;this.writelen=0;this.bufferedRequest=null;this.lastBufferedRequest=null;this.pendingcb=0;this.prefinished=false;this.errorEmitted=false;this.bufferedRequestCount=0;this.corkedRequestsFree=new CorkedRequest(this)}WritableState.prototype.getBuffer=function writableStateGetBuffer(){var current=this.bufferedRequest;var out=[];while(current){out.push(current);current=current.next}return out};(function(){try{Object.defineProperty(WritableState.prototype,"buffer",{get:internalUtil.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer "+"instead.")})}catch(_){}})();var Duplex;function Writable(options){Duplex=Duplex||require("./_stream_duplex");if(!(this instanceof Writable)&&!(this instanceof Duplex))return new Writable(options);this._writableState=new WritableState(options,this);this.writable=true;if(options){if(typeof options.write==="function")this._write=options.write;if(typeof options.writev==="function")this._writev=options.writev}Stream.call(this)}Writable.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe, not readable"))};function writeAfterEnd(stream,cb){var er=new Error("write after end");stream.emit("error",er);processNextTick(cb,er)}function validChunk(stream,state,chunk,cb){var valid=true;var er=false;if(chunk===null){er=new TypeError("May not write null values to stream")}else if(!Buffer.isBuffer(chunk)&&typeof chunk!=="string"&&chunk!==undefined&&!state.objectMode){er=new TypeError("Invalid non-string/buffer chunk")}if(er){stream.emit("error",er);processNextTick(cb,er);valid=false}return valid}Writable.prototype.write=function(chunk,encoding,cb){var state=this._writableState;var ret=false;if(typeof encoding==="function"){cb=encoding;encoding=null}if(Buffer.isBuffer(chunk))encoding="buffer";else if(!encoding)encoding=state.defaultEncoding;if(typeof cb!=="function")cb=nop;if(state.ended)writeAfterEnd(this,cb);else if(validChunk(this,state,chunk,cb)){
+state.pendingcb++;ret=writeOrBuffer(this,state,chunk,encoding,cb)}return ret};Writable.prototype.cork=function(){var state=this._writableState;state.corked++};Writable.prototype.uncork=function(){var state=this._writableState;if(state.corked){state.corked--;if(!state.writing&&!state.corked&&!state.finished&&!state.bufferProcessing&&state.bufferedRequest)clearBuffer(this,state)}};Writable.prototype.setDefaultEncoding=function setDefaultEncoding(encoding){if(typeof encoding==="string")encoding=encoding.toLowerCase();if(!(["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le","raw"].indexOf((encoding+"").toLowerCase())>-1))throw new TypeError("Unknown encoding: "+encoding);this._writableState.defaultEncoding=encoding;return this};function decodeChunk(state,chunk,encoding){if(!state.objectMode&&state.decodeStrings!==false&&typeof chunk==="string"){chunk=bufferShim.from(chunk,encoding)}return chunk}function writeOrBuffer(stream,state,chunk,encoding,cb){chunk=decodeChunk(state,chunk,encoding);if(Buffer.isBuffer(chunk))encoding="buffer";var len=state.objectMode?1:chunk.length;state.length+=len;var ret=state.length<state.highWaterMark;if(!ret)state.needDrain=true;if(state.writing||state.corked){var last=state.lastBufferedRequest;state.lastBufferedRequest=new WriteReq(chunk,encoding,cb);if(last){last.next=state.lastBufferedRequest}else{state.bufferedRequest=state.lastBufferedRequest}state.bufferedRequestCount+=1}else{doWrite(stream,state,false,len,chunk,encoding,cb)}return ret}function doWrite(stream,state,writev,len,chunk,encoding,cb){state.writelen=len;state.writecb=cb;state.writing=true;state.sync=true;if(writev)stream._writev(chunk,state.onwrite);else stream._write(chunk,encoding,state.onwrite);state.sync=false}function onwriteError(stream,state,sync,er,cb){--state.pendingcb;if(sync)processNextTick(cb,er);else cb(er);stream._writableState.errorEmitted=true;stream.emit("error",er)}function onwriteStateUpdate(state){state.writing=false;state.writecb=null;state.length-=state.writelen;state.writelen=0}function onwrite(stream,er){var state=stream._writableState;var sync=state.sync;var cb=state.writecb;onwriteStateUpdate(state);if(er)onwriteError(stream,state,sync,er,cb);else{var finished=needFinish(state);if(!finished&&!state.corked&&!state.bufferProcessing&&state.bufferedRequest){clearBuffer(stream,state)}if(sync){asyncWrite(afterWrite,stream,state,finished,cb)}else{afterWrite(stream,state,finished,cb)}}}function afterWrite(stream,state,finished,cb){if(!finished)onwriteDrain(stream,state);state.pendingcb--;cb();finishMaybe(stream,state)}function onwriteDrain(stream,state){if(state.length===0&&state.needDrain){state.needDrain=false;stream.emit("drain")}}function clearBuffer(stream,state){state.bufferProcessing=true;var entry=state.bufferedRequest;if(stream._writev&&entry&&entry.next){var l=state.bufferedRequestCount;var buffer=new Array(l);var holder=state.corkedRequestsFree;holder.entry=entry;var count=0;while(entry){buffer[count]=entry;entry=entry.next;count+=1}doWrite(stream,state,true,state.length,buffer,"",holder.finish);state.pendingcb++;state.lastBufferedRequest=null;if(holder.next){state.corkedRequestsFree=holder.next;holder.next=null}else{state.corkedRequestsFree=new CorkedRequest(state)}}else{while(entry){var chunk=entry.chunk;var encoding=entry.encoding;var cb=entry.callback;var len=state.objectMode?1:chunk.length;doWrite(stream,state,false,len,chunk,encoding,cb);entry=entry.next;if(state.writing){break}}if(entry===null)state.lastBufferedRequest=null}state.bufferedRequestCount=0;state.bufferedRequest=entry;state.bufferProcessing=false}Writable.prototype._write=function(chunk,encoding,cb){cb(new Error("not implemented"))};Writable.prototype._writev=null;Writable.prototype.end=function(chunk,encoding,cb){var state=this._writableState;if(typeof chunk==="function"){cb=chunk;chunk=null;encoding=null}else if(typeof encoding==="function"){cb=encoding;encoding=null}if(chunk!==null&&chunk!==undefined)this.write(chunk,encoding);if(state.corked){state.corked=1;this.uncork()}if(!state.ending&&!state.finished)endWritable(this,state,cb)};function needFinish(state){return state.ending&&state.length===0&&state.bufferedRequest===null&&!state.finished&&!state.writing}function prefinish(stream,state){if(!state.prefinished){state.prefinished=true;stream.emit("prefinish")}}function finishMaybe(stream,state){var need=needFinish(state);if(need){if(state.pendingcb===0){prefinish(stream,state);state.finished=true;stream.emit("finish")}else{prefinish(stream,state)}}return need}function endWritable(stream,state,cb){state.ending=true;finishMaybe(stream,state);if(cb){if(state.finished)processNextTick(cb);else stream.once("finish",cb)}state.ended=true;stream.writable=false}function CorkedRequest(state){var _this=this;this.next=null;this.entry=null;this.finish=function(err){var entry=_this.entry;_this.entry=null;while(entry){var cb=entry.callback;state.pendingcb--;cb(err);entry=entry.next}if(state.corkedRequestsFree){state.corkedRequestsFree.next=_this}else{state.corkedRequestsFree=_this}}}}).call(this,require("_process"))},{"./_stream_duplex":44,_process:42,buffer:5,"buffer-shims":4,"core-util-is":6,events:28,inherits:38,"process-nextick-args":41,"util-deprecate":57}],49:[function(require,module,exports){"use strict";var Buffer=require("buffer").Buffer;var bufferShim=require("buffer-shims");module.exports=BufferList;function BufferList(){this.head=null;this.tail=null;this.length=0}BufferList.prototype.push=function(v){var entry={data:v,next:null};if(this.length>0)this.tail.next=entry;else this.head=entry;this.tail=entry;++this.length};BufferList.prototype.unshift=function(v){var entry={data:v,next:this.head};if(this.length===0)this.tail=entry;this.head=entry;++this.length};BufferList.prototype.shift=function(){if(this.length===0)return;var ret=this.head.data;if(this.length===1)this.head=this.tail=null;else this.head=this.head.next;--this.length;return ret};BufferList.prototype.clear=function(){this.head=this.tail=null;this.length=0};BufferList.prototype.join=function(s){if(this.length===0)return"";var p=this.head;var ret=""+p.data;while(p=p.next){ret+=s+p.data}return ret};BufferList.prototype.concat=function(n){if(this.length===0)return bufferShim.alloc(0);if(this.length===1)return this.head.data;var ret=bufferShim.allocUnsafe(n>>>0);var p=this.head;var i=0;while(p){p.data.copy(ret,i);i+=p.data.length;p=p.next}return ret}},{buffer:5,"buffer-shims":4}],50:[function(require,module,exports){module.exports=require("./lib/_stream_passthrough.js")},{"./lib/_stream_passthrough.js":45}],51:[function(require,module,exports){(function(process){var Stream=function(){try{return require("st"+"ream")}catch(_){}}();exports=module.exports=require("./lib/_stream_readable.js");exports.Stream=Stream||exports;exports.Readable=exports;exports.Writable=require("./lib/_stream_writable.js");exports.Duplex=require("./lib/_stream_duplex.js");exports.Transform=require("./lib/_stream_transform.js");exports.PassThrough=require("./lib/_stream_passthrough.js");if(!process.browser&&process.env.READABLE_STREAM==="disable"&&Stream){module.exports=Stream}}).call(this,require("_process"))},{"./lib/_stream_duplex.js":44,"./lib/_stream_passthrough.js":45,"./lib/_stream_readable.js":46,"./lib/_stream_transform.js":47,"./lib/_stream_writable.js":48,_process:42}],52:[function(require,module,exports){module.exports=require("./lib/_stream_transform.js")},{"./lib/_stream_transform.js":47}],53:[function(require,module,exports){module.exports=require("./lib/_stream_writable.js")},{"./lib/_stream_writable.js":48}],54:[function(require,module,exports){module.exports=function(string){return string.replace(/[-\\^$*+?.()|[\]{}]/g,"\\$&")}},{}],55:[function(require,module,exports){module.exports=Stream;var EE=require("events").EventEmitter;var inherits=require("inherits");inherits(Stream,EE);Stream.Readable=require("readable-stream/readable.js");Stream.Writable=require("readable-stream/writable.js");Stream.Duplex=require("readable-stream/duplex.js");Stream.Transform=require("readable-stream/transform.js");Stream.PassThrough=require("readable-stream/passthrough.js");Stream.Stream=Stream;function Stream(){EE.call(this)}Stream.prototype.pipe=function(dest,options){var source=this;function ondata(chunk){if(dest.writable){if(false===dest.write(chunk)&&source.pause){source.pause()}}}source.on("data",ondata);function ondrain(){if(source.readable&&source.resume){source.resume()}}dest.on("drain",ondrain);if(!dest._isStdio&&(!options||options.end!==false)){source.on("end",onend);source.on("close",onclose)}var didOnEnd=false;function onend(){if(didOnEnd)return;didOnEnd=true;dest.end()}function onclose(){if(didOnEnd)return;didOnEnd=true;if(typeof dest.destroy==="function")dest.destroy()}function onerror(er){cleanup();if(EE.listenerCount(this,"error")===0){throw er}}source.on("error",onerror);dest.on("error",onerror);function cleanup(){source.removeListener("data",ondata);dest.removeListener("drain",ondrain);source.removeListener("end",onend);source.removeListener("close",onclose);source.removeListener("error",onerror);dest.removeListener("error",onerror);source.removeListener("end",cleanup);source.removeListener("close",cleanup);dest.removeListener("close",cleanup)}source.on("end",cleanup);source.on("close",cleanup);dest.on("close",cleanup);dest.emit("pipe",source);return dest}},{events:28,inherits:38,"readable-stream/duplex.js":43,"readable-stream/passthrough.js":50,"readable-stream/readable.js":51,"readable-stream/transform.js":52,"readable-stream/writable.js":53}],56:[function(require,module,exports){var Buffer=require("buffer").Buffer;var isBufferEncoding=Buffer.isEncoding||function(encoding){switch(encoding&&encoding.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return true;default:return false}};function assertEncoding(encoding){if(encoding&&!isBufferEncoding(encoding)){throw new Error("Unknown encoding: "+encoding)}}var StringDecoder=exports.StringDecoder=function(encoding){this.encoding=(encoding||"utf8").toLowerCase().replace(/[-_]/,"");assertEncoding(encoding);switch(this.encoding){case"utf8":this.surrogateSize=3;break;case"ucs2":case"utf16le":this.surrogateSize=2;this.detectIncompleteChar=utf16DetectIncompleteChar;break;case"base64":this.surrogateSize=3;this.detectIncompleteChar=base64DetectIncompleteChar;break;default:this.write=passThroughWrite;return}this.charBuffer=new Buffer(6);this.charReceived=0;this.charLength=0};StringDecoder.prototype.write=function(buffer){var charStr="";while(this.charLength){var available=buffer.length>=this.charLength-this.charReceived?this.charLength-this.charReceived:buffer.length;buffer.copy(this.charBuffer,this.charReceived,0,available);this.charReceived+=available;if(this.charReceived<this.charLength){return""}buffer=buffer.slice(available,buffer.length);charStr=this.charBuffer.slice(0,this.charLength).toString(this.encoding);var charCode=charStr.charCodeAt(charStr.length-1);if(charCode>=55296&&charCode<=56319){this.charLength+=this.surrogateSize;charStr="";continue}this.charReceived=this.charLength=0;if(buffer.length===0){return charStr}break}this.detectIncompleteChar(buffer);var end=buffer.length;if(this.charLength){buffer.copy(this.charBuffer,0,buffer.length-this.charReceived,end);end-=this.charReceived}charStr+=buffer.toString(this.encoding,0,end);var end=charStr.length-1;var charCode=charStr.charCodeAt(end);if(charCode>=55296&&charCode<=56319){var size=this.surrogateSize;this.charLength+=size;this.charReceived+=size;this.charBuffer.copy(this.charBuffer,size,0,size);buffer.copy(this.charBuffer,0,0,size);return charStr.substring(0,end)}return charStr};StringDecoder.prototype.detectIncompleteChar=function(buffer){var i=buffer.length>=3?3:buffer.length;for(;i>0;i--){var c=buffer[buffer.length-i];if(i==1&&c>>5==6){this.charLength=2;break}if(i<=2&&c>>4==14){this.charLength=3;break}if(i<=3&&c>>3==30){this.charLength=4;break}}this.charReceived=i};StringDecoder.prototype.end=function(buffer){var res="";if(buffer&&buffer.length)res=this.write(buffer);if(this.charReceived){var cr=this.charReceived;var buf=this.charBuffer;var enc=this.encoding;res+=buf.slice(0,cr).toString(enc)}return res};function passThroughWrite(buffer){return buffer.toString(this.encoding)}function utf16DetectIncompleteChar(buffer){this.charReceived=buffer.length%2;this.charLength=this.charReceived?2:0}function base64DetectIncompleteChar(buffer){this.charReceived=buffer.length%3;this.charLength=this.charReceived?3:0}},{buffer:5}],57:[function(require,module,exports){(function(global){module.exports=deprecate;function deprecate(fn,msg){if(config("noDeprecation")){return fn}var warned=false;function deprecated(){if(!warned){if(config("throwDeprecation")){throw new Error(msg)}else if(config("traceDeprecation")){console.trace(msg)}else{console.warn(msg)}warned=true}return fn.apply(this,arguments)}return deprecated}function config(name){try{if(!global.localStorage)return false}catch(_){return false}var val=global.localStorage[name];if(null==val)return false;return String(val).toLowerCase()==="true"}}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{}],58:[function(require,module,exports){module.exports=extend;var hasOwnProperty=Object.prototype.hasOwnProperty;function extend(){var target={};for(var i=0;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(hasOwnProperty.call(source,key)){target[key]=source[key]}}}return target}},{}]},{},[1])(1)});
+
+/**
+ * swagger-client - swagger-client is a javascript client for use with swaggering APIs.
+ * @version v2.1.32
+ * @link http://swagger.io
+ * @license Apache-2.0
+ */
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.SwaggerClient = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
+'use strict';
+
+var auth = require('./lib/auth');
+var helpers = require('./lib/helpers');
+var SwaggerClient = require('./lib/client');
+var deprecationWrapper = function (url, options) {
+  helpers.log('This is deprecated, use "new SwaggerClient" instead.');
+
+  return new SwaggerClient(url, options);
+};
+
+/* Here for IE8 Support */
+if (!Array.prototype.indexOf) {
+  Array.prototype.indexOf = function(obj, start) {
+    for (var i = (start || 0), j = this.length; i < j; i++) {
+      if (this[i] === obj) { return i; }
+    }
+    return -1;
+  };
+}
+
+/* Here for IE8 Support */
+if (!String.prototype.trim) {
+  String.prototype.trim = function () {
+    return this.replace(/^\s+|\s+$/g, '');
+  };
+}
+
+/* Here for node 10.x support */
+if (!String.prototype.endsWith) {
+  String.prototype.endsWith = function(suffix) {
+    return this.indexOf(suffix, this.length - suffix.length) !== -1;
+  };
+}
+
+module.exports = SwaggerClient;
+
+SwaggerClient.ApiKeyAuthorization = auth.ApiKeyAuthorization;
+SwaggerClient.PasswordAuthorization = auth.PasswordAuthorization;
+SwaggerClient.CookieAuthorization = auth.CookieAuthorization;
+SwaggerClient.SwaggerApi = deprecationWrapper;
+SwaggerClient.SwaggerClient = deprecationWrapper;
+SwaggerClient.SchemaMarkup = require('./lib/schema-markup');
+
+},{"./lib/auth":2,"./lib/client":3,"./lib/helpers":4,"./lib/schema-markup":7}],2:[function(require,module,exports){
+'use strict';
+
+var helpers = require('./helpers');
+var btoa = require('btoa'); // jshint ignore:line
+var CookieJar = require('cookiejar').CookieJar;
+var _ = {
+  each: require('lodash-compat/collection/each'),
+  includes: require('lodash-compat/collection/includes'),
+  isObject: require('lodash-compat/lang/isObject'),
+  isArray: require('lodash-compat/lang/isArray')
+};
+
+/**
+ * SwaggerAuthorizations applies the correct authorization to an operation being executed
+ */
+var SwaggerAuthorizations = module.exports.SwaggerAuthorizations = function (authz) {
+  this.authz = authz || {};
+};
+
+/**
+ * Add auths to the hash
+ * Will overwrite any existing
+ *
+ */
+SwaggerAuthorizations.prototype.add = function (name, auth) {
+  if(_.isObject(name)) {
+    for (var key in name) {
+      this.authz[key] = name[key];
+    }
+  } else if(typeof name === 'string' ){
+    this.authz[name] = auth;
+  }
+
+  return auth;
+};
+
+SwaggerAuthorizations.prototype.remove = function (name) {
+  return delete this.authz[name];
+};
+
+SwaggerAuthorizations.prototype.apply = function (obj, securities) {
+  var status = true;
+  var applyAll = !securities;
+  var flattenedSecurities = [];
+
+  // favor the object-level authorizations over global
+  var authz = obj.clientAuthorizations || this.authz;
+
+  // Securities could be [ {} ]
+  _.each(securities, function (obj, key) {
+
+    // Make sure we account for securities being [ str ]
+    if(typeof key === 'string') {
+      flattenedSecurities.push(key);
+    }
+
+    // Flatten keys in to our array
+    _.each(obj, function (val, key) {
+      flattenedSecurities.push(key);
+    });
+  });
+
+  _.each(authz, function (auth, authName) {
+    if(applyAll || _.includes(flattenedSecurities, authName)) {
+      var newStatus = auth.apply(obj);
+      status = status && !!newStatus; // logical ORs regarding status
+    }
+  });
+
+  return status;
+};
+
+/**
+ * ApiKeyAuthorization allows a query param or header to be injected
+ */
+var ApiKeyAuthorization = module.exports.ApiKeyAuthorization = function (name, value, type) {
+  this.name = name;
+  this.value = value;
+  this.type = type;
+};
+
+ApiKeyAuthorization.prototype.apply = function (obj) {
+  if (this.type === 'query') {
+    // see if already applied.  If so, don't do it again
+
+    var qp;
+    if (obj.url.indexOf('?') > 0) {
+      qp = obj.url.substring(obj.url.indexOf('?') + 1);
+      var parts = qp.split('&');
+      if(parts && parts.length > 0) {
+        for(var i = 0; i < parts.length; i++) {
+          var kv = parts[i].split('=');
+          if(kv && kv.length > 0) {
+            if (kv[0] === this.name) {
+              // skip it
+              return false;
+            }
+          }
+        }
+      }
+    }
+
+    if (obj.url.indexOf('?') > 0) {
+      obj.url = obj.url + '&' + this.name + '=' + this.value;
+    } else {
+      obj.url = obj.url + '?' + this.name + '=' + this.value;
+    }
+
+    return true;
+  } else if (this.type === 'header') {
+    if(typeof obj.headers[this.name] === 'undefined') {
+      obj.headers[this.name] = this.value;
+    }
+
+    return true;
+  }
+};
+
+var CookieAuthorization = module.exports.CookieAuthorization = function (cookie) {
+  this.cookie = cookie;
+};
+
+CookieAuthorization.prototype.apply = function (obj) {
+  obj.cookieJar = obj.cookieJar || new CookieJar();
+  obj.cookieJar.setCookie(this.cookie);
+
+  return true;
+};
+
+/**
+ * Password Authorization is a basic auth implementation
+ */
+var PasswordAuthorization = module.exports.PasswordAuthorization = function (username, password) {
+  if (arguments.length === 3) {
+    helpers.log('PasswordAuthorization: the \'name\' argument has been removed, pass only username and password');
+    username = arguments[1];
+    password = arguments[2];
+  }
+  this.username = username;
+  this.password = password;
+};
+
+PasswordAuthorization.prototype.apply = function (obj) {
+  if(typeof obj.headers.Authorization === 'undefined') {
+    obj.headers.Authorization = 'Basic ' + btoa(this.username + ':' + this.password);
+  }
+
+  return true;
+};
+
+},{"./helpers":4,"btoa":13,"cookiejar":18,"lodash-compat/collection/each":52,"lodash-compat/collection/includes":55,"lodash-compat/lang/isArray":140,"lodash-compat/lang/isObject":144}],3:[function(require,module,exports){
+'use strict';
+
+var _ = {
+  bind: require('lodash-compat/function/bind'),
+  cloneDeep: require('lodash-compat/lang/cloneDeep'),
+  find: require('lodash-compat/collection/find'),
+  forEach: require('lodash-compat/collection/forEach'),
+  indexOf: require('lodash-compat/array/indexOf'),
+  isArray: require('lodash-compat/lang/isArray'),
+  isObject: require('lodash-compat/lang/isObject'),
+  isFunction: require('lodash-compat/lang/isFunction'),
+  isPlainObject: require('lodash-compat/lang/isPlainObject'),
+  isUndefined: require('lodash-compat/lang/isUndefined')
+};
+var auth = require('./auth');
+var helpers = require('./helpers');
+var Model = require('./types/model');
+var Operation = require('./types/operation');
+var OperationGroup = require('./types/operationGroup');
+var Resolver = require('./resolver');
+var SwaggerHttp = require('./http');
+var SwaggerSpecConverter = require('./spec-converter');
+var Q = require('q');
+
+// We have to keep track of the function/property names to avoid collisions for tag names which are used to allow the
+// following usage: 'client.{tagName}'
+var reservedClientTags = [
+  'apis',
+  'authorizationScheme',
+  'authorizations',
+  'basePath',
+  'build',
+  'buildFrom1_1Spec',
+  'buildFrom1_2Spec',
+  'buildFromSpec',
+  'clientAuthorizations',
+  'convertInfo',
+  'debug',
+  'defaultErrorCallback',
+  'defaultSuccessCallback',
+  'enableCookies',
+  'fail',
+  'failure',
+  'finish',
+  'help',
+  'host',
+  'idFromOp',
+  'info',
+  'initialize',
+  'isBuilt',
+  'isValid',
+  'modelPropertyMacro',
+  'models',
+  'modelsArray',
+  'options',
+  'parameterMacro',
+  'parseUri',
+  'progress',
+  'resourceCount',
+  'sampleModels',
+  'selfReflect',
+  'setConsolidatedModels',
+  'spec',
+  'supportedSubmitMethods',
+  'swaggerRequestHeaders',
+  'tagFromLabel',
+  'title',
+  'url',
+  'useJQuery',
+  'jqueryAjaxCache'
+];
+// We have to keep track of the function/property names to avoid collisions for tag names which are used to allow the
+// following usage: 'client.apis.{tagName}'
+var reservedApiTags = [
+  'apis',
+  'asCurl',
+  'description',
+  'externalDocs',
+  'help',
+  'label',
+  'name',
+  'operation',
+  'operations',
+  'operationsArray',
+  'path',
+  'tag'
+];
+var supportedOperationMethods = ['delete', 'get', 'head', 'options', 'patch', 'post', 'put'];
+var SwaggerClient = module.exports = function (url, options) {
+  this.authorizations = null;
+  this.authorizationScheme = null;
+  this.basePath = null;
+  this.debug = false;
+  this.enableCookies = false;
+  this.info = null;
+  this.isBuilt = false;
+  this.isValid = false;
+  this.modelsArray = [];
+  this.resourceCount = 0;
+  this.url = null;
+  this.useJQuery = false;
+  this.jqueryAjaxCache = false;
+  this.swaggerObject = {};
+  this.deferredClient = undefined;
+
+  this.clientAuthorizations = new auth.SwaggerAuthorizations();
+
+  if (typeof url !== 'undefined') {
+    return this.initialize(url, options);
+  } else {
+    return this;
+  }
+};
+
+SwaggerClient.prototype.initialize = function (url, options) {
+  this.models = {};
+  this.sampleModels = {};
+
+  if (typeof url === 'string') {
+    this.url = url;
+  } else if (_.isObject(url)) {
+    options = url;
+    this.url = options.url;
+  }
+
+  if(this.url && this.url.indexOf('http:') === -1 && this.url.indexOf('https:') === -1) {
+    // no protocol, so we can only use window if it exists
+    if(typeof(window) !== 'undefined' && typeof(window.location) !== 'undefined') {
+      this.url = window.location.origin + this.url;
+    }
+  }
+
+  options = options || {};
+  this.clientAuthorizations.add(options.authorizations);
+  this.swaggerRequestHeaders = options.swaggerRequestHeaders || 'application/json;charset=utf-8,*/*';
+  this.defaultSuccessCallback = options.defaultSuccessCallback || null;
+  this.defaultErrorCallback = options.defaultErrorCallback || null;
+  this.modelPropertyMacro = options.modelPropertyMacro || null;
+  this.connectionAgent = options.connectionAgent || null;
+  this.parameterMacro = options.parameterMacro || null;
+  this.usePromise = options.usePromise || null;
+
+  // operation request timeout default
+  this.timeout = options.timeout || null;
+  // default to request timeout when not specified
+  this.fetchSpecTimeout = typeof options.fetchSpecTimeout !== 'undefined' ?
+      options.fetchSpecTimeout : options.timeout || null;
+
+  if(this.usePromise) {
+    this.deferredClient = Q.defer();
+  }
+
+  if (typeof options.success === 'function') {
+    this.success = options.success;
+  }
+  if (options.useJQuery) {
+    this.useJQuery = options.useJQuery;
+  }
+
+  if (options.jqueryAjaxCache) {
+    this.jqueryAjaxCache = options.jqueryAjaxCache;
+  }
+
+  if (options.enableCookies) {
+    this.enableCookies = options.enableCookies;
+  }
+
+  this.options = options || {};
+
+  // maybe don't need this?
+  this.options.timeout = this.timeout;
+  this.options.fetchSpecTimeout = this.fetchSpecTimeout;
+
+  this.supportedSubmitMethods = options.supportedSubmitMethods || [];
+  this.failure = options.failure || function (err) { throw err; };
+  this.progress = options.progress || function () {};
+  this.spec = _.cloneDeep(options.spec); // Clone so we do not alter the provided document
+
+  if (options.scheme) {
+    this.scheme = options.scheme;
+  }
+
+  if (this.usePromise || typeof options.success === 'function') {
+    this.ready = true;
+    return this.build();
+  }
+};
+
+SwaggerClient.prototype.build = function (mock) {
+  if (this.isBuilt) {
+    return this;
+  }
+
+  var self = this;
+
+  if (this.spec) {
+    this.progress('fetching resource list; Please wait.');
+  } else {
+    this.progress('fetching resource list: ' + this.url + '; Please wait.');
+  }
+
+  var obj = {
+    useJQuery: this.useJQuery,
+    jqueryAjaxCache: this.jqueryAjaxCache,
+    connectionAgent: this.connectionAgent,
+    enableCookies: this.enableCookies,
+    url: this.url,
+    method: 'get',
+    headers: {
+      accept: this.swaggerRequestHeaders
+    },
+    on: {
+      error: function (response) {
+        if (self && self.url && self.url.substring(0, 4) !== 'http') {
+          return self.fail('Please specify the protocol for ' + self.url);
+        } else if (response.errObj && (response.errObj.code === 'ECONNABORTED' || response.errObj.message.indexOf('timeout') !== -1)) {
+          return self.fail('Request timed out after ' + self.fetchSpecTimeout + 'ms');
+        } else if (response.status === 0) {
+          return self.fail('Can\'t read from server.  It may not have the appropriate access-control-origin settings.');
+        } else if (response.status === 404) {
+          return self.fail('Can\'t read swagger JSON from ' + self.url);
+        } else {
+          return self.fail(response.status + ' : ' + response.statusText + ' ' + self.url);
+        }
+      },
+      response: function (resp) {
+
+        var responseObj = resp.obj;
+        if(!responseObj) {
+          return self.fail('failed to parse JSON/YAML response');
+        }
+
+        self.swaggerVersion = responseObj.swaggerVersion;
+        self.swaggerObject = responseObj;
+
+        if (responseObj.swagger && parseInt(responseObj.swagger) === 2) {
+          self.swaggerVersion = responseObj.swagger;
+
+          new Resolver().resolve(responseObj, self.url, self.buildFromSpec, self);
+
+          self.isValid = true;
+        } else {
+          var converter = new SwaggerSpecConverter();
+          self.oldSwaggerObject = self.swaggerObject;
+
+          converter.setDocumentationLocation(self.url);
+          converter.convert(responseObj, self.clientAuthorizations, self.options, function(spec) {
+            self.swaggerObject = spec;
+            new Resolver().resolve(spec, self.url, self.buildFromSpec, self);
+            self.isValid = true;
+          });
+        }
+      }
+    }
+  };
+
+  // only set timeout when specified
+  if (this.fetchSpecTimeout) {
+    obj.timeout = this.fetchSpecTimeout;
+  }
+
+  if (this.spec && typeof this.spec === 'object') {
+    self.swaggerObject = this.spec;
+    setTimeout(function () {
+      new Resolver().resolve(self.spec, self.url, self.buildFromSpec, self);
+    }, 10);
+  } else {
+    this.clientAuthorizations.apply(obj);
+
+    if (mock) {
+      return obj;
+    }
+
+    new SwaggerHttp().execute(obj, this.options);
+  }
+
+  return (this.usePromise) ? this.deferredClient.promise : this;
+};
+
+SwaggerClient.prototype.buildFromSpec = function (response) {
+  if (this.isBuilt) {
+    return this;
+  }
+
+  this.apis = {};
+  this.apisArray = [];
+  this.basePath = response.basePath || '';
+  this.consumes = response.consumes;
+  this.host = response.host || '';
+  this.info = response.info || {};
+  this.produces = response.produces;
+  this.schemes = response.schemes || [];
+  this.securityDefinitions = _.cloneDeep(response.securityDefinitions);
+  this.security = response.security;
+  this.title = response.title || '';
+
+  var key, definedTags = {}, k, location, self = this, i;
+
+  if (response.externalDocs) {
+    this.externalDocs = response.externalDocs;
+  }
+
+  // legacy support
+  this.authSchemes = this.securityDefinitions;
+
+  if(this.securityDefinitions) {
+    for(key in this.securityDefinitions) {
+      var securityDefinition = this.securityDefinitions[key];
+      securityDefinition.vendorExtensions = {};
+      for(var ext in securityDefinition) {
+        helpers.extractExtensions(ext, securityDefinition);
+        if (ext === 'scopes') {
+          var scopes = securityDefinition[ext];
+          if(typeof scopes === 'object') {
+            scopes.vendorExtensions = {};
+            for (var s in scopes) {
+              helpers.extractExtensions(s, scopes);
+              if(s.indexOf('x-') === 0) {
+                delete scopes[s];
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  if (Array.isArray(response.tags)) {
+    definedTags = {};
+
+    for (k = 0; k < response.tags.length; k++) {
+      var t = _.cloneDeep(response.tags[k]);
+      definedTags[t.name] = t;
+      for(i in t) {
+        if(i === 'externalDocs' && typeof t[i] === 'object') {
+          for(var j in t[i]) {
+            helpers.extractExtensions(j, t[i]);
+          }
+        }
+        helpers.extractExtensions(i, t);
+      }
+    }
+  }
+
+
+  if (typeof this.url === 'string') {
+    location = this.parseUri(this.url);
+    if (typeof this.scheme === 'undefined' && typeof this.schemes === 'undefined' || this.schemes.length === 0) {
+      if (typeof location !== 'undefined' && typeof(location.scheme) !== 'undefined') {
+        this.scheme = location.scheme;
+      }
+      if(typeof window !== 'undefined' && typeof(window.location) !== 'undefined') {
+        // use the window scheme
+        this.scheme = window.location.protocol.replace(':','');
+      }
+      else {
+        this.scheme = location.scheme || 'http';
+      }
+    } else if (typeof window !== 'undefined' && typeof(window.location) !== 'undefined' && window.location.protocol.indexOf('chrome-extension') === 0) {
+               // if it is chrome swagger ui extension scheme then let swagger doc url scheme decide the protocol
+               this.scheme = location.scheme;
+       } else if (typeof this.scheme === 'undefined') {
+      if(typeof window !== 'undefined' && typeof(window.location) !== 'undefined') {
+        var scheme = window.location.protocol.replace(':','');
+        if(scheme === 'https' && this.schemes.indexOf(scheme) === -1) {
+          // can't call http from https served page in a browser!
+          helpers.log('Cannot call a http server from https inside a browser!');
+          this.scheme = 'http';
+        }
+        else if(this.schemes.indexOf(scheme) !== -1) {
+          this.scheme = scheme;
+        }
+        else {
+          if(this.schemes.indexOf('https') !== -1) {
+            this.scheme = 'https';
+          }
+          else {
+            this.scheme = 'http';
+          }
+        }
+      }
+      else {
+        this.scheme = this.schemes[0] || location.scheme;
+      }
+    }
+
+    if (typeof this.host === 'undefined' || this.host === '') {
+      this.host = location.host;
+
+      if (location.port) {
+        this.host = this.host + ':' + location.port;
+      }
+    }
+  }
+  else {
+    if (typeof this.schemes === 'undefined' || this.schemes.length === 0) {
+      this.scheme = 'http';
+    }
+    else if (typeof this.scheme === 'undefined') {
+      this.scheme = this.schemes[0];
+    }
+  }
+
+  this.definitions = response.definitions;
+
+  for (key in this.definitions) {
+    var model = new Model(key, this.definitions[key], this.models, this.modelPropertyMacro);
+
+    if (model) {
+      this.models[key] = model;
+    }
+  }
+
+  // get paths, create functions for each operationId
+
+  // Bind help to 'client.apis'
+  self.apis.help = _.bind(self.help, self);
+
+  _.forEach(response.paths, function (pathObj, path) {
+    // Only process a path if it's an object
+    if (!_.isPlainObject(pathObj)) {
+      return;
+    }
+
+    _.forEach(supportedOperationMethods, function (method) {
+      var operation = pathObj[method];
+
+      if (_.isUndefined(operation)) {
+        // Operation does not exist
+        return;
+      } else if (!_.isPlainObject(operation)) {
+        // Operation exists but it is not an Operation Object.  Since this is invalid, log it.
+        helpers.log('The \'' + method + '\' operation for \'' + path + '\' path is not an Operation Object');
+
+        return;
+      }
+
+      var tags = operation.tags;
+
+      if (_.isUndefined(tags) || !_.isArray(tags) || tags.length === 0) {
+        tags = operation.tags = [ 'default' ];
+      }
+
+      var operationId = self.idFromOp(path, method, operation);
+
+      var operationObject = new Operation(self,
+        operation.scheme,
+        operationId,
+        method,
+        path,
+        operation,
+        self.definitions,
+        self.models,
+        self.clientAuthorizations);
+
+      operationObject.connectionAgent = self.connectionAgent;
+      operationObject.vendorExtensions = {};
+      for(i in operation) {
+        helpers.extractExtensions(i, operationObject, operation[i]);
+      }
+      operationObject.externalDocs = operation.externalDocs;
+      if(operationObject.externalDocs) {
+        operationObject.externalDocs = _.cloneDeep(operationObject.externalDocs);
+        operationObject.externalDocs.vendorExtensions = {};
+        for(i in operationObject.externalDocs) {
+          helpers.extractExtensions(i, operationObject.externalDocs);
+        }
+      }
+
+      // bind self operation's execute command to the api
+      _.forEach(tags, function (tag) {
+        var clientProperty = _.indexOf(reservedClientTags, tag) > -1 ? '_' + tag : tag;
+        var apiProperty = _.indexOf(reservedApiTags, tag) > -1 ? '_' + tag : tag;
+        var operationGroup = self[clientProperty];
+
+        if (clientProperty !== tag) {
+          helpers.log('The \'' + tag + '\' tag conflicts with a SwaggerClient function/property name.  Use \'client.' +
+                      clientProperty + '\' or \'client.apis.' + tag + '\' instead of \'client.' + tag + '\'.');
+        }
+
+        if (apiProperty !== tag) {
+          helpers.log('The \'' + tag + '\' tag conflicts with a SwaggerClient operation function/property name.  Use ' +
+                      '\'client.apis.' + apiProperty + '\' instead of \'client.apis.' + tag + '\'.');
+        }
+
+        if (_.indexOf(reservedApiTags, operationId) > -1) {
+          helpers.log('The \'' + operationId + '\' operationId conflicts with a SwaggerClient operation ' +
+                      'function/property name.  Use \'client.apis.' + apiProperty + '._' + operationId +
+                      '\' instead of \'client.apis.' + apiProperty + '.' + operationId + '\'.');
+
+          operationId = '_' + operationId;
+          operationObject.nickname = operationId; // So 'client.apis.[tag].operationId.help() works properly
+        }
+
+        if (_.isUndefined(operationGroup)) {
+          operationGroup = self[clientProperty] = self.apis[apiProperty] = {};
+
+          operationGroup.operations = {};
+          operationGroup.label = apiProperty;
+          operationGroup.apis = {};
+
+          var tagDef = definedTags[tag];
+
+          if (!_.isUndefined(tagDef)) {
+            operationGroup.description = tagDef.description;
+            operationGroup.externalDocs = tagDef.externalDocs;
+            operationGroup.vendorExtensions = tagDef.vendorExtensions;
+          }
+
+          self[clientProperty].help = _.bind(self.help, operationGroup);
+          self.apisArray.push(new OperationGroup(tag, operationGroup.description, operationGroup.externalDocs, operationObject));
+        }
+
+        operationId = self.makeUniqueOperationId(operationId, self.apis[apiProperty]);
+
+        // Bind tag help
+        if (!_.isFunction(operationGroup.help)) {
+          operationGroup.help = _.bind(self.help, operationGroup);
+        }
+
+        // bind to the apis object
+        self.apis[apiProperty][operationId] = operationGroup[operationId] = _.bind(operationObject.execute,
+                                                                                  operationObject);
+        self.apis[apiProperty][operationId].help = operationGroup[operationId].help = _.bind(operationObject.help,
+                                                                                             operationObject);
+        self.apis[apiProperty][operationId].asCurl = operationGroup[operationId].asCurl = _.bind(operationObject.asCurl,
+                                                                                                 operationObject);
+
+        operationGroup.apis[operationId] = operationGroup.operations[operationId] = operationObject;
+
+        // legacy UI feature
+        var api = _.find(self.apisArray, function (api) {
+          return api.tag === tag;
+        });
+
+        if (api) {
+          api.operationsArray.push(operationObject);
+        }
+      });
+    });
+  });
+
+  // sort the apisArray according to the tags
+  var sortedApis = [];
+  _.forEach(Object.keys(definedTags), function (tag) {
+    var pos;
+    for(pos in self.apisArray) {
+      var _api = self.apisArray[pos];
+      if(_api && tag === _api.name) {
+        sortedApis.push(_api);
+        self.apisArray[pos] = null;
+      }
+    }
+  });
+  // add anything left
+  _.forEach(self.apisArray, function (api) {
+    if(api) {
+      sortedApis.push(api);
+    }
+  });
+  self.apisArray = sortedApis;
+
+  _.forEach(response.definitions, function (definitionObj, definition) {
+    definitionObj.id = definition.toLowerCase();
+    definitionObj.name = definition;
+    self.modelsArray.push(definitionObj);
+  });
+
+  this.isBuilt = true;
+
+  if (this.usePromise) {
+    this.isValid = true;
+    this.isBuilt = true;
+    this.deferredClient.resolve(this);
+
+    return this.deferredClient.promise;
+  }
+
+  if (this.success) {
+    this.success();
+  }
+
+  return this;
+};
+
+SwaggerClient.prototype.makeUniqueOperationId = function(operationId, api) {
+  var count = 0;
+  var name = operationId;
+
+  // make unique across this operation group
+  while(true) {
+    var matched = false;
+    _.forEach(api.operations, function (operation) {
+      if(operation.nickname === name) {
+        matched = true;
+      }
+    });
+    if(!matched) {
+      return name;
+    }
+    name = operationId + '_' + count;
+    count ++;
+  }
+
+  return operationId;
+};
+
+SwaggerClient.prototype.parseUri = function (uri) {
+  var urlParseRE = /^(((([^:\/#\?]+:)?(?:(\/\/)((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/;
+  var parts = urlParseRE.exec(uri);
+
+  return {
+    scheme: parts[4] ? parts[4].replace(':','') : undefined,
+    host: parts[11],
+    port: parts[12],
+    path: parts[15]
+  };
+};
+
+SwaggerClient.prototype.help = function (dontPrint) {
+  var output = '';
+
+  if (this instanceof SwaggerClient) {
+    _.forEach(this.apis, function (api, name) {
+      if (_.isPlainObject(api)) {
+        output += 'operations for the \'' + name + '\' tag\n';
+
+        _.forEach(api.operations, function (operation, name) {
+          output += '  * ' + name + ': ' + operation.summary + '\n';
+        });
+      }
+    });
+  } else if (this instanceof OperationGroup || _.isPlainObject(this)) {
+    output += 'operations for the \'' + this.label + '\' tag\n';
+
+    _.forEach(this.apis, function (operation, name) {
+      output += '  * ' + name + ': ' + operation.summary + '\n';
+    });
+  }
+
+  if (dontPrint) {
+    return output;
+  } else {
+    helpers.log(output);
+
+    return output;
+  }
+};
+
+SwaggerClient.prototype.tagFromLabel = function (label) {
+  return label;
+};
+
+SwaggerClient.prototype.idFromOp = function (path, httpMethod, op) {
+  if(!op || !op.operationId) {
+    op = op || {};
+    op.operationId = httpMethod + '_' + path;
+  }
+  var opId = op.operationId.replace(/[\s!@#$%^&*()_+=\[{\]};:<>|.\/?,\\'""-]/g, '_') || (path.substring(1) + '_' + httpMethod);
+
+  opId = opId.replace(/((_){2,})/g, '_');
+  opId = opId.replace(/^(_)*/g, '');
+  opId = opId.replace(/([_])*$/g, '');
+
+  return opId;
+};
+
+SwaggerClient.prototype.setHost = function (host) {
+  this.host = host;
+
+  if(this.apis) {
+    _.forEach(this.apis, function(api) {
+      if(api.operations) {
+        _.forEach(api.operations, function(operation) {
+          operation.host = host;
+        });
+      }
+    });
+  }
+};
+
+SwaggerClient.prototype.setBasePath = function (basePath) {
+  this.basePath = basePath;
+
+  if(this.apis) {
+    _.forEach(this.apis, function(api) {
+      if(api.operations) {
+        _.forEach(api.operations, function(operation) {
+          operation.basePath = basePath;
+        });
+      }
+    });
+  }
+};
+
+SwaggerClient.prototype.setSchemes = function (schemes) {
+  this.schemes = schemes;
+
+  if(schemes && schemes.length > 0) {
+    if(this.apis) {
+      _.forEach(this.apis, function (api) {
+        if (api.operations) {
+          _.forEach(api.operations, function (operation) {
+            operation.scheme = schemes[0];
+          });
+        }
+      });
+    }
+  }
+};
+
+SwaggerClient.prototype.fail = function (message) {
+  if (this.usePromise) {
+    this.deferredClient.reject(message);
+    return this.deferredClient.promise;
+  } else {
+    if (this.failure) {
+      this.failure(message);
+    }
+    else {
+      this.failure(message);
+    }
+  }
+};
+
+},{"./auth":2,"./helpers":4,"./http":5,"./resolver":6,"./spec-converter":8,"./types/model":9,"./types/operation":10,"./types/operationGroup":11,"lodash-compat/array/indexOf":49,"lodash-compat/collection/find":53,"lodash-compat/collection/forEach":54,"lodash-compat/function/bind":58,"lodash-compat/lang/cloneDeep":138,"lodash-compat/lang/isArray":140,"lodash-compat/lang/isFunction":142,"lodash-compat/lang/isObject":144,"lodash-compat/lang/isPlainObject":145,"lodash-compat/lang/isUndefined":148,"q":157}],4:[function(require,module,exports){
+(function (process){
+'use strict';
+
+var _ = {
+  isPlainObject: require('lodash-compat/lang/isPlainObject'),
+  indexOf: require('lodash-compat/array/indexOf')
+};
+
+module.exports.__bind = function (fn, me) {
+  return function(){
+    return fn.apply(me, arguments);
+  };
+};
+
+var log = module.exports.log = function() {
+  // Only log if available and we're not testing
+  if (console && process.env.NODE_ENV !== 'test') {
+    console.log(Array.prototype.slice.call(arguments)[0]);
+  }
+};
+
+module.exports.fail = function (message) {
+  log(message);
+};
+
+module.exports.optionHtml = function (label, value) {
+  return '<tr><td class="optionName">' + label + ':</td><td>' + value + '</td></tr>';
+};
+
+var resolveSchema = module.exports.resolveSchema = function (schema) {
+  if (_.isPlainObject(schema.schema)) {
+    schema = resolveSchema(schema.schema);
+  }
+
+  return schema;
+};
+
+module.exports.simpleRef = function (name) {
+  if (typeof name === 'undefined') {
+    return null;
+  }
+
+  if (name.indexOf('#/definitions/') === 0) {
+    return name.substring('#/definitions/'.length);
+  } else {
+    return name;
+  }
+};
+
+/**
+ * helper to remove extensions and add them to an object
+ *
+ * @param keyname
+ * @param obj
+ */
+module.exports.extractExtensions = function (keyname, obj, value) {
+  if(!keyname || !obj) {
+    return;
+  }
+
+  if (typeof keyname === 'string' && keyname.indexOf('x-') === 0) {
+    obj.vendorExtensions = obj.vendorExtensions || {};
+    if(value) {
+      obj.vendorExtensions[keyname] = value;
+    }
+    else {
+      obj.vendorExtensions[keyname] = obj[keyname];
+    }
+  }
+};
+}).call(this,require('_process'))
+
+},{"_process":12,"lodash-compat/array/indexOf":49,"lodash-compat/lang/isPlainObject":145}],5:[function(require,module,exports){
+(function (Buffer){
+'use strict';
+
+var helpers = require('./helpers');
+var request = require('superagent');
+var jsyaml = require('js-yaml');
+var _ = {
+  isObject: require('lodash-compat/lang/isObject'),
+  keys: require('lodash-compat/object/keys')
+};
+
+/*
+ * JQueryHttpClient is a light-weight, node or browser HTTP client
+ */
+var JQueryHttpClient = function () {
+  this.type = 'JQueryHttpClient';
+};
+
+/*
+ * SuperagentHttpClient is a light-weight, node or browser HTTP client
+ */
+var SuperagentHttpClient = function () {
+  this.type = 'SuperagentHttpClient';
+};
+
+/**
+ * SwaggerHttp is a wrapper for executing requests
+ */
+var SwaggerHttp = module.exports = function () {};
+
+SwaggerHttp.prototype.execute = function (obj, opts) {
+  var client;
+
+  if(opts && opts.client) {
+    client = opts.client;
+  }
+  else {
+    client = new SuperagentHttpClient(opts);
+  }
+  client.opts = opts || {};
+
+  if (opts && opts.requestAgent) {
+    request = opts.requestAgent;
+  }
+
+  // legacy support
+  var hasJQuery = false;
+  if(typeof window !== 'undefined') {
+    if(typeof window.jQuery !== 'undefined') {
+      hasJQuery = true;
+    }
+  }
+  // OPTIONS support
+  if(obj.method.toLowerCase() === 'options' && client.type === 'SuperagentHttpClient') {
+    log('forcing jQuery as OPTIONS are not supported by SuperAgent');
+    obj.useJQuery = true;
+  }
+  if(this.isInternetExplorer() && (obj.useJQuery === false || !hasJQuery )) {
+    throw new Error('Unsupported configuration! JQuery is required but not available');
+  }
+  if ((obj && obj.useJQuery === true) || this.isInternetExplorer() && hasJQuery) {
+    client = new JQueryHttpClient(opts);
+  }
+
+  var success = obj.on.response;
+  var error = obj.on.error;
+
+  var requestInterceptor = function(data) {
+    if(opts && opts.requestInterceptor) {
+      data = opts.requestInterceptor.apply(data);
+    }
+    return data;
+  };
+
+  var responseInterceptor = function(data) {
+    if(opts && opts.responseInterceptor) {
+      data = opts.responseInterceptor.apply(data, [obj]);
+    }
+    return success(data);
+  };
+
+  var errorInterceptor = function(data) {
+    if(opts && opts.responseInterceptor) {
+      data = opts.responseInterceptor.apply(data, [obj]);
+    }
+    error(data);
+  };
+
+  obj.on.error = function(data) {
+    errorInterceptor(data);
+  };
+
+  obj.on.response = function(data) {
+    if(data && data.status >= 400) {
+      errorInterceptor(data);
+    }
+    else {
+      responseInterceptor(data);
+    }
+  };
+
+  if (_.isObject(obj) && _.isObject(obj.body)) {
+    // special processing for file uploads via jquery
+    if (obj.body.type && obj.body.type === 'formData'){
+      if(opts.useJQuery) {
+        obj.contentType = false;
+        obj.processData = false;
+        delete obj.headers['Content-Type'];
+      }
+    }
+  }
+
+  obj = requestInterceptor(obj) || obj;
+  if (obj.beforeSend) {
+    obj.beforeSend(function(_obj) {
+      client.execute(_obj || obj);
+    });
+  } else {
+    client.execute(obj);
+  }
+
+  return (obj.deferred) ? obj.deferred.promise : obj;
+};
+
+SwaggerHttp.prototype.isInternetExplorer = function () {
+  var detectedIE = false;
+
+  if (typeof navigator !== 'undefined' && navigator.userAgent) {
+    var nav = navigator.userAgent.toLowerCase();
+
+    if (nav.indexOf('msie') !== -1) {
+      var version = parseInt(nav.split('msie')[1]);
+
+      if (version <= 8) {
+        detectedIE = true;
+      }
+    }
+  }
+
+  return detectedIE;
+};
+
+JQueryHttpClient.prototype.execute = function (obj) {
+  var jq = this.jQuery || (typeof window !== 'undefined' && window.jQuery);
+  var cb = obj.on;
+  var request = obj;
+
+  if(typeof jq === 'undefined' || jq === false) {
+    throw new Error('Unsupported configuration! JQuery is required but not available');
+  }
+
+  obj.type = obj.method;
+  obj.cache = obj.jqueryAjaxCache;
+  obj.data = obj.body;
+  delete obj.jqueryAjaxCache;
+  delete obj.useJQuery;
+  delete obj.body;
+
+  obj.complete = function (response) {
+    var headers = {};
+    var headerArray = response.getAllResponseHeaders().split('\n');
+
+    for (var i = 0; i < headerArray.length; i++) {
+      var toSplit = headerArray[i].trim();
+
+      if (toSplit.length === 0) {
+        continue;
+      }
+
+      var separator = toSplit.indexOf(':');
+
+      if (separator === -1) {
+        // Name but no value in the header
+        headers[toSplit] = null;
+
+        continue;
+      }
+
+      var name = toSplit.substring(0, separator).trim();
+      var value = toSplit.substring(separator + 1).trim();
+
+      headers[name] = value;
+    }
+
+    var out = {
+      url: request.url,
+      method: request.method,
+      status: response.status,
+      statusText: response.statusText,
+      data: response.responseText,
+      headers: headers
+    };
+
+    try {
+      var possibleObj =  response.responseJSON || jsyaml.safeLoad(response.responseText);
+      out.obj = (typeof possibleObj === 'string') ? {} : possibleObj;
+    } catch (ex) {
+      // do not set out.obj
+      helpers.log('unable to parse JSON/YAML content');
+    }
+
+    // I can throw, or parse null?
+    out.obj = out.obj || null;
+
+    if (response.status >= 200 && response.status < 300) {
+      cb.response(out);
+    } else if (response.status === 0 || (response.status >= 400 && response.status < 599)) {
+      cb.error(out);
+    } else {
+      return cb.response(out);
+    }
+  };
+
+  jq.support.cors = true;
+
+  return jq.ajax(obj);
+};
+
+SuperagentHttpClient.prototype.execute = function (obj) {
+  var method = obj.method.toLowerCase();
+  var timeout = obj.timeout;
+
+  if (method === 'delete') {
+    method = 'del';
+  }
+  var headers = obj.headers || {};
+
+  var r = request[method](obj.url);
+
+  if (obj.connectionAgent) {
+    r.agent(obj.connectionAgent);
+  }
+
+  if (timeout) {
+    r.timeout(timeout);
+  }
+
+  if (obj.enableCookies) {
+    r.withCredentials();
+  }
+
+  var accept = obj.headers.Accept;
+
+  if(this.binaryRequest(accept)) {
+    r.on('request', function () {
+      if(this.xhr) {
+        this.xhr.responseType = 'blob';
+      }
+    });
+  }
+
+  if(obj.body) {
+    if(_.isObject(obj.body)) {
+      var contentType = obj.headers['Content-Type'] || '';
+      if (contentType.indexOf('multipart/form-data') === 0) {
+        delete headers['Content-Type'];
+        if({}.toString.apply(obj.body) === '[object FormData]') {
+          r.send(obj.body);
+        }
+        else {
+          var keyname, value, v;
+          for (keyname in obj.body) {
+            value = obj.body[keyname];
+            if(Array.isArray(value)) {
+              for(v in value) {
+                r.field(keyname, v);
+              }
+            }
+            else {
+              r.field(keyname, value);
+            }
+          }
+        }
+      }
+      else if (_.isObject(obj.body)) {
+        // non multipart/form-data
+        obj.body = JSON.stringify(obj.body);
+        r.send(obj.body);
+      }
+    }
+    else {
+      r.send(obj.body);
+    }
+  }
+
+  var name;
+  for (name in headers) {
+    r.set(name, headers[name]);
+  }
+
+  if(typeof r.buffer === 'function') {
+    r.buffer(); // force superagent to populate res.text with the raw response data
+  }
+
+  r.end(function (err, res) {
+    res = res || {
+      status: 0,
+      headers: {error: 'no response from server'}
+    };
+    var response = {
+      url: obj.url,
+      method: obj.method,
+      headers: res.headers
+    };
+    var cb;
+
+    if (!err && res.error) {
+      err = res.error;
+    }
+
+    if (err && obj.on && obj.on.error) {
+      response.errObj = err;
+      response.status = res ? res.status : 500;
+      response.statusText = res ? res.text : err.message;
+      if (res.headers && res.headers['content-type']) {
+        if (res.headers['content-type'].indexOf('application/json') >= 0) {
+          try {
+            response.obj = JSON.parse(response.statusText);
+          }
+          catch (e) {
+            response.obj = null;
+          }
+        }
+      }
+      cb = obj.on.error;
+    } else if (res && obj.on && obj.on.response) {
+      var possibleObj;
+
+      // Already parsed by by superagent?
+      if (res.body && _.keys(res.body).length > 0) {
+        possibleObj = res.body;
+      } else {
+        try {
+          possibleObj = jsyaml.safeLoad(res.text);
+          // can parse into a string... which we don't need running around in the system
+          possibleObj = (typeof possibleObj === 'string') ? null : possibleObj;
+        } catch (e) {
+          helpers.log('cannot parse JSON/YAML content');
+        }
+      }
+
+      // null means we can't parse into object
+      if(typeof Buffer === 'function' && Buffer.isBuffer(possibleObj)) {
+        response.data = possibleObj;
+      }
+      else {
+        response.obj = (typeof possibleObj === 'object') ? possibleObj : null;
+      }
+
+      response.status = res.status;
+      response.statusText = res.text;
+      cb = obj.on.response;
+    }
+    if (res.xhr && res.xhr.response) {
+      response.data = res.xhr.response;
+    }
+    else if(!response.data) {
+      response.data = response.statusText;
+    }
+
+    if (cb) {
+      cb(response);
+    }
+  });
+};
+
+SuperagentHttpClient.prototype. binaryRequest = function (accept) {
+  if(!accept) {
+    return false;
+  }
+  return (/^image/i).test(accept)
+    || (/^application\/pdf/).test(accept)
+    || (/^application\/octet-stream/).test(accept);
+};
+
+}).call(this,require("buffer").Buffer)
+
+},{"./helpers":4,"buffer":14,"js-yaml":19,"lodash-compat/lang/isObject":144,"lodash-compat/object/keys":149,"superagent":158}],6:[function(require,module,exports){
+'use strict';
+
+var SwaggerHttp = require('./http');
+var _ = {
+  isObject: require('lodash-compat/lang/isObject'),
+  cloneDeep: require('lodash-compat/lang/cloneDeep'),
+  isArray: require('lodash-compat/lang/isArray'),
+  isString: require('lodash-compat/lang/isString')
+};
+
+
+/**
+ * Resolves a spec's remote references
+ */
+var Resolver = module.exports = function () {
+  this.failedUrls = [];
+  this.resolverCache = {};
+  this.pendingUrls = {};
+};
+
+Resolver.prototype.processAllOf = function(root, name, definition, resolutionTable, unresolvedRefs, spec) {
+  var i, location, property;
+
+  definition['x-resolved-from'] = [ '#/definitions/' + name ];
+  var allOf = definition.allOf;
+  // the refs go first
+  allOf.sort(function(a, b) {
+    if(a.$ref && b.$ref) { return 0; }
+    else if(a.$ref) { return -1; }
+    else { return 1; }
+  });
+  for (i = 0; i < allOf.length; i++) {
+    property = allOf[i];
+    location = '/definitions/' + name + '/allOf';
+    this.resolveInline(root, spec, property, resolutionTable, unresolvedRefs, location);
+  }
+};
+
+Resolver.prototype.resolve = function (spec, arg1, arg2, arg3) {
+  this.spec = spec;
+  var root = arg1, callback = arg2, scope = arg3, opts = {}, location, i;
+  if(typeof arg1 === 'function') {
+    root = null;
+    callback = arg1;
+    scope = arg2;
+  }
+  var _root = root, modelName;
+  this.scope = (scope || this);
+  this.iteration = this.iteration || 0;
+
+  if(this.scope.options && this.scope.options.requestInterceptor){
+    opts.requestInterceptor = this.scope.options.requestInterceptor;
+  }
+
+  if(this.scope.options && this.scope.options.responseInterceptor){
+    opts.responseInterceptor = this.scope.options.responseInterceptor;
+  }
+
+  var name, path, property, propertyName, parameter, done, counter;
+  var processedCalls = 0, resolvedRefs = {}, unresolvedRefs = {};
+  var resolutionTable = []; // store objects for dereferencing
+
+  spec.definitions = spec.definitions || {};
+  // definitions
+  for (name in spec.definitions) {
+    var definition = spec.definitions[name];
+    if(definition.$ref) {
+      this.resolveInline(root, spec, definition, resolutionTable, unresolvedRefs, definition);
+    }
+    else {
+      for (propertyName in definition.properties) {
+        property = definition.properties[propertyName];
+        if (_.isArray(property.allOf)) {
+          this.processAllOf(root, name, property, resolutionTable, unresolvedRefs, spec);
+        }
+        else {
+          this.resolveTo(root, property, resolutionTable, '/definitions');
+        }
+      }
+
+      if (definition.allOf) {
+        this.processAllOf(root, name, definition, resolutionTable, unresolvedRefs, spec);
+      }
+    }
+  }
+
+  // shared parameters
+  spec.parameters = spec.parameters || {};
+  for(name in spec.parameters) {
+    parameter = spec.parameters[name];
+    if (parameter.in === 'body' && parameter.schema) {
+      if(_.isArray(parameter.schema.allOf)) {
+        // move to a definition
+        modelName = 'inline_model';
+        var _name = modelName;
+        done = false; counter = 0;
+        while(!done) {
+          if(typeof spec.definitions[_name] === 'undefined') {
+            done = true;
+            break;
+          }
+          _name = modelName + '_' + counter;
+          counter ++;
+        }
+        spec.definitions[_name] = { allOf: parameter.schema.allOf };
+        delete parameter.schema.allOf;
+        parameter.schema.$ref = '#/definitions/' + _name;
+        this.processAllOf(root, _name, spec.definitions[_name], resolutionTable, unresolvedRefs, spec);
+      }
+      else {
+        this.resolveTo(root, parameter.schema, resolutionTable, location);
+      }
+    }
+
+    if (parameter.$ref) {
+      // parameter reference
+      this.resolveInline(root, spec, parameter, resolutionTable, unresolvedRefs, parameter.$ref);
+    }
+  }
+
+  // operations
+  for (name in spec.paths) {
+    var method, operation, responseCode;
+    path = spec.paths[name];
+
+    if(typeof path === 'object') {
+      for (method in path) {
+        // operation reference
+        if (method === '$ref') {
+          // location = path[method];
+          location = '/paths' + name;
+          this.resolveInline(root, spec, path, resolutionTable, unresolvedRefs, location);
+        }
+        else {
+          operation = path[method];
+          var sharedParameters = path.parameters || [];
+          var parameters = operation.parameters || [];
+
+          sharedParameters.forEach(function(parameter) {
+            parameters.unshift(parameter);
+          });
+
+          if (method !== 'parameters' && _.isObject(operation)) {
+            operation.parameters = operation.parameters || parameters;
+          }
+
+          for (i in parameters) {
+            parameter = parameters[i];
+            location = '/paths' + name + '/' + method + '/parameters';
+
+            if (parameter.in === 'body' && parameter.schema) {
+              if (_.isArray(parameter.schema.allOf)) {
+                // move to a definition
+                modelName = 'inline_model';
+                name = modelName;
+                done = false;
+                counter = 0;
+                while (!done) {
+                  if (typeof spec.definitions[name] === 'undefined') {
+                    done = true;
+                    break;
+                  }
+                  name = modelName + '_' + counter;
+                  counter++;
+                }
+                spec.definitions[name] = {allOf: parameter.schema.allOf};
+                delete parameter.schema.allOf;
+                parameter.schema.$ref = '#/definitions/' + name;
+                this.processAllOf(root, name, spec.definitions[name], resolutionTable, unresolvedRefs, spec);
+              }
+              else {
+                this.resolveTo(root, parameter.schema, resolutionTable, location);
+              }
+            }
+
+            if (parameter.$ref) {
+              // parameter reference
+              this.resolveInline(root, spec, parameter, resolutionTable, unresolvedRefs, parameter.$ref);
+            }
+          }
+
+          for (responseCode in operation.responses) {
+            var response = operation.responses[responseCode];
+            location = '/paths' + name + '/' + method + '/responses/' + responseCode;
+
+            if (_.isObject(response)) {
+              if (response.$ref) {
+                // response reference
+                this.resolveInline(root, spec, response, resolutionTable, unresolvedRefs, location);
+              }
+              if (response.schema) {
+                var responseObj = response;
+                if (_.isArray(responseObj.schema.allOf)) {
+                  // move to a definition
+                  modelName = 'inline_model';
+                  name = modelName;
+                  done = false;
+                  counter = 0;
+                  while (!done) {
+                    if (typeof spec.definitions[name] === 'undefined') {
+                      done = true;
+                      break;
+                    }
+                    name = modelName + '_' + counter;
+                    counter++;
+                  }
+                  spec.definitions[name] = {allOf: responseObj.schema.allOf};
+                  delete responseObj.schema.allOf;
+                  delete responseObj.schema.type;
+                  responseObj.schema.$ref = '#/definitions/' + name;
+                  this.processAllOf(root, name, spec.definitions[name], resolutionTable, unresolvedRefs, spec);
+                }
+                else if ('array' === responseObj.schema.type) {
+                  if (responseObj.schema.items && responseObj.schema.items.$ref) {
+                    // response reference
+                    this.resolveInline(root, spec, responseObj.schema.items, resolutionTable, unresolvedRefs, location);
+                  }
+                }
+                else {
+                  this.resolveTo(root, response.schema, resolutionTable, location);
+                }
+              }
+            }
+          }
+        }
+      }
+      // clear them out to avoid multiple resolutions
+      path.parameters = [];
+    }
+  }
+
+  var expectedCalls = 0, toResolve = [];
+  // if the root is same as obj[i].root we can resolve locally
+  var all = resolutionTable;
+
+  var parts;
+  for(i = 0; i < all.length; i++) {
+    var a = all[i];
+    if(root === a.root) {
+      if(a.resolveAs === 'ref') {
+        // resolve any path walking
+        var joined = ((a.root || '') + '/' + a.key).split('/');
+        var normalized = [];
+        var url = '';
+        var k;
+
+        if(a.key.indexOf('../') >= 0) {
+          for(var j = 0; j < joined.length; j++) {
+            if(joined[j] === '..') {
+              normalized = normalized.slice(0, normalized.length-1);
+            }
+            else {
+              normalized.push(joined[j]);
+            }
+          }
+          for(k = 0; k < normalized.length; k ++) {
+            if(k > 0) {
+              url += '/';
+            }
+            url += normalized[k];
+          }
+          // we now have to remote resolve this because the path has changed
+          a.root = url;
+          toResolve.push(a);
+        }
+        else {
+          parts = a.key.split('#');
+          if(parts.length === 2) {
+            if(parts[0].indexOf('http:') === 0 || parts[0].indexOf('https:') === 0) {
+              a.root = parts[0];
+            }
+            location = parts[1].split('/');
+            var r;
+            var s = spec;
+            for(k = 0; k < location.length; k++) {
+              var part = location[k];
+              if(part !== '') {
+                s = s[part];
+                if(typeof s !== 'undefined') {
+                  r = s;
+                }
+                else {
+                  r = null;
+                  break;
+                }
+              }
+            }
+            if(r === null) {
+              // must resolve this too
+              toResolve.push(a);
+            }
+          }
+        }
+      }
+      else {
+        if (a.resolveAs === 'inline') {
+          if(a.key && a.key.indexOf('#') === -1 && a.key.charAt(0) !== '/') {
+            // handle relative schema
+            parts = a.root.split('/');
+            location = '';
+            for(i = 0; i < parts.length - 1; i++) {
+              location += parts[i] + '/';
+            }
+            location += a.key;
+            a.root = location;
+            a.location = '';
+          }
+          toResolve.push(a);
+        }
+      }
+    }
+    else {
+      toResolve.push(a);
+    }
+  }
+  expectedCalls = toResolve.length;
+
+  // resolve anything that is local
+
+  var lock = {};
+  for(var ii = 0; ii < toResolve.length; ii++) {
+    (function(item, spec, self, lock, ii) {
+      if(!item.root || item.root === root) {
+        // local resolve
+        self.resolveItem(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, item);
+        processedCalls += 1;
+
+        if(processedCalls === expectedCalls) {
+          self.finish(spec, root, resolutionTable, resolvedRefs, unresolvedRefs, callback, true);
+        }
+      }
+      else if(self.failedUrls.indexOf(item.root) === -1) {
+        var obj = {
+          useJQuery: false,  // TODO
+          url: item.root,
+          method: 'get',
+          headers: {
+            accept: self.scope.swaggerRequestHeaders || 'application/json'
+          },
+          on: {
+            error: function (error) {
+              processedCalls += 1;
+              console.log('failed url: ' + obj.url);
+              self.failedUrls.push(obj.url);
+              if (lock) {
+                delete lock[item.root];
+              }
+              unresolvedRefs[item.key] = {
+                root: item.root,
+                location: item.location
+              };
+
+              if (processedCalls === expectedCalls) {
+                self.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback);
+              }
+            },  // jshint ignore:line
+            response: function (response) {
+              var swagger = response.obj;
+              if (lock) {
+                delete lock[item.root];
+              }
+              if (self.resolverCache) {
+                self.resolverCache[item.root] = swagger;
+              }
+              self.resolveItem(swagger, item.root, resolutionTable, resolvedRefs, unresolvedRefs, item);
+              processedCalls += 1;
+
+              if (processedCalls === expectedCalls) {
+                self.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback);
+              }
+            }
+          } // jshint ignore:line
+        };
+
+        // apply timeout only when specified
+        if (scope && scope.fetchSpecTimeout) {
+          obj.timeout = scope.fetchSpecTimeout;
+        }
+
+        if (scope && scope.clientAuthorizations) {
+          scope.clientAuthorizations.apply(obj);
+        }
+
+        (function waitForUnlock() {
+          setTimeout(function() {
+            if (lock[obj.url]) {
+              waitForUnlock();
+            }
+            else {
+              var cached = self.resolverCache[obj.url];
+              if (_.isObject(cached)) {
+                obj.on.response({obj: cached});
+              }
+              else {
+                lock[obj.url] = true;
+                new SwaggerHttp().execute(obj, opts);
+              }
+            }
+          }, 0);
+        })();
+      }
+
+      else {
+        processedCalls += 1;
+        unresolvedRefs[item.key] = {
+          root: item.root,
+          location: item.location
+        };
+        if (processedCalls === expectedCalls) {
+          self.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback);
+        }
+      }
+    }(toResolve[ii], spec, this, lock, ii));
+  }
+
+  if (Object.keys(toResolve).length === 0) {
+    this.finish(spec, _root, resolutionTable, resolvedRefs, unresolvedRefs, callback);
+  }
+};
+
+Resolver.prototype.resolveItem = function(spec, root, resolutionTable, resolvedRefs, unresolvedRefs, item) {
+  var path = item.location;
+  var location = spec, parts = path.split('/');
+  if(path !== '') {
+    for (var j = 0; j < parts.length; j++) {
+      var segment = parts[j];
+      if (segment.indexOf('~1') !== -1) {
+        segment = parts[j].replace(/~0/g, '~').replace(/~1/g, '/');
+        if (segment.charAt(0) !== '/') {
+          segment = '/' + segment;
+        }
+      }
+      if (typeof location === 'undefined' || location === null) {
+        break;
+      }
+      if (segment === '' && j === (parts.length - 1) && parts.length > 1) {
+        location = null;
+        break;
+      }
+      if (segment.length > 0) {
+        location = location[segment];
+      }
+    }
+  }
+  var resolved = item.key;
+  parts = item.key.split('/');
+  var resolvedName = parts[parts.length-1];
+
+  if(resolvedName.indexOf('#') >= 0) {
+    resolvedName = resolvedName.split('#')[1];
+  }
+
+  if (location !== null && typeof location !== 'undefined') {
+    resolvedRefs[resolved] = {
+      name: resolvedName,
+      obj: location,
+      key: item.key,
+      root: item.root
+    };
+  } else {
+    unresolvedRefs[resolved] = {
+      root: item.root,
+      location: item.location
+    };
+  }
+};
+
+Resolver.prototype.finish = function (spec, root, resolutionTable, resolvedRefs, unresolvedRefs, callback, localResolve) {
+  // walk resolution table and replace with resolved refs
+  var ref, abs;
+  for (ref in resolutionTable) {
+    var item = resolutionTable[ref];
+
+    var key = item.key;
+    var resolvedTo = resolvedRefs[key];
+    if (resolvedTo) {
+      spec.definitions = spec.definitions || {};
+      if (item.resolveAs === 'ref') {
+        if (localResolve !== true) {
+          // don't retain root for local definitions
+          for (key in resolvedTo.obj) {
+            abs = this.retainRoot(key, resolvedTo.obj[key], item.root);
+            resolvedTo.obj[key] = abs;
+          }
+        }
+        spec.definitions[resolvedTo.name] = resolvedTo.obj;
+        item.obj.$ref = '#/definitions/' + resolvedTo.name;
+      } else if (item.resolveAs === 'inline') {
+        var targetObj = item.obj;
+        targetObj['x-resolved-from'] = [ item.key ];
+        delete targetObj.$ref;
+
+        for (key in resolvedTo.obj) {
+          abs = resolvedTo.obj[key];
+
+          if (localResolve !== true) {
+            // don't retain root for local definitions
+            abs = this.retainRoot(key, resolvedTo.obj[key], item.root);
+          }
+          targetObj[key] = abs;
+        }
+      }
+    }
+  }
+  var existingUnresolved = this.countUnresolvedRefs(spec);
+
+  if(existingUnresolved === 0 || this.iteration > 5) {
+    this.resolveAllOf(spec.definitions);
+    this.resolverCache = null;
+    callback.call(this.scope, spec, unresolvedRefs);
+  }
+  else {
+    this.iteration += 1;
+    this.resolve(spec, root, callback, this.scope);
+  }
+};
+
+Resolver.prototype.countUnresolvedRefs = function(spec) {
+  var i;
+  var refs = this.getRefs(spec);
+  var keys = [];
+  var unresolvedKeys = [];
+  for(i in refs) {
+    if(i.indexOf('#') === 0) {
+      keys.push(i.substring(1));
+    }
+    else {
+      unresolvedKeys.push(i);
+    }
+  }
+
+  // verify possible keys
+  for (i = 0; i < keys.length; i++) {
+    var part = keys[i];
+    var parts = part.split('/');
+    var obj = spec;
+
+    for (var k = 0; k < parts.length; k++) {
+      var key = parts[k];
+      if(key !== '') {
+        obj = obj[key];
+        if(typeof obj === 'undefined') {
+          unresolvedKeys.push(part);
+          break;
+        }
+      }
+    }
+  }
+  return unresolvedKeys.length;
+};
+
+Resolver.prototype.getRefs = function(spec, obj) {
+  obj = obj || spec;
+  var output = {};
+  for(var key in obj) {
+    if (!obj.hasOwnProperty(key)) {
+      continue;
+    }
+    var item = obj[key];
+    if(key === '$ref' && typeof item === 'string') {
+      output[item] = null;
+    }
+    else if(_.isObject(item)) {
+      var o = this.getRefs(item);
+      for(var k in o) {
+        output[k] = null;
+      }
+    }
+  }
+  return output;
+};
+
+function splitUrl(url) {
+  var result = {};
+  var proto = /[a-z]+:\/\//i.exec(url);
+  if (proto) {
+    result.proto = proto[0].slice(0, -3);
+    url = url.slice(result.proto.length + 1);
+  }
+  if (url.slice(0, 2) === '//') {
+    result.domain = url.slice(2).split('/')[0];
+    url = url.slice(2 + result.domain.length);
+  }
+  var p = url.split('#');
+  if (p[0].length) {
+    result.path = p[0];
+  }
+  if (p.length > 1) {
+    result.fragment = p.slice(1).join('#');
+  }
+  return result;
+}
+
+function unsplitUrl(url) {
+  var result = url.path;
+  if (result === undefined) {
+    result = '';
+  }
+  if (url.fragment !== undefined) {
+    result += '#' + url.fragment;
+  }
+  if (url.domain !== undefined) {
+    if (result.slice(0, 1) === '/') {
+      result = result.slice(1);
+    }
+    result = '//' + url.domain + '/' + result;
+    if (url.proto !== undefined) {
+      result = url.proto + ':' + result;
+    }
+  }
+  return result;
+}
+
+function joinUrl(base, rel) {
+  var relsp = splitUrl(rel);
+  if (relsp.domain !== undefined) {
+    return rel;
+  }
+  var result = splitUrl(base);
+  if (relsp.path === undefined) {
+    // change only fragment part
+    result.fragment = relsp.fragment;
+  } else if (relsp.path.slice(0, 1) === '/') {
+    // relative to domain
+    result.path = relsp.path;
+    result.fragment = relsp.fragment;
+  } else {
+    // relative to path
+    var path = result.path === undefined ? [] : result.path.split('/');
+    var relpath = relsp.path.split('/');
+    if (path.length) {
+      path.pop();
+    }
+    while (relpath[0] === '..' || relpath[0] === '.') {
+      if (relpath[0] === '..') {
+        path.pop();
+      }
+      relpath.shift();
+    }
+    result.path = path.concat(relpath).join('/');
+    result.fragment = relsp.fragment;
+  }
+  return unsplitUrl(result);
+}
+
+Resolver.prototype.retainRoot = function(origKey, obj, root) {
+  // walk object and look for relative $refs
+  if(_.isObject(obj)) {
+    for(var key in obj) {
+      var item = obj[key];
+      if (key === '$ref' && typeof item === 'string') {
+        obj[key] = joinUrl(root, item);
+      }
+      else if (_.isObject(item)) {
+        this.retainRoot(key, item, root);
+      }
+    }
+  }
+  else if(_.isString(obj) && origKey === '$ref') {
+    obj = joinUrl(root, obj);
+  }
+  return obj;
+};
+
+/**
+ * immediately in-lines local refs, queues remote refs
+ * for inline resolution
+ */
+Resolver.prototype.resolveInline = function (root, spec, property, resolutionTable, unresolvedRefs, location) {
+  var key = property.$ref, ref = property.$ref, i, p, p2, rs;
+  var rootTrimmed = false;
+
+  root = root || ''; // Guard against .split. @fehguy, you'll need to check if this logic fits
+  // More imporantly is how do we gracefully handle relative urls, when provided just a 'spec', not a 'url' ?
+
+  if (ref) {
+    if(ref.indexOf('../') === 0) {
+      // reset root
+      p = ref.split('../');
+      p2 = root.split('/');
+      ref = '';
+      for(i = 0; i < p.length; i++) {
+        if(p[i] === '') {
+          p2 = p2.slice(0, p2.length-1);
+        }
+        else {
+          ref += p[i];
+        }
+      }
+      root = '';
+      for(i = 0; i < p2.length - 1; i++) {
+        if(i > 0) { root += '/'; }
+        root += p2[i];
+      }
+      rootTrimmed = true;
+    }
+    if(ref.indexOf('#') >= 0) {
+      if(ref.indexOf('/') === 0) {
+        rs = ref.split('#');
+        p  = root.split('//');
+        p2 = p[1].split('/');
+        root = p[0] + '//' + p2[0] + rs[0];
+        location = rs[1];
+      }
+      else {
+        rs = ref.split('#');
+        if(rs[0] !== '') {
+          p2 = root.split('/');
+          p2 = p2.slice(0, p2.length - 1);
+          if(!rootTrimmed) {
+            root = '';
+            for (var k = 0; k < p2.length; k++) {
+              if(k > 0) { root += '/'; }
+              root += p2[k];
+            }
+          }
+          root += '/' + ref.split('#')[0];
+        }
+        location = rs[1];
+      }
+    }
+    if (ref.indexOf('http:') === 0 || ref.indexOf('https:') === 0) {
+      if(ref.indexOf('#') >= 0) {
+        root = ref.split('#')[0];
+        location = ref.split('#')[1];
+      }
+      else {
+        root = ref;
+        location = '';
+      }
+      resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location});
+    } else if (ref.indexOf('#') === 0) {
+      location = ref.split('#')[1];
+      resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location});
+    } else if (ref.indexOf('/') === 0 && ref.indexOf('#') === -1) {
+      location = ref;
+      var matches = root.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i);
+      if(matches) {
+        root = matches[0] + ref.substring(1);
+        location = '';
+      }
+      resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location});
+    }
+    else {
+      resolutionTable.push({obj: property, resolveAs: 'inline', root: root, key: key, location: location});
+    }
+  }
+  else if (property.type === 'array') {
+    this.resolveTo(root, property.items, resolutionTable, location);
+  }
+};
+
+Resolver.prototype.resolveTo = function (root, property, resolutionTable, location) {
+  var sp, i;
+  var ref = property.$ref;
+  var lroot = root;
+  if ((typeof ref !== 'undefined') && (ref !== null)) {
+    if(ref.indexOf('#') >= 0) {
+      var parts = ref.split('#');
+
+      // #/definitions/foo
+      // foo.json#/bar
+      if(parts[0] && ref.indexOf('/') === 0) {
+
+      }
+      else if(parts[0] && (parts[0].indexOf('http:') === 0 || parts[0].indexOf('https:') === 0)) {
+        lroot = parts[0];
+        ref = parts[1];
+      }
+      else if(parts[0] && parts[0].length > 0) {
+        // relative file
+        sp = root.split('/');
+        lroot = '';
+        for(i = 0; i < sp.length - 1; i++) {
+          lroot += sp[i] + '/';
+        }
+        lroot += parts[0];
+      }
+      else {
+
+      }
+
+      location = parts[1];
+    }
+    else if (ref.indexOf('http:') === 0 || ref.indexOf('https:') === 0) {
+      lroot = ref;
+      location = '';
+    }
+    else {
+      // relative file
+      sp = root.split('/');
+      lroot = '';
+      for(i = 0; i < sp.length - 1; i++) {
+        lroot += sp[i] + '/';
+      }
+      lroot += ref;
+      location = '';
+    }
+    resolutionTable.push({
+      obj: property, resolveAs: 'ref', root: lroot, key: ref, location: location
+    });
+  } else if (property.type === 'array') {
+    var items = property.items;
+    this.resolveTo(root, items, resolutionTable, location);
+  } else {
+    if(property && (property.properties || property.additionalProperties)) {
+      var name = this.uniqueName('inline_model');
+      if (property.title) {
+        name = this.uniqueName(property.title);
+      }
+      delete property.title;
+      this.spec.definitions[name] = _.cloneDeep(property);
+      property.$ref = '#/definitions/' + name;
+      delete property.type;
+      delete property.properties;
+    }
+  }
+};
+
+Resolver.prototype.uniqueName = function(base) {
+  var name = base;
+  var count = 0;
+  while(true) {
+    if(!_.isObject(this.spec.definitions[name])) {
+      return name;
+    }
+    name = base + '_' + count;
+    count++;
+  }
+};
+
+Resolver.prototype.resolveAllOf = function(spec, obj, depth) {
+  depth = depth || 0;
+  obj = obj || spec;
+  var name;
+  for(var key in obj) {
+    if (!obj.hasOwnProperty(key)) {
+      continue;
+    }
+    var item = obj[key];
+    if(item === null) {
+      throw new TypeError('Swagger 2.0 does not support null types (' + obj + ').  See https://github.com/swagger-api/swagger-spec/issues/229.');
+    }
+    if(typeof item === 'object') {
+      this.resolveAllOf(spec, item, depth + 1);
+    }
+    if(item && typeof item.allOf !== 'undefined') {
+      var allOf = item.allOf;
+      if(_.isArray(allOf)) {
+        var output = _.cloneDeep(item);
+        delete output.allOf;
+
+        output['x-composed'] = true;
+        if (typeof item['x-resolved-from'] !== 'undefined') {
+          output['x-resolved-from'] = item['x-resolved-from'];
+        }
+
+        for(var i = 0; i < allOf.length; i++) {
+          var component = allOf[i];
+          var source = 'self';
+          if(typeof component['x-resolved-from'] !== 'undefined') {
+            source = component['x-resolved-from'][0];
+          }
+
+          for(var part in component) {
+            if(!output.hasOwnProperty(part)) {
+              output[part] = _.cloneDeep(component[part]);
+              if(part === 'properties') {
+                for(name in output[part]) {
+                  output[part][name]['x-resolved-from'] = source;
+                }
+              }
+            }
+            else {
+              if(part === 'properties') {
+                var properties = component[part];
+                for(name in properties) {
+                  output.properties[name] = _.cloneDeep(properties[name]);
+                  var resolvedFrom = properties[name]['x-resolved-from'];
+                  if (typeof resolvedFrom === 'undefined' || resolvedFrom === 'self') {
+                    resolvedFrom = source;
+                  }
+                  output.properties[name]['x-resolved-from'] = resolvedFrom;
+                }
+              }
+              else if(part === 'required') {
+                // merge & dedup the required array
+                var a = output.required.concat(component[part]);
+                for(var k = 0; k < a.length; ++k) {
+                  for(var j = k + 1; j < a.length; ++j) {
+                    if(a[k] === a[j]) { a.splice(j--, 1); }
+                  }
+                }
+                output.required = a;
+              }
+              else if(part === 'x-resolved-from') {
+                output['x-resolved-from'].push(source);
+              }
+              else {
+                // TODO: need to merge this property
+                // console.log('what to do with ' + part)
+              }
+            }
+          }
+        }
+        obj[key] = output;
+      }
+    }
+  }
+};
+
+},{"./http":5,"lodash-compat/lang/cloneDeep":138,"lodash-compat/lang/isArray":140,"lodash-compat/lang/isObject":144,"lodash-compat/lang/isString":146}],7:[function(require,module,exports){
+'use strict';
+
+var Helpers = require('./helpers');
+
+var _ = {
+  isPlainObject: require('lodash-compat/lang/isPlainObject'),
+  isUndefined: require('lodash-compat/lang/isUndefined'),
+  isArray: require('lodash-compat/lang/isArray'),
+  isObject: require('lodash-compat/lang/isObject'),
+  isEmpty: require('lodash-compat/lang/isEmpty'),
+  map: require('lodash-compat/collection/map'),
+  indexOf: require('lodash-compat/array/indexOf'),
+  cloneDeep: require('lodash-compat/lang/cloneDeep'),
+  keys: require('lodash-compat/object/keys'),
+  forEach: require('lodash-compat/collection/forEach')
+};
+
+var optionHtml = module.exports.optionHtml = function  (label, value) {
+  return '<tr><td class="optionName">' + label + ':</td><td>' + value + '</td></tr>';
+};
+
+module.exports.typeFromJsonSchema = function (type, format) {
+  var str;
+
+  if (type === 'integer' && format === 'int32') {
+    str = 'integer';
+  } else if (type === 'integer' && format === 'int64') {
+    str = 'long';
+  } else if (type === 'integer' && typeof format === 'undefined') {
+    str = 'long';
+  } else if (type === 'string' && format === 'date-time') {
+    str = 'date-time';
+  } else if (type === 'string' && format === 'date') {
+    str = 'date';
+  } else if (type === 'number' && format === 'float') {
+    str = 'float';
+  } else if (type === 'number' && format === 'double') {
+    str = 'double';
+  } else if (type === 'number' && typeof format === 'undefined') {
+    str = 'double';
+  } else if (type === 'boolean') {
+    str = 'boolean';
+  } else if (type === 'string') {
+    str = 'string';
+  }
+
+  return str;
+};
+
+var getStringSignature = module.exports.getStringSignature = function (obj, baseComponent) {
+  var str = '';
+
+  if (typeof obj.$ref !== 'undefined') {
+    str += Helpers.simpleRef(obj.$ref);
+  } else if (typeof obj.type === 'undefined') {
+    str += 'object';
+  } else if (obj.type === 'array') {
+    if (baseComponent) {
+      str += getStringSignature((obj.items || obj.$ref || {}));
+    } else {
+      str += 'Array[';
+      str += getStringSignature((obj.items || obj.$ref || {}));
+      str += ']';
+    }
+  } else if (obj.type === 'integer' && obj.format === 'int32') {
+    str += 'integer';
+  } else if (obj.type === 'integer' && obj.format === 'int64') {
+    str += 'long';
+  } else if (obj.type === 'integer' && typeof obj.format === 'undefined') {
+    str += 'long';
+  } else if (obj.type === 'string' && obj.format === 'date-time') {
+    str += 'date-time';
+  } else if (obj.type === 'string' && obj.format === 'date') {
+    str += 'date';
+  } else if (obj.type === 'string' && typeof obj.format === 'undefined') {
+    str += 'string';
+  } else if (obj.type === 'number' && obj.format === 'float') {
+    str += 'float';
+  } else if (obj.type === 'number' && obj.format === 'double') {
+    str += 'double';
+  } else if (obj.type === 'number' && typeof obj.format === 'undefined') {
+    str += 'double';
+  } else if (obj.type === 'boolean') {
+    str += 'boolean';
+  } else if (obj.$ref) {
+    str += Helpers.simpleRef(obj.$ref);
+  } else {
+    str += obj.type;
+  }
+
+  return str;
+};
+
+var schemaToJSON = module.exports.schemaToJSON = function (schema, models, modelsToIgnore, modelPropertyMacro) {
+  // Resolve the schema (Handle nested schemas)
+  schema = Helpers.resolveSchema(schema);
+
+  if(typeof modelPropertyMacro !== 'function') {
+    modelPropertyMacro = function(prop){
+      return (prop || {}).default;
+    };
+  }
+
+  modelsToIgnore= modelsToIgnore || {};
+
+  var type = schema.type || 'object';
+  var format = schema.format;
+  var model;
+  var output;
+
+  if (!_.isUndefined(schema.example)) {
+    output = schema.example;
+  } else if (_.isUndefined(schema.items) && _.isArray(schema.enum)) {
+    output = schema.enum[0];
+  }
+
+  if (_.isUndefined(output)) {
+    if (schema.$ref) {
+      model = models[Helpers.simpleRef(schema.$ref)];
+
+      if (!_.isUndefined(model)) {
+        if (_.isUndefined(modelsToIgnore[model.name])) {
+          modelsToIgnore[model.name] = model;
+          output = schemaToJSON(model.definition, models, modelsToIgnore, modelPropertyMacro);
+          delete modelsToIgnore[model.name];
+        } else {
+          if (model.type === 'array') {
+            output = [];
+          } else {
+            output = {};
+          }
+        }
+      }
+    } else if (!_.isUndefined(schema.default)) {
+      output = schema.default;
+    } else if (type === 'string') {
+      if (format === 'date-time') {
+        output = new Date().toISOString();
+      } else if (format === 'date') {
+        output = new Date().toISOString().split('T')[0];
+      } else {
+        output = 'string';
+      }
+    } else if (type === 'integer') {
+      output = 0;
+    } else if (type === 'number') {
+      output = 0.0;
+    } else if (type === 'boolean') {
+      output = true;
+    } else if (type === 'object') {
+      output = {};
+
+      _.forEach(schema.properties, function (property, name) {
+        var cProperty = _.cloneDeep(property);
+
+        // Allow macro to set the default value
+        cProperty.default = modelPropertyMacro(property);
+
+        output[name] = schemaToJSON(cProperty, models, modelsToIgnore, modelPropertyMacro);
+      });
+    } else if (type === 'array') {
+      output = [];
+
+      if (_.isArray(schema.items)) {
+        _.forEach(schema.items, function (item) {
+          output.push(schemaToJSON(item, models, modelsToIgnore, modelPropertyMacro));
+        });
+      } else if (_.isPlainObject(schema.items)) {
+        output.push(schemaToJSON(schema.items, models, modelsToIgnore, modelPropertyMacro));
+      } else if (_.isUndefined(schema.items)) {
+        output.push({});
+      } else {
+        Helpers.log('Array type\'s \'items\' property is not an array or an object, cannot process');
+      }
+    }
+  }
+
+  return output;
+};
+
+module.exports.schemaToHTML =function (name, schema, models, modelPropertyMacro) {
+  var strongOpen = '<span class="strong">';
+  var strongClose = '</span>';
+
+  // Allow for ignoring the 'name' argument.... shifting the rest
+  if(_.isObject(arguments[0])) {
+    name = void 0;
+    schema = arguments[0];
+    models = arguments[1];
+    modelPropertyMacro = arguments[2];
+  }
+
+  models = models || {};
+
+  // Resolve the schema (Handle nested schemas)
+  schema = Helpers.resolveSchema(schema);
+
+  // Return for empty object
+  if(_.isEmpty(schema)) {
+    return strongOpen + 'Empty' + strongClose;
+  }
+
+  // Dereference $ref from 'models'
+  if(typeof schema.$ref === 'string') {
+    name = Helpers.simpleRef(schema.$ref);
+    schema = models[name];
+    if(typeof schema === 'undefined')
+    {
+      return strongOpen + name + ' is not defined!' + strongClose;
+    }
+  }
+
+  if(typeof name !== 'string') {
+    name = schema.title || 'Inline Model';
+  }
+
+  // If we are a Model object... adjust accordingly
+  if(schema.definition) {
+    schema = schema.definition;
+  }
+
+  if(typeof modelPropertyMacro !== 'function') {
+    modelPropertyMacro = function(prop){
+      return (prop || {}).default;
+    };
+  }
+
+  var references = {};
+  var seenModels = [];
+  var inlineModels = 0;
+
+
+
+  // Generate current HTML
+  var html = processModel(schema, name);
+
+  // Generate references HTML
+  while (_.keys(references).length > 0) {
+    /* jshint ignore:start */
+    _.forEach(references, function (schema, name) {
+      var seenModel = _.indexOf(seenModels, name) > -1;
+
+      delete references[name];
+
+      if (!seenModel) {
+        seenModels.push(name);
+
+        html += '<br />' + processModel(schema, name);
+      }
+    });
+    /* jshint ignore:end */
+  }
+
+  return html;
+
+  /////////////////////////////////
+
+  function addReference(schema, name, skipRef) {
+    var modelName = name;
+    var model;
+
+    if (schema.$ref) {
+      modelName = schema.title || Helpers.simpleRef(schema.$ref);
+      model = models[modelName];
+    } else if (_.isUndefined(name)) {
+      modelName = schema.title || 'Inline Model ' + (++inlineModels);
+      model = {definition: schema};
+    }
+
+    if (skipRef !== true) {
+      references[modelName] = _.isUndefined(model) ? {} : model.definition;
+    }
+
+    return modelName;
+  }
+
+  function primitiveToHTML(schema) {
+    var html = '<span class="propType">';
+    var type = schema.type || 'object';
+
+    if (schema.$ref) {
+      html += addReference(schema, Helpers.simpleRef(schema.$ref));
+    } else if (type === 'object') {
+      if (!_.isUndefined(schema.properties)) {
+        html += addReference(schema);
+      } else {
+        html += 'object';
+      }
+    } else if (type === 'array') {
+      html += 'Array[';
+
+      if (_.isArray(schema.items)) {
+        html += _.map(schema.items, addReference).join(',');
+      } else if (_.isPlainObject(schema.items)) {
+        if (_.isUndefined(schema.items.$ref)) {
+          if (!_.isUndefined(schema.items.type) && _.indexOf(['array', 'object'], schema.items.type) === -1) {
+            html += schema.items.type;
+          } else {
+            html += addReference(schema.items);
+          }
+        } else {
+          html += addReference(schema.items, Helpers.simpleRef(schema.items.$ref));
+        }
+      } else {
+        Helpers.log('Array type\'s \'items\' schema is not an array or an object, cannot process');
+        html += 'object';
+      }
+
+      html += ']';
+    } else {
+      html += schema.type;
+    }
+
+    html += '</span>';
+
+    return html;
+  }
+
+  function primitiveToOptionsHTML(schema, html) {
+    var options = '';
+    var type = schema.type || 'object';
+    var isArray = type === 'array';
+
+    if (isArray) {
+      if (_.isPlainObject(schema.items) && !_.isUndefined(schema.items.type)) {
+        type = schema.items.type;
+      } else {
+        type = 'object';
+      }
+    }
+
+    if (!_.isUndefined(schema.default)) {
+      options += optionHtml('Default', schema.default);
+    }
+
+    switch (type) {
+    case 'string':
+      if (schema.minLength) {
+        options += optionHtml('Min. Length', schema.minLength);
+      }
+
+      if (schema.maxLength) {
+        options += optionHtml('Max. Length', schema.maxLength);
+      }
+
+      if (schema.pattern) {
+        options += optionHtml('Reg. Exp.', schema.pattern);
+      }
+      break;
+    case 'integer':
+    case 'number':
+      if (schema.minimum) {
+        options += optionHtml('Min. Value', schema.minimum);
+      }
+
+      if (schema.exclusiveMinimum) {
+        options += optionHtml('Exclusive Min.', 'true');
+      }
+
+      if (schema.maximum) {
+        options += optionHtml('Max. Value', schema.maximum);
+      }
+
+      if (schema.exclusiveMaximum) {
+        options += optionHtml('Exclusive Max.', 'true');
+      }
+
+      if (schema.multipleOf) {
+        options += optionHtml('Multiple Of', schema.multipleOf);
+      }
+
+      break;
+    }
+
+    if (isArray) {
+      if (schema.minItems) {
+        options += optionHtml('Min. Items', schema.minItems);
+      }
+
+      if (schema.maxItems) {
+        options += optionHtml('Max. Items', schema.maxItems);
+      }
+
+      if (schema.uniqueItems) {
+        options += optionHtml('Unique Items', 'true');
+      }
+
+      if (schema.collectionFormat) {
+        options += optionHtml('Coll. Format', schema.collectionFormat);
+      }
+    }
+
+    if (_.isUndefined(schema.items)) {
+      if (_.isArray(schema.enum)) {
+        var enumString;
+
+        if (type === 'number' || type === 'integer') {
+          enumString = schema.enum.join(', ');
+        } else {
+          enumString = '"' + schema.enum.join('", "') + '"';
+        }
+
+        options += optionHtml('Enum', enumString);
+      }
+    }
+
+    if (options.length > 0) {
+      html = '<span class="propWrap">' + html + '<table class="optionsWrapper"><tr><th colspan="2">' + type + '</th></tr>' + options + '</table></span>';
+    }
+
+    return html;
+  }
+
+  function processModel(schema, name) {
+    var type = schema.type || 'object';
+    var isArray = schema.type === 'array';
+    var html = strongOpen + name + ' ' + (isArray ? '[' : '{') + strongClose;
+
+    if (name) {
+      seenModels.push(name);
+    }
+
+    if (isArray) {
+      if (_.isArray(schema.items)) {
+        html += '<div>' + _.map(schema.items, function (item) {
+          var type = item.type || 'object';
+
+          if (_.isUndefined(item.$ref)) {
+            if (_.indexOf(['array', 'object'], type) > -1) {
+              if (type === 'object' && _.isUndefined(item.properties)) {
+                return 'object';
+              } else {
+                return addReference(item);
+              }
+            } else {
+              return primitiveToOptionsHTML(item, type);
+            }
+          } else {
+            return addReference(item, Helpers.simpleRef(item.$ref));
+          }
+        }).join(',</div><div>');
+      } else if (_.isPlainObject(schema.items)) {
+        if (_.isUndefined(schema.items.$ref)) {
+          if (_.indexOf(['array', 'object'], schema.items.type || 'object') > -1) {
+            if ((_.isUndefined(schema.items.type) || schema.items.type === 'object') && _.isUndefined(schema.items.properties)) {
+              html += '<div>object</div>';
+            } else {
+              html += '<div>' + addReference(schema.items) + '</div>';
+            }
+          } else {
+            html += '<div>' + primitiveToOptionsHTML(schema.items, schema.items.type) + '</div>';
+          }
+        } else {
+          html += '<div>' + addReference(schema.items, Helpers.simpleRef(schema.items.$ref)) + '</div>';
+        }
+      } else {
+        Helpers.log('Array type\'s \'items\' property is not an array or an object, cannot process');
+        html += '<div>object</div>';
+      }
+    } else {
+      if (schema.$ref) {
+        html += '<div>' + addReference(schema, name) + '</div>';
+      } else if (type === 'object') {
+        if (_.isPlainObject(schema.properties)) {
+          var contents = _.map(schema.properties, function (property, name) {
+            var propertyIsRequired = (_.indexOf(schema.required, name) >= 0);
+            var cProperty = _.cloneDeep(property);
+
+            var requiredClass = propertyIsRequired ? 'required' : '';
+            var html = '<span class="propName ' + requiredClass + '">' + name + '</span> (';
+            var model;
+            var propDescription;
+
+            // Allow macro to set the default value
+            cProperty.default = modelPropertyMacro(cProperty);
+
+            // Resolve the schema (Handle nested schemas)
+            cProperty = Helpers.resolveSchema(cProperty);
+
+            propDescription = property.description || cProperty.description;
+
+            // We need to handle property references to primitives (Issue 339)
+            if (!_.isUndefined(cProperty.$ref)) {
+              model = models[Helpers.simpleRef(cProperty.$ref)];
+
+              if (!_.isUndefined(model) && _.indexOf([undefined, 'array', 'object'], model.definition.type) === -1) {
+                // Use referenced schema
+                cProperty = Helpers.resolveSchema(model.definition);
+              }
+            }
+
+            html += primitiveToHTML(cProperty);
+
+            if(!propertyIsRequired) {
+              html += ', <span class="propOptKey">optional</span>';
+            }
+
+            if(property.readOnly) {
+                html += ', <span class="propReadOnly">read only</span>';
+            }
+
+            html += ')';
+
+            if (!_.isUndefined(propDescription)) {
+              html += ': ' + '<span class="propDesc">' + propDescription + '</span>';
+            }
+
+            if (cProperty.enum) {
+              html += ' = <span class="propVals">[\'' + cProperty.enum.join('\', \'') + '\']</span>';
+            }
+
+            return '<div' + (property.readOnly ? ' class="readOnly"' : '') + '>' + primitiveToOptionsHTML(cProperty, html);
+          }).join(',</div>');
+
+          if (contents) {
+            html += contents + '</div>';
+          }
+        }
+      } else {
+        html += '<div>' + primitiveToOptionsHTML(schema, type) + '</div>';
+      }
+    }
+
+    return html + strongOpen + (isArray ? ']' : '}') + strongClose;
+  }
+};
+},{"./helpers":4,"lodash-compat/array/indexOf":49,"lodash-compat/collection/forEach":54,"lodash-compat/collection/map":56,"lodash-compat/lang/cloneDeep":138,"lodash-compat/lang/isArray":140,"lodash-compat/lang/isEmpty":141,"lodash-compat/lang/isObject":144,"lodash-compat/lang/isPlainObject":145,"lodash-compat/lang/isUndefined":148,"lodash-compat/object/keys":149}],8:[function(require,module,exports){
+'use strict';
+
+var SwaggerHttp = require('./http');
+var _ = {
+  isObject: require('lodash-compat/lang/isObject')
+};
+
+var SwaggerSpecConverter = module.exports = function () {
+  this.errors = [];
+  this.warnings = [];
+  this.modelMap = {};
+};
+
+SwaggerSpecConverter.prototype.setDocumentationLocation = function (location) {
+  this.docLocation = location;
+};
+
+/**
+ * converts a resource listing OR api declaration
+ **/
+SwaggerSpecConverter.prototype.convert = function (obj, clientAuthorizations, opts, callback) {
+  // not a valid spec
+  if(!obj || !Array.isArray(obj.apis)) {
+    return this.finish(callback, null);
+  }
+  this.clientAuthorizations = clientAuthorizations;
+
+  // create a new swagger object to return
+  var swagger = { swagger: '2.0' };
+
+  swagger.originalVersion = obj.swaggerVersion;
+
+  // add the info
+  this.apiInfo(obj, swagger);
+
+  // add security definitions
+  this.securityDefinitions(obj, swagger);
+
+  // take basePath into account
+  if (obj.basePath) {
+    this.setDocumentationLocation(obj.basePath);
+  }
+
+  // see if this is a single-file swagger definition
+  var isSingleFileSwagger = false;
+  var i;
+  for(i = 0; i < obj.apis.length; i++) {
+    var api = obj.apis[i];
+    if(Array.isArray(api.operations)) {
+      isSingleFileSwagger = true;
+    }
+  }
+  if(isSingleFileSwagger) {
+    this.declaration(obj, swagger);
+    this.finish(callback, swagger);
+  }
+  else {
+    this.resourceListing(obj, swagger, opts, callback);
+  }
+};
+
+SwaggerSpecConverter.prototype.declaration = function(obj, swagger) {
+  var name, i, p, pos;
+  if(!obj.apis) {
+    return;
+  }
+
+  if (obj.basePath.indexOf('http://') === 0) {
+    p = obj.basePath.substring('http://'.length);
+    pos = p.indexOf('/');
+    if (pos > 0) {
+      swagger.host = p.substring(0, pos);
+      swagger.basePath = p.substring(pos);
+    }
+    else {
+      swagger.host = p;
+      swagger.basePath = '/';
+    }
+  } else if (obj.basePath.indexOf('https://') === 0) {
+    p = obj.basePath.substring('https://'.length);
+    pos = p.indexOf('/');
+    if (pos > 0) {
+      swagger.host = p.substring(0, pos);
+      swagger.basePath = p.substring(pos);
+    }
+    else {
+      swagger.host = p;
+      swagger.basePath = '/';
+    }
+  } else {
+    swagger.basePath = obj.basePath;
+  }
+
+  var resourceLevelAuth;
+  if(obj.authorizations) {
+    resourceLevelAuth = obj.authorizations;
+  }
+  if(obj.consumes) {
+    swagger.consumes = obj.consumes;
+  }
+  if(obj.produces) {
+    swagger.produces = obj.produces;
+  }
+
+  // build a mapping of id to name for 1.0 model resolutions
+  if(_.isObject(obj)) {
+    for(name in obj.models) {
+      var existingModel = obj.models[name];
+      var key = (existingModel.id || name);
+      this.modelMap[key] = name;
+    }
+  }
+
+  for(i = 0; i < obj.apis.length; i++) {
+    var api = obj.apis[i];
+    var path = api.path;
+    var operations = api.operations;
+    this.operations(path, obj.resourcePath, operations, resourceLevelAuth, swagger);
+  }
+
+  var models = obj.models || {};
+  this.models(models, swagger);
+};
+
+SwaggerSpecConverter.prototype.models = function(obj, swagger) {
+  if(!_.isObject(obj)) {
+    return;
+  }
+  var name;
+
+  swagger.definitions = swagger.definitions || {};
+  for(name in obj) {
+    var existingModel = obj[name];
+    var _required = [];
+    var schema = { properties: {}};
+    var propertyName;
+    for(propertyName in existingModel.properties) {
+      var existingProperty = existingModel.properties[propertyName];
+      var property = {};
+      this.dataType(existingProperty, property);
+      if(existingProperty.description) {
+        property.description = existingProperty.description;
+      }
+      if(existingProperty['enum']) {
+        property['enum'] = existingProperty['enum'];
+      }
+      if(typeof existingProperty.required === 'boolean' && existingProperty.required === true) {
+        _required.push(propertyName);
+      }
+      if(typeof existingProperty.required === 'string' && existingProperty.required === 'true') {
+        _required.push(propertyName);
+      }
+      schema.properties[propertyName] = property;
+    }
+    if(_required.length > 0) {
+      schema.required = _required;
+    } else {
+      schema.required = existingModel.required;
+    }
+    swagger.definitions[name] = schema;
+  }
+};
+
+SwaggerSpecConverter.prototype.extractTag = function(resourcePath) {
+  var pathString = resourcePath || 'default';
+  if(pathString.indexOf('http:') === 0 || pathString.indexOf('https:') === 0) {
+    pathString = pathString.split(['/']);
+    pathString = pathString[pathString.length -1].substring();
+  }
+  if(pathString.endsWith('.json')) {
+    pathString = pathString.substring(0, pathString.length - '.json'.length);
+  }
+  return pathString.replace('/','');
+};
+
+SwaggerSpecConverter.prototype.operations = function(path, resourcePath, obj, resourceLevelAuth, swagger) {
+  if(!Array.isArray(obj)) {
+    return;
+  }
+  var i;
+
+  if(!swagger.paths) {
+    swagger.paths = {};
+  }
+
+  var pathObj = swagger.paths[path] || {};
+  var tag = this.extractTag(resourcePath);
+  swagger.tags = swagger.tags || [];
+  var matched = false;
+  for(i = 0; i < swagger.tags.length; i++) {
+    var tagObject = swagger.tags[i];
+    if(tagObject.name === tag) {
+      matched = true;
+    }
+  }
+  if(!matched) {
+    swagger.tags.push({name: tag});
+  }
+
+  for(i = 0; i < obj.length; i++) {
+    var existingOperation = obj[i];
+    var method = (existingOperation.method || existingOperation.httpMethod).toLowerCase();
+    var operation = {tags: [tag]};
+    var existingAuthorizations = existingOperation.authorizations;
+
+    if(existingAuthorizations && Object.keys(existingAuthorizations).length === 0) {
+      existingAuthorizations = resourceLevelAuth;
+    }
+
+    if(typeof existingAuthorizations !== 'undefined') {
+      var scopesObject;
+      for(var key in existingAuthorizations) {
+        operation.security = operation.security || [];
+        var scopes = existingAuthorizations[key];
+        if(scopes) {
+          var securityScopes = [];
+          for(var j in scopes) {
+            securityScopes.push(scopes[j].scope);
+          }
+          scopesObject = {};
+          scopesObject[key] = securityScopes;
+          operation.security.push(scopesObject);
+        }
+        else {
+          scopesObject = {};
+          scopesObject[key] = [];
+          operation.security.push(scopesObject);
+        }
+      }
+    }
+
+    if(existingOperation.consumes) {
+      operation.consumes = existingOperation.consumes;
+    }
+    else if(swagger.consumes) {
+      operation.consumes = swagger.consumes;
+    }
+    if(existingOperation.produces) {
+      operation.produces = existingOperation.produces;
+    }
+    else if(swagger.produces) {
+      operation.produces = swagger.produces;
+    }
+    if(existingOperation.summary) {
+      operation.summary = existingOperation.summary;
+    }
+    if(existingOperation.notes) {
+      operation.description = existingOperation.notes;
+    }
+    if(existingOperation.nickname) {
+      operation.operationId = existingOperation.nickname;
+    }
+    if(existingOperation.deprecated) {
+      operation.deprecated = existingOperation.deprecated;
+    }
+
+    this.authorizations(existingAuthorizations, swagger);
+    this.parameters(operation, existingOperation.parameters, swagger);
+    this.responseMessages(operation, existingOperation, swagger);
+
+    pathObj[method] = operation;
+  }
+
+  swagger.paths[path] = pathObj;
+};
+
+SwaggerSpecConverter.prototype.responseMessages = function(operation, existingOperation) {
+  if(!_.isObject(existingOperation)) {
+    return;
+  }
+  // build default response from the operation (1.x)
+  var defaultResponse = {};
+  this.dataType(existingOperation, defaultResponse);
+  // TODO: look into the real problem of rendering responses in swagger-ui
+  // ....should reponseType have an implicit schema?
+  if(!defaultResponse.schema && defaultResponse.type) {
+    defaultResponse = {schema: defaultResponse};
+  }
+
+  operation.responses = operation.responses || {};
+
+  // grab from responseMessages (1.2)
+  var has200 = false;
+  if(Array.isArray(existingOperation.responseMessages)) {
+    var i;
+    var existingResponses = existingOperation.responseMessages;
+    for(i = 0; i < existingResponses.length; i++) {
+      var existingResponse = existingResponses[i];
+      var response = { description: existingResponse.message };
+      if(existingResponse.code === 200) {
+        has200 = true;
+      }
+      // Convert responseModel -> schema{$ref: responseModel}
+      if(existingResponse.responseModel) {
+        response.schema = {'$ref': '#/definitions/' + existingResponse.responseModel};
+      }
+      operation.responses['' + existingResponse.code] = response;
+    }
+  }
+
+  if(has200) {
+    operation.responses['default'] = defaultResponse;
+  }
+  else {
+    operation.responses['200'] = defaultResponse;
+  }
+};
+
+SwaggerSpecConverter.prototype.authorizations = function(obj) {
+  // TODO
+  if(!_.isObject(obj)) {
+    return;
+  }
+};
+
+SwaggerSpecConverter.prototype.parameters = function(operation, obj) {
+  if(!Array.isArray(obj)) {
+    return;
+  }
+  var i;
+  for(i = 0; i < obj.length; i++) {
+    var existingParameter = obj[i];
+    var parameter = {};
+    parameter.name = existingParameter.name;
+    parameter.description = existingParameter.description;
+    parameter.required = existingParameter.required;
+    parameter.in = existingParameter.paramType;
+
+    // per #168
+    if(parameter.in === 'body') {
+      parameter.name = 'body';
+    }
+    if(parameter.in === 'form') {
+      parameter.in = 'formData';
+    }
+
+    if(existingParameter.enum) {
+      parameter.enum = existingParameter.enum;
+    }
+
+    if(existingParameter.allowMultiple === true || existingParameter.allowMultiple === 'true') {
+      var innerType = {};
+      this.dataType(existingParameter, innerType);
+      parameter.type = 'array';
+      parameter.items = innerType;
+
+      if(existingParameter.allowableValues) {
+        var av = existingParameter.allowableValues;
+        if(av.valueType === 'LIST') {
+          parameter['enum'] = av.values;
+        }
+      }
+    }
+    else {
+      this.dataType(existingParameter, parameter);
+    }
+    if(typeof existingParameter.defaultValue !== 'undefined') {
+      parameter.default = existingParameter.defaultValue;
+    }
+
+    operation.parameters = operation.parameters || [];
+    operation.parameters.push(parameter);
+  }
+};
+
+SwaggerSpecConverter.prototype.dataType = function(source, target) {
+  if(!_.isObject(source)) {
+    return;
+  }
+
+  if(source.minimum) {
+    target.minimum = source.minimum;
+  }
+  if(source.maximum) {
+    target.maximum = source.maximum;
+  }
+  if (source.format) {
+    target.format = source.format;
+  }
+
+  // default can be 'false'
+  if(typeof source.defaultValue !== 'undefined') {
+    target.default = source.defaultValue;
+  }
+
+  var jsonSchemaType = this.toJsonSchema(source);
+  if(jsonSchemaType) {
+    target = target || {};
+    if(jsonSchemaType.type) {
+      target.type = jsonSchemaType.type;
+    }
+    if(jsonSchemaType.format) {
+      target.format = jsonSchemaType.format;
+    }
+    if(jsonSchemaType.$ref) {
+      target.schema = {$ref: jsonSchemaType.$ref};
+    }
+    if(jsonSchemaType.items) {
+      target.items = jsonSchemaType.items;
+    }
+  }
+};
+
+SwaggerSpecConverter.prototype.toJsonSchema = function(source) {
+  if(!source) {
+    return 'object';
+  }
+  var detectedType = (source.type || source.dataType || source.responseClass || '');
+  var lcType = detectedType.toLowerCase();
+  var format = (source.format || '').toLowerCase();
+
+  if(lcType.indexOf('list[') === 0) {
+    var innerType = detectedType.substring(5, detectedType.length - 1);
+    var jsonType = this.toJsonSchema({type: innerType});
+    return {type: 'array', items: jsonType};
+  } else if(lcType === 'int' || (lcType === 'integer' && format === 'int32')) {
+    {return {type: 'integer', format: 'int32'};}
+  } else if(lcType === 'long' || (lcType === 'integer' && format === 'int64')) {
+    {return {type: 'integer', format: 'int64'};}
+  } else if(lcType === 'integer') {
+    {return {type: 'integer', format: 'int64'};}
+  } else if(lcType === 'float' || (lcType === 'number' && format === 'float')) {
+    {return {type: 'number', format: 'float'};}
+  } else if(lcType === 'double' || (lcType === 'number' && format === 'double')) {
+    {return {type: 'number', format: 'double'};}
+  } else if((lcType === 'string' && format === 'date-time') || (lcType === 'date')) {
+    {return {type: 'string', format: 'date-time'};}
+  } else if(lcType === 'string') {
+    {return {type: 'string'};}
+  } else if(lcType === 'file') {
+    {return {type: 'file'};}
+  } else if(lcType === 'boolean') {
+    {return {type: 'boolean'};}
+  } else if(lcType === 'boolean') {
+    {return {type: 'boolean'};}
+  } else if(lcType === 'array' || lcType === 'list') {
+    if(source.items) {
+      var it = this.toJsonSchema(source.items);
+      return {type: 'array', items: it};
+    }
+    else {
+      return {type: 'array', items: {type: 'object'}};
+    }
+  } else if(source.$ref) {
+    return {$ref: this.modelMap[source.$ref] ? '#/definitions/' + this.modelMap[source.$ref] : source.$ref};
+  } else if(lcType === 'void' || lcType === '') {
+    {return {};}
+  } else if (this.modelMap[source.type]) {
+    // If this a model using `type` instead of `$ref`, that's fine.
+    return {$ref: '#/definitions/' + this.modelMap[source.type]};
+  } else {
+    // Unknown model type or 'object', pass it along.
+    return {type: source.type};
+  }
+};
+
+SwaggerSpecConverter.prototype.resourceListing = function(obj, swagger, opts, callback) {
+  var i;
+  var processedCount = 0;   // jshint ignore:line
+  var self = this;          // jshint ignore:line
+  var expectedCount = obj.apis.length;
+  var _swagger = swagger;   // jshint ignore:line
+  var _opts = {};
+
+  if(opts && opts.requestInterceptor){
+    _opts.requestInterceptor = opts.requestInterceptor;
+  }
+
+  if(opts && opts.responseInterceptor){
+    _opts.responseInterceptor = opts.responseInterceptor;
+  }
+
+  var swaggerRequestHeaders = 'application/json';
+
+  if(opts && opts.swaggerRequestHeaders) {
+    swaggerRequestHeaders = opts.swaggerRequestHeaders;
+  }
+
+  if(expectedCount === 0) {
+    this.finish(callback, swagger);
+  }
+
+  for(i = 0; i < expectedCount; i++) {
+    var api = obj.apis[i];
+    var path = api.path;
+    var absolutePath = this.getAbsolutePath(obj.swaggerVersion, this.docLocation, path);
+
+    if(api.description) {
+      swagger.tags = swagger.tags || [];
+      swagger.tags.push({
+        name : this.extractTag(api.path),
+        description : api.description || ''
+      });
+    }
+    var http = {
+      url: absolutePath,
+      headers: { accept: swaggerRequestHeaders },
+      on: {},
+      method: 'get',
+      timeout: opts.timeout
+    };
+    /* jshint ignore:start */
+    http.on.response = function(data) {
+      processedCount += 1;
+      var obj = data.obj;
+      if(obj) {
+        self.declaration(obj, _swagger);
+      }
+      if(processedCount === expectedCount) {
+        self.finish(callback, _swagger);
+      }
+    };
+    http.on.error = function(data) {
+      console.error(data);
+      processedCount += 1;
+      if(processedCount === expectedCount) {
+        self.finish(callback, _swagger);
+      }
+    };
+    /* jshint ignore:end */
+
+    if(this.clientAuthorizations && typeof this.clientAuthorizations.apply === 'function') {
+      this.clientAuthorizations.apply(http);
+    }
+
+    new SwaggerHttp().execute(http, _opts);
+  }
+};
+
+SwaggerSpecConverter.prototype.getAbsolutePath = function(version, docLocation, path)  {
+  if(version === '1.0') {
+    if(docLocation.endsWith('.json')) {
+      // get root path
+      var pos = docLocation.lastIndexOf('/');
+      if(pos > 0) {
+        docLocation = docLocation.substring(0, pos);
+      }
+    }
+  }
+
+  var location = docLocation;
+  if(path.indexOf('http:') === 0 || path.indexOf('https:') === 0) {
+    location = path;
+  }
+  else {
+    if(docLocation.endsWith('/')) {
+      location = docLocation.substring(0, docLocation.length - 1);
+    }
+    location += path;
+  }
+  location = location.replace('{format}', 'json');
+  return location;
+};
+
+SwaggerSpecConverter.prototype.securityDefinitions = function(obj, swagger) {
+  if(obj.authorizations) {
+    var name;
+    for(name in obj.authorizations) {
+      var isValid = false;
+      var securityDefinition = {
+        vendorExtensions: {}
+      };
+      var definition = obj.authorizations[name];
+      if(definition.type === 'apiKey') {
+        securityDefinition.type = 'apiKey';
+        securityDefinition.in = definition.passAs;
+        securityDefinition.name = definition.keyname || name;
+        isValid = true;
+      }
+      else if(definition.type === 'basicAuth') {
+        securityDefinition.type = 'basicAuth';
+        isValid = true;
+      }
+      else if(definition.type === 'oauth2') {
+        var existingScopes = definition.scopes || [];
+        var scopes = {};
+        var i;
+        for(i in existingScopes) {
+          var scope = existingScopes[i];
+          scopes[scope.scope] = scope.description;
+        }
+        securityDefinition.type = 'oauth2';
+        if(i > 0) {
+          securityDefinition.scopes = scopes;
+        }
+        if(definition.grantTypes) {
+          if(definition.grantTypes.implicit) {
+            var implicit = definition.grantTypes.implicit;
+            securityDefinition.flow = 'implicit';
+            securityDefinition.authorizationUrl = implicit.loginEndpoint;
+            isValid = true;
+          }
+          /* jshint ignore:start */
+          if(definition.grantTypes['authorization_code']) {
+            if(!securityDefinition.flow) {
+              // cannot set if flow is already defined
+              var authCode = definition.grantTypes['authorization_code'];
+              securityDefinition.flow = 'accessCode';
+              securityDefinition.authorizationUrl = authCode.tokenRequestEndpoint.url;
+              securityDefinition.tokenUrl = authCode.tokenEndpoint.url;
+              isValid = true;
+            }
+          }
+          /* jshint ignore:end */
+        }
+      }
+      if(isValid) {
+        swagger.securityDefinitions = swagger.securityDefinitions || {};
+        swagger.securityDefinitions[name] = securityDefinition;
+      }
+    }
+  }
+};
+
+SwaggerSpecConverter.prototype.apiInfo = function(obj, swagger) {
+  // info section
+  if(obj.info) {
+    var info = obj.info;
+    swagger.info = {};
+
+    if(info.contact) {
+      swagger.info.contact = {};
+      swagger.info.contact.email = info.contact;
+    }
+    if(info.description) {
+      swagger.info.description = info.description;
+    }
+    if(info.title) {
+      swagger.info.title = info.title;
+    }
+    if(info.termsOfServiceUrl) {
+      swagger.info.termsOfService = info.termsOfServiceUrl;
+    }
+    if(info.license || info.licenseUrl) {
+      swagger.license = {};
+      if(info.license) {
+        swagger.license.name = info.license;
+      }
+      if(info.licenseUrl) {
+        swagger.license.url = info.licenseUrl;
+      }
+    }
+  }
+  else {
+    this.warnings.push('missing info section');
+  }
+};
+
+SwaggerSpecConverter.prototype.finish = function (callback, obj) {
+  callback(obj);
+};
+
+},{"./http":5,"lodash-compat/lang/isObject":144}],9:[function(require,module,exports){
+'use strict';
+
+var log = require('../helpers').log;
+var _ = {
+  isPlainObject: require('lodash-compat/lang/isPlainObject'),
+  isString: require('lodash-compat/lang/isString'),
+};
+
+var SchemaMarkup = require('../schema-markup.js');
+var jsyaml = require('js-yaml');
+
+var Model = module.exports = function (name, definition, models, modelPropertyMacro) {
+  this.definition = definition || {};
+  this.isArray = definition.type === 'array';
+  this.models = models || {};
+  this.name = name || definition.title || 'Inline Model';
+  this.modelPropertyMacro = modelPropertyMacro || function (property) {
+    return property.default;
+  };
+
+  return this;
+};
+
+// Note!  This function will be removed in 2.2.x!
+Model.prototype.createJSONSample = Model.prototype.getSampleValue = function (modelsToIgnore) {
+  modelsToIgnore = modelsToIgnore || {};
+
+  modelsToIgnore[this.name] = this;
+
+  // Response support
+  if (this.examples && _.isPlainObject(this.examples) && this.examples['application/json']) {
+    this.definition.example = this.examples['application/json'];
+
+    if (_.isString(this.definition.example)) {
+      this.definition.example = jsyaml.safeLoad(this.definition.example);
+    }
+  } else if (!this.definition.example) {
+    this.definition.example = this.examples;
+  }
+
+  return SchemaMarkup.schemaToJSON(this.definition, this.models, modelsToIgnore, this.modelPropertyMacro);
+};
+
+Model.prototype.getMockSignature = function () {
+  return SchemaMarkup.schemaToHTML(this.name, this.definition, this.models, this.modelPropertyMacro);
+};
+
+},{"../helpers":4,"../schema-markup.js":7,"js-yaml":19,"lodash-compat/lang/isPlainObject":145,"lodash-compat/lang/isString":146}],10:[function(require,module,exports){
+'use strict';
+
+var _ = {
+  cloneDeep: require('lodash-compat/lang/cloneDeep'),
+  isUndefined: require('lodash-compat/lang/isUndefined'),
+  isEmpty: require('lodash-compat/lang/isEmpty'),
+  isObject: require('lodash-compat/lang/isObject')
+};
+var helpers = require('../helpers');
+var Model = require('./model');
+var SwaggerHttp = require('../http');
+var Q = require('q');
+
+var Operation = module.exports = function (parent, scheme, operationId, httpMethod, path, args, definitions, models, clientAuthorizations) {
+  var errors = [];
+
+  parent = parent || {};
+  args = args || {};
+
+  if(parent && parent.options) {
+    this.client = parent.options.client || null;
+    this.requestInterceptor = parent.options.requestInterceptor || null;
+    this.responseInterceptor = parent.options.responseInterceptor || null;
+    this.requestAgent = parent.options.requestAgent;
+  }
+  this.authorizations = args.security;
+  this.basePath = parent.basePath || '/';
+  this.clientAuthorizations = clientAuthorizations;
+  this.consumes = args.consumes || parent.consumes || ['application/json'];
+  this.produces = args.produces || parent.produces || ['application/json'];
+  this.deprecated = args.deprecated;
+  this.description = args.description;
+  this.host = parent.host;
+  this.method = (httpMethod || errors.push('Operation ' + operationId + ' is missing method.'));
+  this.models = models || {};
+  this.nickname = (operationId || errors.push('Operations must have a nickname.'));
+  this.operation = args;
+  this.operations = {};
+  this.parameters = args !== null ? (args.parameters || []) : {};
+  this.parent = parent;
+  this.path = (path || errors.push('Operation ' + this.nickname + ' is missing path.'));
+  this.responses = (args.responses || {});
+  this.scheme = scheme || parent.scheme || 'http';
+  this.schemes = args.schemes || parent.schemes;
+  this.security = args.security || parent.security;
+  this.summary = args.summary || '';
+  this.timeout = parent.timeout;
+  this.type = null;
+  this.useJQuery = parent.useJQuery;
+  this.jqueryAjaxCache = parent.jqueryAjaxCache;
+  this.enableCookies = parent.enableCookies;
+
+  var key;
+
+  if(!this.host) {
+    if(typeof window !== 'undefined') {
+      this.host = window.location.host;
+    }
+    else {
+      this.host = 'localhost';
+    }
+  }
+  this.parameterMacro = parent.parameterMacro || function (operation, parameter) {
+    return parameter.default;
+  };
+
+  this.inlineModels = [];
+
+  if(this.basePath !== '/' && this.basePath.slice(-1) === '/') {
+    this.basePath = this.basePath.slice(0, -1);
+  }
+
+  if (typeof this.deprecated === 'string') {
+    switch(this.deprecated.toLowerCase()) {
+      case 'true': case 'yes': case '1': {
+        this.deprecated = true;
+        break;
+      }
+
+      case 'false': case 'no': case '0': case null: {
+        this.deprecated = false;
+        break;
+      }
+
+      default: this.deprecated = Boolean(this.deprecated);
+    }
+  }
+
+  var i, model;
+
+  if (definitions) {
+    // add to global models
+    for (key in definitions) {
+      model = new Model(key, definitions[key], this.models, parent.modelPropertyMacro);
+
+      if (model) {
+        this.models[key] = model;
+      }
+    }
+  }
+  else {
+    definitions = {};
+  }
+
+  for (i = 0; i < this.parameters.length; i++) {
+    var d, param = this.parameters[i];
+
+    // Allow macro to set the default value
+    param.default = this.parameterMacro(this, param);
+
+    if (param.type === 'array') {
+      param.isList = true;
+      param.allowMultiple = true;
+    }
+
+    var innerType = this.getType(param);
+
+    if (innerType && innerType.toString().toLowerCase() === 'boolean') {
+      param.allowableValues = {};
+      param.isList = true;
+      param['enum'] = [true, false]; // use actual primitives
+    }
+
+    for(key in param) {
+      helpers.extractExtensions(key, param);
+    }
+    if(typeof param['x-example'] !== 'undefined') {
+      d = param['x-example'];
+      param.default = d;
+    }
+    if(param['x-examples']) {
+      d = param['x-examples'].default;
+      if(typeof d !== 'undefined') {
+        param.default = d;
+      }
+    }
+
+    var enumValues = param['enum'] || (param.items && param.items['enum']);
+
+    if (typeof enumValues !== 'undefined') {
+      var id;
+
+      param.allowableValues = {};
+      param.allowableValues.values = [];
+      param.allowableValues.descriptiveValues = [];
+
+      for (id = 0; id < enumValues.length; id++) {
+        var value = enumValues[id];
+        var isDefault = (value === param.default || value+'' === param.default);
+
+        param.allowableValues.values.push(value);
+        // Always have string for descriptive values....
+        param.allowableValues.descriptiveValues.push({value : value+'', isDefault: isDefault});
+      }
+    }
+
+    if (param.type === 'array') {
+      innerType = [innerType];
+
+      if (typeof param.allowableValues === 'undefined') {
+        // can't show as a list if no values to select from
+        delete param.isList;
+        delete param.allowMultiple;
+      }
+    }
+
+    param.modelSignature = {type: innerType, definitions: this.models};
+    param.signature = this.getModelSignature(innerType, this.models).toString();
+    param.sampleJSON = this.getModelSampleJSON(innerType, this.models);
+    param.responseClassSignature = param.signature;
+  }
+
+  var keyname, defaultResponseCode, response, responses = this.responses;
+
+  if (responses['200']) {
+    response = responses['200'];
+    defaultResponseCode = '200';
+  } else if (responses['201']) {
+    response = responses['201'];
+    defaultResponseCode = '201';
+  } else if (responses['202']) {
+    response = responses['202'];
+    defaultResponseCode = '202';
+  } else if (responses['203']) {
+    response = responses['203'];
+    defaultResponseCode = '203';
+  } else if (responses['204']) {
+    response = responses['204'];
+    defaultResponseCode = '204';
+  } else if (responses['205']) {
+    response = responses['205'];
+    defaultResponseCode = '205';
+  } else if (responses['206']) {
+    response = responses['206'];
+    defaultResponseCode = '206';
+  } else if (responses['default']) {
+    response = responses['default'];
+    defaultResponseCode = 'default';
+  }
+
+  for(keyname in responses) {
+    helpers.extractExtensions(keyname, responses);
+    if(typeof keyname === 'string' && keyname.indexOf('x-') === -1) {
+      var responseObject = responses[keyname];
+      if(typeof responseObject === 'object' && typeof responseObject.headers === 'object') {
+        var headers = responseObject.headers;
+        for(var headerName in headers) {
+          var header = headers[headerName];
+          if(typeof header === 'object') {
+            for(var headerKey in header) {
+              helpers.extractExtensions(headerKey, header);
+            }
+          }
+        }
+      }
+    }
+  }
+
+  if (response) {
+    for(keyname in response) {
+      helpers.extractExtensions(keyname, response);
+    }
+  }
+
+  if (response && response.schema) {
+    var resolvedModel = this.resolveModel(response.schema, definitions);
+    var successResponse;
+
+    delete responses[defaultResponseCode];
+
+    if (resolvedModel) {
+      this.successResponse = {};
+      successResponse = this.successResponse[defaultResponseCode] = resolvedModel;
+    } else if (!response.schema.type || response.schema.type === 'object' || response.schema.type === 'array') {
+      // Inline model
+      this.successResponse = {};
+      successResponse = this.successResponse[defaultResponseCode] = new Model(undefined, response.schema || {}, this.models, parent.modelPropertyMacro);
+    } else {
+      // Primitive
+      this.successResponse = {};
+      successResponse = this.successResponse[defaultResponseCode] = response.schema;
+    }
+
+    if (successResponse) {
+      successResponse.vendorExtensions = response.vendorExtensions;
+      // Attach response properties
+      if (response.description) {
+        successResponse.description = response.description;
+      }
+
+      if (response.examples) {
+        successResponse.examples = response.examples;
+      }
+
+      if (response.headers) {
+        successResponse.headers = response.headers;
+      }
+    }
+
+    this.type = response;
+  }
+
+  if (errors.length > 0) {
+    if (this.resource && this.resource.api && this.resource.api.fail) {
+      this.resource.api.fail(errors);
+    }
+  }
+
+  return this;
+};
+
+Operation.prototype.isDefaultArrayItemValue = function(value, param) {
+  if (param.default && Array.isArray(param.default)) {
+    return param.default.indexOf(value) !== -1;
+  }
+  return value === param.default;
+};
+
+Operation.prototype.getType = function (param) {
+  var type = param.type;
+  var format = param.format;
+  var isArray = false;
+  var str;
+
+  if (type === 'integer' && format === 'int32') {
+    str = 'integer';
+  } else if (type === 'integer' && format === 'int64') {
+    str = 'long';
+  } else if (type === 'integer') {
+    str = 'integer';
+  } else if (type === 'string') {
+    if (format === 'date-time') {
+      str = 'date-time';
+    } else if (format === 'date') {
+      str = 'date';
+    } else {
+      str = 'string';
+    }
+  } else if (type === 'number' && format === 'float') {
+    str = 'float';
+  } else if (type === 'number' && format === 'double') {
+    str = 'double';
+  } else if (type === 'number') {
+    str = 'double';
+  } else if (type === 'boolean') {
+    str = 'boolean';
+  } else if (type === 'array') {
+    isArray = true;
+
+    if (param.items) {
+      str = this.getType(param.items);
+    }
+  } else if (type === 'file') {
+    str = 'file';
+  }
+
+  if (param.$ref) {
+    str = helpers.simpleRef(param.$ref);
+  }
+
+  var schema = param.schema;
+
+  if (schema) {
+    var ref = schema.$ref;
+
+    if (ref) {
+      ref = helpers.simpleRef(ref);
+
+      if (isArray) {
+        return [ ref ];
+      } else {
+        return ref;
+      }
+    } else {
+      // If inline schema, we add it our interal hash -> which gives us it's ID (int)
+      if(schema.type === 'object') {
+        return this.addInlineModel(schema);
+      }
+      return this.getType(schema);
+    }
+  }
+  if (isArray) {
+    return [ str ];
+  } else {
+    return str;
+  }
+};
+
+/**
+ * adds an inline schema (model) to a hash, where we can ref it later
+ * @param {object} schema a schema
+ * @return {number} the ID of the schema being added, or null
+ **/
+Operation.prototype.addInlineModel = function (schema) {
+  var len = this.inlineModels.length;
+  var model = this.resolveModel(schema, {});
+  if(model) {
+    this.inlineModels.push(model);
+    return 'Inline Model '+len; // return string ref of the inline model (used with #getInlineModel)
+  }
+  return null; // report errors?
+};
+
+/**
+ * gets the internal ref to an inline model
+ * @param {string} inline_str a string reference to an inline model
+ * @return {Model} the model being referenced. Or null
+ **/
+Operation.prototype.getInlineModel = function(inlineStr) {
+  if(/^Inline Model \d+$/.test(inlineStr)) {
+    var id = parseInt(inlineStr.substr('Inline Model'.length).trim(),10); //
+    var model = this.inlineModels[id];
+    return model;
+  }
+  // I'm returning null here, should I rather throw an error?
+  return null;
+};
+
+Operation.prototype.resolveModel = function (schema, definitions) {
+  if (typeof schema.$ref !== 'undefined') {
+    var ref = schema.$ref;
+
+    if (ref.indexOf('#/definitions/') === 0) {
+      ref = ref.substring('#/definitions/'.length);
+    }
+
+    if (definitions[ref]) {
+      return new Model(ref, definitions[ref], this.models, this.parent.modelPropertyMacro);
+    }
+  // schema must at least be an object to get resolved to an inline Model
+  } else if (schema && typeof schema === 'object' &&
+            (schema.type === 'object' || _.isUndefined(schema.type))) {
+    return new Model(undefined, schema, this.models, this.parent.modelPropertyMacro);
+  }
+
+  return null;
+};
+
+Operation.prototype.help = function (dontPrint) {
+  var out = this.nickname + ': ' + this.summary + '\n';
+
+  for (var i = 0; i < this.parameters.length; i++) {
+    var param = this.parameters[i];
+    var typeInfo = param.signature;
+
+    out += '\n  * ' + param.name + ' (' + typeInfo + '): ' + param.description;
+  }
+
+  if (typeof dontPrint === 'undefined') {
+    helpers.log(out);
+  }
+
+  return out;
+};
+
+Operation.prototype.getModelSignature = function (type, definitions) {
+  var isPrimitive, listType;
+
+  if (type instanceof Array) {
+    listType = true;
+    type = type[0];
+  }
+
+  // Convert undefined to string of 'undefined'
+  if (typeof type === 'undefined') {
+    type = 'undefined';
+    isPrimitive = true;
+
+  } else if (definitions[type]){
+    // a model def exists?
+    type = definitions[type]; /* Model */
+    isPrimitive = false;
+
+  } else if (this.getInlineModel(type)) {
+    type = this.getInlineModel(type); /* Model */
+    isPrimitive = false;
+
+  } else {
+    // We default to primitive
+    isPrimitive = true;
+  }
+
+  if (isPrimitive) {
+    if (listType) {
+      return 'Array[' + type + ']';
+    } else {
+      return type.toString();
+    }
+  } else {
+    if (listType) {
+      return 'Array[' + type.getMockSignature() + ']';
+    } else {
+      return type.getMockSignature();
+    }
+  }
+};
+
+Operation.prototype.supportHeaderParams = function () {
+  return true;
+};
+
+Operation.prototype.supportedSubmitMethods = function () {
+  return this.parent.supportedSubmitMethods;
+};
+
+Operation.prototype.getHeaderParams = function (args) {
+  var headers = this.setContentTypes(args, {});
+  var headerParamsByLowerCase = {};
+
+  for (var i = 0; i < this.parameters.length; i++) {
+    var param = this.parameters[i];
+
+    if (param.in === 'header') {
+      headerParamsByLowerCase[param.name.toLowerCase()] = param;
+    }
+  }
+
+  for (var arg in args) {
+    var headerParam = headerParamsByLowerCase[arg.toLowerCase()];
+    if (typeof headerParam !== 'undefined') {
+      var value = args[arg];
+
+      if (Array.isArray(value)) {
+        value = value.toString();
+      }
+
+      headers[headerParam.name] = value;
+    }
+  }
+
+  return headers;
+};
+
+Operation.prototype.urlify = function (args, maskPasswords) {
+  var formParams = {};
+  var requestUrl = this.path.replace(/#.*/, ''); // remove URL fragment
+  var querystring = ''; // grab params from the args, build the querystring along the way
+
+  for (var i = 0; i < this.parameters.length; i++) {
+    var param = this.parameters[i];
+
+    if (typeof args[param.name] !== 'undefined') {
+      var isPassword;
+      if(param.type === 'string' && param.format === 'password' && maskPasswords) {
+        isPassword = true;
+      }
+
+      if (param.in === 'path') {
+        var reg = new RegExp('\{' + param.name + '\}', 'gi');
+        var value = args[param.name];
+
+        if (Array.isArray(value)) {
+          value = this.encodePathCollection(param.collectionFormat, param.name, value, isPassword);
+        } else {
+          if((typeof(param['x-escape']) === 'undefined') || (param['x-escape'] === true)) {
+            value = this.encodePathParam(value, isPassword);
+          }
+        }
+
+        requestUrl = requestUrl.replace(reg, value);
+      } else if (param.in === 'query' && typeof args[param.name] !== 'undefined') {
+        if (querystring === '' && requestUrl.indexOf('?') < 0) {
+          querystring += '?';
+        } else {
+          querystring += '&';
+        }
+
+        if (typeof param.collectionFormat !== 'undefined') {
+          var qp = args[param.name];
+
+          if (Array.isArray(qp)) {
+            querystring += this.encodeQueryCollection(param.collectionFormat, param.name, qp, isPassword);
+          } else {
+            querystring += this.encodeQueryKey(param.name) + '=' + this.encodeQueryParam(args[param.name], isPassword);
+          }
+        } else {
+          querystring += this.encodeQueryKey(param.name) + '=' + this.encodeQueryParam(args[param.name], isPassword);
+        }
+      } else if (param.in === 'formData') {
+        formParams[param.name] = args[param.name];
+      }
+    } else if(param.in === 'query' && typeof args[param.name] === 'undefined' && param.allowEmptyValue === true) {
+      if (querystring === '' && requestUrl.indexOf('?') < 0) {
+        querystring += '?';
+      } else {
+        querystring += '&';
+      }
+
+      if (typeof param.collectionFormat !== 'undefined' || param.type === 'array') {
+        var qp;
+        var collectionFormat = param.collectionFormat || 'multi';
+
+        if (Array.isArray(qp)) {
+          querystring += this.encodeQueryCollection(collectionFormat, param.name, qp, isPassword);
+        } else {
+          querystring += this.encodeQueryCollection(collectionFormat, param.name, [qp], isPassword);
+        }
+      } else {
+        querystring += this.encodeQueryKey(param.name) + '=' + this.encodeQueryParam('', isPassword);
+      }
+
+    }
+  }
+  var url = this.scheme + '://' + this.host;
+
+  if (this.basePath !== '/') {
+    url += this.basePath;
+  }
+  return url + requestUrl + querystring;
+};
+
+Operation.prototype.getMissingParams = function (args) {
+  var missingParams = []; // check required params, track the ones that are missing
+  var i;
+
+  for (i = 0; i < this.parameters.length; i++) {
+    var param = this.parameters[i];
+
+    if (param.required === true) {
+      if (typeof args[param.name] === 'undefined') {
+        missingParams = param.name;
+      }
+    }
+  }
+
+  return missingParams;
+};
+
+Operation.prototype.getBody = function (headers, args, opts) {
+  var formParams = {}, hasFormParams, param, body, key, value, hasBody = false;
+
+  // look at each param and put form params in an object
+  for (var i = 0; i < this.parameters.length; i++) {
+    param = this.parameters[i];
+    if (typeof args[param.name] !== 'undefined') {
+      var isPassword;
+      if(param.type === 'string' && param.format === 'password') {
+        isPassword = 'password';
+      }
+      if (param.in === 'body') {
+        body = args[param.name];
+      } else if (param.in === 'formData') {
+        formParams[param.name] = {
+          param: param,
+          value: args[param.name],
+          password: isPassword
+        };
+        hasFormParams = true;
+      }
+    }
+    else {
+      if(param.in === 'body') {
+        hasBody = true;
+      }
+    }
+  }
+
+  // if body is null and hasBody is true, AND a JSON body is requested, send empty {}
+  if(hasBody && typeof body === 'undefined') {
+    var contentType = headers['Content-Type'];
+    if(contentType && contentType.indexOf('application/json') === 0) {
+      body = '{}';
+    }
+  }
+
+  var isMultiPart = false;
+  if(headers['Content-Type'] && headers['Content-Type'].indexOf('multipart/form-data') >= 0) {
+    isMultiPart = true;
+  }
+
+  // handle form params
+  if (hasFormParams && !isMultiPart) {
+    var encoded = '';
+
+    for (key in formParams) {
+      param = formParams[key].param;
+      value = formParams[key].value;
+      var password;
+
+      if(opts && opts.maskPasswords) {
+        password = formParams[key].password;
+      }
+
+      if (typeof value !== 'undefined') {
+        if (Array.isArray(value)) {
+          if (encoded !== '') {
+            encoded += '&';
+          }
+          encoded += this.encodeQueryCollection(param.collectionFormat, key, value, password);
+        }
+        else {
+          if (encoded !== '') {
+            encoded += '&';
+          }
+
+          encoded += encodeURIComponent(key) + '=' + mask(encodeURIComponent(value), password);
+        }
+      }
+    }
+
+    body = encoded;
+  } else if (isMultiPart) {
+    var bodyParam;
+    if (typeof FormData === 'function') {
+      bodyParam = new FormData();
+
+      bodyParam.type = 'formData';
+
+      for (key in formParams) {
+        param = formParams[key].param;
+        value = args[key];
+
+        if (typeof value !== 'undefined') {
+          if({}.toString.apply(value) === '[object File]') {
+            bodyParam.append(key, value);
+          }
+          else if (value.type === 'file' && value.value) {
+            bodyParam.append(key, value.value);
+          } else {
+            if (Array.isArray(value)) {
+              if(param.collectionFormat === 'multi') {
+                bodyParam.delete(key);
+                for(var v in value) {
+                  bodyParam.append(key, value[v]);
+                }
+              }
+              else {
+                bodyParam.append(key, this.encodeQueryCollection(param.collectionFormat, key, value).split('=').slice(1).join('='));
+              }
+            }
+            else {
+              bodyParam.append(key, value);
+            }
+          }
+        }
+      }
+      body = bodyParam;
+    }
+    else {
+      bodyParam = {};
+      for (key in formParams) {
+        value = args[key];
+        if (Array.isArray(value)) {
+          var delimeter;
+          var format = param.collectionFormat || 'multi';
+          if(format === 'ssv') {
+            delimeter = ' ';
+          }
+          else if(format === 'pipes') {
+            delimeter = '|';
+          }
+          else if(format === 'tsv') {
+            delimeter = '\t';
+          }
+          else if(format === 'multi') {
+            bodyParam[key] = value;
+            break;
+          }
+          else {
+            delimeter = ',';
+          }
+          var data;
+          value.forEach(function(v) {
+            if(data) {
+              data += delimeter;
+            }
+            else {
+              data = '';
+            }
+            data += v;
+          });
+          bodyParam[key] = data;
+        }
+        else {
+          bodyParam[key] = value;
+        }
+      }
+      body = bodyParam;
+    }
+    headers['Content-Type'] = 'multipart/form-data';
+  }
+
+  return body;
+};
+
+/**
+ * gets sample response for a single operation
+ **/
+Operation.prototype.getModelSampleJSON = function (type, models) {
+  var listType, sampleJson, innerType;
+  models = models || {};
+
+  listType = (type instanceof Array);
+  innerType = listType ? type[0] : type;
+
+  if(models[innerType]) {
+    sampleJson = models[innerType].createJSONSample();
+  } else if (this.getInlineModel(innerType)){
+    sampleJson = this.getInlineModel(innerType).createJSONSample(); // may return null, if type isn't correct
+  }
+
+
+  if (sampleJson) {
+    sampleJson = listType ? [sampleJson] : sampleJson;
+
+    if (typeof sampleJson === 'string') {
+      return sampleJson;
+    } else if (_.isObject(sampleJson)) {
+      var t = sampleJson;
+
+      if (sampleJson instanceof Array && sampleJson.length > 0) {
+        t = sampleJson[0];
+      }
+
+      if (t.nodeName && typeof t === 'Node') {
+        var xmlString = new XMLSerializer().serializeToString(t);
+
+        return this.formatXml(xmlString);
+      } else {
+        return JSON.stringify(sampleJson, null, 2);
+      }
+    } else {
+      return sampleJson;
+    }
+  }
+};
+
+/**
+ * legacy binding
+ **/
+Operation.prototype.do = function (args, opts, callback, error, parent) {
+  return this.execute(args, opts, callback, error, parent);
+};
+
+/**
+ * executes an operation
+ **/
+Operation.prototype.execute = function (arg1, arg2, arg3, arg4, parent) {
+  var args = arg1 || {};
+  var opts = {}, success, error, deferred, timeout;
+
+  if (_.isObject(arg2)) {
+    opts = arg2;
+    success = arg3;
+    error = arg4;
+  }
+
+  timeout = typeof opts.timeout !== 'undefined' ? opts.timeout : this.timeout;
+
+  if(this.client) {
+    opts.client = this.client;
+  }
+
+  if(this.requestAgent) {
+    opts.requestAgent = this.requestAgent;
+  }
+
+  // add the request interceptor from parent, if none sent from client
+  if(!opts.requestInterceptor && this.requestInterceptor ) {
+    opts.requestInterceptor = this.requestInterceptor ;
+  }
+
+  if(!opts.responseInterceptor && this.responseInterceptor) {
+    opts.responseInterceptor = this.responseInterceptor;
+  }
+
+  if (typeof arg2 === 'function') {
+    success = arg2;
+    error = arg3;
+  }
+
+  if (this.parent.usePromise) {
+    deferred = Q.defer();
+  } else {
+    success = (success || this.parent.defaultSuccessCallback || helpers.log);
+    error = (error || this.parent.defaultErrorCallback || helpers.log);
+  }
+
+  if (typeof opts.useJQuery === 'undefined') {
+    opts.useJQuery = this.useJQuery;
+  }
+
+  if (typeof opts.jqueryAjaxCache === 'undefined') {
+    opts.jqueryAjaxCache = this.jqueryAjaxCache;
+  }
+
+  if (typeof opts.enableCookies === 'undefined') {
+    opts.enableCookies = this.enableCookies;
+  }
+
+  var missingParams = this.getMissingParams(args);
+
+  if (missingParams.length > 0) {
+    var message = 'missing required params: ' + missingParams;
+
+    helpers.fail(message);
+
+    if (this.parent.usePromise) {
+      deferred.reject(message);
+      return deferred.promise;
+    } else {
+      error(message, parent);
+      return {};
+    }
+  }
+
+  var allHeaders = this.getHeaderParams(args);
+  var contentTypeHeaders = this.setContentTypes(args, opts);
+  var headers = {}, attrname;
+
+  for (attrname in allHeaders) { headers[attrname] = allHeaders[attrname]; }
+  for (attrname in contentTypeHeaders) { headers[attrname] = contentTypeHeaders[attrname]; }
+
+  var body = this.getBody(contentTypeHeaders, args, opts);
+  var url = this.urlify(args, opts.maskPasswords);
+
+  if(url.indexOf('.{format}') > 0) {
+    if(headers) {
+      var format = headers.Accept || headers.accept;
+      if(format && format.indexOf('json') > 0) {
+        url = url.replace('.{format}', '.json');
+      }
+      else if(format && format.indexOf('xml') > 0) {
+        url = url.replace('.{format}', '.xml');
+      }
+    }
+  }
+
+  var obj = {
+    url: url,
+    method: this.method.toUpperCase(),
+    body: body,
+    enableCookies: opts.enableCookies,
+    useJQuery: opts.useJQuery,
+    jqueryAjaxCache: opts.jqueryAjaxCache,
+    deferred: deferred,
+    headers: headers,
+    clientAuthorizations: opts.clientAuthorizations,
+    operation: this,
+    connectionAgent: this.connectionAgent,
+    on: {
+      response: function (response) {
+        if (deferred) {
+          deferred.resolve(response);
+          return deferred.promise;
+        } else {
+          return success(response, parent);
+        }
+      },
+      error: function (response) {
+        if (deferred) {
+          deferred.reject(response);
+          return deferred.promise;
+        } else {
+          return error(response, parent);
+        }
+      }
+    }
+  };
+
+  if (timeout) {
+    obj.timeout = timeout;
+  }
+
+  this.clientAuthorizations.apply(obj, this.operation.security);
+  if (opts.mock === true) {
+    if(opts.requestInterceptor) {
+      opts.requestInterceptor.apply(obj);
+    }
+    return obj;
+  } else {
+    return new SwaggerHttp().execute(obj, opts);
+  }
+};
+
+function itemByPriority(col, itemPriority) {
+
+  // No priorities? return first...
+  if(_.isEmpty(itemPriority)) {
+    return col[0];
+  }
+
+  for (var i = 0, len = itemPriority.length; i < len; i++) {
+    if(col.indexOf(itemPriority[i]) > -1) {
+      return itemPriority[i];
+    }
+  }
+
+  // Otherwise return first
+  return col[0];
+}
+
+Operation.prototype.setContentTypes = function (args, opts) {
+  // default type
+  var allDefinedParams = this.parameters;
+  var body;
+  var consumes = args.parameterContentType || itemByPriority(this.consumes, ['application/json', 'application/yaml']);
+  var accepts = opts.responseContentType || itemByPriority(this.produces, ['application/json', 'application/yaml']);
+  var definedFileParams = [];
+  var definedFormParams = [];
+  var headers = {};
+  var i;
+
+  // get params from the operation and set them in definedFileParams, definedFormParams, headers
+  for (i = 0; i < allDefinedParams.length; i++) {
+    var param = allDefinedParams[i];
+
+    if (param.in === 'formData') {
+      if (param.type === 'file') {
+        definedFileParams.push(param);
+      } else {
+        definedFormParams.push(param);
+      }
+    } else if (param.in === 'header' && opts) {
+      var key = param.name;
+      var headerValue = opts[param.name];
+
+      if (typeof opts[param.name] !== 'undefined') {
+        headers[key] = headerValue;
+      }
+    } else if (param.in === 'body' && typeof args[param.name] !== 'undefined') {
+      body = args[param.name];
+    }
+  }
+
+  // if there's a body, need to set the consumes header via requestContentType
+  var hasBody = body || definedFileParams.length || definedFormParams.length;
+  if (this.method === 'post' || this.method === 'put' || this.method === 'patch' ||
+      ((this.method === 'delete' || this.method === 'get') && hasBody)) {
+    if (opts.requestContentType) {
+      consumes = opts.requestContentType;
+    }
+    // if any form params, content type must be set
+    if (definedFormParams.length > 0) {
+      consumes = undefined;
+      if (opts.requestContentType) {             // override if set
+        consumes = opts.requestContentType;
+      } else if (definedFileParams.length > 0) { // if a file, must be multipart/form-data
+        consumes = 'multipart/form-data';
+      } else {
+        if (this.consumes && this.consumes.length > 0) {
+          // use the consumes setting
+          for(var c in this.consumes) {
+            var chk = this.consumes[c];
+            if(chk.indexOf('application/x-www-form-urlencoded') === 0 || chk.indexOf('multipart/form-data') === 0) {
+              consumes = chk;
+            }
+          }
+        }
+      }
+      if(typeof consumes === 'undefined') {
+        // default to x-www-from-urlencoded
+        consumes = 'application/x-www-form-urlencoded';
+      }
+    }
+  }
+  else {
+    consumes = null;
+  }
+
+  if (consumes && this.consumes) {
+    if (this.consumes.indexOf(consumes) === -1) {
+      helpers.log('server doesn\'t consume ' + consumes + ', try ' + JSON.stringify(this.consumes));
+    }
+  }
+
+  if (!this.matchesAccept(accepts)) {
+    helpers.log('server can\'t produce ' + accepts);
+  }
+
+  if ((consumes && body !== '') || (consumes === 'application/x-www-form-urlencoded')) {
+    headers['Content-Type'] = consumes;
+  }
+  else if(this.consumes && this.consumes.length > 0 && this.consumes[0] === 'application/x-www-form-urlencoded') {
+    headers['Content-Type'] = this.consumes[0];
+  }
+
+  if (accepts) {
+    headers.Accept = accepts;
+  }
+
+  return headers;
+};
+
+/**
+ * Returns true if the request accepts header matches anything in this.produces.
+ *  If this.produces contains * / *, ignore the accept header.
+ * @param {string=} accepts The client request accept header.
+ * @return {boolean}
+ */
+Operation.prototype.matchesAccept = function(accepts) {
+  // no accepts or produces, no problem!
+  if (!accepts || !this.produces) {
+    return true;
+  }
+  return this.produces.indexOf(accepts) !== -1 || this.produces.indexOf('*/*') !== -1;
+};
+
+Operation.prototype.asCurl = function (args1, args2) {
+  var opts = {mock: true, maskPasswords: true};
+  if (typeof args2 === 'object') {
+    for (var argKey in args2) {
+      opts[argKey] = args2[argKey];
+    }
+  }
+  var obj = this.execute(args1, opts);
+
+  this.clientAuthorizations.apply(obj, this.operation.security);
+
+  var results = [];
+
+  results.push('-X ' + this.method.toUpperCase());
+
+  if (typeof obj.headers !== 'undefined') {
+    var key;
+
+    for (key in obj.headers) {
+      var value = obj.headers[key];
+      if(typeof value === 'string'){
+        value = value.replace(/\'/g, '\\u0027');
+      }
+      results.push('--header \'' + key + ': ' + value + '\'');
+    }
+  }
+  var isFormData = false;
+  var isMultipart = false;
+
+  var type = obj.headers['Content-Type'];
+  if(type && type.indexOf('application/x-www-form-urlencoded') === 0) {
+    isFormData = true;
+  }
+  else if (type && type.indexOf('multipart/form-data') === 0) {
+    isFormData = true;
+    isMultipart = true;
+  }
+
+  if (obj.body) {
+    var body;
+    if (_.isObject(obj.body)) {
+      if(isMultipart) {
+        isMultipart = true;
+        // add the form data
+        for(var i = 0; i < this.parameters.length; i++) {
+          var parameter = this.parameters[i];
+          if(parameter.in === 'formData') {
+            if (!body) {
+              body = '';
+            }
+
+            var paramValue;
+            if(typeof FormData === 'function' && obj.body instanceof FormData) {
+              paramValue = obj.body.getAll(parameter.name);
+            }
+            else {
+              paramValue = obj.body[parameter.name];
+            }
+            if (paramValue) {
+              if (parameter.type === 'file') {
+                if(paramValue.name) {
+                  body += '-F ' + parameter.name + '=@"' + paramValue.name + '" ';
+                }
+              }
+              else {
+                if (Array.isArray(paramValue)) {
+                  if(parameter.collectionFormat === 'multi') {
+                    for(var v in paramValue) {
+                      body += '-F ' + this.encodeQueryKey(parameter.name) + '=' + mask(paramValue[v], parameter.format) + ' ';
+                    }
+                  }
+                  else {
+                    body += '-F ' + this.encodeQueryCollection(parameter.collectionFormat, parameter.name, mask(paramValue, parameter.format)) + ' ';
+                  }
+                } else {
+                  body += '-F ' + this.encodeQueryKey(parameter.name) + '=' + mask(paramValue, parameter.format) + ' ';
+                }
+              }
+            }
+          }
+        }
+      }
+      if(!body) {
+        body = JSON.stringify(obj.body);
+      }
+    } else {
+      body = obj.body;
+    }
+    // escape @ => %40, ' => %27
+    body = body.replace(/\'/g, '%27').replace(/\n/g, ' \\ \n ');
+
+    if(!isFormData) {
+      // escape & => %26
+      body = body.replace(/&/g, '%26');
+    }
+    if(isMultipart) {
+      results.push(body);
+    }
+    else {
+      results.push('-d \'' + body.replace(/@/g, '%40') + '\'');
+    }
+  }
+
+  return 'curl ' + (results.join(' ')) + ' \'' + obj.url + '\'';
+};
+
+Operation.prototype.encodePathCollection = function (type, name, value, maskPasswords) {
+  var encoded = '';
+  var i;
+  var separator = '';
+
+  if (type === 'ssv') {
+    separator = '%20';
+  } else if (type === 'tsv') {
+    separator = '%09';
+  } else if (type === 'pipes') {
+    separator = '|';
+  } else {
+    separator = ',';
+  }
+
+  for (i = 0; i < value.length; i++) {
+    if (i === 0) {
+      encoded = this.encodeQueryParam(value[i], maskPasswords);
+    } else {
+      encoded += separator + this.encodeQueryParam(value[i], maskPasswords);
+    }
+  }
+
+  return encoded;
+};
+
+Operation.prototype.encodeQueryCollection = function (type, name, value, maskPasswords) {
+  var encoded = '';
+  var i;
+
+  type = type || 'default';
+  if (type === 'default' || type === 'multi') {
+    for (i = 0; i < value.length; i++) {
+      if (i > 0) {encoded += '&';}
+
+      encoded += this.encodeQueryKey(name) + '=' + mask(this.encodeQueryParam(value[i]), maskPasswords);
+    }
+  } else {
+    var separator = '';
+
+    if (type === 'csv') {
+      separator = ',';
+    } else if (type === 'ssv') {
+      separator = '%20';
+    } else if (type === 'tsv') {
+      separator = '%09';
+    } else if (type === 'pipes') {
+      separator = '|';
+    } else if (type === 'brackets') {
+      for (i = 0; i < value.length; i++) {
+        if (i !== 0) {
+          encoded += '&';
+        }
+        encoded += this.encodeQueryKey(name) + '[]=' + mask(this.encodeQueryParam(value[i]), maskPasswords);
+      }
+    }
+
+    if (separator !== '') {
+      for (i = 0; i < value.length; i++) {
+        if (i === 0) {
+          encoded = this.encodeQueryKey(name) + '=' + this.encodeQueryParam(value[i]);
+        } else {
+          encoded += separator + this.encodeQueryParam(value[i]);
+        }
+      }
+    }
+  }
+
+  return encoded;
+};
+
+Operation.prototype.encodeQueryKey = function (arg) {
+  return encodeURIComponent(arg)
+      .replace('%5B','[').replace('%5D', ']').replace('%24', '$');
+};
+
+Operation.prototype.encodeQueryParam = function (arg, maskPasswords) {
+  if(maskPasswords) {
+    return "******";
+  }
+  if(arg !== undefined && arg !== null) {
+    return encodeURIComponent(arg);
+  }
+  else {
+    return '';
+  }
+};
+
+/**
+ * TODO revisit, might not want to leave '/'
+ **/
+Operation.prototype.encodePathParam = function (pathParam, maskPasswords) {
+  return encodeURIComponent(pathParam, maskPasswords);
+};
+
+var mask = function(value, format) {
+  if(typeof format === 'string' && format === 'password') {
+    return '******';
+  }
+  return value;
+}
+
+},{"../helpers":4,"../http":5,"./model":9,"lodash-compat/lang/cloneDeep":138,"lodash-compat/lang/isEmpty":141,"lodash-compat/lang/isObject":144,"lodash-compat/lang/isUndefined":148,"q":157}],11:[function(require,module,exports){
+'use strict';
+
+var OperationGroup = module.exports = function (tag, description, externalDocs, operation) {
+  this.description = description;
+  this.externalDocs = externalDocs;
+  this.name = tag;
+  this.operation = operation;
+  this.operationsArray = [];
+  this.path = tag;
+  this.tag = tag;
+};
+
+OperationGroup.prototype.sort = function () {
+
+};
+
+
+},{}],12:[function(require,module,exports){
+// shim for using process in browser
+
+var process = module.exports = {};
+var queue = [];
+var draining = false;
+
+function drainQueue() {
+    if (draining) {
+        return;
+    }
+    draining = true;
+    var currentQueue;
+    var len = queue.length;
+    while(len) {
+        currentQueue = queue;
+        queue = [];
+        var i = -1;
+        while (++i < len) {
+            currentQueue[i]();
+        }
+        len = queue.length;
+    }
+    draining = false;
+}
+process.nextTick = function (fun) {
+    queue.push(fun);
+    if (!draining) {
+        setTimeout(drainQueue, 0);
+    }
+};
+
+process.title = 'browser';
+process.browser = true;
+process.env = {};
+process.argv = [];
+process.version = ''; // empty string to avoid regexp issues
+process.versions = {};
+
+function noop() {}
+
+process.on = noop;
+process.addListener = noop;
+process.once = noop;
+process.off = noop;
+process.removeListener = noop;
+process.removeAllListeners = noop;
+process.emit = noop;
+
+process.binding = function (name) {
+    throw new Error('process.binding is not supported');
+};
+
+// TODO(shtylman)
+process.cwd = function () { return '/' };
+process.chdir = function (dir) {
+    throw new Error('process.chdir is not supported');
+};
+process.umask = function() { return 0; };
+
+},{}],13:[function(require,module,exports){
+(function (Buffer){
+(function () {
+  "use strict";
+
+  function btoa(str) {
+    var buffer
+      ;
+
+    if (str instanceof Buffer) {
+      buffer = str;
+    } else {
+      buffer = new Buffer(str.toString(), 'binary');
+    }
+
+    return buffer.toString('base64');
+  }
+
+  module.exports = btoa;
+}());
+
+}).call(this,require("buffer").Buffer)
+
+},{"buffer":14}],14:[function(require,module,exports){
+/*!
+ * The buffer module from node.js, for the browser.
+ *
+ * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
+ * @license  MIT
+ */
+
+var base64 = require('base64-js')
+var ieee754 = require('ieee754')
+var isArray = require('is-array')
+
+exports.Buffer = Buffer
+exports.SlowBuffer = SlowBuffer
+exports.INSPECT_MAX_BYTES = 50
+Buffer.poolSize = 8192 // not used by this implementation
+
+var rootParent = {}
+
+/**
+ * If `Buffer.TYPED_ARRAY_SUPPORT`:
+ *   === true    Use Uint8Array implementation (fastest)
+ *   === false   Use Object implementation (most compatible, even IE6)
+ *
+ * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
+ * Opera 11.6+, iOS 4.2+.
+ *
+ * Due to various browser bugs, sometimes the Object implementation will be used even
+ * when the browser supports typed arrays.
+ *
+ * Note:
+ *
+ *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,
+ *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.
+ *
+ *   - Safari 5-7 lacks support for changing the `Object.prototype.constructor` property
+ *     on objects.
+ *
+ *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.
+ *
+ *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of
+ *     incorrect length in some situations.
+
+ * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they
+ * get the Object implementation, which is slower but behaves correctly.
+ */
+Buffer.TYPED_ARRAY_SUPPORT = (function () {
+  function Bar () {}
+  try {
+    var arr = new Uint8Array(1)
+    arr.foo = function () { return 42 }
+    arr.constructor = Bar
+    return arr.foo() === 42 && // typed array instances can be augmented
+        arr.constructor === Bar && // constructor can be set
+        typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`
+        arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`
+  } catch (e) {
+    return false
+  }
+})()
+
+function kMaxLength () {
+  return Buffer.TYPED_ARRAY_SUPPORT
+    ? 0x7fffffff
+    : 0x3fffffff
+}
+
+/**
+ * Class: Buffer
+ * =============
+ *
+ * The Buffer constructor returns instances of `Uint8Array` that are augmented
+ * with function properties for all the node `Buffer` API functions. We use
+ * `Uint8Array` so that square bracket notation works as expected -- it returns
+ * a single octet.
+ *
+ * By augmenting the instances, we can avoid modifying the `Uint8Array`
+ * prototype.
+ */
+function Buffer (arg) {
+  if (!(this instanceof Buffer)) {
+    // Avoid going through an ArgumentsAdaptorTrampoline in the common case.
+    if (arguments.length > 1) return new Buffer(arg, arguments[1])
+    return new Buffer(arg)
+  }
+
+  this.length = 0
+  this.parent = undefined
+
+  // Common case.
+  if (typeof arg === 'number') {
+    return fromNumber(this, arg)
+  }
+
+  // Slightly less common case.
+  if (typeof arg === 'string') {
+    return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8')
+  }
+
+  // Unusual.
+  return fromObject(this, arg)
+}
+
+function fromNumber (that, length) {
+  that = allocate(that, length < 0 ? 0 : checked(length) | 0)
+  if (!Buffer.TYPED_ARRAY_SUPPORT) {
+    for (var i = 0; i < length; i++) {
+      that[i] = 0
+    }
+  }
+  return that
+}
+
+function fromString (that, string, encoding) {
+  if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8'
+
+  // Assumption: byteLength() return value is always < kMaxLength.
+  var length = byteLength(string, encoding) | 0
+  that = allocate(that, length)
+
+  that.write(string, encoding)
+  return that
+}
+
+function fromObject (that, object) {
+  if (Buffer.isBuffer(object)) return fromBuffer(that, object)
+
+  if (isArray(object)) return fromArray(that, object)
+
+  if (object == null) {
+    throw new TypeError('must start with number, buffer, array or string')
+  }
+
+  if (typeof ArrayBuffer !== 'undefined') {
+    if (object.buffer instanceof ArrayBuffer) {
+      return fromTypedArray(that, object)
+    }
+    if (object instanceof ArrayBuffer) {
+      return fromArrayBuffer(that, object)
+    }
+  }
+
+  if (object.length) return fromArrayLike(that, object)
+
+  return fromJsonObject(that, object)
+}
+
+function fromBuffer (that, buffer) {
+  var length = checked(buffer.length) | 0
+  that = allocate(that, length)
+  buffer.copy(that, 0, 0, length)
+  return that
+}
+
+function fromArray (that, array) {
+  var length = checked(array.length) | 0
+  that = allocate(that, length)
+  for (var i = 0; i < length; i += 1) {
+    that[i] = array[i] & 255
+  }
+  return that
+}
+
+// Duplicate of fromArray() to keep fromArray() monomorphic.
+function fromTypedArray (that, array) {
+  var length = checked(array.length) | 0
+  that = allocate(that, length)
+  // Truncating the elements is probably not what people expect from typed
+  // arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior
+  // of the old Buffer constructor.
+  for (var i = 0; i < length; i += 1) {
+    that[i] = array[i] & 255
+  }
+  return that
+}
+
+function fromArrayBuffer (that, array) {
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    // Return an augmented `Uint8Array` instance, for best performance
+    array.byteLength
+    that = Buffer._augment(new Uint8Array(array))
+  } else {
+    // Fallback: Return an object instance of the Buffer class
+    that = fromTypedArray(that, new Uint8Array(array))
+  }
+  return that
+}
+
+function fromArrayLike (that, array) {
+  var length = checked(array.length) | 0
+  that = allocate(that, length)
+  for (var i = 0; i < length; i += 1) {
+    that[i] = array[i] & 255
+  }
+  return that
+}
+
+// Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object.
+// Returns a zero-length buffer for inputs that don't conform to the spec.
+function fromJsonObject (that, object) {
+  var array
+  var length = 0
+
+  if (object.type === 'Buffer' && isArray(object.data)) {
+    array = object.data
+    length = checked(array.length) | 0
+  }
+  that = allocate(that, length)
+
+  for (var i = 0; i < length; i += 1) {
+    that[i] = array[i] & 255
+  }
+  return that
+}
+
+function allocate (that, length) {
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    // Return an augmented `Uint8Array` instance, for best performance
+    that = Buffer._augment(new Uint8Array(length))
+  } else {
+    // Fallback: Return an object instance of the Buffer class
+    that.length = length
+    that._isBuffer = true
+  }
+
+  var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1
+  if (fromPool) that.parent = rootParent
+
+  return that
+}
+
+function checked (length) {
+  // Note: cannot use `length < kMaxLength` here because that fails when
+  // length is NaN (which is otherwise coerced to zero.)
+  if (length >= kMaxLength()) {
+    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
+                         'size: 0x' + kMaxLength().toString(16) + ' bytes')
+  }
+  return length | 0
+}
+
+function SlowBuffer (subject, encoding) {
+  if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding)
+
+  var buf = new Buffer(subject, encoding)
+  delete buf.parent
+  return buf
+}
+
+Buffer.isBuffer = function isBuffer (b) {
+  return !!(b != null && b._isBuffer)
+}
+
+Buffer.compare = function compare (a, b) {
+  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
+    throw new TypeError('Arguments must be Buffers')
+  }
+
+  if (a === b) return 0
+
+  var x = a.length
+  var y = b.length
+
+  var i = 0
+  var len = Math.min(x, y)
+  while (i < len) {
+    if (a[i] !== b[i]) break
+
+    ++i
+  }
+
+  if (i !== len) {
+    x = a[i]
+    y = b[i]
+  }
+
+  if (x < y) return -1
+  if (y < x) return 1
+  return 0
+}
+
+Buffer.isEncoding = function isEncoding (encoding) {
+  switch (String(encoding).toLowerCase()) {
+    case 'hex':
+    case 'utf8':
+    case 'utf-8':
+    case 'ascii':
+    case 'binary':
+    case 'base64':
+    case 'raw':
+    case 'ucs2':
+    case 'ucs-2':
+    case 'utf16le':
+    case 'utf-16le':
+      return true
+    default:
+      return false
+  }
+}
+
+Buffer.concat = function concat (list, length) {
+  if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.')
+
+  if (list.length === 0) {
+    return new Buffer(0)
+  }
+
+  var i
+  if (length === undefined) {
+    length = 0
+    for (i = 0; i < list.length; i++) {
+      length += list[i].length
+    }
+  }
+
+  var buf = new Buffer(length)
+  var pos = 0
+  for (i = 0; i < list.length; i++) {
+    var item = list[i]
+    item.copy(buf, pos)
+    pos += item.length
+  }
+  return buf
+}
+
+function byteLength (string, encoding) {
+  if (typeof string !== 'string') string = '' + string
+
+  var len = string.length
+  if (len === 0) return 0
+
+  // Use a for loop to avoid recursion
+  var loweredCase = false
+  for (;;) {
+    switch (encoding) {
+      case 'ascii':
+      case 'binary':
+      // Deprecated
+      case 'raw':
+      case 'raws':
+        return len
+      case 'utf8':
+      case 'utf-8':
+        return utf8ToBytes(string).length
+      case 'ucs2':
+      case 'ucs-2':
+      case 'utf16le':
+      case 'utf-16le':
+        return len * 2
+      case 'hex':
+        return len >>> 1
+      case 'base64':
+        return base64ToBytes(string).length
+      default:
+        if (loweredCase) return utf8ToBytes(string).length // assume utf8
+        encoding = ('' + encoding).toLowerCase()
+        loweredCase = true
+    }
+  }
+}
+Buffer.byteLength = byteLength
+
+// pre-set for values that may exist in the future
+Buffer.prototype.length = undefined
+Buffer.prototype.parent = undefined
+
+function slowToString (encoding, start, end) {
+  var loweredCase = false
+
+  start = start | 0
+  end = end === undefined || end === Infinity ? this.length : end | 0
+
+  if (!encoding) encoding = 'utf8'
+  if (start < 0) start = 0
+  if (end > this.length) end = this.length
+  if (end <= start) return ''
+
+  while (true) {
+    switch (encoding) {
+      case 'hex':
+        return hexSlice(this, start, end)
+
+      case 'utf8':
+      case 'utf-8':
+        return utf8Slice(this, start, end)
+
+      case 'ascii':
+        return asciiSlice(this, start, end)
+
+      case 'binary':
+        return binarySlice(this, start, end)
+
+      case 'base64':
+        return base64Slice(this, start, end)
+
+      case 'ucs2':
+      case 'ucs-2':
+      case 'utf16le':
+      case 'utf-16le':
+        return utf16leSlice(this, start, end)
+
+      default:
+        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
+        encoding = (encoding + '').toLowerCase()
+        loweredCase = true
+    }
+  }
+}
+
+Buffer.prototype.toString = function toString () {
+  var length = this.length | 0
+  if (length === 0) return ''
+  if (arguments.length === 0) return utf8Slice(this, 0, length)
+  return slowToString.apply(this, arguments)
+}
+
+Buffer.prototype.equals = function equals (b) {
+  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
+  if (this === b) return true
+  return Buffer.compare(this, b) === 0
+}
+
+Buffer.prototype.inspect = function inspect () {
+  var str = ''
+  var max = exports.INSPECT_MAX_BYTES
+  if (this.length > 0) {
+    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')
+    if (this.length > max) str += ' ... '
+  }
+  return '<Buffer ' + str + '>'
+}
+
+Buffer.prototype.compare = function compare (b) {
+  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
+  if (this === b) return 0
+  return Buffer.compare(this, b)
+}
+
+Buffer.prototype.indexOf = function indexOf (val, byteOffset) {
+  if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff
+  else if (byteOffset < -0x80000000) byteOffset = -0x80000000
+  byteOffset >>= 0
+
+  if (this.length === 0) return -1
+  if (byteOffset >= this.length) return -1
+
+  // Negative offsets start from the end of the buffer
+  if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0)
+
+  if (typeof val === 'string') {
+    if (val.length === 0) return -1 // special case: looking for empty string always fails
+    return String.prototype.indexOf.call(this, val, byteOffset)
+  }
+  if (Buffer.isBuffer(val)) {
+    return arrayIndexOf(this, val, byteOffset)
+  }
+  if (typeof val === 'number') {
+    if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') {
+      return Uint8Array.prototype.indexOf.call(this, val, byteOffset)
+    }
+    return arrayIndexOf(this, [ val ], byteOffset)
+  }
+
+  function arrayIndexOf (arr, val, byteOffset) {
+    var foundIndex = -1
+    for (var i = 0; byteOffset + i < arr.length; i++) {
+      if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) {
+        if (foundIndex === -1) foundIndex = i
+        if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex
+      } else {
+        foundIndex = -1
+      }
+    }
+    return -1
+  }
+
+  throw new TypeError('val must be string, number or Buffer')
+}
+
+// `get` is deprecated
+Buffer.prototype.get = function get (offset) {
+  console.log('.get() is deprecated. Access using array indexes instead.')
+  return this.readUInt8(offset)
+}
+
+// `set` is deprecated
+Buffer.prototype.set = function set (v, offset) {
+  console.log('.set() is deprecated. Access using array indexes instead.')
+  return this.writeUInt8(v, offset)
+}
+
+function hexWrite (buf, string, offset, length) {
+  offset = Number(offset) || 0
+  var remaining = buf.length - offset
+  if (!length) {
+    length = remaining
+  } else {
+    length = Number(length)
+    if (length > remaining) {
+      length = remaining
+    }
+  }
+
+  // must be an even number of digits
+  var strLen = string.length
+  if (strLen % 2 !== 0) throw new Error('Invalid hex string')
+
+  if (length > strLen / 2) {
+    length = strLen / 2
+  }
+  for (var i = 0; i < length; i++) {
+    var parsed = parseInt(string.substr(i * 2, 2), 16)
+    if (isNaN(parsed)) throw new Error('Invalid hex string')
+    buf[offset + i] = parsed
+  }
+  return i
+}
+
+function utf8Write (buf, string, offset, length) {
+  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
+}
+
+function asciiWrite (buf, string, offset, length) {
+  return blitBuffer(asciiToBytes(string), buf, offset, length)
+}
+
+function binaryWrite (buf, string, offset, length) {
+  return asciiWrite(buf, string, offset, length)
+}
+
+function base64Write (buf, string, offset, length) {
+  return blitBuffer(base64ToBytes(string), buf, offset, length)
+}
+
+function ucs2Write (buf, string, offset, length) {
+  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
+}
+
+Buffer.prototype.write = function write (string, offset, length, encoding) {
+  // Buffer#write(string)
+  if (offset === undefined) {
+    encoding = 'utf8'
+    length = this.length
+    offset = 0
+  // Buffer#write(string, encoding)
+  } else if (length === undefined && typeof offset === 'string') {
+    encoding = offset
+    length = this.length
+    offset = 0
+  // Buffer#write(string, offset[, length][, encoding])
+  } else if (isFinite(offset)) {
+    offset = offset | 0
+    if (isFinite(length)) {
+      length = length | 0
+      if (encoding === undefined) encoding = 'utf8'
+    } else {
+      encoding = length
+      length = undefined
+    }
+  // legacy write(string, encoding, offset, length) - remove in v0.13
+  } else {
+    var swap = encoding
+    encoding = offset
+    offset = length | 0
+    length = swap
+  }
+
+  var remaining = this.length - offset
+  if (length === undefined || length > remaining) length = remaining
+
+  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
+    throw new RangeError('attempt to write outside buffer bounds')
+  }
+
+  if (!encoding) encoding = 'utf8'
+
+  var loweredCase = false
+  for (;;) {
+    switch (encoding) {
+      case 'hex':
+        return hexWrite(this, string, offset, length)
+
+      case 'utf8':
+      case 'utf-8':
+        return utf8Write(this, string, offset, length)
+
+      case 'ascii':
+        return asciiWrite(this, string, offset, length)
+
+      case 'binary':
+        return binaryWrite(this, string, offset, length)
+
+      case 'base64':
+        // Warning: maxLength not taken into account in base64Write
+        return base64Write(this, string, offset, length)
+
+      case 'ucs2':
+      case 'ucs-2':
+      case 'utf16le':
+      case 'utf-16le':
+        return ucs2Write(this, string, offset, length)
+
+      default:
+        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
+        encoding = ('' + encoding).toLowerCase()
+        loweredCase = true
+    }
+  }
+}
+
+Buffer.prototype.toJSON = function toJSON () {
+  return {
+    type: 'Buffer',
+    data: Array.prototype.slice.call(this._arr || this, 0)
+  }
+}
+
+function base64Slice (buf, start, end) {
+  if (start === 0 && end === buf.length) {
+    return base64.fromByteArray(buf)
+  } else {
+    return base64.fromByteArray(buf.slice(start, end))
+  }
+}
+
+function utf8Slice (buf, start, end) {
+  end = Math.min(buf.length, end)
+  var res = []
+
+  var i = start
+  while (i < end) {
+    var firstByte = buf[i]
+    var codePoint = null
+    var bytesPerSequence = (firstByte > 0xEF) ? 4
+      : (firstByte > 0xDF) ? 3
+      : (firstByte > 0xBF) ? 2
+      : 1
+
+    if (i + bytesPerSequence <= end) {
+      var secondByte, thirdByte, fourthByte, tempCodePoint
+
+      switch (bytesPerSequence) {
+        case 1:
+          if (firstByte < 0x80) {
+            codePoint = firstByte
+          }
+          break
+        case 2:
+          secondByte = buf[i + 1]
+          if ((secondByte & 0xC0) === 0x80) {
+            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
+            if (tempCodePoint > 0x7F) {
+              codePoint = tempCodePoint
+            }
+          }
+          break
+        case 3:
+          secondByte = buf[i + 1]
+          thirdByte = buf[i + 2]
+          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
+            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
+            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
+              codePoint = tempCodePoint
+            }
+          }
+          break
+        case 4:
+          secondByte = buf[i + 1]
+          thirdByte = buf[i + 2]
+          fourthByte = buf[i + 3]
+          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
+            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
+            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
+              codePoint = tempCodePoint
+            }
+          }
+      }
+    }
+
+    if (codePoint === null) {
+      // we did not generate a valid codePoint so insert a
+      // replacement char (U+FFFD) and advance only 1 byte
+      codePoint = 0xFFFD
+      bytesPerSequence = 1
+    } else if (codePoint > 0xFFFF) {
+      // encode to utf16 (surrogate pair dance)
+      codePoint -= 0x10000
+      res.push(codePoint >>> 10 & 0x3FF | 0xD800)
+      codePoint = 0xDC00 | codePoint & 0x3FF
+    }
+
+    res.push(codePoint)
+    i += bytesPerSequence
+  }
+
+  return decodeCodePointsArray(res)
+}
+
+// Based on http://stackoverflow.com/a/22747272/680742, the browser with
+// the lowest limit is Chrome, with 0x10000 args.
+// We go 1 magnitude less, for safety
+var MAX_ARGUMENTS_LENGTH = 0x1000
+
+function decodeCodePointsArray (codePoints) {
+  var len = codePoints.length
+  if (len <= MAX_ARGUMENTS_LENGTH) {
+    return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
+  }
+
+  // Decode in chunks to avoid "call stack size exceeded".
+  var res = ''
+  var i = 0
+  while (i < len) {
+    res += String.fromCharCode.apply(
+      String,
+      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
+    )
+  }
+  return res
+}
+
+function asciiSlice (buf, start, end) {
+  var ret = ''
+  end = Math.min(buf.length, end)
+
+  for (var i = start; i < end; i++) {
+    ret += String.fromCharCode(buf[i] & 0x7F)
+  }
+  return ret
+}
+
+function binarySlice (buf, start, end) {
+  var ret = ''
+  end = Math.min(buf.length, end)
+
+  for (var i = start; i < end; i++) {
+    ret += String.fromCharCode(buf[i])
+  }
+  return ret
+}
+
+function hexSlice (buf, start, end) {
+  var len = buf.length
+
+  if (!start || start < 0) start = 0
+  if (!end || end < 0 || end > len) end = len
+
+  var out = ''
+  for (var i = start; i < end; i++) {
+    out += toHex(buf[i])
+  }
+  return out
+}
+
+function utf16leSlice (buf, start, end) {
+  var bytes = buf.slice(start, end)
+  var res = ''
+  for (var i = 0; i < bytes.length; i += 2) {
+    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)
+  }
+  return res
+}
+
+Buffer.prototype.slice = function slice (start, end) {
+  var len = this.length
+  start = ~~start
+  end = end === undefined ? len : ~~end
+
+  if (start < 0) {
+    start += len
+    if (start < 0) start = 0
+  } else if (start > len) {
+    start = len
+  }
+
+  if (end < 0) {
+    end += len
+    if (end < 0) end = 0
+  } else if (end > len) {
+    end = len
+  }
+
+  if (end < start) end = start
+
+  var newBuf
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    newBuf = Buffer._augment(this.subarray(start, end))
+  } else {
+    var sliceLen = end - start
+    newBuf = new Buffer(sliceLen, undefined)
+    for (var i = 0; i < sliceLen; i++) {
+      newBuf[i] = this[i + start]
+    }
+  }
+
+  if (newBuf.length) newBuf.parent = this.parent || this
+
+  return newBuf
+}
+
+/*
+ * Need to make sure that buffer isn't trying to write out of bounds.
+ */
+function checkOffset (offset, ext, length) {
+  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
+  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
+}
+
+Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
+  offset = offset | 0
+  byteLength = byteLength | 0
+  if (!noAssert) checkOffset(offset, byteLength, this.length)
+
+  var val = this[offset]
+  var mul = 1
+  var i = 0
+  while (++i < byteLength && (mul *= 0x100)) {
+    val += this[offset + i] * mul
+  }
+
+  return val
+}
+
+Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
+  offset = offset | 0
+  byteLength = byteLength | 0
+  if (!noAssert) {
+    checkOffset(offset, byteLength, this.length)
+  }
+
+  var val = this[offset + --byteLength]
+  var mul = 1
+  while (byteLength > 0 && (mul *= 0x100)) {
+    val += this[offset + --byteLength] * mul
+  }
+
+  return val
+}
+
+Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 1, this.length)
+  return this[offset]
+}
+
+Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 2, this.length)
+  return this[offset] | (this[offset + 1] << 8)
+}
+
+Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 2, this.length)
+  return (this[offset] << 8) | this[offset + 1]
+}
+
+Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+
+  return ((this[offset]) |
+      (this[offset + 1] << 8) |
+      (this[offset + 2] << 16)) +
+      (this[offset + 3] * 0x1000000)
+}
+
+Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+
+  return (this[offset] * 0x1000000) +
+    ((this[offset + 1] << 16) |
+    (this[offset + 2] << 8) |
+    this[offset + 3])
+}
+
+Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
+  offset = offset | 0
+  byteLength = byteLength | 0
+  if (!noAssert) checkOffset(offset, byteLength, this.length)
+
+  var val = this[offset]
+  var mul = 1
+  var i = 0
+  while (++i < byteLength && (mul *= 0x100)) {
+    val += this[offset + i] * mul
+  }
+  mul *= 0x80
+
+  if (val >= mul) val -= Math.pow(2, 8 * byteLength)
+
+  return val
+}
+
+Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
+  offset = offset | 0
+  byteLength = byteLength | 0
+  if (!noAssert) checkOffset(offset, byteLength, this.length)
+
+  var i = byteLength
+  var mul = 1
+  var val = this[offset + --i]
+  while (i > 0 && (mul *= 0x100)) {
+    val += this[offset + --i] * mul
+  }
+  mul *= 0x80
+
+  if (val >= mul) val -= Math.pow(2, 8 * byteLength)
+
+  return val
+}
+
+Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 1, this.length)
+  if (!(this[offset] & 0x80)) return (this[offset])
+  return ((0xff - this[offset] + 1) * -1)
+}
+
+Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 2, this.length)
+  var val = this[offset] | (this[offset + 1] << 8)
+  return (val & 0x8000) ? val | 0xFFFF0000 : val
+}
+
+Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 2, this.length)
+  var val = this[offset + 1] | (this[offset] << 8)
+  return (val & 0x8000) ? val | 0xFFFF0000 : val
+}
+
+Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+
+  return (this[offset]) |
+    (this[offset + 1] << 8) |
+    (this[offset + 2] << 16) |
+    (this[offset + 3] << 24)
+}
+
+Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+
+  return (this[offset] << 24) |
+    (this[offset + 1] << 16) |
+    (this[offset + 2] << 8) |
+    (this[offset + 3])
+}
+
+Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+  return ieee754.read(this, offset, true, 23, 4)
+}
+
+Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 4, this.length)
+  return ieee754.read(this, offset, false, 23, 4)
+}
+
+Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 8, this.length)
+  return ieee754.read(this, offset, true, 52, 8)
+}
+
+Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
+  if (!noAssert) checkOffset(offset, 8, this.length)
+  return ieee754.read(this, offset, false, 52, 8)
+}
+
+function checkInt (buf, value, offset, ext, max, min) {
+  if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance')
+  if (value > max || value < min) throw new RangeError('value is out of bounds')
+  if (offset + ext > buf.length) throw new RangeError('index out of range')
+}
+
+Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
+  value = +value
+  offset = offset | 0
+  byteLength = byteLength | 0
+  if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)
+
+  var mul = 1
+  var i = 0
+  this[offset] = value & 0xFF
+  while (++i < byteLength && (mul *= 0x100)) {
+    this[offset + i] = (value / mul) & 0xFF
+  }
+
+  return offset + byteLength
+}
+
+Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
+  value = +value
+  offset = offset | 0
+  byteLength = byteLength | 0
+  if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)
+
+  var i = byteLength - 1
+  var mul = 1
+  this[offset + i] = value & 0xFF
+  while (--i >= 0 && (mul *= 0x100)) {
+    this[offset + i] = (value / mul) & 0xFF
+  }
+
+  return offset + byteLength
+}
+
+Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
+  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
+  this[offset] = value
+  return offset + 1
+}
+
+function objectWriteUInt16 (buf, value, offset, littleEndian) {
+  if (value < 0) value = 0xffff + value + 1
+  for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) {
+    buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
+      (littleEndian ? i : 1 - i) * 8
+  }
+}
+
+Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = value
+    this[offset + 1] = (value >>> 8)
+  } else {
+    objectWriteUInt16(this, value, offset, true)
+  }
+  return offset + 2
+}
+
+Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value >>> 8)
+    this[offset + 1] = value
+  } else {
+    objectWriteUInt16(this, value, offset, false)
+  }
+  return offset + 2
+}
+
+function objectWriteUInt32 (buf, value, offset, littleEndian) {
+  if (value < 0) value = 0xffffffff + value + 1
+  for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) {
+    buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
+  }
+}
+
+Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset + 3] = (value >>> 24)
+    this[offset + 2] = (value >>> 16)
+    this[offset + 1] = (value >>> 8)
+    this[offset] = value
+  } else {
+    objectWriteUInt32(this, value, offset, true)
+  }
+  return offset + 4
+}
+
+Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value >>> 24)
+    this[offset + 1] = (value >>> 16)
+    this[offset + 2] = (value >>> 8)
+    this[offset + 3] = value
+  } else {
+    objectWriteUInt32(this, value, offset, false)
+  }
+  return offset + 4
+}
+
+Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) {
+    var limit = Math.pow(2, 8 * byteLength - 1)
+
+    checkInt(this, value, offset, byteLength, limit - 1, -limit)
+  }
+
+  var i = 0
+  var mul = 1
+  var sub = value < 0 ? 1 : 0
+  this[offset] = value & 0xFF
+  while (++i < byteLength && (mul *= 0x100)) {
+    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
+  }
+
+  return offset + byteLength
+}
+
+Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) {
+    var limit = Math.pow(2, 8 * byteLength - 1)
+
+    checkInt(this, value, offset, byteLength, limit - 1, -limit)
+  }
+
+  var i = byteLength - 1
+  var mul = 1
+  var sub = value < 0 ? 1 : 0
+  this[offset + i] = value & 0xFF
+  while (--i >= 0 && (mul *= 0x100)) {
+    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
+  }
+
+  return offset + byteLength
+}
+
+Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
+  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
+  if (value < 0) value = 0xff + value + 1
+  this[offset] = value
+  return offset + 1
+}
+
+Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = value
+    this[offset + 1] = (value >>> 8)
+  } else {
+    objectWriteUInt16(this, value, offset, true)
+  }
+  return offset + 2
+}
+
+Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value >>> 8)
+    this[offset + 1] = value
+  } else {
+    objectWriteUInt16(this, value, offset, false)
+  }
+  return offset + 2
+}
+
+Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = value
+    this[offset + 1] = (value >>> 8)
+    this[offset + 2] = (value >>> 16)
+    this[offset + 3] = (value >>> 24)
+  } else {
+    objectWriteUInt32(this, value, offset, true)
+  }
+  return offset + 4
+}
+
+Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
+  value = +value
+  offset = offset | 0
+  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
+  if (value < 0) value = 0xffffffff + value + 1
+  if (Buffer.TYPED_ARRAY_SUPPORT) {
+    this[offset] = (value >>> 24)
+    this[offset + 1] = (value >>> 16)
+    this[offset + 2] = (value >>> 8)
+    this[offset + 3] = value
+  } else {
+    objectWriteUInt32(this, value, offset, false)
+  }
+  return offset + 4
+}
+
+function checkIEEE754 (buf, value, offset, ext, max, min) {
+  if (value > max || value < min) throw new RangeError('value is out of bounds')
+  if (offset + ext > buf.length) throw new RangeError('index out of range')
+  if (offset < 0) throw new RangeError('index out of range')
+}
+
+function writeFloat (buf, value, offset, littleEndian, noAssert) {
+  if (!noAssert) {
+    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
+  }
+  ieee754.write(buf, value, offset, littleEndian, 23, 4)
+  return offset + 4
+}
+
+Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
+  return writeFloat(this, value, offset, true, noAssert)
+}
+
+Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
+  return writeFloat(this, value, offset, false, noAssert)
+}
+
+function writeDouble (buf, value, offset, littleEndian, noAssert) {
+  if (!noAssert) {
+    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
+  }
+  ieee754.write(buf, value, offset, littleEndian, 52, 8)
+  return offset + 8
+}
+
+Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
+  return writeDouble(this, value, offset, true, noAssert)
+}
+
+Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
+  return writeDouble(this, value, offset, false, noAssert)
+}
+
+// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
+Buffer.prototype.copy = function copy (target, targetStart, start, end) {
+  if (!start) start = 0
+  if (!end && end !== 0) end = this.length
+  if (targetStart >= target.length) targetStart = target.length
+  if (!targetStart) targetStart = 0
+  if (end > 0 && end < start) end = start
+
+  // Copy 0 bytes; we're done
+  if (end === start) return 0
+  if (target.length === 0 || this.length === 0) return 0
+
+  // Fatal error conditions
+  if (targetStart < 0) {
+    throw new RangeError('targetStart out of bounds')
+  }
+  if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')
+  if (end < 0) throw new RangeError('sourceEnd out of bounds')
+
+  // Are we oob?
+  if (end > this.length) end = this.length
+  if (target.length - targetStart < end - start) {
+    end = target.length - targetStart + start
+  }
+
+  var len = end - start
+  var i
+
+  if (this === target && start < targetStart && targetStart < end) {
+    // descending copy from end
+    for (i = len - 1; i >= 0; i--) {
+      target[i + targetStart] = this[i + start]
+    }
+  } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {
+    // ascending copy from start
+    for (i = 0; i < len; i++) {
+      target[i + targetStart] = this[i + start]
+    }
+  } else {
+    target._set(this.subarray(start, start + len), targetStart)
+  }
+
+  return len
+}
+
+// fill(value, start=0, end=buffer.length)
+Buffer.prototype.fill = function fill (value, start, end) {
+  if (!value) value = 0
+  if (!start) start = 0
+  if (!end) end = this.length
+
+  if (end < start) throw new RangeError('end < start')
+
+  // Fill 0 bytes; we're done
+  if (end === start) return
+  if (this.length === 0) return
+
+  if (start < 0 || start >= this.length) throw new RangeError('start out of bounds')
+  if (end < 0 || end > this.length) throw new RangeError('end out of bounds')
+
+  var i
+  if (typeof value === 'number') {
+    for (i = start; i < end; i++) {
+      this[i] = value
+    }
+  } else {
+    var bytes = utf8ToBytes(value.toString())
+    var len = bytes.length
+    for (i = start; i < end; i++) {
+      this[i] = bytes[i % len]
+    }
+  }
+
+  return this
+}
+
+/**
+ * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance.
+ * Added in Node 0.12. Only available in browsers that support ArrayBuffer.
+ */
+Buffer.prototype.toArrayBuffer = function toArrayBuffer () {
+  if (typeof Uint8Array !== 'undefined') {
+    if (Buffer.TYPED_ARRAY_SUPPORT) {
+      return (new Buffer(this)).buffer
+    } else {
+      var buf = new Uint8Array(this.length)
+      for (var i = 0, len = buf.length; i < len; i += 1) {
+        buf[i] = this[i]
+      }
+      return buf.buffer
+    }
+  } else {
+    throw new TypeError('Buffer.toArrayBuffer not supported in this browser')
+  }
+}
+
+// HELPER FUNCTIONS
+// ================
+
+var BP = Buffer.prototype
+
+/**
+ * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods
+ */
+Buffer._augment = function _augment (arr) {
+  arr.constructor = Buffer
+  arr._isBuffer = true
+
+  // save reference to original Uint8Array set method before overwriting
+  arr._set = arr.set
+
+  // deprecated
+  arr.get = BP.get
+  arr.set = BP.set
+
+  arr.write = BP.write
+  arr.toString = BP.toString
+  arr.toLocaleString = BP.toString
+  arr.toJSON = BP.toJSON
+  arr.equals = BP.equals
+  arr.compare = BP.compare
+  arr.indexOf = BP.indexOf
+  arr.copy = BP.copy
+  arr.slice = BP.slice
+  arr.readUIntLE = BP.readUIntLE
+  arr.readUIntBE = BP.readUIntBE
+  arr.readUInt8 = BP.readUInt8
+  arr.readUInt16LE = BP.readUInt16LE
+  arr.readUInt16BE = BP.readUInt16BE
+  arr.readUInt32LE = BP.readUInt32LE
+  arr.readUInt32BE = BP.readUInt32BE
+  arr.readIntLE = BP.readIntLE
+  arr.readIntBE = BP.readIntBE
+  arr.readInt8 = BP.readInt8
+  arr.readInt16LE = BP.readInt16LE
+  arr.readInt16BE = BP.readInt16BE
+  arr.readInt32LE = BP.readInt32LE
+  arr.readInt32BE = BP.readInt32BE
+  arr.readFloatLE = BP.readFloatLE
+  arr.readFloatBE = BP.readFloatBE
+  arr.readDoubleLE = BP.readDoubleLE
+  arr.readDoubleBE = BP.readDoubleBE
+  arr.writeUInt8 = BP.writeUInt8
+  arr.writeUIntLE = BP.writeUIntLE
+  arr.writeUIntBE = BP.writeUIntBE
+  arr.writeUInt16LE = BP.writeUInt16LE
+  arr.writeUInt16BE = BP.writeUInt16BE
+  arr.writeUInt32LE = BP.writeUInt32LE
+  arr.writeUInt32BE = BP.writeUInt32BE
+  arr.writeIntLE = BP.writeIntLE
+  arr.writeIntBE = BP.writeIntBE
+  arr.writeInt8 = BP.writeInt8
+  arr.writeInt16LE = BP.writeInt16LE
+  arr.writeInt16BE = BP.writeInt16BE
+  arr.writeInt32LE = BP.writeInt32LE
+  arr.writeInt32BE = BP.writeInt32BE
+  arr.writeFloatLE = BP.writeFloatLE
+  arr.writeFloatBE = BP.writeFloatBE
+  arr.writeDoubleLE = BP.writeDoubleLE
+  arr.writeDoubleBE = BP.writeDoubleBE
+  arr.fill = BP.fill
+  arr.inspect = BP.inspect
+  arr.toArrayBuffer = BP.toArrayBuffer
+
+  return arr
+}
+
+var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g
+
+function base64clean (str) {
+  // Node strips out invalid characters like \n and \t from the string, base64-js does not
+  str = stringtrim(str).replace(INVALID_BASE64_RE, '')
+  // Node converts strings with length < 2 to ''
+  if (str.length < 2) return ''
+  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
+  while (str.length % 4 !== 0) {
+    str = str + '='
+  }
+  return str
+}
+
+function stringtrim (str) {
+  if (str.trim) return str.trim()
+  return str.replace(/^\s+|\s+$/g, '')
+}
+
+function toHex (n) {
+  if (n < 16) return '0' + n.toString(16)
+  return n.toString(16)
+}
+
+function utf8ToBytes (string, units) {
+  units = units || Infinity
+  var codePoint
+  var length = string.length
+  var leadSurrogate = null
+  var bytes = []
+
+  for (var i = 0; i < length; i++) {
+    codePoint = string.charCodeAt(i)
+
+    // is surrogate component
+    if (codePoint > 0xD7FF && codePoint < 0xE000) {
+      // last char was a lead
+      if (!leadSurrogate) {
+        // no lead yet
+        if (codePoint > 0xDBFF) {
+          // unexpected trail
+          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+          continue
+        } else if (i + 1 === length) {
+          // unpaired lead
+          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+          continue
+        }
+
+        // valid lead
+        leadSurrogate = codePoint
+
+        continue
+      }
+
+      // 2 leads in a row
+      if (codePoint < 0xDC00) {
+        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+        leadSurrogate = codePoint
+        continue
+      }
+
+      // valid surrogate pair
+      codePoint = leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00 | 0x10000
+    } else if (leadSurrogate) {
+      // valid bmp char, but last char was a lead
+      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+    }
+
+    leadSurrogate = null
+
+    // encode utf8
+    if (codePoint < 0x80) {
+      if ((units -= 1) < 0) break
+      bytes.push(codePoint)
+    } else if (codePoint < 0x800) {
+      if ((units -= 2) < 0) break
+      bytes.push(
+        codePoint >> 0x6 | 0xC0,
+        codePoint & 0x3F | 0x80
+      )
+    } else if (codePoint < 0x10000) {
+      if ((units -= 3) < 0) break
+      bytes.push(
+        codePoint >> 0xC | 0xE0,
+        codePoint >> 0x6 & 0x3F | 0x80,
+        codePoint & 0x3F | 0x80
+      )
+    } else if (codePoint < 0x110000) {
+      if ((units -= 4) < 0) break
+      bytes.push(
+        codePoint >> 0x12 | 0xF0,
+        codePoint >> 0xC & 0x3F | 0x80,
+        codePoint >> 0x6 & 0x3F | 0x80,
+        codePoint & 0x3F | 0x80
+      )
+    } else {
+      throw new Error('Invalid code point')
+    }
+  }
+
+  return bytes
+}
+
+function asciiToBytes (str) {
+  var byteArray = []
+  for (var i = 0; i < str.length; i++) {
+    // Node's code seems to be doing this and not & 0x7F..
+    byteArray.push(str.charCodeAt(i) & 0xFF)
+  }
+  return byteArray
+}
+
+function utf16leToBytes (str, units) {
+  var c, hi, lo
+  var byteArray = []
+  for (var i = 0; i < str.length; i++) {
+    if ((units -= 2) < 0) break
+
+    c = str.charCodeAt(i)
+    hi = c >> 8
+    lo = c % 256
+    byteArray.push(lo)
+    byteArray.push(hi)
+  }
+
+  return byteArray
+}
+
+function base64ToBytes (str) {
+  return base64.toByteArray(base64clean(str))
+}
+
+function blitBuffer (src, dst, offset, length) {
+  for (var i = 0; i < length; i++) {
+    if ((i + offset >= dst.length) || (i >= src.length)) break
+    dst[i + offset] = src[i]
+  }
+  return i
+}
+
+},{"base64-js":15,"ieee754":16,"is-array":17}],15:[function(require,module,exports){
+var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+
+;(function (exports) {
+       'use strict';
+
+  var Arr = (typeof Uint8Array !== 'undefined')
+    ? Uint8Array
+    : Array
+
+       var PLUS   = '+'.charCodeAt(0)
+       var SLASH  = '/'.charCodeAt(0)
+       var NUMBER = '0'.charCodeAt(0)
+       var LOWER  = 'a'.charCodeAt(0)
+       var UPPER  = 'A'.charCodeAt(0)
+       var PLUS_URL_SAFE = '-'.charCodeAt(0)
+       var SLASH_URL_SAFE = '_'.charCodeAt(0)
+
+       function decode (elt) {
+               var code = elt.charCodeAt(0)
+               if (code === PLUS ||
+                   code === PLUS_URL_SAFE)
+                       return 62 // '+'
+               if (code === SLASH ||
+                   code === SLASH_URL_SAFE)
+                       return 63 // '/'
+               if (code < NUMBER)
+                       return -1 //no match
+               if (code < NUMBER + 10)
+                       return code - NUMBER + 26 + 26
+               if (code < UPPER + 26)
+                       return code - UPPER
+               if (code < LOWER + 26)
+                       return code - LOWER + 26
+       }
+
+       function b64ToByteArray (b64) {
+               var i, j, l, tmp, placeHolders, arr
+
+               if (b64.length % 4 > 0) {
+                       throw new Error('Invalid string. Length must be a multiple of 4')
+               }
+
+               // the number of equal signs (place holders)
+               // if there are two placeholders, than the two characters before it
+               // represent one byte
+               // if there is only one, then the three characters before it represent 2 bytes
+               // this is just a cheap hack to not do indexOf twice
+               var len = b64.length
+               placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0
+
+               // base64 is 4/3 + up to two characters of the original data
+               arr = new Arr(b64.length * 3 / 4 - placeHolders)
+
+               // if there are placeholders, only get up to the last complete 4 chars
+               l = placeHolders > 0 ? b64.length - 4 : b64.length
+
+               var L = 0
+
+               function push (v) {
+                       arr[L++] = v
+               }
+
+               for (i = 0, j = 0; i < l; i += 4, j += 3) {
+                       tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3))
+                       push((tmp & 0xFF0000) >> 16)
+                       push((tmp & 0xFF00) >> 8)
+                       push(tmp & 0xFF)
+               }
+
+               if (placeHolders === 2) {
+                       tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4)
+                       push(tmp & 0xFF)
+               } else if (placeHolders === 1) {
+                       tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2)
+                       push((tmp >> 8) & 0xFF)
+                       push(tmp & 0xFF)
+               }
+
+               return arr
+       }
+
+       function uint8ToBase64 (uint8) {
+               var i,
+                       extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes
+                       output = "",
+                       temp, length
+
+               function encode (num) {
+                       return lookup.charAt(num)
+               }
+
+               function tripletToBase64 (num) {
+                       return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F)
+               }
+
+               // go through the array every three bytes, we'll deal with trailing stuff later
+               for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) {
+                       temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
+                       output += tripletToBase64(temp)
+               }
+
+               // pad the end with zeros, but make sure to not forget the extra bytes
+               switch (extraBytes) {
+                       case 1:
+                               temp = uint8[uint8.length - 1]
+                               output += encode(temp >> 2)
+                               output += encode((temp << 4) & 0x3F)
+                               output += '=='
+                               break
+                       case 2:
+                               temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1])
+                               output += encode(temp >> 10)
+                               output += encode((temp >> 4) & 0x3F)
+                               output += encode((temp << 2) & 0x3F)
+                               output += '='
+                               break
+               }
+
+               return output
+       }
+
+       exports.toByteArray = b64ToByteArray
+       exports.fromByteArray = uint8ToBase64
+}(typeof exports === 'undefined' ? (this.base64js = {}) : exports))
+
+},{}],16:[function(require,module,exports){
+exports.read = function (buffer, offset, isLE, mLen, nBytes) {
+  var e, m
+  var eLen = nBytes * 8 - mLen - 1
+  var eMax = (1 << eLen) - 1
+  var eBias = eMax >> 1
+  var nBits = -7
+  var i = isLE ? (nBytes - 1) : 0
+  var d = isLE ? -1 : 1
+  var s = buffer[offset + i]
+
+  i += d
+
+  e = s & ((1 << (-nBits)) - 1)
+  s >>= (-nBits)
+  nBits += eLen
+  for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}
+
+  m = e & ((1 << (-nBits)) - 1)
+  e >>= (-nBits)
+  nBits += mLen
+  for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}
+
+  if (e === 0) {
+    e = 1 - eBias
+  } else if (e === eMax) {
+    return m ? NaN : ((s ? -1 : 1) * Infinity)
+  } else {
+    m = m + Math.pow(2, mLen)
+    e = e - eBias
+  }
+  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
+}
+
+exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
+  var e, m, c
+  var eLen = nBytes * 8 - mLen - 1
+  var eMax = (1 << eLen) - 1
+  var eBias = eMax >> 1
+  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
+  var i = isLE ? 0 : (nBytes - 1)
+  var d = isLE ? 1 : -1
+  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
+
+  value = Math.abs(value)
+
+  if (isNaN(value) || value === Infinity) {
+    m = isNaN(value) ? 1 : 0
+    e = eMax
+  } else {
+    e = Math.floor(Math.log(value) / Math.LN2)
+    if (value * (c = Math.pow(2, -e)) < 1) {
+      e--
+      c *= 2
+    }
+    if (e + eBias >= 1) {
+      value += rt / c
+    } else {
+      value += rt * Math.pow(2, 1 - eBias)
+    }
+    if (value * c >= 2) {
+      e++
+      c /= 2
+    }
+
+    if (e + eBias >= eMax) {
+      m = 0
+      e = eMax
+    } else if (e + eBias >= 1) {
+      m = (value * c - 1) * Math.pow(2, mLen)
+      e = e + eBias
+    } else {
+      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
+      e = 0
+    }
+  }
+
+  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
+
+  e = (e << mLen) | m
+  eLen += mLen
+  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
+
+  buffer[offset + i - d] |= s * 128
+}
+
+},{}],17:[function(require,module,exports){
+
+/**
+ * isArray
+ */
+
+var isArray = Array.isArray;
+
+/**
+ * toString
+ */
+
+var str = Object.prototype.toString;
+
+/**
+ * Whether or not the given `val`
+ * is an array.
+ *
+ * example:
+ *
+ *        isArray([]);
+ *        // > true
+ *        isArray(arguments);
+ *        // > false
+ *        isArray('');
+ *        // > false
+ *
+ * @param {mixed} val
+ * @return {bool}
+ */
+
+module.exports = isArray || function (val) {
+  return !! val && '[object Array]' == str.call(val);
+};
+
+},{}],18:[function(require,module,exports){
+/* jshint node: true */
+(function () {
+    "use strict";
+
+    function CookieAccessInfo(domain, path, secure, script) {
+        if (this instanceof CookieAccessInfo) {
+            this.domain = domain || undefined;
+            this.path = path || "/";
+            this.secure = !!secure;
+            this.script = !!script;
+            return this;
+        }
+        return new CookieAccessInfo(domain, path, secure, script);
+    }
+    exports.CookieAccessInfo = CookieAccessInfo;
+
+    function Cookie(cookiestr, request_domain, request_path) {
+        if (cookiestr instanceof Cookie) {
+            return cookiestr;
+        }
+        if (this instanceof Cookie) {
+            this.name = null;
+            this.value = null;
+            this.expiration_date = Infinity;
+            this.path = String(request_path || "/");
+            this.explicit_path = false;
+            this.domain = request_domain || null;
+            this.explicit_domain = false;
+            this.secure = false; //how to define default?
+            this.noscript = false; //httponly
+            if (cookiestr) {
+                this.parse(cookiestr, request_domain, request_path);
+            }
+            return this;
+        }
+        return new Cookie(cookiestr, request_domain, request_path);
+    }
+    exports.Cookie = Cookie;
+
+    Cookie.prototype.toString = function toString() {
+        var str = [this.name + "=" + this.value];
+        if (this.expiration_date !== Infinity) {
+            str.push("expires=" + (new Date(this.expiration_date)).toGMTString());
+        }
+        if (this.domain) {
+            str.push("domain=" + this.domain);
+        }
+        if (this.path) {
+            str.push("path=" + this.path);
+        }
+        if (this.secure) {
+            str.push("secure");
+        }
+        if (this.noscript) {
+            str.push("httponly");
+        }
+        return str.join("; ");
+    };
+
+    Cookie.prototype.toValueString = function toValueString() {
+        return this.name + "=" + this.value;
+    };
+
+    var cookie_str_splitter = /[:](?=\s*[a-zA-Z0-9_\-]+\s*[=])/g;
+    Cookie.prototype.parse = function parse(str, request_domain, request_path) {
+        if (this instanceof Cookie) {
+            var parts = str.split(";").filter(function (value) {
+                    return !!value;
+                }),
+                pair = parts[0].match(/([^=]+)=([\s\S]*)/),
+                key = pair[1],
+                value = pair[2],
+                i;
+            this.name = key;
+            this.value = value;
+
+            for (i = 1; i < parts.length; i += 1) {
+                pair = parts[i].match(/([^=]+)(?:=([\s\S]*))?/);
+                key = pair[1].trim().toLowerCase();
+                value = pair[2];
+                switch (key) {
+                case "httponly":
+                    this.noscript = true;
+                    break;
+                case "expires":
+                    this.expiration_date = value ?
+                            Number(Date.parse(value)) :
+                            Infinity;
+                    break;
+                case "path":
+                    this.path = value ?
+                            value.trim() :
+                            "";
+                    this.explicit_path = true;
+                    break;
+                case "domain":
+                    this.domain = value ?
+                            value.trim() :
+                            "";
+                    this.explicit_domain = !!this.domain;
+                    break;
+                case "secure":
+                    this.secure = true;
+                    break;
+                }
+            }
+
+            if (!this.explicit_path) {
+               this.path = request_path || "/";
+            }
+            if (!this.explicit_domain) {
+               this.domain = request_domain;
+            }
+
+            return this;
+        }
+        return new Cookie().parse(str, request_domain, request_path);
+    };
+
+    Cookie.prototype.matches = function matches(access_info) {
+        if (this.noscript && access_info.script ||
+                this.secure && !access_info.secure ||
+                !this.collidesWith(access_info)) {
+            return false;
+        }
+        return true;
+    };
+
+    Cookie.prototype.collidesWith = function collidesWith(access_info) {
+        if ((this.path && !access_info.path) || (this.domain && !access_info.domain)) {
+            return false;
+        }
+        if (this.path && access_info.path.indexOf(this.path) !== 0) {
+            return false;
+        }
+        if (this.explicit_path && access_info.path.indexOf( this.path ) !== 0) {
+           return false;
+        }
+        var access_domain = access_info.domain && access_info.domain.replace(/^[\.]/,'');
+        var cookie_domain = this.domain && this.domain.replace(/^[\.]/,'');
+        if (cookie_domain === access_domain) {
+            return true;
+        }
+        if (cookie_domain) {
+            if (!this.explicit_domain) {
+                return false; // we already checked if the domains were exactly the same
+            }
+            var wildcard = access_domain.indexOf(cookie_domain);
+            if (wildcard === -1 || wildcard !== access_domain.length - cookie_domain.length) {
+                return false;
+            }
+            return true;
+        }
+        return true;
+    };
+
+    function CookieJar() {
+        var cookies, cookies_list, collidable_cookie;
+        if (this instanceof CookieJar) {
+            cookies = Object.create(null); //name: [Cookie]
+
+            this.setCookie = function setCookie(cookie, request_domain, request_path) {
+                var remove, i;
+                cookie = new Cookie(cookie, request_domain, request_path);
+                //Delete the cookie if the set is past the current time
+                remove = cookie.expiration_date <= Date.now();
+                if (cookies[cookie.name] !== undefined) {
+                    cookies_list = cookies[cookie.name];
+                    for (i = 0; i < cookies_list.length; i += 1) {
+                        collidable_cookie = cookies_list[i];
+                        if (collidable_cookie.collidesWith(cookie)) {
+                            if (remove) {
+                                cookies_list.splice(i, 1);
+                                if (cookies_list.length === 0) {
+                                    delete cookies[cookie.name];
+                                }
+                                return false;
+                            }
+                            cookies_list[i] = cookie;
+                            return cookie;
+                        }
+                    }
+                    if (remove) {
+                        return false;
+                    }
+                    cookies_list.push(cookie);
+                    return cookie;
+                }
+                if (remove) {
+                    return false;
+                }
+                cookies[cookie.name] = [cookie];
+                return cookies[cookie.name];
+            };
+            //returns a cookie
+            this.getCookie = function getCookie(cookie_name, access_info) {
+                var cookie, i;
+                cookies_list = cookies[cookie_name];
+                if (!cookies_list) {
+                    return;
+                }
+                for (i = 0; i < cookies_list.length; i += 1) {
+                    cookie = cookies_list[i];
+                    if (cookie.expiration_date <= Date.now()) {
+                        if (cookies_list.length === 0) {
+                            delete cookies[cookie.name];
+                        }
+                        continue;
+                    }
+
+                    if (cookie.matches(access_info)) {
+                        return cookie;
+                    }
+                }
+            };
+            //returns a list of cookies
+            this.getCookies = function getCookies(access_info) {
+                var matches = [], cookie_name, cookie;
+                for (cookie_name in cookies) {
+                    cookie = this.getCookie(cookie_name, access_info);
+                    if (cookie) {
+                        matches.push(cookie);
+                    }
+                }
+                matches.toString = function toString() {
+                    return matches.join(":");
+                };
+                matches.toValueString = function toValueString() {
+                    return matches.map(function (c) {
+                        return c.toValueString();
+                    }).join(';');
+                };
+                return matches;
+            };
+
+            return this;
+        }
+        return new CookieJar();
+    }
+    exports.CookieJar = CookieJar;
+
+    //returns list of cookies that were set correctly. Cookies that are expired and removed are not returned.
+    CookieJar.prototype.setCookies = function setCookies(cookies, request_domain, request_path) {
+        cookies = Array.isArray(cookies) ?
+                cookies :
+                cookies.split(cookie_str_splitter);
+        var successful = [],
+            i,
+            cookie;
+        cookies = cookies.map(function(item){
+            return new Cookie(item, request_domain, request_path);
+        });
+        for (i = 0; i < cookies.length; i += 1) {
+            cookie = cookies[i];
+            if (this.setCookie(cookie, request_domain, request_path)) {
+                successful.push(cookie);
+            }
+        }
+        return successful;
+    };
+}());
+
+},{}],19:[function(require,module,exports){
+'use strict';
+
+
+var yaml = require('./lib/js-yaml.js');
+
+
+module.exports = yaml;
+
+},{"./lib/js-yaml.js":20}],20:[function(require,module,exports){
+'use strict';
+
+
+var loader = require('./js-yaml/loader');
+var dumper = require('./js-yaml/dumper');
+
+
+function deprecated(name) {
+  return function () {
+    throw new Error('Function ' + name + ' is deprecated and cannot be used.');
+  };
+}
+
+
+module.exports.Type                = require('./js-yaml/type');
+module.exports.Schema              = require('./js-yaml/schema');
+module.exports.FAILSAFE_SCHEMA     = require('./js-yaml/schema/failsafe');
+module.exports.JSON_SCHEMA         = require('./js-yaml/schema/json');
+module.exports.CORE_SCHEMA         = require('./js-yaml/schema/core');
+module.exports.DEFAULT_SAFE_SCHEMA = require('./js-yaml/schema/default_safe');
+module.exports.DEFAULT_FULL_SCHEMA = require('./js-yaml/schema/default_full');
+module.exports.load                = loader.load;
+module.exports.loadAll             = loader.loadAll;
+module.exports.safeLoad            = loader.safeLoad;
+module.exports.safeLoadAll         = loader.safeLoadAll;
+module.exports.dump                = dumper.dump;
+module.exports.safeDump            = dumper.safeDump;
+module.exports.YAMLException       = require('./js-yaml/exception');
+
+// Deprecated schema names from JS-YAML 2.0.x
+module.exports.MINIMAL_SCHEMA = require('./js-yaml/schema/failsafe');
+module.exports.SAFE_SCHEMA    = require('./js-yaml/schema/default_safe');
+module.exports.DEFAULT_SCHEMA = require('./js-yaml/schema/default_full');
+
+// Deprecated functions from JS-YAML 1.x.x
+module.exports.scan           = deprecated('scan');
+module.exports.parse          = deprecated('parse');
+module.exports.compose        = deprecated('compose');
+module.exports.addConstructor = deprecated('addConstructor');
+
+},{"./js-yaml/dumper":22,"./js-yaml/exception":23,"./js-yaml/loader":24,"./js-yaml/schema":26,"./js-yaml/schema/core":27,"./js-yaml/schema/default_full":28,"./js-yaml/schema/default_safe":29,"./js-yaml/schema/failsafe":30,"./js-yaml/schema/json":31,"./js-yaml/type":32}],21:[function(require,module,exports){
+'use strict';
+
+
+function isNothing(subject) {
+  return (typeof subject === 'undefined') || (subject === null);
+}
+
+
+function isObject(subject) {
+  return (typeof subject === 'object') && (subject !== null);
+}
+
+
+function toArray(sequence) {
+  if (Array.isArray(sequence)) return sequence;
+  else if (isNothing(sequence)) return [];
+
+  return [ sequence ];
+}
+
+
+function extend(target, source) {
+  var index, length, key, sourceKeys;
+
+  if (source) {
+    sourceKeys = Object.keys(source);
+
+    for (index = 0, length = sourceKeys.length; index < length; index += 1) {
+      key = sourceKeys[index];
+      target[key] = source[key];
+    }
+  }
+
+  return target;
+}
+
+
+function repeat(string, count) {
+  var result = '', cycle;
+
+  for (cycle = 0; cycle < count; cycle += 1) {
+    result += string;
+  }
+
+  return result;
+}
+
+
+function isNegativeZero(number) {
+  return (number === 0) && (Number.NEGATIVE_INFINITY === 1 / number);
+}
+
+
+module.exports.isNothing      = isNothing;
+module.exports.isObject       = isObject;
+module.exports.toArray        = toArray;
+module.exports.repeat         = repeat;
+module.exports.isNegativeZero = isNegativeZero;
+module.exports.extend         = extend;
+
+},{}],22:[function(require,module,exports){
+'use strict';
+
+/*eslint-disable no-use-before-define*/
+
+var common              = require('./common');
+var YAMLException       = require('./exception');
+var DEFAULT_FULL_SCHEMA = require('./schema/default_full');
+var DEFAULT_SAFE_SCHEMA = require('./schema/default_safe');
+
+var _toString       = Object.prototype.toString;
+var _hasOwnProperty = Object.prototype.hasOwnProperty;
+
+var CHAR_TAB                  = 0x09; /* Tab */
+var CHAR_LINE_FEED            = 0x0A; /* LF */
+var CHAR_SPACE                = 0x20; /* Space */
+var CHAR_EXCLAMATION          = 0x21; /* ! */
+var CHAR_DOUBLE_QUOTE         = 0x22; /* " */
+var CHAR_SHARP                = 0x23; /* # */
+var CHAR_PERCENT              = 0x25; /* % */
+var CHAR_AMPERSAND            = 0x26; /* & */
+var CHAR_SINGLE_QUOTE         = 0x27; /* ' */
+var CHAR_ASTERISK             = 0x2A; /* * */
+var CHAR_COMMA                = 0x2C; /* , */
+var CHAR_MINUS                = 0x2D; /* - */
+var CHAR_COLON                = 0x3A; /* : */
+var CHAR_GREATER_THAN         = 0x3E; /* > */
+var CHAR_QUESTION             = 0x3F; /* ? */
+var CHAR_COMMERCIAL_AT        = 0x40; /* @ */
+var CHAR_LEFT_SQUARE_BRACKET  = 0x5B; /* [ */
+var CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */
+var CHAR_GRAVE_ACCENT         = 0x60; /* ` */
+var CHAR_LEFT_CURLY_BRACKET   = 0x7B; /* { */
+var CHAR_VERTICAL_LINE        = 0x7C; /* | */
+var CHAR_RIGHT_CURLY_BRACKET  = 0x7D; /* } */
+
+var ESCAPE_SEQUENCES = {};
+
+ESCAPE_SEQUENCES[0x00]   = '\\0';
+ESCAPE_SEQUENCES[0x07]   = '\\a';
+ESCAPE_SEQUENCES[0x08]   = '\\b';
+ESCAPE_SEQUENCES[0x09]   = '\\t';
+ESCAPE_SEQUENCES[0x0A]   = '\\n';
+ESCAPE_SEQUENCES[0x0B]   = '\\v';
+ESCAPE_SEQUENCES[0x0C]   = '\\f';
+ESCAPE_SEQUENCES[0x0D]   = '\\r';
+ESCAPE_SEQUENCES[0x1B]   = '\\e';
+ESCAPE_SEQUENCES[0x22]   = '\\"';
+ESCAPE_SEQUENCES[0x5C]   = '\\\\';
+ESCAPE_SEQUENCES[0x85]   = '\\N';
+ESCAPE_SEQUENCES[0xA0]   = '\\_';
+ESCAPE_SEQUENCES[0x2028] = '\\L';
+ESCAPE_SEQUENCES[0x2029] = '\\P';
+
+var DEPRECATED_BOOLEANS_SYNTAX = [
+  'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON',
+  'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF'
+];
+
+function compileStyleMap(schema, map) {
+  var result, keys, index, length, tag, style, type;
+
+  if (map === null) return {};
+
+  result = {};
+  keys = Object.keys(map);
+
+  for (index = 0, length = keys.length; index < length; index += 1) {
+    tag = keys[index];
+    style = String(map[tag]);
+
+    if (tag.slice(0, 2) === '!!') {
+      tag = 'tag:yaml.org,2002:' + tag.slice(2);
+    }
+
+    type = schema.compiledTypeMap[tag];
+
+    if (type && _hasOwnProperty.call(type.styleAliases, style)) {
+      style = type.styleAliases[style];
+    }
+
+    result[tag] = style;
+  }
+
+  return result;
+}
+
+function encodeHex(character) {
+  var string, handle, length;
+
+  string = character.toString(16).toUpperCase();
+
+  if (character <= 0xFF) {
+    handle = 'x';
+    length = 2;
+  } else if (character <= 0xFFFF) {
+    handle = 'u';
+    length = 4;
+  } else if (character <= 0xFFFFFFFF) {
+    handle = 'U';
+    length = 8;
+  } else {
+    throw new YAMLException('code point within a string may not be greater than 0xFFFFFFFF');
+  }
+
+  return '\\' + handle + common.repeat('0', length - string.length) + string;
+}
+
+function State(options) {
+  this.schema       = options['schema'] || DEFAULT_FULL_SCHEMA;
+  this.indent       = Math.max(1, (options['indent'] || 2));
+  this.skipInvalid  = options['skipInvalid'] || false;
+  this.flowLevel    = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']);
+  this.styleMap     = compileStyleMap(this.schema, options['styles'] || null);
+  this.sortKeys     = options['sortKeys'] || false;
+  this.lineWidth    = options['lineWidth'] || 80;
+  this.noRefs       = options['noRefs'] || false;
+  this.noCompatMode = options['noCompatMode'] || false;
+
+  this.implicitTypes = this.schema.compiledImplicit;
+  this.explicitTypes = this.schema.compiledExplicit;
+
+  this.tag = null;
+  this.result = '';
+
+  this.duplicates = [];
+  this.usedDuplicates = null;
+}
+
+// Indents every line in a string. Empty lines (\n only) are not indented.
+function indentString(string, spaces) {
+  var ind = common.repeat(' ', spaces),
+      position = 0,
+      next = -1,
+      result = '',
+      line,
+      length = string.length;
+
+  while (position < length) {
+    next = string.indexOf('\n', position);
+    if (next === -1) {
+      line = string.slice(position);
+      position = length;
+    } else {
+      line = string.slice(position, next + 1);
+      position = next + 1;
+    }
+
+    if (line.length && line !== '\n') result += ind;
+
+    result += line;
+  }
+
+  return result;
+}
+
+function generateNextLine(state, level) {
+  return '\n' + common.repeat(' ', state.indent * level);
+}
+
+function testImplicitResolving(state, str) {
+  var index, length, type;
+
+  for (index = 0, length = state.implicitTypes.length; index < length; index += 1) {
+    type = state.implicitTypes[index];
+
+    if (type.resolve(str)) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+// [33] s-white ::= s-space | s-tab
+function isWhitespace(c) {
+  return c === CHAR_SPACE || c === CHAR_TAB;
+}
+
+// Returns true if the character can be printed without escaping.
+// From YAML 1.2: "any allowed characters known to be non-printable
+// should also be escaped. [However,] This isn’t mandatory"
+// Derived from nb-char - \t - #x85 - #xA0 - #x2028 - #x2029.
+function isPrintable(c) {
+  return  (0x00020 <= c && c <= 0x00007E)
+      || ((0x000A1 <= c && c <= 0x00D7FF) && c !== 0x2028 && c !== 0x2029)
+      || ((0x0E000 <= c && c <= 0x00FFFD) && c !== 0xFEFF /* BOM */)
+      ||  (0x10000 <= c && c <= 0x10FFFF);
+}
+
+// Simplified test for values allowed after the first character in plain style.
+function isPlainSafe(c) {
+  // Uses a subset of nb-char - c-flow-indicator - ":" - "#"
+  // where nb-char ::= c-printable - b-char - c-byte-order-mark.
+  return isPrintable(c) && c !== 0xFEFF
+    // - c-flow-indicator
+    && c !== CHAR_COMMA
+    && c !== CHAR_LEFT_SQUARE_BRACKET
+    && c !== CHAR_RIGHT_SQUARE_BRACKET
+    && c !== CHAR_LEFT_CURLY_BRACKET
+    && c !== CHAR_RIGHT_CURLY_BRACKET
+    // - ":" - "#"
+    && c !== CHAR_COLON
+    && c !== CHAR_SHARP;
+}
+
+// Simplified test for values allowed as the first character in plain style.
+function isPlainSafeFirst(c) {
+  // Uses a subset of ns-char - c-indicator
+  // where ns-char = nb-char - s-white.
+  return isPrintable(c) && c !== 0xFEFF
+    && !isWhitespace(c) // - s-white
+    // - (c-indicator ::=
+    // “-” | “?” | “:” | “,” | “[” | “]” | “{” | “}”
+    && c !== CHAR_MINUS
+    && c !== CHAR_QUESTION
+    && c !== CHAR_COLON
+    && c !== CHAR_COMMA
+    && c !== CHAR_LEFT_SQUARE_BRACKET
+    && c !== CHAR_RIGHT_SQUARE_BRACKET
+    && c !== CHAR_LEFT_CURLY_BRACKET
+    && c !== CHAR_RIGHT_CURLY_BRACKET
+    // | “#” | “&” | “*” | “!” | “|” | “>” | “'” | “"”
+    && c !== CHAR_SHARP
+    && c !== CHAR_AMPERSAND
+    && c !== CHAR_ASTERISK
+    && c !== CHAR_EXCLAMATION
+    && c !== CHAR_VERTICAL_LINE
+    && c !== CHAR_GREATER_THAN
+    && c !== CHAR_SINGLE_QUOTE
+    && c !== CHAR_DOUBLE_QUOTE
+    // | “%” | “@” | “`”)
+    && c !== CHAR_PERCENT
+    && c !== CHAR_COMMERCIAL_AT
+    && c !== CHAR_GRAVE_ACCENT;
+}
+
+var STYLE_PLAIN   = 1,
+    STYLE_SINGLE  = 2,
+    STYLE_LITERAL = 3,
+    STYLE_FOLDED  = 4,
+    STYLE_DOUBLE  = 5;
+
+// Determines which scalar styles are possible and returns the preferred style.
+// lineWidth = -1 => no limit.
+// Pre-conditions: str.length > 0.
+// Post-conditions:
+//    STYLE_PLAIN or STYLE_SINGLE => no \n are in the string.
+//    STYLE_LITERAL => no lines are suitable for folding (or lineWidth is -1).
+//    STYLE_FOLDED => a line > lineWidth and can be folded (and lineWidth != -1).
+function chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth, testAmbiguousType) {
+  var i;
+  var char;
+  var hasLineBreak = false;
+  var hasFoldableLine = false; // only checked if shouldTrackWidth
+  var shouldTrackWidth = lineWidth !== -1;
+  var previousLineBreak = -1; // count the first line correctly
+  var plain = isPlainSafeFirst(string.charCodeAt(0))
+          && !isWhitespace(string.charCodeAt(string.length - 1));
+
+  if (singleLineOnly) {
+    // Case: no block styles.
+    // Check for disallowed characters to rule out plain and single.
+    for (i = 0; i < string.length; i++) {
+      char = string.charCodeAt(i);
+      if (!isPrintable(char)) {
+        return STYLE_DOUBLE;
+      }
+      plain = plain && isPlainSafe(char);
+    }
+  } else {
+    // Case: block styles permitted.
+    for (i = 0; i < string.length; i++) {
+      char = string.charCodeAt(i);
+      if (char === CHAR_LINE_FEED) {
+        hasLineBreak = true;
+        // Check if any line can be folded.
+        if (shouldTrackWidth) {
+          hasFoldableLine = hasFoldableLine ||
+            // Foldable line = too long, and not more-indented.
+            (i - previousLineBreak - 1 > lineWidth &&
+             string[previousLineBreak + 1] !== ' ');
+          previousLineBreak = i;
+        }
+      } else if (!isPrintable(char)) {
+        return STYLE_DOUBLE;
+      }
+      plain = plain && isPlainSafe(char);
+    }
+    // in case the end is missing a \n
+    hasFoldableLine = hasFoldableLine || (shouldTrackWidth &&
+      (i - previousLineBreak - 1 > lineWidth &&
+       string[previousLineBreak + 1] !== ' '));
+  }
+  // Although every style can represent \n without escaping, prefer block styles
+  // for multiline, since they're more readable and they don't add empty lines.
+  // Also prefer folding a super-long line.
+  if (!hasLineBreak && !hasFoldableLine) {
+    // Strings interpretable as another type have to be quoted;
+    // e.g. the string 'true' vs. the boolean true.
+    return plain && !testAmbiguousType(string)
+      ? STYLE_PLAIN : STYLE_SINGLE;
+  }
+  // Edge case: block indentation indicator can only have one digit.
+  if (string[0] === ' ' && indentPerLevel > 9) {
+    return STYLE_DOUBLE;
+  }
+  // At this point we know block styles are valid.
+  // Prefer literal style unless we want to fold.
+  return hasFoldableLine ? STYLE_FOLDED : STYLE_LITERAL;
+}
+
+// Note: line breaking/folding is implemented for only the folded style.
+// NB. We drop the last trailing newline (if any) of a returned block scalar
+//  since the dumper adds its own newline. This always works:
+//    • No ending newline => unaffected; already using strip "-" chomping.
+//    • Ending newline    => removed then restored.
+//  Importantly, this keeps the "+" chomp indicator from gaining an extra line.
+function writeScalar(state, string, level, iskey) {
+  state.dump = (function () {
+    if (string.length === 0) {
+      return "''";
+    }
+    if (!state.noCompatMode &&
+        DEPRECATED_BOOLEANS_SYNTAX.indexOf(string) !== -1) {
+      return "'" + string + "'";
+    }
+
+    var indent = state.indent * Math.max(1, level); // no 0-indent scalars
+    // As indentation gets deeper, let the width decrease monotonically
+    // to the lower bound min(state.lineWidth, 40).
+    // Note that this implies
+    //  state.lineWidth ≤ 40 + state.indent: width is fixed at the lower bound.
+    //  state.lineWidth > 40 + state.indent: width decreases until the lower bound.
+    // This behaves better than a constant minimum width which disallows narrower options,
+    // or an indent threshold which causes the width to suddenly increase.
+    var lineWidth = state.lineWidth === -1
+      ? -1 : Math.max(Math.min(state.lineWidth, 40), state.lineWidth - indent);
+
+    // Without knowing if keys are implicit/explicit, assume implicit for safety.
+    var singleLineOnly = iskey
+      // No block styles in flow mode.
+      || (state.flowLevel > -1 && level >= state.flowLevel);
+    function testAmbiguity(string) {
+      return testImplicitResolving(state, string);
+    }
+
+    switch (chooseScalarStyle(string, singleLineOnly, state.indent, lineWidth, testAmbiguity)) {
+      case STYLE_PLAIN:
+        return string;
+      case STYLE_SINGLE:
+        return "'" + string.replace(/'/g, "''") + "'";
+      case STYLE_LITERAL:
+        return '|' + blockHeader(string, state.indent)
+          + dropEndingNewline(indentString(string, indent));
+      case STYLE_FOLDED:
+        return '>' + blockHeader(string, state.indent)
+          + dropEndingNewline(indentString(foldString(string, lineWidth), indent));
+      case STYLE_DOUBLE:
+        return '"' + escapeString(string, lineWidth) + '"';
+      default:
+        throw new YAMLException('impossible error: invalid scalar style');
+    }
+  }());
+}
+
+// Pre-conditions: string is valid for a block scalar, 1 <= indentPerLevel <= 9.
+function blockHeader(string, indentPerLevel) {
+  var indentIndicator = (string[0] === ' ') ? String(indentPerLevel) : '';
+
+  // note the special case: the string '\n' counts as a "trailing" empty line.
+  var clip =          string[string.length - 1] === '\n';
+  var keep = clip && (string[string.length - 2] === '\n' || string === '\n');
+  var chomp = keep ? '+' : (clip ? '' : '-');
+
+  return indentIndicator + chomp + '\n';
+}
+
+// (See the note for writeScalar.)
+function dropEndingNewline(string) {
+  return string[string.length - 1] === '\n' ? string.slice(0, -1) : string;
+}
+
+// Note: a long line without a suitable break point will exceed the width limit.
+// Pre-conditions: every char in str isPrintable, str.length > 0, width > 0.
+function foldString(string, width) {
+  // In folded style, $k$ consecutive newlines output as $k+1$ newlines—
+  // unless they're before or after a more-indented line, or at the very
+  // beginning or end, in which case $k$ maps to $k$.
+  // Therefore, parse each chunk as newline(s) followed by a content line.
+  var lineRe = /(\n+)([^\n]*)/g;
+
+  // first line (possibly an empty line)
+  var result = (function () {
+    var nextLF = string.indexOf('\n');
+    nextLF = nextLF !== -1 ? nextLF : string.length;
+    lineRe.lastIndex = nextLF;
+    return foldLine(string.slice(0, nextLF), width);
+  }());
+  // If we haven't reached the first content line yet, don't add an extra \n.
+  var prevMoreIndented = string[0] === '\n' || string[0] === ' ';
+  var moreIndented;
+
+  // rest of the lines
+  var match;
+  while ((match = lineRe.exec(string))) {
+    var prefix = match[1], line = match[2];
+    moreIndented = (line[0] === ' ');
+    result += prefix
+      + (!prevMoreIndented && !moreIndented && line !== ''
+        ? '\n' : '')
+      + foldLine(line, width);
+    prevMoreIndented = moreIndented;
+  }
+
+  return result;
+}
+
+// Greedy line breaking.
+// Picks the longest line under the limit each time,
+// otherwise settles for the shortest line over the limit.
+// NB. More-indented lines *cannot* be folded, as that would add an extra \n.
+function foldLine(line, width) {
+  if (line === '' || line[0] === ' ') return line;
+
+  // Since a more-indented line adds a \n, breaks can't be followed by a space.
+  var breakRe = / [^ ]/g; // note: the match index will always be <= length-2.
+  var match;
+  // start is an inclusive index. end, curr, and next are exclusive.
+  var start = 0, end, curr = 0, next = 0;
+  var result = '';
+
+  // Invariants: 0 <= start <= length-1.
+  //   0 <= curr <= next <= max(0, length-2). curr - start <= width.
+  // Inside the loop:
+  //   A match implies length >= 2, so curr and next are <= length-2.
+  while ((match = breakRe.exec(line))) {
+    next = match.index;
+    // maintain invariant: curr - start <= width
+    if (next - start > width) {
+      end = (curr > start) ? curr : next; // derive end <= length-2
+      result += '\n' + line.slice(start, end);
+      // skip the space that was output as \n
+      start = end + 1;                    // derive start <= length-1
+    }
+    curr = next;
+  }
+
+  // By the invariants, start <= length-1, so there is something left over.
+  // It is either the whole string or a part starting from non-whitespace.
+  result += '\n';
+  // Insert a break if the remainder is too long and there is a break available.
+  if (line.length - start > width && curr > start) {
+    result += line.slice(start, curr) + '\n' + line.slice(curr + 1);
+  } else {
+    result += line.slice(start);
+  }
+
+  return result.slice(1); // drop extra \n joiner
+}
+
+// Escapes a double-quoted string.
+function escapeString(string) {
+  var result = '';
+  var char;
+  var escapeSeq;
+
+  for (var i = 0; i < string.length; i++) {
+    char = string.charCodeAt(i);
+    escapeSeq = ESCAPE_SEQUENCES[char];
+    result += !escapeSeq && isPrintable(char)
+      ? string[i]
+      : escapeSeq || encodeHex(char);
+  }
+
+  return result;
+}
+
+function writeFlowSequence(state, level, object) {
+  var _result = '',
+      _tag    = state.tag,
+      index,
+      length;
+
+  for (index = 0, length = object.length; index < length; index += 1) {
+    // Write only valid elements.
+    if (writeNode(state, level, object[index], false, false)) {
+      if (index !== 0) _result += ', ';
+      _result += state.dump;
+    }
+  }
+
+  state.tag = _tag;
+  state.dump = '[' + _result + ']';
+}
+
+function writeBlockSequence(state, level, object, compact) {
+  var _result = '',
+      _tag    = state.tag,
+      index,
+      length;
+
+  for (index = 0, length = object.length; index < length; index += 1) {
+    // Write only valid elements.
+    if (writeNode(state, level + 1, object[index], true, true)) {
+      if (!compact || index !== 0) {
+        _result += generateNextLine(state, level);
+      }
+      _result += '- ' + state.dump;
+    }
+  }
+
+  state.tag = _tag;
+  state.dump = _result || '[]'; // Empty sequence if no valid values.
+}
+
+function writeFlowMapping(state, level, object) {
+  var _result       = '',
+      _tag          = state.tag,
+      objectKeyList = Object.keys(object),
+      index,
+      length,
+      objectKey,
+      objectValue,
+      pairBuffer;
+
+  for (index = 0, length = objectKeyList.length; index < length; index += 1) {
+    pairBuffer = '';
+
+    if (index !== 0) pairBuffer += ', ';
+
+    objectKey = objectKeyList[index];
+    objectValue = object[objectKey];
+
+    if (!writeNode(state, level, objectKey, false, false)) {
+      continue; // Skip this pair because of invalid key;
+    }
+
+    if (state.dump.length > 1024) pairBuffer += '? ';
+
+    pairBuffer += state.dump + ': ';
+
+    if (!writeNode(state, level, objectValue, false, false)) {
+      continue; // Skip this pair because of invalid value.
+    }
+
+    pairBuffer += state.dump;
+
+    // Both key and value are valid.
+    _result += pairBuffer;
+  }
+
+  state.tag = _tag;
+  state.dump = '{' + _result + '}';
+}
+
+function writeBlockMapping(state, level, object, compact) {
+  var _result       = '',
+      _tag          = state.tag,
+      objectKeyList = Object.keys(object),
+      index,
+      length,
+      objectKey,
+      objectValue,
+      explicitPair,
+      pairBuffer;
+
+  // Allow sorting keys so that the output file is deterministic
+  if (state.sortKeys === true) {
+    // Default sorting
+    objectKeyList.sort();
+  } else if (typeof state.sortKeys === 'function') {
+    // Custom sort function
+    objectKeyList.sort(state.sortKeys);
+  } else if (state.sortKeys) {
+    // Something is wrong
+    throw new YAMLException('sortKeys must be a boolean or a function');
+  }
+
+  for (index = 0, length = objectKeyList.length; index < length; index += 1) {
+    pairBuffer = '';
+
+    if (!compact || index !== 0) {
+      pairBuffer += generateNextLine(state, level);
+    }
+
+    objectKey = objectKeyList[index];
+    objectValue = object[objectKey];
+
+    if (!writeNode(state, level + 1, objectKey, true, true, true)) {
+      continue; // Skip this pair because of invalid key.
+    }
+
+    explicitPair = (state.tag !== null && state.tag !== '?') ||
+                   (state.dump && state.dump.length > 1024);
+
+    if (explicitPair) {
+      if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {
+        pairBuffer += '?';
+      } else {
+        pairBuffer += '? ';
+      }
+    }
+
+    pairBuffer += state.dump;
+
+    if (explicitPair) {
+      pairBuffer += generateNextLine(state, level);
+    }
+
+    if (!writeNode(state, level + 1, objectValue, true, explicitPair)) {
+      continue; // Skip this pair because of invalid value.
+    }
+
+    if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {
+      pairBuffer += ':';
+    } else {
+      pairBuffer += ': ';
+    }
+
+    pairBuffer += state.dump;
+
+    // Both key and value are valid.
+    _result += pairBuffer;
+  }
+
+  state.tag = _tag;
+  state.dump = _result || '{}'; // Empty mapping if no valid pairs.
+}
+
+function detectType(state, object, explicit) {
+  var _result, typeList, index, length, type, style;
+
+  typeList = explicit ? state.explicitTypes : state.implicitTypes;
+
+  for (index = 0, length = typeList.length; index < length; index += 1) {
+    type = typeList[index];
+
+    if ((type.instanceOf  || type.predicate) &&
+        (!type.instanceOf || ((typeof object === 'object') && (object instanceof type.instanceOf))) &&
+        (!type.predicate  || type.predicate(object))) {
+
+      state.tag = explicit ? type.tag : '?';
+
+      if (type.represent) {
+        style = state.styleMap[type.tag] || type.defaultStyle;
+
+        if (_toString.call(type.represent) === '[object Function]') {
+          _result = type.represent(object, style);
+        } else if (_hasOwnProperty.call(type.represent, style)) {
+          _result = type.represent[style](object, style);
+        } else {
+          throw new YAMLException('!<' + type.tag + '> tag resolver accepts not "' + style + '" style');
+        }
+
+        state.dump = _result;
+      }
+
+      return true;
+    }
+  }
+
+  return false;
+}
+
+// Serializes `object` and writes it to global `result`.
+// Returns true on success, or false on invalid object.
+//
+function writeNode(state, level, object, block, compact, iskey) {
+  state.tag = null;
+  state.dump = object;
+
+  if (!detectType(state, object, false)) {
+    detectType(state, object, true);
+  }
+
+  var type = _toString.call(state.dump);
+
+  if (block) {
+    block = (state.flowLevel < 0 || state.flowLevel > level);
+  }
+
+  var objectOrArray = type === '[object Object]' || type === '[object Array]',
+      duplicateIndex,
+      duplicate;
+
+  if (objectOrArray) {
+    duplicateIndex = state.duplicates.indexOf(object);
+    duplicate = duplicateIndex !== -1;
+  }
+
+  if ((state.tag !== null && state.tag !== '?') || duplicate || (state.indent !== 2 && level > 0)) {
+    compact = false;
+  }
+
+  if (duplicate && state.usedDuplicates[duplicateIndex]) {
+    state.dump = '*ref_' + duplicateIndex;
+  } else {
+    if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) {
+      state.usedDuplicates[duplicateIndex] = true;
+    }
+    if (type === '[object Object]') {
+      if (block && (Object.keys(state.dump).length !== 0)) {
+        writeBlockMapping(state, level, state.dump, compact);
+        if (duplicate) {
+          state.dump = '&ref_' + duplicateIndex + state.dump;
+        }
+      } else {
+        writeFlowMapping(state, level, state.dump);
+        if (duplicate) {
+          state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;
+        }
+      }
+    } else if (type === '[object Array]') {
+      if (block && (state.dump.length !== 0)) {
+        writeBlockSequence(state, level, state.dump, compact);
+        if (duplicate) {
+          state.dump = '&ref_' + duplicateIndex + state.dump;
+        }
+      } else {
+        writeFlowSequence(state, level, state.dump);
+        if (duplicate) {
+          state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;
+        }
+      }
+    } else if (type === '[object String]') {
+      if (state.tag !== '?') {
+        writeScalar(state, state.dump, level, iskey);
+      }
+    } else {
+      if (state.skipInvalid) return false;
+      throw new YAMLException('unacceptable kind of an object to dump ' + type);
+    }
+
+    if (state.tag !== null && state.tag !== '?') {
+      state.dump = '!<' + state.tag + '> ' + state.dump;
+    }
+  }
+
+  return true;
+}
+
+function getDuplicateReferences(object, state) {
+  var objects = [],
+      duplicatesIndexes = [],
+      index,
+      length;
+
+  inspectNode(object, objects, duplicatesIndexes);
+
+  for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) {
+    state.duplicates.push(objects[duplicatesIndexes[index]]);
+  }
+  state.usedDuplicates = new Array(length);
+}
+
+function inspectNode(object, objects, duplicatesIndexes) {
+  var objectKeyList,
+      index,
+      length;
+
+  if (object !== null && typeof object === 'object') {
+    index = objects.indexOf(object);
+    if (index !== -1) {
+      if (duplicatesIndexes.indexOf(index) === -1) {
+        duplicatesIndexes.push(index);
+      }
+    } else {
+      objects.push(object);
+
+      if (Array.isArray(object)) {
+        for (index = 0, length = object.length; index < length; index += 1) {
+          inspectNode(object[index], objects, duplicatesIndexes);
+        }
+      } else {
+        objectKeyList = Object.keys(object);
+
+        for (index = 0, length = objectKeyList.length; index < length; index += 1) {
+          inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes);
+        }
+      }
+    }
+  }
+}
+
+function dump(input, options) {
+  options = options || {};
+
+  var state = new State(options);
+
+  if (!state.noRefs) getDuplicateReferences(input, state);
+
+  if (writeNode(state, 0, input, true, true)) return state.dump + '\n';
+
+  return '';
+}
+
+function safeDump(input, options) {
+  return dump(input, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options));
+}
+
+module.exports.dump     = dump;
+module.exports.safeDump = safeDump;
+
+},{"./common":21,"./exception":23,"./schema/default_full":28,"./schema/default_safe":29}],23:[function(require,module,exports){
+// YAML error class. http://stackoverflow.com/questions/8458984
+//
+'use strict';
+
+function YAMLException(reason, mark) {
+  // Super constructor
+  Error.call(this);
+
+  // Include stack trace in error object
+  if (Error.captureStackTrace) {
+    // Chrome and NodeJS
+    Error.captureStackTrace(this, this.constructor);
+  } else {
+    // FF, IE 10+ and Safari 6+. Fallback for others
+    this.stack = (new Error()).stack || '';
+  }
+
+  this.name = 'YAMLException';
+  this.reason = reason;
+  this.mark = mark;
+  this.message = (this.reason || '(unknown reason)') + (this.mark ? ' ' + this.mark.toString() : '');
+}
+
+
+// Inherit from Error
+YAMLException.prototype = Object.create(Error.prototype);
+YAMLException.prototype.constructor = YAMLException;
+
+
+YAMLException.prototype.toString = function toString(compact) {
+  var result = this.name + ': ';
+
+  result += this.reason || '(unknown reason)';
+
+  if (!compact && this.mark) {
+    result += ' ' + this.mark.toString();
+  }
+
+  return result;
+};
+
+
+module.exports = YAMLException;
+
+},{}],24:[function(require,module,exports){
+'use strict';
+
+/*eslint-disable max-len,no-use-before-define*/
+
+var common              = require('./common');
+var YAMLException       = require('./exception');
+var Mark                = require('./mark');
+var DEFAULT_SAFE_SCHEMA = require('./schema/default_safe');
+var DEFAULT_FULL_SCHEMA = require('./schema/default_full');
+
+
+var _hasOwnProperty = Object.prototype.hasOwnProperty;
+
+
+var CONTEXT_FLOW_IN   = 1;
+var CONTEXT_FLOW_OUT  = 2;
+var CONTEXT_BLOCK_IN  = 3;
+var CONTEXT_BLOCK_OUT = 4;
+
+
+var CHOMPING_CLIP  = 1;
+var CHOMPING_STRIP = 2;
+var CHOMPING_KEEP  = 3;
+
+
+var PATTERN_NON_PRINTABLE         = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/;
+var PATTERN_NON_ASCII_LINE_BREAKS = /[\x85\u2028\u2029]/;
+var PATTERN_FLOW_INDICATORS       = /[,\[\]\{\}]/;
+var PATTERN_TAG_HANDLE            = /^(?:!|!!|![a-z\-]+!)$/i;
+var PATTERN_TAG_URI               = /^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;
+
+
+function is_EOL(c) {
+  return (c === 0x0A/* LF */) || (c === 0x0D/* CR */);
+}
+
+function is_WHITE_SPACE(c) {
+  return (c === 0x09/* Tab */) || (c === 0x20/* Space */);
+}
+
+function is_WS_OR_EOL(c) {
+  return (c === 0x09/* Tab */) ||
+         (c === 0x20/* Space */) ||
+         (c === 0x0A/* LF */) ||
+         (c === 0x0D/* CR */);
+}
+
+function is_FLOW_INDICATOR(c) {
+  return c === 0x2C/* , */ ||
+         c === 0x5B/* [ */ ||
+         c === 0x5D/* ] */ ||
+         c === 0x7B/* { */ ||
+         c === 0x7D/* } */;
+}
+
+function fromHexCode(c) {
+  var lc;
+
+  if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {
+    return c - 0x30;
+  }
+
+  /*eslint-disable no-bitwise*/
+  lc = c | 0x20;
+
+  if ((0x61/* a */ <= lc) && (lc <= 0x66/* f */)) {
+    return lc - 0x61 + 10;
+  }
+
+  return -1;
+}
+
+function escapedHexLen(c) {
+  if (c === 0x78/* x */) { return 2; }
+  if (c === 0x75/* u */) { return 4; }
+  if (c === 0x55/* U */) { return 8; }
+  return 0;
+}
+
+function fromDecimalCode(c) {
+  if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {
+    return c - 0x30;
+  }
+
+  return -1;
+}
+
+function simpleEscapeSequence(c) {
+  return (c === 0x30/* 0 */) ? '\x00' :
+        (c === 0x61/* a */) ? '\x07' :
+        (c === 0x62/* b */) ? '\x08' :
+        (c === 0x74/* t */) ? '\x09' :
+        (c === 0x09/* Tab */) ? '\x09' :
+        (c === 0x6E/* n */) ? '\x0A' :
+        (c === 0x76/* v */) ? '\x0B' :
+        (c === 0x66/* f */) ? '\x0C' :
+        (c === 0x72/* r */) ? '\x0D' :
+        (c === 0x65/* e */) ? '\x1B' :
+        (c === 0x20/* Space */) ? ' ' :
+        (c === 0x22/* " */) ? '\x22' :
+        (c === 0x2F/* / */) ? '/' :
+        (c === 0x5C/* \ */) ? '\x5C' :
+        (c === 0x4E/* N */) ? '\x85' :
+        (c === 0x5F/* _ */) ? '\xA0' :
+        (c === 0x4C/* L */) ? '\u2028' :
+        (c === 0x50/* P */) ? '\u2029' : '';
+}
+
+function charFromCodepoint(c) {
+  if (c <= 0xFFFF) {
+    return String.fromCharCode(c);
+  }
+  // Encode UTF-16 surrogate pair
+  // https://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF
+  return String.fromCharCode(((c - 0x010000) >> 10) + 0xD800,
+                             ((c - 0x010000) & 0x03FF) + 0xDC00);
+}
+
+var simpleEscapeCheck = new Array(256); // integer, for fast access
+var simpleEscapeMap = new Array(256);
+for (var i = 0; i < 256; i++) {
+  simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0;
+  simpleEscapeMap[i] = simpleEscapeSequence(i);
+}
+
+
+function State(input, options) {
+  this.input = input;
+
+  this.filename  = options['filename']  || null;
+  this.schema    = options['schema']    || DEFAULT_FULL_SCHEMA;
+  this.onWarning = options['onWarning'] || null;
+  this.legacy    = options['legacy']    || false;
+  this.json      = options['json']      || false;
+  this.listener  = options['listener']  || null;
+
+  this.implicitTypes = this.schema.compiledImplicit;
+  this.typeMap       = this.schema.compiledTypeMap;
+
+  this.length     = input.length;
+  this.position   = 0;
+  this.line       = 0;
+  this.lineStart  = 0;
+  this.lineIndent = 0;
+
+  this.documents = [];
+
+  /*
+  this.version;
+  this.checkLineBreaks;
+  this.tagMap;
+  this.anchorMap;
+  this.tag;
+  this.anchor;
+  this.kind;
+  this.result;*/
+
+}
+
+
+function generateError(state, message) {
+  return new YAMLException(
+    message,
+    new Mark(state.filename, state.input, state.position, state.line, (state.position - state.lineStart)));
+}
+
+function throwError(state, message) {
+  throw generateError(state, message);
+}
+
+function throwWarning(state, message) {
+  if (state.onWarning) {
+    state.onWarning.call(null, generateError(state, message));
+  }
+}
+
+
+var directiveHandlers = {
+
+  YAML: function handleYamlDirective(state, name, args) {
+
+    var match, major, minor;
+
+    if (state.version !== null) {
+      throwError(state, 'duplication of %YAML directive');
+    }
+
+    if (args.length !== 1) {
+      throwError(state, 'YAML directive accepts exactly one argument');
+    }
+
+    match = /^([0-9]+)\.([0-9]+)$/.exec(args[0]);
+
+    if (match === null) {
+      throwError(state, 'ill-formed argument of the YAML directive');
+    }
+
+    major = parseInt(match[1], 10);
+    minor = parseInt(match[2], 10);
+
+    if (major !== 1) {
+      throwError(state, 'unacceptable YAML version of the document');
+    }
+
+    state.version = args[0];
+    state.checkLineBreaks = (minor < 2);
+
+    if (minor !== 1 && minor !== 2) {
+      throwWarning(state, 'unsupported YAML version of the document');
+    }
+  },
+
+  TAG: function handleTagDirective(state, name, args) {
+
+    var handle, prefix;
+
+    if (args.length !== 2) {
+      throwError(state, 'TAG directive accepts exactly two arguments');
+    }
+
+    handle = args[0];
+    prefix = args[1];
+
+    if (!PATTERN_TAG_HANDLE.test(handle)) {
+      throwError(state, 'ill-formed tag handle (first argument) of the TAG directive');
+    }
+
+    if (_hasOwnProperty.call(state.tagMap, handle)) {
+      throwError(state, 'there is a previously declared suffix for "' + handle + '" tag handle');
+    }
+
+    if (!PATTERN_TAG_URI.test(prefix)) {
+      throwError(state, 'ill-formed tag prefix (second argument) of the TAG directive');
+    }
+
+    state.tagMap[handle] = prefix;
+  }
+};
+
+
+function captureSegment(state, start, end, checkJson) {
+  var _position, _length, _character, _result;
+
+  if (start < end) {
+    _result = state.input.slice(start, end);
+
+    if (checkJson) {
+      for (_position = 0, _length = _result.length;
+           _position < _length;
+           _position += 1) {
+        _character = _result.charCodeAt(_position);
+        if (!(_character === 0x09 ||
+              (0x20 <= _character && _character <= 0x10FFFF))) {
+          throwError(state, 'expected valid JSON character');
+        }
+      }
+    } else if (PATTERN_NON_PRINTABLE.test(_result)) {
+      throwError(state, 'the stream contains non-printable characters');
+    }
+
+    state.result += _result;
+  }
+}
+
+function mergeMappings(state, destination, source, overridableKeys) {
+  var sourceKeys, key, index, quantity;
+
+  if (!common.isObject(source)) {
+    throwError(state, 'cannot merge mappings; the provided source object is unacceptable');
+  }
+
+  sourceKeys = Object.keys(source);
+
+  for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) {
+    key = sourceKeys[index];
+
+    if (!_hasOwnProperty.call(destination, key)) {
+      destination[key] = source[key];
+      overridableKeys[key] = true;
+    }
+  }
+}
+
+function storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode) {
+  var index, quantity;
+
+  keyNode = String(keyNode);
+
+  if (_result === null) {
+    _result = {};
+  }
+
+  if (keyTag === 'tag:yaml.org,2002:merge') {
+    if (Array.isArray(valueNode)) {
+      for (index = 0, quantity = valueNode.length; index < quantity; index += 1) {
+        mergeMappings(state, _result, valueNode[index], overridableKeys);
+      }
+    } else {
+      mergeMappings(state, _result, valueNode, overridableKeys);
+    }
+  } else {
+    if (!state.json &&
+        !_hasOwnProperty.call(overridableKeys, keyNode) &&
+        _hasOwnProperty.call(_result, keyNode)) {
+      throwError(state, 'duplicated mapping key');
+    }
+    _result[keyNode] = valueNode;
+    delete overridableKeys[keyNode];
+  }
+
+  return _result;
+}
+
+function readLineBreak(state) {
+  var ch;
+
+  ch = state.input.charCodeAt(state.position);
+
+  if (ch === 0x0A/* LF */) {
+    state.position++;
+  } else if (ch === 0x0D/* CR */) {
+    state.position++;
+    if (state.input.charCodeAt(state.position) === 0x0A/* LF */) {
+      state.position++;
+    }
+  } else {
+    throwError(state, 'a line break is expected');
+  }
+
+  state.line += 1;
+  state.lineStart = state.position;
+}
+
+function skipSeparationSpace(state, allowComments, checkIndent) {
+  var lineBreaks = 0,
+      ch = state.input.charCodeAt(state.position);
+
+  while (ch !== 0) {
+    while (is_WHITE_SPACE(ch)) {
+      ch = state.input.charCodeAt(++state.position);
+    }
+
+    if (allowComments && ch === 0x23/* # */) {
+      do {
+        ch = state.input.charCodeAt(++state.position);
+      } while (ch !== 0x0A/* LF */ && ch !== 0x0D/* CR */ && ch !== 0);
+    }
+
+    if (is_EOL(ch)) {
+      readLineBreak(state);
+
+      ch = state.input.charCodeAt(state.position);
+      lineBreaks++;
+      state.lineIndent = 0;
+
+      while (ch === 0x20/* Space */) {
+        state.lineIndent++;
+        ch = state.input.charCodeAt(++state.position);
+      }
+    } else {
+      break;
+    }
+  }
+
+  if (checkIndent !== -1 && lineBreaks !== 0 && state.lineIndent < checkIndent) {
+    throwWarning(state, 'deficient indentation');
+  }
+
+  return lineBreaks;
+}
+
+function testDocumentSeparator(state) {
+  var _position = state.position,
+      ch;
+
+  ch = state.input.charCodeAt(_position);
+
+  // Condition state.position === state.lineStart is tested
+  // in parent on each call, for efficiency. No needs to test here again.
+  if ((ch === 0x2D/* - */ || ch === 0x2E/* . */) &&
+      ch === state.input.charCodeAt(_position + 1) &&
+      ch === state.input.charCodeAt(_position + 2)) {
+
+    _position += 3;
+
+    ch = state.input.charCodeAt(_position);
+
+    if (ch === 0 || is_WS_OR_EOL(ch)) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+function writeFoldedLines(state, count) {
+  if (count === 1) {
+    state.result += ' ';
+  } else if (count > 1) {
+    state.result += common.repeat('\n', count - 1);
+  }
+}
+
+
+function readPlainScalar(state, nodeIndent, withinFlowCollection) {
+  var preceding,
+      following,
+      captureStart,
+      captureEnd,
+      hasPendingContent,
+      _line,
+      _lineStart,
+      _lineIndent,
+      _kind = state.kind,
+      _result = state.result,
+      ch;
+
+  ch = state.input.charCodeAt(state.position);
+
+  if (is_WS_OR_EOL(ch)      ||
+      is_FLOW_INDICATOR(ch) ||
+      ch === 0x23/* # */    ||
+      ch === 0x26/* & */    ||
+      ch === 0x2A/* * */    ||
+      ch === 0x21/* ! */    ||
+      ch === 0x7C/* | */    ||
+      ch === 0x3E/* > */    ||
+      ch === 0x27/* ' */    ||
+      ch === 0x22/* " */    ||
+      ch === 0x25/* % */    ||
+      ch === 0x40/* @ */    ||
+      ch === 0x60/* ` */) {
+    return false;
+  }
+
+  if (ch === 0x3F/* ? */ || ch === 0x2D/* - */) {
+    following = state.input.charCodeAt(state.position + 1);
+
+    if (is_WS_OR_EOL(following) ||
+        withinFlowCollection && is_FLOW_INDICATOR(following)) {
+      return false;
+    }
+  }
+
+  state.kind = 'scalar';
+  state.result = '';
+  captureStart = captureEnd = state.position;
+  hasPendingContent = false;
+
+  while (ch !== 0) {
+    if (ch === 0x3A/* : */) {
+      following = state.input.charCodeAt(state.position + 1);
+
+      if (is_WS_OR_EOL(following) ||
+          withinFlowCollection && is_FLOW_INDICATOR(following)) {
+        break;
+      }
+
+    } else if (ch === 0x23/* # */) {
+      preceding = state.input.charCodeAt(state.position - 1);
+
+      if (is_WS_OR_EOL(preceding)) {
+        break;
+      }
+
+    } else if ((state.position === state.lineStart && testDocumentSeparator(state)) ||
+               withinFlowCollection && is_FLOW_INDICATOR(ch)) {
+      break;
+
+    } else if (is_EOL(ch)) {
+      _line = state.line;
+      _lineStart = state.lineStart;
+      _lineIndent = state.lineIndent;
+      skipSeparationSpace(state, false, -1);
+
+      if (state.lineIndent >= nodeIndent) {
+        hasPendingContent = true;
+        ch = state.input.charCodeAt(state.position);
+        continue;
+      } else {
+        state.position = captureEnd;
+        state.line = _line;
+        state.lineStart = _lineStart;
+        state.lineIndent = _lineIndent;
+        break;
+      }
+    }
+
+    if (hasPendingContent) {
+      captureSegment(state, captureStart, captureEnd, false);
+      writeFoldedLines(state, state.line - _line);
+      captureStart = captureEnd = state.position;
+      hasPendingContent = false;
+    }
+
+    if (!is_WHITE_SPACE(ch)) {
+      captureEnd = state.position + 1;
+    }
+
+    ch = state.input.charCodeAt(++state.position);
+  }
+
+  captureSegment(state, captureStart, captureEnd, false);
+
+  if (state.result) {
+    return true;
+  }
+
+  state.kind = _kind;
+  state.result = _result;
+  return false;
+}
+
+function readSingleQuotedScalar(state, nodeIndent) {
+  var ch,
+      captureStart, captureEnd;
+
+  ch = state.input.charCodeAt(state.position);
+
+  if (ch !== 0x27/* ' */) {
+    return false;
+  }
+
+  state.kind = 'scalar';
+  state.result = '';
+  state.position++;
+  captureStart = captureEnd = state.position;
+
+  while ((ch = state.input.charCodeAt(state.position)) !== 0) {
+    if (ch === 0x27/* ' */) {
+      captureSegment(state, captureStart, state.position, true);
+      ch = state.input.charCodeAt(++state.position);
+
+      if (ch === 0x27/* ' */) {
+        captureStart = captureEnd = state.position;
+        state.position++;
+      } else {
+        return true;
+      }
+
+    } else if (is_EOL(ch)) {
+      captureSegment(state, captureStart, captureEnd, true);
+      writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));
+      captureStart = captureEnd = state.position;
+
+    } else if (state.position === state.lineStart && testDocumentSeparator(state)) {
+      throwError(state, 'unexpected end of the document within a single quoted scalar');
+
+    } else {
+      state.position++;
+      captureEnd = state.position;
+    }
+  }
+
+  throwError(state, 'unexpected end of the stream within a single quoted scalar');
+}
+
+function readDoubleQuotedScalar(state, nodeIndent) {
+  var captureStart,
+      captureEnd,
+      hexLength,
+      hexResult,
+      tmp,
+      ch;
+
+  ch = state.input.charCodeAt(state.position);
+
+  if (ch !== 0x22/* " */) {
+    return false;
+  }
+
+  state.kind = 'scalar';
+  state.result = '';
+  state.position++;
+  captureStart = captureEnd = state.position;
+
+  while ((ch = state.input.charCodeAt(state.position)) !== 0) {
+    if (ch === 0x22/* " */) {
+      captureSegment(state, captureStart, state.position, true);
+      state.position++;
+      return true;
+
+    } else if (ch === 0x5C/* \ */) {
+      captureSegment(state, captureStart, state.position, true);
+      ch = state.input.charCodeAt(++state.position);
+
+      if (is_EOL(ch)) {
+        skipSeparationSpace(state, false, nodeIndent);
+
+        // TODO: rework to inline fn with no type cast?
+      } else if (ch < 256 && simpleEscapeCheck[ch]) {
+        state.result += simpleEscapeMap[ch];
+        state.position++;
+
+      } else if ((tmp = escapedHexLen(ch)) > 0) {
+        hexLength = tmp;
+        hexResult = 0;
+
+        for (; hexLength > 0; hexLength--) {
+          ch = state.input.charCodeAt(++state.position);
+
+          if ((tmp = fromHexCode(ch)) >= 0) {
+            hexResult = (hexResult << 4) + tmp;
+
+          } else {
+            throwError(state, 'expected hexadecimal character');
+          }
+        }
+
+        state.result += charFromCodepoint(hexResult);
+
+        state.position++;
+
+      } else {
+        throwError(state, 'unknown escape sequence');
+      }
+
+      captureStart = captureEnd = state.position;
+
+    } else if (is_EOL(ch)) {
+      captureSegment(state, captureStart, captureEnd, true);
+      writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));
+      captureStart = captureEnd = state.position;
+
+    } else if (state.position === state.lineStart && testDocumentSeparator(state)) {
+      throwError(state, 'unexpected end of the document within a double quoted scalar');
+
+    } else {
+      state.position++;
+      captureEnd = state.position;
+    }
+  }
+
+  throwError(state, 'unexpected end of the stream within a double quoted scalar');
+}
+
+function readFlowCollection(state, nodeIndent) {
+  var readNext = true,
+      _line,
+      _tag     = state.tag,
+      _result,
+      _anchor  = state.anchor,
+      following,
+      terminator,
+      isPair,
+      isExplicitPair,
+      isMapping,
+      overridableKeys = {},
+      keyNode,
+      keyTag,
+      valueNode,
+      ch;
+
+  ch = state.input.charCodeAt(state.position);
+
+  if (ch === 0x5B/* [ */) {
+    terminator = 0x5D;/* ] */
+    isMapping = false;
+    _result = [];
+  } else if (ch === 0x7B/* { */) {
+    terminator = 0x7D;/* } */
+    isMapping = true;
+    _result = {};
+  } else {
+    return false;
+  }
+
+  if (state.anchor !== null) {
+    state.anchorMap[state.anchor] = _result;
+  }
+
+  ch = state.input.charCodeAt(++state.position);
+
+  while (ch !== 0) {
+    skipSeparationSpace(state, true, nodeIndent);
+
+    ch = state.input.charCodeAt(state.position);
+
+    if (ch === terminator) {
+      state.position++;
+      state.tag = _tag;
+      state.anchor = _anchor;
+      state.kind = isMapping ? 'mapping' : 'sequence';
+      state.result = _result;
+      return true;
+    } else if (!readNext) {
+      throwError(state, 'missed comma between flow collection entries');
+    }
+
+    keyTag = keyNode = valueNode = null;
+    isPair = isExplicitPair = false;
+
+    if (ch === 0x3F/* ? */) {
+      following = state.input.charCodeAt(state.position + 1);
+
+      if (is_WS_OR_EOL(following)) {
+        isPair = isExplicitPair = true;
+        state.position++;
+        skipSeparationSpace(state, true, nodeIndent);
+      }
+    }
+
+    _line = state.line;
+    composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);
+    keyTag = state.tag;
+    keyNode = state.result;
+    skipSeparationSpace(state, true, nodeIndent);
+
+    ch = state.input.charCodeAt(state.position);
+
+    if ((isExplicitPair || state.line === _line) && ch === 0x3A/* : */) {
+      isPair = true;
+      ch = state.input.charCodeAt(++state.position);
+      skipSeparationSpace(state, true, nodeIndent);
+      composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);
+      valueNode = state.result;
+    }
+
+    if (isMapping) {
+      storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode);
+    } else if (isPair) {
+      _result.push(storeMappingPair(state, null, overridableKeys, keyTag, keyNode, valueNode));
+    } else {
+      _result.push(keyNode);
+    }
+
+    skipSeparationSpace(state, true, nodeIndent);
+
+    ch = state.input.charCodeAt(state.position);
+
+    if (ch === 0x2C/* , */) {
+      readNext = true;
+      ch = state.input.charCodeAt(++state.position);
+    } else {
+      readNext = false;
+    }
+  }
+
+  throwError(state, 'unexpected end of the stream within a flow collection');
+}
+
+function readBlockScalar(state, nodeIndent) {
+  var captureStart,
+      folding,
+      chomping       = CHOMPING_CLIP,
+      didReadContent = false,
+      detectedIndent = false,
+      textIndent     = nodeIndent,
+      emptyLines     = 0,
+      atMoreIndented = false,
+      tmp,
+      ch;
+
+  ch = state.input.charCodeAt(state.position);
+
+  if (ch === 0x7C/* | */) {
+    folding = false;
+  } else if (ch === 0x3E/* > */) {
+    folding = true;
+  } else {
+    return false;
+  }
+
+  state.kind = 'scalar';
+  state.result = '';
+
+  while (ch !== 0) {
+    ch = state.input.charCodeAt(++state.position);
+
+    if (ch === 0x2B/* + */ || ch === 0x2D/* - */) {
+      if (CHOMPING_CLIP === chomping) {
+        chomping = (ch === 0x2B/* + */) ? CHOMPING_KEEP : CHOMPING_STRIP;
+      } else {
+        throwError(state, 'repeat of a chomping mode identifier');
+      }
+
+    } else if ((tmp = fromDecimalCode(ch)) >= 0) {
+      if (tmp === 0) {
+        throwError(state, 'bad explicit indentation width of a block scalar; it cannot be less than one');
+      } else if (!detectedIndent) {
+        textIndent = nodeIndent + tmp - 1;
+        detectedIndent = true;
+      } else {
+        throwError(state, 'repeat of an indentation width identifier');
+      }
+
+    } else {
+      break;
+    }
+  }
+
+  if (is_WHITE_SPACE(ch)) {
+    do { ch = state.input.charCodeAt(++state.position); }
+    while (is_WHITE_SPACE(ch));
+
+    if (ch === 0x23/* # */) {
+      do { ch = state.input.charCodeAt(++state.position); }
+      while (!is_EOL(ch) && (ch !== 0));
+    }
+  }
+
+  while (ch !== 0) {
+    readLineBreak(state);
+    state.lineIndent = 0;
+
+    ch = state.input.charCodeAt(state.position);
+
+    while ((!detectedIndent || state.lineIndent < textIndent) &&
+           (ch === 0x20/* Space */)) {
+      state.lineIndent++;
+      ch = state.input.charCodeAt(++state.position);
+    }
+
+    if (!detectedIndent && state.lineIndent > textIndent) {
+      textIndent = state.lineIndent;
+    }
+
+    if (is_EOL(ch)) {
+      emptyLines++;
+      continue;
+    }
+
+    // End of the scalar.
+    if (state.lineIndent < textIndent) {
+
+      // Perform the chomping.
+      if (chomping === CHOMPING_KEEP) {
+        state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines);
+      } else if (chomping === CHOMPING_CLIP) {
+        if (didReadContent) { // i.e. only if the scalar is not empty.
+          state.result += '\n';
+        }
+      }
+
+      // Break this `while` cycle and go to the funciton's epilogue.
+      break;
+    }
+
+    // Folded style: use fancy rules to handle line breaks.
+    if (folding) {
+
+      // Lines starting with white space characters (more-indented lines) are not folded.
+      if (is_WHITE_SPACE(ch)) {
+        atMoreIndented = true;
+        // except for the first content line (cf. Example 8.1)
+        state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines);
+
+      // End of more-indented block.
+      } else if (atMoreIndented) {
+        atMoreIndented = false;
+        state.result += common.repeat('\n', emptyLines + 1);
+
+      // Just one line break - perceive as the same line.
+      } else if (emptyLines === 0) {
+        if (didReadContent) { // i.e. only if we have already read some scalar content.
+          state.result += ' ';
+        }
+
+      // Several line breaks - perceive as different lines.
+      } else {
+        state.result += common.repeat('\n', emptyLines);
+      }
+
+    // Literal style: just add exact number of line breaks between content lines.
+    } else {
+      // Keep all line breaks except the header line break.
+      state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines);
+    }
+
+    didReadContent = true;
+    detectedIndent = true;
+    emptyLines = 0;
+    captureStart = state.position;
+
+    while (!is_EOL(ch) && (ch !== 0)) {
+      ch = state.input.charCodeAt(++state.position);
+    }
+
+    captureSegment(state, captureStart, state.position, false);
+  }
+
+  return true;
+}
+
+function readBlockSequence(state, nodeIndent) {
+  var _line,
+      _tag      = state.tag,
+      _anchor   = state.anchor,
+      _result   = [],
+      following,
+      detected  = false,
+      ch;
+
+  if (state.anchor !== null) {
+    state.anchorMap[state.anchor] = _result;
+  }
+
+  ch = state.input.charCodeAt(state.position);
+
+  while (ch !== 0) {
+
+    if (ch !== 0x2D/* - */) {
+      break;
+    }
+
+    following = state.input.charCodeAt(state.position + 1);
+
+    if (!is_WS_OR_EOL(following)) {
+      break;
+    }
+
+    detected = true;
+    state.position++;
+
+    if (skipSeparationSpace(state, true, -1)) {
+      if (state.lineIndent <= nodeIndent) {
+        _result.push(null);
+        ch = state.input.charCodeAt(state.position);
+        continue;
+      }
+    }
+
+    _line = state.line;
+    composeNode(state, nodeIndent, CONTEXT_BLOCK_IN, false, true);
+    _result.push(state.result);
+    skipSeparationSpace(state, true, -1);
+
+    ch = state.input.charCodeAt(state.position);
+
+    if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) {
+      throwError(state, 'bad indentation of a sequence entry');
+    } else if (state.lineIndent < nodeIndent) {
+      break;
+    }
+  }
+
+  if (detected) {
+    state.tag = _tag;
+    state.anchor = _anchor;
+    state.kind = 'sequence';
+    state.result = _result;
+    return true;
+  }
+  return false;
+}
+
+function readBlockMapping(state, nodeIndent, flowIndent) {
+  var following,
+      allowCompact,
+      _line,
+      _tag          = state.tag,
+      _anchor       = state.anchor,
+      _result       = {},
+      overridableKeys = {},
+      keyTag        = null,
+      keyNode       = null,
+      valueNode     = null,
+      atExplicitKey = false,
+      detected      = false,
+      ch;
+
+  if (state.anchor !== null) {
+    state.anchorMap[state.anchor] = _result;
+  }
+
+  ch = state.input.charCodeAt(state.position);
+
+  while (ch !== 0) {
+    following = state.input.charCodeAt(state.position + 1);
+    _line = state.line; // Save the current line.
+
+    //
+    // Explicit notation case. There are two separate blocks:
+    // first for the key (denoted by "?") and second for the value (denoted by ":")
+    //
+    if ((ch === 0x3F/* ? */ || ch === 0x3A/* : */) && is_WS_OR_EOL(following)) {
+
+      if (ch === 0x3F/* ? */) {
+        if (atExplicitKey) {
+          storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null);
+          keyTag = keyNode = valueNode = null;
+        }
+
+        detected = true;
+        atExplicitKey = true;
+        allowCompact = true;
+
+      } else if (atExplicitKey) {
+        // i.e. 0x3A/* : */ === character after the explicit key.
+        atExplicitKey = false;
+        allowCompact = true;
+
+      } else {
+        throwError(state, 'incomplete explicit mapping pair; a key node is missed');
+      }
+
+      state.position += 1;
+      ch = following;
+
+    //
+    // Implicit notation case. Flow-style node as the key first, then ":", and the value.
+    //
+    } else if (composeNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true)) {
+
+      if (state.line === _line) {
+        ch = state.input.charCodeAt(state.position);
+
+        while (is_WHITE_SPACE(ch)) {
+          ch = state.input.charCodeAt(++state.position);
+        }
+
+        if (ch === 0x3A/* : */) {
+          ch = state.input.charCodeAt(++state.position);
+
+          if (!is_WS_OR_EOL(ch)) {
+            throwError(state, 'a whitespace character is expected after the key-value separator within a block mapping');
+          }
+
+          if (atExplicitKey) {
+            storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null);
+            keyTag = keyNode = valueNode = null;
+          }
+
+          detected = true;
+          atExplicitKey = false;
+          allowCompact = false;
+          keyTag = state.tag;
+          keyNode = state.result;
+
+        } else if (detected) {
+          throwError(state, 'can not read an implicit mapping pair; a colon is missed');
+
+        } else {
+          state.tag = _tag;
+          state.anchor = _anchor;
+          return true; // Keep the result of `composeNode`.
+        }
+
+      } else if (detected) {
+        throwError(state, 'can not read a block mapping entry; a multiline key may not be an implicit key');
+
+      } else {
+        state.tag = _tag;
+        state.anchor = _anchor;
+        return true; // Keep the result of `composeNode`.
+      }
+
+    } else {
+      break; // Reading is done. Go to the epilogue.
+    }
+
+    //
+    // Common reading code for both explicit and implicit notations.
+    //
+    if (state.line === _line || state.lineIndent > nodeIndent) {
+      if (composeNode(state, nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) {
+        if (atExplicitKey) {
+          keyNode = state.result;
+        } else {
+          valueNode = state.result;
+        }
+      }
+
+      if (!atExplicitKey) {
+        storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode);
+        keyTag = keyNode = valueNode = null;
+      }
+
+      skipSeparationSpace(state, true, -1);
+      ch = state.input.charCodeAt(state.position);
+    }
+
+    if (state.lineIndent > nodeIndent && (ch !== 0)) {
+      throwError(state, 'bad indentation of a mapping entry');
+    } else if (state.lineIndent < nodeIndent) {
+      break;
+    }
+  }
+
+  //
+  // Epilogue.
+  //
+
+  // Special case: last mapping's node contains only the key in explicit notation.
+  if (atExplicitKey) {
+    storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null);
+  }
+
+  // Expose the resulting mapping.
+  if (detected) {
+    state.tag = _tag;
+    state.anchor = _anchor;
+    state.kind = 'mapping';
+    state.result = _result;
+  }
+
+  return detected;
+}
+
+function readTagProperty(state) {
+  var _position,
+      isVerbatim = false,
+      isNamed    = false,
+      tagHandle,
+      tagName,
+      ch;
+
+  ch = state.input.charCodeAt(state.position);
+
+  if (ch !== 0x21/* ! */) return false;
+
+  if (state.tag !== null) {
+    throwError(state, 'duplication of a tag property');
+  }
+
+  ch = state.input.charCodeAt(++state.position);
+
+  if (ch === 0x3C/* < */) {
+    isVerbatim = true;
+    ch = state.input.charCodeAt(++state.position);
+
+  } else if (ch === 0x21/* ! */) {
+    isNamed = true;
+    tagHandle = '!!';
+    ch = state.input.charCodeAt(++state.position);
+
+  } else {
+    tagHandle = '!';
+  }
+
+  _position = state.position;
+
+  if (isVerbatim) {
+    do { ch = state.input.charCodeAt(++state.position); }
+    while (ch !== 0 && ch !== 0x3E/* > */);
+
+    if (state.position < state.length) {
+      tagName = state.input.slice(_position, state.position);
+      ch = state.input.charCodeAt(++state.position);
+    } else {
+      throwError(state, 'unexpected end of the stream within a verbatim tag');
+    }
+  } else {
+    while (ch !== 0 && !is_WS_OR_EOL(ch)) {
+
+      if (ch === 0x21/* ! */) {
+        if (!isNamed) {
+          tagHandle = state.input.slice(_position - 1, state.position + 1);
+
+          if (!PATTERN_TAG_HANDLE.test(tagHandle)) {
+            throwError(state, 'named tag handle cannot contain such characters');
+          }
+
+          isNamed = true;
+          _position = state.position + 1;
+        } else {
+          throwError(state, 'tag suffix cannot contain exclamation marks');
+        }
+      }
+
+      ch = state.input.charCodeAt(++state.position);
+    }
+
+    tagName = state.input.slice(_position, state.position);
+
+    if (PATTERN_FLOW_INDICATORS.test(tagName)) {
+      throwError(state, 'tag suffix cannot contain flow indicator characters');
+    }
+  }
+
+  if (tagName && !PATTERN_TAG_URI.test(tagName)) {
+    throwError(state, 'tag name cannot contain such characters: ' + tagName);
+  }
+
+  if (isVerbatim) {
+    state.tag = tagName;
+
+  } else if (_hasOwnProperty.call(state.tagMap, tagHandle)) {
+    state.tag = state.tagMap[tagHandle] + tagName;
+
+  } else if (tagHandle === '!') {
+    state.tag = '!' + tagName;
+
+  } else if (tagHandle === '!!') {
+    state.tag = 'tag:yaml.org,2002:' + tagName;
+
+  } else {
+    throwError(state, 'undeclared tag handle "' + tagHandle + '"');
+  }
+
+  return true;
+}
+
+function readAnchorProperty(state) {
+  var _position,
+      ch;
+
+  ch = state.input.charCodeAt(state.position);
+
+  if (ch !== 0x26/* & */) return false;
+
+  if (state.anchor !== null) {
+    throwError(state, 'duplication of an anchor property');
+  }
+
+  ch = state.input.charCodeAt(++state.position);
+  _position = state.position;
+
+  while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {
+    ch = state.input.charCodeAt(++state.position);
+  }
+
+  if (state.position === _position) {
+    throwError(state, 'name of an anchor node must contain at least one character');
+  }
+
+  state.anchor = state.input.slice(_position, state.position);
+  return true;
+}
+
+function readAlias(state) {
+  var _position, alias,
+      ch;
+
+  ch = state.input.charCodeAt(state.position);
+
+  if (ch !== 0x2A/* * */) return false;
+
+  ch = state.input.charCodeAt(++state.position);
+  _position = state.position;
+
+  while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {
+    ch = state.input.charCodeAt(++state.position);
+  }
+
+  if (state.position === _position) {
+    throwError(state, 'name of an alias node must contain at least one character');
+  }
+
+  alias = state.input.slice(_position, state.position);
+
+  if (!state.anchorMap.hasOwnProperty(alias)) {
+    throwError(state, 'unidentified alias "' + alias + '"');
+  }
+
+  state.result = state.anchorMap[alias];
+  skipSeparationSpace(state, true, -1);
+  return true;
+}
+
+function composeNode(state, parentIndent, nodeContext, allowToSeek, allowCompact) {
+  var allowBlockStyles,
+      allowBlockScalars,
+      allowBlockCollections,
+      indentStatus = 1, // 1: this>parent, 0: this=parent, -1: this<parent
+      atNewLine  = false,
+      hasContent = false,
+      typeIndex,
+      typeQuantity,
+      type,
+      flowIndent,
+      blockIndent;
+
+  if (state.listener !== null) {
+    state.listener('open', state);
+  }
+
+  state.tag    = null;
+  state.anchor = null;
+  state.kind   = null;
+  state.result = null;
+
+  allowBlockStyles = allowBlockScalars = allowBlockCollections =
+    CONTEXT_BLOCK_OUT === nodeContext ||
+    CONTEXT_BLOCK_IN  === nodeContext;
+
+  if (allowToSeek) {
+    if (skipSeparationSpace(state, true, -1)) {
+      atNewLine = true;
+
+      if (state.lineIndent > parentIndent) {
+        indentStatus = 1;
+      } else if (state.lineIndent === parentIndent) {
+        indentStatus = 0;
+      } else if (state.lineIndent < parentIndent) {
+        indentStatus = -1;
+      }
+    }
+  }
+
+  if (indentStatus === 1) {
+    while (readTagProperty(state) || readAnchorProperty(state)) {
+      if (skipSeparationSpace(state, true, -1)) {
+        atNewLine = true;
+        allowBlockCollections = allowBlockStyles;
+
+        if (state.lineIndent > parentIndent) {
+          indentStatus = 1;
+        } else if (state.lineIndent === parentIndent) {
+          indentStatus = 0;
+        } else if (state.lineIndent < parentIndent) {
+          indentStatus = -1;
+        }
+      } else {
+        allowBlockCollections = false;
+      }
+    }
+  }
+
+  if (allowBlockCollections) {
+    allowBlockCollections = atNewLine || allowCompact;
+  }
+
+  if (indentStatus === 1 || CONTEXT_BLOCK_OUT === nodeContext) {
+    if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) {
+      flowIndent = parentIndent;
+    } else {
+      flowIndent = parentIndent + 1;
+    }
+
+    blockIndent = state.position - state.lineStart;
+
+    if (indentStatus === 1) {
+      if (allowBlockCollections &&
+          (readBlockSequence(state, blockIndent) ||
+           readBlockMapping(state, blockIndent, flowIndent)) ||
+          readFlowCollection(state, flowIndent)) {
+        hasContent = true;
+      } else {
+        if ((allowBlockScalars && readBlockScalar(state, flowIndent)) ||
+            readSingleQuotedScalar(state, flowIndent) ||
+            readDoubleQuotedScalar(state, flowIndent)) {
+          hasContent = true;
+
+        } else if (readAlias(state)) {
+          hasContent = true;
+
+          if (state.tag !== null || state.anchor !== null) {
+            throwError(state, 'alias node should not have any properties');
+          }
+
+        } else if (readPlainScalar(state, flowIndent, CONTEXT_FLOW_IN === nodeContext)) {
+          hasContent = true;
+
+          if (state.tag === null) {
+            state.tag = '?';
+          }
+        }
+
+        if (state.anchor !== null) {
+          state.anchorMap[state.anchor] = state.result;
+        }
+      }
+    } else if (indentStatus === 0) {
+      // Special case: block sequences are allowed to have same indentation level as the parent.
+      // http://www.yaml.org/spec/1.2/spec.html#id2799784
+      hasContent = allowBlockCollections && readBlockSequence(state, blockIndent);
+    }
+  }
+
+  if (state.tag !== null && state.tag !== '!') {
+    if (state.tag === '?') {
+      for (typeIndex = 0, typeQuantity = state.implicitTypes.length;
+           typeIndex < typeQuantity;
+           typeIndex += 1) {
+        type = state.implicitTypes[typeIndex];
+
+        // Implicit resolving is not allowed for non-scalar types, and '?'
+        // non-specific tag is only assigned to plain scalars. So, it isn't
+        // needed to check for 'kind' conformity.
+
+        if (type.resolve(state.result)) { // `state.result` updated in resolver if matched
+          state.result = type.construct(state.result);
+          state.tag = type.tag;
+          if (state.anchor !== null) {
+            state.anchorMap[state.anchor] = state.result;
+          }
+          break;
+        }
+      }
+    } else if (_hasOwnProperty.call(state.typeMap, state.tag)) {
+      type = state.typeMap[state.tag];
+
+      if (state.result !== null && type.kind !== state.kind) {
+        throwError(state, 'unacceptable node kind for !<' + state.tag + '> tag; it should be "' + type.kind + '", not "' + state.kind + '"');
+      }
+
+      if (!type.resolve(state.result)) { // `state.result` updated in resolver if matched
+        throwError(state, 'cannot resolve a node with !<' + state.tag + '> explicit tag');
+      } else {
+        state.result = type.construct(state.result);
+        if (state.anchor !== null) {
+          state.anchorMap[state.anchor] = state.result;
+        }
+      }
+    } else {
+      throwError(state, 'unknown tag !<' + state.tag + '>');
+    }
+  }
+
+  if (state.listener !== null) {
+    state.listener('close', state);
+  }
+  return state.tag !== null ||  state.anchor !== null || hasContent;
+}
+
+function readDocument(state) {
+  var documentStart = state.position,
+      _position,
+      directiveName,
+      directiveArgs,
+      hasDirectives = false,
+      ch;
+
+  state.version = null;
+  state.checkLineBreaks = state.legacy;
+  state.tagMap = {};
+  state.anchorMap = {};
+
+  while ((ch = state.input.charCodeAt(state.position)) !== 0) {
+    skipSeparationSpace(state, true, -1);
+
+    ch = state.input.charCodeAt(state.position);
+
+    if (state.lineIndent > 0 || ch !== 0x25/* % */) {
+      break;
+    }
+
+    hasDirectives = true;
+    ch = state.input.charCodeAt(++state.position);
+    _position = state.position;
+
+    while (ch !== 0 && !is_WS_OR_EOL(ch)) {
+      ch = state.input.charCodeAt(++state.position);
+    }
+
+    directiveName = state.input.slice(_position, state.position);
+    directiveArgs = [];
+
+    if (directiveName.length < 1) {
+      throwError(state, 'directive name must not be less than one character in length');
+    }
+
+    while (ch !== 0) {
+      while (is_WHITE_SPACE(ch)) {
+        ch = state.input.charCodeAt(++state.position);
+      }
+
+      if (ch === 0x23/* # */) {
+        do { ch = state.input.charCodeAt(++state.position); }
+        while (ch !== 0 && !is_EOL(ch));
+        break;
+      }
+
+      if (is_EOL(ch)) break;
+
+      _position = state.position;
+
+      while (ch !== 0 && !is_WS_OR_EOL(ch)) {
+        ch = state.input.charCodeAt(++state.position);
+      }
+
+      directiveArgs.push(state.input.slice(_position, state.position));
+    }
+
+    if (ch !== 0) readLineBreak(state);
+
+    if (_hasOwnProperty.call(directiveHandlers, directiveName)) {
+      directiveHandlers[directiveName](state, directiveName, directiveArgs);
+    } else {
+      throwWarning(state, 'unknown document directive "' + directiveName + '"');
+    }
+  }
+
+  skipSeparationSpace(state, true, -1);
+
+  if (state.lineIndent === 0 &&
+      state.input.charCodeAt(state.position)     === 0x2D/* - */ &&
+      state.input.charCodeAt(state.position + 1) === 0x2D/* - */ &&
+      state.input.charCodeAt(state.position + 2) === 0x2D/* - */) {
+    state.position += 3;
+    skipSeparationSpace(state, true, -1);
+
+  } else if (hasDirectives) {
+    throwError(state, 'directives end mark is expected');
+  }
+
+  composeNode(state, state.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true);
+  skipSeparationSpace(state, true, -1);
+
+  if (state.checkLineBreaks &&
+      PATTERN_NON_ASCII_LINE_BREAKS.test(state.input.slice(documentStart, state.position))) {
+    throwWarning(state, 'non-ASCII line breaks are interpreted as content');
+  }
+
+  state.documents.push(state.result);
+
+  if (state.position === state.lineStart && testDocumentSeparator(state)) {
+
+    if (state.input.charCodeAt(state.position) === 0x2E/* . */) {
+      state.position += 3;
+      skipSeparationSpace(state, true, -1);
+    }
+    return;
+  }
+
+  if (state.position < (state.length - 1)) {
+    throwError(state, 'end of the stream or a document separator is expected');
+  } else {
+    return;
+  }
+}
+
+
+function loadDocuments(input, options) {
+  input = String(input);
+  options = options || {};
+
+  if (input.length !== 0) {
+
+    // Add tailing `\n` if not exists
+    if (input.charCodeAt(input.length - 1) !== 0x0A/* LF */ &&
+        input.charCodeAt(input.length - 1) !== 0x0D/* CR */) {
+      input += '\n';
+    }
+
+    // Strip BOM
+    if (input.charCodeAt(0) === 0xFEFF) {
+      input = input.slice(1);
+    }
+  }
+
+  var state = new State(input, options);
+
+  // Use 0 as string terminator. That significantly simplifies bounds check.
+  state.input += '\0';
+
+  while (state.input.charCodeAt(state.position) === 0x20/* Space */) {
+    state.lineIndent += 1;
+    state.position += 1;
+  }
+
+  while (state.position < (state.length - 1)) {
+    readDocument(state);
+  }
+
+  return state.documents;
+}
+
+
+function loadAll(input, iterator, options) {
+  var documents = loadDocuments(input, options), index, length;
+
+  for (index = 0, length = documents.length; index < length; index += 1) {
+    iterator(documents[index]);
+  }
+}
+
+
+function load(input, options) {
+  var documents = loadDocuments(input, options);
+
+  if (documents.length === 0) {
+    /*eslint-disable no-undefined*/
+    return undefined;
+  } else if (documents.length === 1) {
+    return documents[0];
+  }
+  throw new YAMLException('expected a single document in the stream, but found more');
+}
+
+
+function safeLoadAll(input, output, options) {
+  loadAll(input, output, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options));
+}
+
+
+function safeLoad(input, options) {
+  return load(input, common.extend({ schema: DEFAULT_SAFE_SCHEMA }, options));
+}
+
+
+module.exports.loadAll     = loadAll;
+module.exports.load        = load;
+module.exports.safeLoadAll = safeLoadAll;
+module.exports.safeLoad    = safeLoad;
+
+},{"./common":21,"./exception":23,"./mark":25,"./schema/default_full":28,"./schema/default_safe":29}],25:[function(require,module,exports){
+'use strict';
+
+
+var common = require('./common');
+
+
+function Mark(name, buffer, position, line, column) {
+  this.name     = name;
+  this.buffer   = buffer;
+  this.position = position;
+  this.line     = line;
+  this.column   = column;
+}
+
+
+Mark.prototype.getSnippet = function getSnippet(indent, maxLength) {
+  var head, start, tail, end, snippet;
+
+  if (!this.buffer) return null;
+
+  indent = indent || 4;
+  maxLength = maxLength || 75;
+
+  head = '';
+  start = this.position;
+
+  while (start > 0 && '\x00\r\n\x85\u2028\u2029'.indexOf(this.buffer.charAt(start - 1)) === -1) {
+    start -= 1;
+    if (this.position - start > (maxLength / 2 - 1)) {
+      head = ' ... ';
+      start += 5;
+      break;
+    }
+  }
+
+  tail = '';
+  end = this.position;
+
+  while (end < this.buffer.length && '\x00\r\n\x85\u2028\u2029'.indexOf(this.buffer.charAt(end)) === -1) {
+    end += 1;
+    if (end - this.position > (maxLength / 2 - 1)) {
+      tail = ' ... ';
+      end -= 5;
+      break;
+    }
+  }
+
+  snippet = this.buffer.slice(start, end);
+
+  return common.repeat(' ', indent) + head + snippet + tail + '\n' +
+         common.repeat(' ', indent + this.position - start + head.length) + '^';
+};
+
+
+Mark.prototype.toString = function toString(compact) {
+  var snippet, where = '';
+
+  if (this.name) {
+    where += 'in "' + this.name + '" ';
+  }
+
+  where += 'at line ' + (this.line + 1) + ', column ' + (this.column + 1);
+
+  if (!compact) {
+    snippet = this.getSnippet();
+
+    if (snippet) {
+      where += ':\n' + snippet;
+    }
+  }
+
+  return where;
+};
+
+
+module.exports = Mark;
+
+},{"./common":21}],26:[function(require,module,exports){
+'use strict';
+
+/*eslint-disable max-len*/
+
+var common        = require('./common');
+var YAMLException = require('./exception');
+var Type          = require('./type');
+
+
+function compileList(schema, name, result) {
+  var exclude = [];
+
+  schema.include.forEach(function (includedSchema) {
+    result = compileList(includedSchema, name, result);
+  });
+
+  schema[name].forEach(function (currentType) {
+    result.forEach(function (previousType, previousIndex) {
+      if (previousType.tag === currentType.tag) {
+        exclude.push(previousIndex);
+      }
+    });
+
+    result.push(currentType);
+  });
+
+  return result.filter(function (type, index) {
+    return exclude.indexOf(index) === -1;
+  });
+}
+
+
+function compileMap(/* lists... */) {
+  var result = {}, index, length;
+
+  function collectType(type) {
+    result[type.tag] = type;
+  }
+
+  for (index = 0, length = arguments.length; index < length; index += 1) {
+    arguments[index].forEach(collectType);
+  }
+
+  return result;
+}
+
+
+function Schema(definition) {
+  this.include  = definition.include  || [];
+  this.implicit = definition.implicit || [];
+  this.explicit = definition.explicit || [];
+
+  this.implicit.forEach(function (type) {
+    if (type.loadKind && type.loadKind !== 'scalar') {
+      throw new YAMLException('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.');
+    }
+  });
+
+  this.compiledImplicit = compileList(this, 'implicit', []);
+  this.compiledExplicit = compileList(this, 'explicit', []);
+  this.compiledTypeMap  = compileMap(this.compiledImplicit, this.compiledExplicit);
+}
+
+
+Schema.DEFAULT = null;
+
+
+Schema.create = function createSchema() {
+  var schemas, types;
+
+  switch (arguments.length) {
+    case 1:
+      schemas = Schema.DEFAULT;
+      types = arguments[0];
+      break;
+
+    case 2:
+      schemas = arguments[0];
+      types = arguments[1];
+      break;
+
+    default:
+      throw new YAMLException('Wrong number of arguments for Schema.create function');
+  }
+
+  schemas = common.toArray(schemas);
+  types = common.toArray(types);
+
+  if (!schemas.every(function (schema) { return schema instanceof Schema; })) {
+    throw new YAMLException('Specified list of super schemas (or a single Schema object) contains a non-Schema object.');
+  }
+
+  if (!types.every(function (type) { return type instanceof Type; })) {
+    throw new YAMLException('Specified list of YAML types (or a single Type object) contains a non-Type object.');
+  }
+
+  return new Schema({
+    include: schemas,
+    explicit: types
+  });
+};
+
+
+module.exports = Schema;
+
+},{"./common":21,"./exception":23,"./type":32}],27:[function(require,module,exports){
+// Standard YAML's Core schema.
+// http://www.yaml.org/spec/1.2/spec.html#id2804923
+//
+// NOTE: JS-YAML does not support schema-specific tag resolution restrictions.
+// So, Core schema has no distinctions from JSON schema is JS-YAML.
+
+
+'use strict';
+
+
+var Schema = require('../schema');
+
+
+module.exports = new Schema({
+  include: [
+    require('./json')
+  ]
+});
+
+},{"../schema":26,"./json":31}],28:[function(require,module,exports){
+// JS-YAML's default schema for `load` function.
+// It is not described in the YAML specification.
+//
+// This schema is based on JS-YAML's default safe schema and includes
+// JavaScript-specific types: !!js/undefined, !!js/regexp and !!js/function.
+//
+// Also this schema is used as default base schema at `Schema.create` function.
+
+
+'use strict';
+
+
+var Schema = require('../schema');
+
+
+module.exports = Schema.DEFAULT = new Schema({
+  include: [
+    require('./default_safe')
+  ],
+  explicit: [
+    require('../type/js/undefined'),
+    require('../type/js/regexp'),
+    require('../type/js/function')
+  ]
+});
+
+},{"../schema":26,"../type/js/function":37,"../type/js/regexp":38,"../type/js/undefined":39,"./default_safe":29}],29:[function(require,module,exports){
+// JS-YAML's default schema for `safeLoad` function.
+// It is not described in the YAML specification.
+//
+// This schema is based on standard YAML's Core schema and includes most of
+// extra types described at YAML tag repository. (http://yaml.org/type/)
+
+
+'use strict';
+
+
+var Schema = require('../schema');
+
+
+module.exports = new Schema({
+  include: [
+    require('./core')
+  ],
+  implicit: [
+    require('../type/timestamp'),
+    require('../type/merge')
+  ],
+  explicit: [
+    require('../type/binary'),
+    require('../type/omap'),
+    require('../type/pairs'),
+    require('../type/set')
+  ]
+});
+
+},{"../schema":26,"../type/binary":33,"../type/merge":41,"../type/omap":43,"../type/pairs":44,"../type/set":46,"../type/timestamp":48,"./core":27}],30:[function(require,module,exports){
+// Standard YAML's Failsafe schema.
+// http://www.yaml.org/spec/1.2/spec.html#id2802346
+
+
+'use strict';
+
+
+var Schema = require('../schema');
+
+
+module.exports = new Schema({
+  explicit: [
+    require('../type/str'),
+    require('../type/seq'),
+    require('../type/map')
+  ]
+});
+
+},{"../schema":26,"../type/map":40,"../type/seq":45,"../type/str":47}],31:[function(require,module,exports){
+// Standard YAML's JSON schema.
+// http://www.yaml.org/spec/1.2/spec.html#id2803231
+//
+// NOTE: JS-YAML does not support schema-specific tag resolution restrictions.
+// So, this schema is not such strict as defined in the YAML specification.
+// It allows numbers in binary notaion, use `Null` and `NULL` as `null`, etc.
+
+
+'use strict';
+
+
+var Schema = require('../schema');
+
+
+module.exports = new Schema({
+  include: [
+    require('./failsafe')
+  ],
+  implicit: [
+    require('../type/null'),
+    require('../type/bool'),
+    require('../type/int'),
+    require('../type/float')
+  ]
+});
+
+},{"../schema":26,"../type/bool":34,"../type/float":35,"../type/int":36,"../type/null":42,"./failsafe":30}],32:[function(require,module,exports){
+'use strict';
+
+var YAMLException = require('./exception');
+
+var TYPE_CONSTRUCTOR_OPTIONS = [
+  'kind',
+  'resolve',
+  'construct',
+  'instanceOf',
+  'predicate',
+  'represent',
+  'defaultStyle',
+  'styleAliases'
+];
+
+var YAML_NODE_KINDS = [
+  'scalar',
+  'sequence',
+  'mapping'
+];
+
+function compileStyleAliases(map) {
+  var result = {};
+
+  if (map !== null) {
+    Object.keys(map).forEach(function (style) {
+      map[style].forEach(function (alias) {
+        result[String(alias)] = style;
+      });
+    });
+  }
+
+  return result;
+}
+
+function Type(tag, options) {
+  options = options || {};
+
+  Object.keys(options).forEach(function (name) {
+    if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) {
+      throw new YAMLException('Unknown option "' + name + '" is met in definition of "' + tag + '" YAML type.');
+    }
+  });
+
+  // TODO: Add tag format check.
+  this.tag          = tag;
+  this.kind         = options['kind']         || null;
+  this.resolve      = options['resolve']      || function () { return true; };
+  this.construct    = options['construct']    || function (data) { return data; };
+  this.instanceOf   = options['instanceOf']   || null;
+  this.predicate    = options['predicate']    || null;
+  this.represent    = options['represent']    || null;
+  this.defaultStyle = options['defaultStyle'] || null;
+  this.styleAliases = compileStyleAliases(options['styleAliases'] || null);
+
+  if (YAML_NODE_KINDS.indexOf(this.kind) === -1) {
+    throw new YAMLException('Unknown kind "' + this.kind + '" is specified for "' + tag + '" YAML type.');
+  }
+}
+
+module.exports = Type;
+
+},{"./exception":23}],33:[function(require,module,exports){
+'use strict';
+
+/*eslint-disable no-bitwise*/
+
+var NodeBuffer;
+
+try {
+  // A trick for browserified version, to not include `Buffer` shim
+  var _require = require;
+  NodeBuffer = _require('buffer').Buffer;
+} catch (__) {}
+
+var Type       = require('../type');
+
+
+// [ 64, 65, 66 ] -> [ padding, CR, LF ]
+var BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r';
+
+
+function resolveYamlBinary(data) {
+  if (data === null) return false;
+
+  var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP;
+
+  // Convert one by one.
+  for (idx = 0; idx < max; idx++) {
+    code = map.indexOf(data.charAt(idx));
+
+    // Skip CR/LF
+    if (code > 64) continue;
+
+    // Fail on illegal characters
+    if (code < 0) return false;
+
+    bitlen += 6;
+  }
+
+  // If there are any bits left, source was corrupted
+  return (bitlen % 8) === 0;
+}
+
+function constructYamlBinary(data) {
+  var idx, tailbits,
+      input = data.replace(/[\r\n=]/g, ''), // remove CR/LF & padding to simplify scan
+      max = input.length,
+      map = BASE64_MAP,
+      bits = 0,
+      result = [];
+
+  // Collect by 6*4 bits (3 bytes)
+
+  for (idx = 0; idx < max; idx++) {
+    if ((idx % 4 === 0) && idx) {
+      result.push((bits >> 16) & 0xFF);
+      result.push((bits >> 8) & 0xFF);
+      result.push(bits & 0xFF);
+    }
+
+    bits = (bits << 6) | map.indexOf(input.charAt(idx));
+  }
+
+  // Dump tail
+
+  tailbits = (max % 4) * 6;
+
+  if (tailbits === 0) {
+    result.push((bits >> 16) & 0xFF);
+    result.push((bits >> 8) & 0xFF);
+    result.push(bits & 0xFF);
+  } else if (tailbits === 18) {
+    result.push((bits >> 10) & 0xFF);
+    result.push((bits >> 2) & 0xFF);
+  } else if (tailbits === 12) {
+    result.push((bits >> 4) & 0xFF);
+  }
+
+  // Wrap into Buffer for NodeJS and leave Array for browser
+  if (NodeBuffer) return new NodeBuffer(result);
+
+  return result;
+}
+
+function representYamlBinary(object /*, style*/) {
+  var result = '', bits = 0, idx, tail,
+      max = object.length,
+      map = BASE64_MAP;
+
+  // Convert every three bytes to 4 ASCII characters.
+
+  for (idx = 0; idx < max; idx++) {
+    if ((idx % 3 === 0) && idx) {
+      result += map[(bits >> 18) & 0x3F];
+      result += map[(bits >> 12) & 0x3F];
+      result += map[(bits >> 6) & 0x3F];
+      result += map[bits & 0x3F];
+    }
+
+    bits = (bits << 8) + object[idx];
+  }
+
+  // Dump tail
+
+  tail = max % 3;
+
+  if (tail === 0) {
+    result += map[(bits >> 18) & 0x3F];
+    result += map[(bits >> 12) & 0x3F];
+    result += map[(bits >> 6) & 0x3F];
+    result += map[bits & 0x3F];
+  } else if (tail === 2) {
+    result += map[(bits >> 10) & 0x3F];
+    result += map[(bits >> 4) & 0x3F];
+    result += map[(bits << 2) & 0x3F];
+    result += map[64];
+  } else if (tail === 1) {
+    result += map[(bits >> 2) & 0x3F];
+    result += map[(bits << 4) & 0x3F];
+    result += map[64];
+    result += map[64];
+  }
+
+  return result;
+}
+
+function isBinary(object) {
+  return NodeBuffer && NodeBuffer.isBuffer(object);
+}
+
+module.exports = new Type('tag:yaml.org,2002:binary', {
+  kind: 'scalar',
+  resolve: resolveYamlBinary,
+  construct: constructYamlBinary,
+  predicate: isBinary,
+  represent: representYamlBinary
+});
+
+},{"../type":32}],34:[function(require,module,exports){
+'use strict';
+
+var Type = require('../type');
+
+function resolveYamlBoolean(data) {
+  if (data === null) return false;
+
+  var max = data.length;
+
+  return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) ||
+         (max === 5 && (data === 'false' || data === 'False' || data === 'FALSE'));
+}
+
+function constructYamlBoolean(data) {
+  return data === 'true' ||
+         data === 'True' ||
+         data === 'TRUE';
+}
+
+function isBoolean(object) {
+  return Object.prototype.toString.call(object) === '[object Boolean]';
+}
+
+module.exports = new Type('tag:yaml.org,2002:bool', {
+  kind: 'scalar',
+  resolve: resolveYamlBoolean,
+  construct: constructYamlBoolean,
+  predicate: isBoolean,
+  represent: {
+    lowercase: function (object) { return object ? 'true' : 'false'; },
+    uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; },
+    camelcase: function (object) { return object ? 'True' : 'False'; }
+  },
+  defaultStyle: 'lowercase'
+});
+
+},{"../type":32}],35:[function(require,module,exports){
+'use strict';
+
+var common = require('../common');
+var Type   = require('../type');
+
+var YAML_FLOAT_PATTERN = new RegExp(
+  '^(?:[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+][0-9]+)?' +
+  '|\\.[0-9_]+(?:[eE][-+][0-9]+)?' +
+  '|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*' +
+  '|[-+]?\\.(?:inf|Inf|INF)' +
+  '|\\.(?:nan|NaN|NAN))$');
+
+function resolveYamlFloat(data) {
+  if (data === null) return false;
+
+  if (!YAML_FLOAT_PATTERN.test(data)) return false;
+
+  return true;
+}
+
+function constructYamlFloat(data) {
+  var value, sign, base, digits;
+
+  value  = data.replace(/_/g, '').toLowerCase();
+  sign   = value[0] === '-' ? -1 : 1;
+  digits = [];
+
+  if ('+-'.indexOf(value[0]) >= 0) {
+    value = value.slice(1);
+  }
+
+  if (value === '.inf') {
+    return (sign === 1) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
+
+  } else if (value === '.nan') {
+    return NaN;
+
+  } else if (value.indexOf(':') >= 0) {
+    value.split(':').forEach(function (v) {
+      digits.unshift(parseFloat(v, 10));
+    });
+
+    value = 0.0;
+    base = 1;
+
+    digits.forEach(function (d) {
+      value += d * base;
+      base *= 60;
+    });
+
+    return sign * value;
+
+  }
+  return sign * parseFloat(value, 10);
+}
+
+
+var SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/;
+
+function representYamlFloat(object, style) {
+  var res;
+
+  if (isNaN(object)) {
+    switch (style) {
+      case 'lowercase': return '.nan';
+      case 'uppercase': return '.NAN';
+      case 'camelcase': return '.NaN';
+    }
+  } else if (Number.POSITIVE_INFINITY === object) {
+    switch (style) {
+      case 'lowercase': return '.inf';
+      case 'uppercase': return '.INF';
+      case 'camelcase': return '.Inf';
+    }
+  } else if (Number.NEGATIVE_INFINITY === object) {
+    switch (style) {
+      case 'lowercase': return '-.inf';
+      case 'uppercase': return '-.INF';
+      case 'camelcase': return '-.Inf';
+    }
+  } else if (common.isNegativeZero(object)) {
+    return '-0.0';
+  }
+
+  res = object.toString(10);
+
+  // JS stringifier can build scientific format without dots: 5e-100,
+  // while YAML requres dot: 5.e-100. Fix it with simple hack
+
+  return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace('e', '.e') : res;
+}
+
+function isFloat(object) {
+  return (Object.prototype.toString.call(object) === '[object Number]') &&
+         (object % 1 !== 0 || common.isNegativeZero(object));
+}
+
+module.exports = new Type('tag:yaml.org,2002:float', {
+  kind: 'scalar',
+  resolve: resolveYamlFloat,
+  construct: constructYamlFloat,
+  predicate: isFloat,
+  represent: representYamlFloat,
+  defaultStyle: 'lowercase'
+});
+
+},{"../common":21,"../type":32}],36:[function(require,module,exports){
+'use strict';
+
+var common = require('../common');
+var Type   = require('../type');
+
+function isHexCode(c) {
+  return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) ||
+         ((0x41/* A */ <= c) && (c <= 0x46/* F */)) ||
+         ((0x61/* a */ <= c) && (c <= 0x66/* f */));
+}
+
+function isOctCode(c) {
+  return ((0x30/* 0 */ <= c) && (c <= 0x37/* 7 */));
+}
+
+function isDecCode(c) {
+  return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */));
+}
+
+function resolveYamlInteger(data) {
+  if (data === null) return false;
+
+  var max = data.length,
+      index = 0,
+      hasDigits = false,
+      ch;
+
+  if (!max) return false;
+
+  ch = data[index];
+
+  // sign
+  if (ch === '-' || ch === '+') {
+    ch = data[++index];
+  }
+
+  if (ch === '0') {
+    // 0
+    if (index + 1 === max) return true;
+    ch = data[++index];
+
+    // base 2, base 8, base 16
+
+    if (ch === 'b') {
+      // base 2
+      index++;
+
+      for (; index < max; index++) {
+        ch = data[index];
+        if (ch === '_') continue;
+        if (ch !== '0' && ch !== '1') return false;
+        hasDigits = true;
+      }
+      return hasDigits;
+    }
+
+
+    if (ch === 'x') {
+      // base 16
+      index++;
+
+      for (; index < max; index++) {
+        ch = data[index];
+        if (ch === '_') continue;
+        if (!isHexCode(data.charCodeAt(index))) return false;
+        hasDigits = true;
+      }
+      return hasDigits;
+    }
+
+    // base 8
+    for (; index < max; index++) {
+      ch = data[index];
+      if (ch === '_') continue;
+      if (!isOctCode(data.charCodeAt(index))) return false;
+      hasDigits = true;
+    }
+    return hasDigits;
+  }
+
+  // base 10 (except 0) or base 60
+
+  for (; index < max; index++) {
+    ch = data[index];
+    if (ch === '_') continue;
+    if (ch === ':') break;
+    if (!isDecCode(data.charCodeAt(index))) {
+      return false;
+    }
+    hasDigits = true;
+  }
+
+  if (!hasDigits) return false;
+
+  // if !base60 - done;
+  if (ch !== ':') return true;
+
+  // base60 almost not used, no needs to optimize
+  return /^(:[0-5]?[0-9])+$/.test(data.slice(index));
+}
+
+function constructYamlInteger(data) {
+  var value = data, sign = 1, ch, base, digits = [];
+
+  if (value.indexOf('_') !== -1) {
+    value = value.replace(/_/g, '');
+  }
+
+  ch = value[0];
+
+  if (ch === '-' || ch === '+') {
+    if (ch === '-') sign = -1;
+    value = value.slice(1);
+    ch = value[0];
+  }
+
+  if (value === '0') return 0;
+
+  if (ch === '0') {
+    if (value[1] === 'b') return sign * parseInt(value.slice(2), 2);
+    if (value[1] === 'x') return sign * parseInt(value, 16);
+    return sign * parseInt(value, 8);
+  }
+
+  if (value.indexOf(':') !== -1) {
+    value.split(':').forEach(function (v) {
+      digits.unshift(parseInt(v, 10));
+    });
+
+    value = 0;
+    base = 1;
+
+    digits.forEach(function (d) {
+      value += (d * base);
+      base *= 60;
+    });
+
+    return sign * value;
+
+  }
+
+  return sign * parseInt(value, 10);
+}
+
+function isInteger(object) {
+  return (Object.prototype.toString.call(object)) === '[object Number]' &&
+         (object % 1 === 0 && !common.isNegativeZero(object));
+}
+
+module.exports = new Type('tag:yaml.org,2002:int', {
+  kind: 'scalar',
+  resolve: resolveYamlInteger,
+  construct: constructYamlInteger,
+  predicate: isInteger,
+  represent: {
+    binary:      function (object) { return '0b' + object.toString(2); },
+    octal:       function (object) { return '0'  + object.toString(8); },
+    decimal:     function (object) { return        object.toString(10); },
+    hexadecimal: function (object) { return '0x' + object.toString(16).toUpperCase(); }
+  },
+  defaultStyle: 'decimal',
+  styleAliases: {
+    binary:      [ 2,  'bin' ],
+    octal:       [ 8,  'oct' ],
+    decimal:     [ 10, 'dec' ],
+    hexadecimal: [ 16, 'hex' ]
+  }
+});
+
+},{"../common":21,"../type":32}],37:[function(require,module,exports){
+'use strict';
+
+var esprima;
+
+// Browserified version does not have esprima
+//
+// 1. For node.js just require module as deps
+// 2. For browser try to require mudule via external AMD system.
+//    If not found - try to fallback to window.esprima. If not
+//    found too - then fail to parse.
+//
+try {
+  // workaround to exclude package from browserify list.
+  var _require = require;
+  esprima = _require('esprima');
+} catch (_) {
+  /*global window */
+  if (typeof window !== 'undefined') esprima = window.esprima;
+}
+
+var Type = require('../../type');
+
+function resolveJavascriptFunction(data) {
+  if (data === null) return false;
+
+  try {
+    var source = '(' + data + ')',
+        ast    = esprima.parse(source, { range: true });
+
+    if (ast.type                    !== 'Program'             ||
+        ast.body.length             !== 1                     ||
+        ast.body[0].type            !== 'ExpressionStatement' ||
+        ast.body[0].expression.type !== 'FunctionExpression') {
+      return false;
+    }
+
+    return true;
+  } catch (err) {
+    return false;
+  }
+}
+
+function constructJavascriptFunction(data) {
+  /*jslint evil:true*/
+
+  var source = '(' + data + ')',
+      ast    = esprima.parse(source, { range: true }),
+      params = [],
+      body;
+
+  if (ast.type                    !== 'Program'             ||
+      ast.body.length             !== 1                     ||
+      ast.body[0].type            !== 'ExpressionStatement' ||
+      ast.body[0].expression.type !== 'FunctionExpression') {
+    throw new Error('Failed to resolve function');
+  }
+
+  ast.body[0].expression.params.forEach(function (param) {
+    params.push(param.name);
+  });
+
+  body = ast.body[0].expression.body.range;
+
+  // Esprima's ranges include the first '{' and the last '}' characters on
+  // function expressions. So cut them out.
+  /*eslint-disable no-new-func*/
+  return new Function(params, source.slice(body[0] + 1, body[1] - 1));
+}
+
+function representJavascriptFunction(object /*, style*/) {
+  return object.toString();
+}
+
+function isFunction(object) {
+  return Object.prototype.toString.call(object) === '[object Function]';
+}
+
+module.exports = new Type('tag:yaml.org,2002:js/function', {
+  kind: 'scalar',
+  resolve: resolveJavascriptFunction,
+  construct: constructJavascriptFunction,
+  predicate: isFunction,
+  represent: representJavascriptFunction
+});
+
+},{"../../type":32}],38:[function(require,module,exports){
+'use strict';
+
+var Type = require('../../type');
+
+function resolveJavascriptRegExp(data) {
+  if (data === null) return false;
+  if (data.length === 0) return false;
+
+  var regexp = data,
+      tail   = /\/([gim]*)$/.exec(data),
+      modifiers = '';
+
+  // if regexp starts with '/' it can have modifiers and must be properly closed
+  // `/foo/gim` - modifiers tail can be maximum 3 chars
+  if (regexp[0] === '/') {
+    if (tail) modifiers = tail[1];
+
+    if (modifiers.length > 3) return false;
+    // if expression starts with /, is should be properly terminated
+    if (regexp[regexp.length - modifiers.length - 1] !== '/') return false;
+  }
+
+  return true;
+}
+
+function constructJavascriptRegExp(data) {
+  var regexp = data,
+      tail   = /\/([gim]*)$/.exec(data),
+      modifiers = '';
+
+  // `/foo/gim` - tail can be maximum 4 chars
+  if (regexp[0] === '/') {
+    if (tail) modifiers = tail[1];
+    regexp = regexp.slice(1, regexp.length - modifiers.length - 1);
+  }
+
+  return new RegExp(regexp, modifiers);
+}
+
+function representJavascriptRegExp(object /*, style*/) {
+  var result = '/' + object.source + '/';
+
+  if (object.global) result += 'g';
+  if (object.multiline) result += 'm';
+  if (object.ignoreCase) result += 'i';
+
+  return result;
+}
+
+function isRegExp(object) {
+  return Object.prototype.toString.call(object) === '[object RegExp]';
+}
+
+module.exports = new Type('tag:yaml.org,2002:js/regexp', {
+  kind: 'scalar',
+  resolve: resolveJavascriptRegExp,
+  construct: constructJavascriptRegExp,
+  predicate: isRegExp,
+  represent: representJavascriptRegExp
+});
+
+},{"../../type":32}],39:[function(require,module,exports){
+'use strict';
+
+var Type = require('../../type');
+
+function resolveJavascriptUndefined() {
+  return true;
+}
+
+function constructJavascriptUndefined() {
+  /*eslint-disable no-undefined*/
+  return undefined;
+}
+
+function representJavascriptUndefined() {
+  return '';
+}
+
+function isUndefined(object) {
+  return typeof object === 'undefined';
+}
+
+module.exports = new Type('tag:yaml.org,2002:js/undefined', {
+  kind: 'scalar',
+  resolve: resolveJavascriptUndefined,
+  construct: constructJavascriptUndefined,
+  predicate: isUndefined,
+  represent: representJavascriptUndefined
+});
+
+},{"../../type":32}],40:[function(require,module,exports){
+'use strict';
+
+var Type = require('../type');
+
+module.exports = new Type('tag:yaml.org,2002:map', {
+  kind: 'mapping',
+  construct: function (data) { return data !== null ? data : {}; }
+});
+
+},{"../type":32}],41:[function(require,module,exports){
+'use strict';
+
+var Type = require('../type');
+
+function resolveYamlMerge(data) {
+  return data === '<<' || data === null;
+}
+
+module.exports = new Type('tag:yaml.org,2002:merge', {
+  kind: 'scalar',
+  resolve: resolveYamlMerge
+});
+
+},{"../type":32}],42:[function(require,module,exports){
+'use strict';
+
+var Type = require('../type');
+
+function resolveYamlNull(data) {
+  if (data === null) return true;
+
+  var max = data.length;
+
+  return (max === 1 && data === '~') ||
+         (max === 4 && (data === 'null' || data === 'Null' || data === 'NULL'));
+}
+
+function constructYamlNull() {
+  return null;
+}
+
+function isNull(object) {
+  return object === null;
+}
+
+module.exports = new Type('tag:yaml.org,2002:null', {
+  kind: 'scalar',
+  resolve: resolveYamlNull,
+  construct: constructYamlNull,
+  predicate: isNull,
+  represent: {
+    canonical: function () { return '~';    },
+    lowercase: function () { return 'null'; },
+    uppercase: function () { return 'NULL'; },
+    camelcase: function () { return 'Null'; }
+  },
+  defaultStyle: 'lowercase'
+});
+
+},{"../type":32}],43:[function(require,module,exports){
+'use strict';
+
+var Type = require('../type');
+
+var _hasOwnProperty = Object.prototype.hasOwnProperty;
+var _toString       = Object.prototype.toString;
+
+function resolveYamlOmap(data) {
+  if (data === null) return true;
+
+  var objectKeys = [], index, length, pair, pairKey, pairHasKey,
+      object = data;
+
+  for (index = 0, length = object.length; index < length; index += 1) {
+    pair = object[index];
+    pairHasKey = false;
+
+    if (_toString.call(pair) !== '[object Object]') return false;
+
+    for (pairKey in pair) {
+      if (_hasOwnProperty.call(pair, pairKey)) {
+        if (!pairHasKey) pairHasKey = true;
+        else return false;
+      }
+    }
+
+    if (!pairHasKey) return false;
+
+    if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey);
+    else return false;
+  }
+
+  return true;
+}
+
+function constructYamlOmap(data) {
+  return data !== null ? data : [];
+}
+
+module.exports = new Type('tag:yaml.org,2002:omap', {
+  kind: 'sequence',
+  resolve: resolveYamlOmap,
+  construct: constructYamlOmap
+});
+
+},{"../type":32}],44:[function(require,module,exports){
+'use strict';
+
+var Type = require('../type');
+
+var _toString = Object.prototype.toString;
+
+function resolveYamlPairs(data) {
+  if (data === null) return true;
+
+  var index, length, pair, keys, result,
+      object = data;
+
+  result = new Array(object.length);
+
+  for (index = 0, length = object.length; index < length; index += 1) {
+    pair = object[index];
+
+    if (_toString.call(pair) !== '[object Object]') return false;
+
+    keys = Object.keys(pair);
+
+    if (keys.length !== 1) return false;
+
+    result[index] = [ keys[0], pair[keys[0]] ];
+  }
+
+  return true;
+}
+
+function constructYamlPairs(data) {
+  if (data === null) return [];
+
+  var index, length, pair, keys, result,
+      object = data;
+
+  result = new Array(object.length);
+
+  for (index = 0, length = object.length; index < length; index += 1) {
+    pair = object[index];
+
+    keys = Object.keys(pair);
+
+    result[index] = [ keys[0], pair[keys[0]] ];
+  }
+
+  return result;
+}
+
+module.exports = new Type('tag:yaml.org,2002:pairs', {
+  kind: 'sequence',
+  resolve: resolveYamlPairs,
+  construct: constructYamlPairs
+});
+
+},{"../type":32}],45:[function(require,module,exports){
+'use strict';
+
+var Type = require('../type');
+
+module.exports = new Type('tag:yaml.org,2002:seq', {
+  kind: 'sequence',
+  construct: function (data) { return data !== null ? data : []; }
+});
+
+},{"../type":32}],46:[function(require,module,exports){
+'use strict';
+
+var Type = require('../type');
+
+var _hasOwnProperty = Object.prototype.hasOwnProperty;
+
+function resolveYamlSet(data) {
+  if (data === null) return true;
+
+  var key, object = data;
+
+  for (key in object) {
+    if (_hasOwnProperty.call(object, key)) {
+      if (object[key] !== null) return false;
+    }
+  }
+
+  return true;
+}
+
+function constructYamlSet(data) {
+  return data !== null ? data : {};
+}
+
+module.exports = new Type('tag:yaml.org,2002:set', {
+  kind: 'mapping',
+  resolve: resolveYamlSet,
+  construct: constructYamlSet
+});
+
+},{"../type":32}],47:[function(require,module,exports){
+'use strict';
+
+var Type = require('../type');
+
+module.exports = new Type('tag:yaml.org,2002:str', {
+  kind: 'scalar',
+  construct: function (data) { return data !== null ? data : ''; }
+});
+
+},{"../type":32}],48:[function(require,module,exports){
+'use strict';
+
+var Type = require('../type');
+
+var YAML_DATE_REGEXP = new RegExp(
+  '^([0-9][0-9][0-9][0-9])'          + // [1] year
+  '-([0-9][0-9])'                    + // [2] month
+  '-([0-9][0-9])$');                   // [3] day
+
+var YAML_TIMESTAMP_REGEXP = new RegExp(
+  '^([0-9][0-9][0-9][0-9])'          + // [1] year
+  '-([0-9][0-9]?)'                   + // [2] month
+  '-([0-9][0-9]?)'                   + // [3] day
+  '(?:[Tt]|[ \\t]+)'                 + // ...
+  '([0-9][0-9]?)'                    + // [4] hour
+  ':([0-9][0-9])'                    + // [5] minute
+  ':([0-9][0-9])'                    + // [6] second
+  '(?:\\.([0-9]*))?'                 + // [7] fraction
+  '(?:[ \\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour
+  '(?::([0-9][0-9]))?))?$');           // [11] tz_minute
+
+function resolveYamlTimestamp(data) {
+  if (data === null) return false;
+  if (YAML_DATE_REGEXP.exec(data) !== null) return true;
+  if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true;
+  return false;
+}
+
+function constructYamlTimestamp(data) {
+  var match, year, month, day, hour, minute, second, fraction = 0,
+      delta = null, tz_hour, tz_minute, date;
+
+  match = YAML_DATE_REGEXP.exec(data);
+  if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data);
+
+  if (match === null) throw new Error('Date resolve error');
+
+  // match: [1] year [2] month [3] day
+
+  year = +(match[1]);
+  month = +(match[2]) - 1; // JS month starts with 0
+  day = +(match[3]);
+
+  if (!match[4]) { // no hour
+    return new Date(Date.UTC(year, month, day));
+  }
+
+  // match: [4] hour [5] minute [6] second [7] fraction
+
+  hour = +(match[4]);
+  minute = +(match[5]);
+  second = +(match[6]);
+
+  if (match[7]) {
+    fraction = match[7].slice(0, 3);
+    while (fraction.length < 3) { // milli-seconds
+      fraction += '0';
+    }
+    fraction = +fraction;
+  }
+
+  // match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute
+
+  if (match[9]) {
+    tz_hour = +(match[10]);
+    tz_minute = +(match[11] || 0);
+    delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds
+    if (match[9] === '-') delta = -delta;
+  }
+
+  date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction));
+
+  if (delta) date.setTime(date.getTime() - delta);
+
+  return date;
+}
+
+function representYamlTimestamp(object /*, style*/) {
+  return object.toISOString();
+}
+
+module.exports = new Type('tag:yaml.org,2002:timestamp', {
+  kind: 'scalar',
+  resolve: resolveYamlTimestamp,
+  construct: constructYamlTimestamp,
+  instanceOf: Date,
+  represent: representYamlTimestamp
+});
+
+},{"../type":32}],49:[function(require,module,exports){
+var baseIndexOf = require('../internal/baseIndexOf'),
+    binaryIndex = require('../internal/binaryIndex');
+
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeMax = Math.max;
+
+/**
+ * Gets the index at which the first occurrence of `value` is found in `array`
+ * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+ * for equality comparisons. If `fromIndex` is negative, it's used as the offset
+ * from the end of `array`. If `array` is sorted providing `true` for `fromIndex`
+ * performs a faster binary search.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to search.
+ * @param {*} value The value to search for.
+ * @param {boolean|number} [fromIndex=0] The index to search from or `true`
+ *  to perform a binary search on a sorted array.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ * @example
+ *
+ * _.indexOf([1, 2, 1, 2], 2);
+ * // => 1
+ *
+ * // using `fromIndex`
+ * _.indexOf([1, 2, 1, 2], 2, 2);
+ * // => 3
+ *
+ * // performing a binary search
+ * _.indexOf([1, 1, 2, 2], 2, true);
+ * // => 2
+ */
+function indexOf(array, value, fromIndex) {
+  var length = array ? array.length : 0;
+  if (!length) {
+    return -1;
+  }
+  if (typeof fromIndex == 'number') {
+    fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex;
+  } else if (fromIndex) {
+    var index = binaryIndex(array, value);
+    if (index < length &&
+        (value === value ? (value === array[index]) : (array[index] !== array[index]))) {
+      return index;
+    }
+    return -1;
+  }
+  return baseIndexOf(array, value, fromIndex || 0);
+}
+
+module.exports = indexOf;
+
+},{"../internal/baseIndexOf":78,"../internal/binaryIndex":92}],50:[function(require,module,exports){
+/**
+ * Gets the last element of `array`.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {Array} array The array to query.
+ * @returns {*} Returns the last element of `array`.
+ * @example
+ *
+ * _.last([1, 2, 3]);
+ * // => 3
+ */
+function last(array) {
+  var length = array ? array.length : 0;
+  return length ? array[length - 1] : undefined;
+}
+
+module.exports = last;
+
+},{}],51:[function(require,module,exports){
+var LazyWrapper = require('../internal/LazyWrapper'),
+    LodashWrapper = require('../internal/LodashWrapper'),
+    baseLodash = require('../internal/baseLodash'),
+    isArray = require('../lang/isArray'),
+    isObjectLike = require('../internal/isObjectLike'),
+    wrapperClone = require('../internal/wrapperClone');
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/**
+ * Creates a `lodash` object which wraps `value` to enable implicit chaining.
+ * Methods that operate on and return arrays, collections, and functions can
+ * be chained together. Methods that retrieve a single value or may return a
+ * primitive value will automatically end the chain returning the unwrapped
+ * value. Explicit chaining may be enabled using `_.chain`. The execution of
+ * chained methods is lazy, that is, execution is deferred until `_#value`
+ * is implicitly or explicitly called.
+ *
+ * Lazy evaluation allows several methods to support shortcut fusion. Shortcut
+ * fusion is an optimization strategy which merge iteratee calls; this can help
+ * to avoid the creation of intermediate data structures and greatly reduce the
+ * number of iteratee executions.
+ *
+ * Chaining is supported in custom builds as long as the `_#value` method is
+ * directly or indirectly included in the build.
+ *
+ * In addition to lodash methods, wrappers have `Array` and `String` methods.
+ *
+ * The wrapper `Array` methods are:
+ * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`,
+ * `splice`, and `unshift`
+ *
+ * The wrapper `String` methods are:
+ * `replace` and `split`
+ *
+ * The wrapper methods that support shortcut fusion are:
+ * `compact`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`,
+ * `first`, `initial`, `last`, `map`, `pluck`, `reject`, `rest`, `reverse`,
+ * `slice`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `toArray`,
+ * and `where`
+ *
+ * The chainable wrapper methods are:
+ * `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`,
+ * `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`,
+ * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defaultsDeep`,
+ * `defer`, `delay`, `difference`, `drop`, `dropRight`, `dropRightWhile`,
+ * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`,
+ * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`,
+ * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`,
+ * `invoke`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`,
+ * `matchesProperty`, `memoize`, `merge`, `method`, `methodOf`, `mixin`,
+ * `modArgs`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`,
+ * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`,
+ * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `restParam`,
+ * `reverse`, `set`, `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`,
+ * `sortByOrder`, `splice`, `spread`, `take`, `takeRight`, `takeRightWhile`,
+ * `takeWhile`, `tap`, `throttle`, `thru`, `times`, `toArray`, `toPlainObject`,
+ * `transform`, `union`, `uniq`, `unshift`, `unzip`, `unzipWith`, `values`,
+ * `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, `zipObject`, `zipWith`
+ *
+ * The wrapper methods that are **not** chainable by default are:
+ * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clone`, `cloneDeep`,
+ * `deburr`, `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`,
+ * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`,
+ * `floor`, `get`, `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`,
+ * `inRange`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`,
+ * `isEmpty`, `isEqual`, `isError`, `isFinite` `isFunction`, `isMatch`,
+ * `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`,
+ * `isRegExp`, `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase`,
+ * `last`, `lastIndexOf`, `lt`, `lte`, `max`, `min`, `noConflict`, `noop`,
+ * `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, `reduce`,
+ * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `shift`, `size`,
+ * `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`,
+ * `startsWith`, `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`,
+ * `unescape`, `uniqueId`, `value`, and `words`
+ *
+ * The wrapper method `sample` will return a wrapped value when `n` is provided,
+ * otherwise an unwrapped value is returned.
+ *
+ * @name _
+ * @constructor
+ * @category Chain
+ * @param {*} value The value to wrap in a `lodash` instance.
+ * @returns {Object} Returns the new `lodash` wrapper instance.
+ * @example
+ *
+ * var wrapped = _([1, 2, 3]);
+ *
+ * // returns an unwrapped value
+ * wrapped.reduce(function(total, n) {
+ *   return total + n;
+ * });
+ * // => 6
+ *
+ * // returns a wrapped value
+ * var squares = wrapped.map(function(n) {
+ *   return n * n;
+ * });
+ *
+ * _.isArray(squares);
+ * // => false
+ *
+ * _.isArray(squares.value());
+ * // => true
+ */
+function lodash(value) {
+  if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
+    if (value instanceof LodashWrapper) {
+      return value;
+    }
+    if (hasOwnProperty.call(value, '__chain__') && hasOwnProperty.call(value, '__wrapped__')) {
+      return wrapperClone(value);
+    }
+  }
+  return new LodashWrapper(value);
+}
+
+// Ensure wrappers are instances of `baseLodash`.
+lodash.prototype = baseLodash.prototype;
+
+module.exports = lodash;
+
+},{"../internal/LazyWrapper":60,"../internal/LodashWrapper":61,"../internal/baseLodash":82,"../internal/isObjectLike":126,"../internal/wrapperClone":137,"../lang/isArray":140}],52:[function(require,module,exports){
+module.exports = require('./forEach');
+
+},{"./forEach":54}],53:[function(require,module,exports){
+var baseEach = require('../internal/baseEach'),
+    createFind = require('../internal/createFind');
+
+/**
+ * Iterates over elements of `collection`, returning the first element
+ * `predicate` returns truthy for. The predicate is bound to `thisArg` and
+ * invoked with three arguments: (value, index|key, collection).
+ *
+ * If a property name is provided for `predicate` the created `_.property`
+ * style callback returns the property value of the given element.
+ *
+ * If a value is also provided for `thisArg` the created `_.matchesProperty`
+ * style callback returns `true` for elements that have a matching property
+ * value, else `false`.
+ *
+ * If an object is provided for `predicate` the created `_.matches` style
+ * callback returns `true` for elements that have the properties of the given
+ * object, else `false`.
+ *
+ * @static
+ * @memberOf _
+ * @alias detect
+ * @category Collection
+ * @param {Array|Object|string} collection The collection to search.
+ * @param {Function|Object|string} [predicate=_.identity] The function invoked
+ *  per iteration.
+ * @param {*} [thisArg] The `this` binding of `predicate`.
+ * @returns {*} Returns the matched element, else `undefined`.
+ * @example
+ *
+ * var users = [
+ *   { 'user': 'barney',  'age': 36, 'active': true },
+ *   { 'user': 'fred',    'age': 40, 'active': false },
+ *   { 'user': 'pebbles', 'age': 1,  'active': true }
+ * ];
+ *
+ * _.result(_.find(users, function(chr) {
+ *   return chr.age < 40;
+ * }), 'user');
+ * // => 'barney'
+ *
+ * // using the `_.matches` callback shorthand
+ * _.result(_.find(users, { 'age': 1, 'active': true }), 'user');
+ * // => 'pebbles'
+ *
+ * // using the `_.matchesProperty` callback shorthand
+ * _.result(_.find(users, 'active', false), 'user');
+ * // => 'fred'
+ *
+ * // using the `_.property` callback shorthand
+ * _.result(_.find(users, 'active'), 'user');
+ * // => 'barney'
+ */
+var find = createFind(baseEach);
+
+module.exports = find;
+
+},{"../internal/baseEach":71,"../internal/createFind":102}],54:[function(require,module,exports){
+var arrayEach = require('../internal/arrayEach'),
+    baseEach = require('../internal/baseEach'),
+    createForEach = require('../internal/createForEach');
+
+/**
+ * Iterates over elements of `collection` invoking `iteratee` for each element.
+ * The `iteratee` is bound to `thisArg` and invoked with three arguments:
+ * (value, index|key, collection). Iteratee functions may exit iteration early
+ * by explicitly returning `false`.
+ *
+ * **Note:** As with other "Collections" methods, objects with a "length" property
+ * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn`
+ * may be used for object iteration.
+ *
+ * @static
+ * @memberOf _
+ * @alias each
+ * @category Collection
+ * @param {Array|Object|string} collection The collection to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @param {*} [thisArg] The `this` binding of `iteratee`.
+ * @returns {Array|Object|string} Returns `collection`.
+ * @example
+ *
+ * _([1, 2]).forEach(function(n) {
+ *   console.log(n);
+ * }).value();
+ * // => logs each value from left to right and returns the array
+ *
+ * _.forEach({ 'a': 1, 'b': 2 }, function(n, key) {
+ *   console.log(n, key);
+ * });
+ * // => logs each value-key pair and returns the object (iteration order is not guaranteed)
+ */
+var forEach = createForEach(arrayEach, baseEach);
+
+module.exports = forEach;
+
+},{"../internal/arrayEach":63,"../internal/baseEach":71,"../internal/createForEach":103}],55:[function(require,module,exports){
+var baseIndexOf = require('../internal/baseIndexOf'),
+    getLength = require('../internal/getLength'),
+    isArray = require('../lang/isArray'),
+    isIterateeCall = require('../internal/isIterateeCall'),
+    isLength = require('../internal/isLength'),
+    isString = require('../lang/isString'),
+    values = require('../object/values');
+
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeMax = Math.max;
+
+/**
+ * Checks if `target` is in `collection` using
+ * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+ * for equality comparisons. If `fromIndex` is negative, it's used as the offset
+ * from the end of `collection`.
+ *
+ * @static
+ * @memberOf _
+ * @alias contains, include
+ * @category Collection
+ * @param {Array|Object|string} collection The collection to search.
+ * @param {*} target The value to search for.
+ * @param {number} [fromIndex=0] The index to search from.
+ * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`.
+ * @returns {boolean} Returns `true` if a matching element is found, else `false`.
+ * @example
+ *
+ * _.includes([1, 2, 3], 1);
+ * // => true
+ *
+ * _.includes([1, 2, 3], 1, 2);
+ * // => false
+ *
+ * _.includes({ 'user': 'fred', 'age': 40 }, 'fred');
+ * // => true
+ *
+ * _.includes('pebbles', 'eb');
+ * // => true
+ */
+function includes(collection, target, fromIndex, guard) {
+  var length = collection ? getLength(collection) : 0;
+  if (!isLength(length)) {
+    collection = values(collection);
+    length = collection.length;
+  }
+  if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) {
+    fromIndex = 0;
+  } else {
+    fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0);
+  }
+  return (typeof collection == 'string' || !isArray(collection) && isString(collection))
+    ? (fromIndex <= length && collection.indexOf(target, fromIndex) > -1)
+    : (!!length && baseIndexOf(collection, target, fromIndex) > -1);
+}
+
+module.exports = includes;
+
+},{"../internal/baseIndexOf":78,"../internal/getLength":112,"../internal/isIterateeCall":122,"../internal/isLength":125,"../lang/isArray":140,"../lang/isString":146,"../object/values":152}],56:[function(require,module,exports){
+var arrayMap = require('../internal/arrayMap'),
+    baseCallback = require('../internal/baseCallback'),
+    baseMap = require('../internal/baseMap'),
+    isArray = require('../lang/isArray');
+
+/**
+ * Creates an array of values by running each element in `collection` through
+ * `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three
+ * arguments: (value, index|key, collection).
+ *
+ * If a property name is provided for `iteratee` the created `_.property`
+ * style callback returns the property value of the given element.
+ *
+ * If a value is also provided for `thisArg` the created `_.matchesProperty`
+ * style callback returns `true` for elements that have a matching property
+ * value, else `false`.
+ *
+ * If an object is provided for `iteratee` the created `_.matches` style
+ * callback returns `true` for elements that have the properties of the given
+ * object, else `false`.
+ *
+ * Many lodash methods are guarded to work as iteratees for methods like
+ * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
+ *
+ * The guarded methods are:
+ * `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`,
+ * `drop`, `dropRight`, `every`, `fill`, `flatten`, `invert`, `max`, `min`,
+ * `parseInt`, `slice`, `sortBy`, `take`, `takeRight`, `template`, `trim`,
+ * `trimLeft`, `trimRight`, `trunc`, `random`, `range`, `sample`, `some`,
+ * `sum`, `uniq`, and `words`
+ *
+ * @static
+ * @memberOf _
+ * @alias collect
+ * @category Collection
+ * @param {Array|Object|string} collection The collection to iterate over.
+ * @param {Function|Object|string} [iteratee=_.identity] The function invoked
+ *  per iteration.
+ * @param {*} [thisArg] The `this` binding of `iteratee`.
+ * @returns {Array} Returns the new mapped array.
+ * @example
+ *
+ * function timesThree(n) {
+ *   return n * 3;
+ * }
+ *
+ * _.map([1, 2], timesThree);
+ * // => [3, 6]
+ *
+ * _.map({ 'a': 1, 'b': 2 }, timesThree);
+ * // => [3, 6] (iteration order is not guaranteed)
+ *
+ * var users = [
+ *   { 'user': 'barney' },
+ *   { 'user': 'fred' }
+ * ];
+ *
+ * // using the `_.property` callback shorthand
+ * _.map(users, 'user');
+ * // => ['barney', 'fred']
+ */
+function map(collection, iteratee, thisArg) {
+  var func = isArray(collection) ? arrayMap : baseMap;
+  iteratee = baseCallback(iteratee, thisArg, 3);
+  return func(collection, iteratee);
+}
+
+module.exports = map;
+
+},{"../internal/arrayMap":64,"../internal/baseCallback":67,"../internal/baseMap":83,"../lang/isArray":140}],57:[function(require,module,exports){
+var getNative = require('../internal/getNative');
+
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeNow = getNative(Date, 'now');
+
+/**
+ * Gets the number of milliseconds that have elapsed since the Unix epoch
+ * (1 January 1970 00:00:00 UTC).
+ *
+ * @static
+ * @memberOf _
+ * @category Date
+ * @example
+ *
+ * _.defer(function(stamp) {
+ *   console.log(_.now() - stamp);
+ * }, _.now());
+ * // => logs the number of milliseconds it took for the deferred function to be invoked
+ */
+var now = nativeNow || function() {
+  return new Date().getTime();
+};
+
+module.exports = now;
+
+},{"../internal/getNative":114}],58:[function(require,module,exports){
+var createWrapper = require('../internal/createWrapper'),
+    replaceHolders = require('../internal/replaceHolders'),
+    restParam = require('./restParam');
+
+/** Used to compose bitmasks for wrapper metadata. */
+var BIND_FLAG = 1,
+    PARTIAL_FLAG = 32;
+
+/**
+ * Creates a function that invokes `func` with the `this` binding of `thisArg`
+ * and prepends any additional `_.bind` arguments to those provided to the
+ * bound function.
+ *
+ * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
+ * may be used as a placeholder for partially applied arguments.
+ *
+ * **Note:** Unlike native `Function#bind` this method does not set the "length"
+ * property of bound functions.
+ *
+ * @static
+ * @memberOf _
+ * @category Function
+ * @param {Function} func The function to bind.
+ * @param {*} thisArg The `this` binding of `func`.
+ * @param {...*} [partials] The arguments to be partially applied.
+ * @returns {Function} Returns the new bound function.
+ * @example
+ *
+ * var greet = function(greeting, punctuation) {
+ *   return greeting + ' ' + this.user + punctuation;
+ * };
+ *
+ * var object = { 'user': 'fred' };
+ *
+ * var bound = _.bind(greet, object, 'hi');
+ * bound('!');
+ * // => 'hi fred!'
+ *
+ * // using placeholders
+ * var bound = _.bind(greet, object, _, '!');
+ * bound('hi');
+ * // => 'hi fred!'
+ */
+var bind = restParam(function(func, thisArg, partials) {
+  var bitmask = BIND_FLAG;
+  if (partials.length) {
+    var holders = replaceHolders(partials, bind.placeholder);
+    bitmask |= PARTIAL_FLAG;
+  }
+  return createWrapper(func, bitmask, thisArg, partials, holders);
+});
+
+// Assign default placeholders.
+bind.placeholder = {};
+
+module.exports = bind;
+
+},{"../internal/createWrapper":106,"../internal/replaceHolders":132,"./restParam":59}],59:[function(require,module,exports){
+/** Used as the `TypeError` message for "Functions" methods. */
+var FUNC_ERROR_TEXT = 'Expected a function';
+
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeMax = Math.max;
+
+/**
+ * Creates a function that invokes `func` with the `this` binding of the
+ * created function and arguments from `start` and beyond provided as an array.
+ *
+ * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/Web/JavaScript/Reference/Functions/rest_parameters).
+ *
+ * @static
+ * @memberOf _
+ * @category Function
+ * @param {Function} func The function to apply a rest parameter to.
+ * @param {number} [start=func.length-1] The start position of the rest parameter.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var say = _.restParam(function(what, names) {
+ *   return what + ' ' + _.initial(names).join(', ') +
+ *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);
+ * });
+ *
+ * say('hello', 'fred', 'barney', 'pebbles');
+ * // => 'hello fred, barney, & pebbles'
+ */
+function restParam(func, start) {
+  if (typeof func != 'function') {
+    throw new TypeError(FUNC_ERROR_TEXT);
+  }
+  start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0);
+  return function() {
+    var args = arguments,
+        index = -1,
+        length = nativeMax(args.length - start, 0),
+        rest = Array(length);
+
+    while (++index < length) {
+      rest[index] = args[start + index];
+    }
+    switch (start) {
+      case 0: return func.call(this, rest);
+      case 1: return func.call(this, args[0], rest);
+      case 2: return func.call(this, args[0], args[1], rest);
+    }
+    var otherArgs = Array(start + 1);
+    index = -1;
+    while (++index < start) {
+      otherArgs[index] = args[index];
+    }
+    otherArgs[start] = rest;
+    return func.apply(this, otherArgs);
+  };
+}
+
+module.exports = restParam;
+
+},{}],60:[function(require,module,exports){
+var baseCreate = require('./baseCreate'),
+    baseLodash = require('./baseLodash');
+
+/** Used as references for `-Infinity` and `Infinity`. */
+var POSITIVE_INFINITY = Number.POSITIVE_INFINITY;
+
+/**
+ * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
+ *
+ * @private
+ * @param {*} value The value to wrap.
+ */
+function LazyWrapper(value) {
+  this.__wrapped__ = value;
+  this.__actions__ = [];
+  this.__dir__ = 1;
+  this.__filtered__ = false;
+  this.__iteratees__ = [];
+  this.__takeCount__ = POSITIVE_INFINITY;
+  this.__views__ = [];
+}
+
+LazyWrapper.prototype = baseCreate(baseLodash.prototype);
+LazyWrapper.prototype.constructor = LazyWrapper;
+
+module.exports = LazyWrapper;
+
+},{"./baseCreate":70,"./baseLodash":82}],61:[function(require,module,exports){
+var baseCreate = require('./baseCreate'),
+    baseLodash = require('./baseLodash');
+
+/**
+ * The base constructor for creating `lodash` wrapper objects.
+ *
+ * @private
+ * @param {*} value The value to wrap.
+ * @param {boolean} [chainAll] Enable chaining for all wrapper methods.
+ * @param {Array} [actions=[]] Actions to peform to resolve the unwrapped value.
+ */
+function LodashWrapper(value, chainAll, actions) {
+  this.__wrapped__ = value;
+  this.__actions__ = actions || [];
+  this.__chain__ = !!chainAll;
+}
+
+LodashWrapper.prototype = baseCreate(baseLodash.prototype);
+LodashWrapper.prototype.constructor = LodashWrapper;
+
+module.exports = LodashWrapper;
+
+},{"./baseCreate":70,"./baseLodash":82}],62:[function(require,module,exports){
+/**
+ * Copies the values of `source` to `array`.
+ *
+ * @private
+ * @param {Array} source The array to copy values from.
+ * @param {Array} [array=[]] The array to copy values to.
+ * @returns {Array} Returns `array`.
+ */
+function arrayCopy(source, array) {
+  var index = -1,
+      length = source.length;
+
+  array || (array = Array(length));
+  while (++index < length) {
+    array[index] = source[index];
+  }
+  return array;
+}
+
+module.exports = arrayCopy;
+
+},{}],63:[function(require,module,exports){
+/**
+ * A specialized version of `_.forEach` for arrays without support for callback
+ * shorthands and `this` binding.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns `array`.
+ */
+function arrayEach(array, iteratee) {
+  var index = -1,
+      length = array.length;
+
+  while (++index < length) {
+    if (iteratee(array[index], index, array) === false) {
+      break;
+    }
+  }
+  return array;
+}
+
+module.exports = arrayEach;
+
+},{}],64:[function(require,module,exports){
+/**
+ * A specialized version of `_.map` for arrays without support for callback
+ * shorthands and `this` binding.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns the new mapped array.
+ */
+function arrayMap(array, iteratee) {
+  var index = -1,
+      length = array.length,
+      result = Array(length);
+
+  while (++index < length) {
+    result[index] = iteratee(array[index], index, array);
+  }
+  return result;
+}
+
+module.exports = arrayMap;
+
+},{}],65:[function(require,module,exports){
+/**
+ * A specialized version of `_.some` for arrays without support for callback
+ * shorthands and `this` binding.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} predicate The function invoked per iteration.
+ * @returns {boolean} Returns `true` if any element passes the predicate check,
+ *  else `false`.
+ */
+function arraySome(array, predicate) {
+  var index = -1,
+      length = array.length;
+
+  while (++index < length) {
+    if (predicate(array[index], index, array)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+module.exports = arraySome;
+
+},{}],66:[function(require,module,exports){
+var baseCopy = require('./baseCopy'),
+    keys = require('../object/keys');
+
+/**
+ * The base implementation of `_.assign` without support for argument juggling,
+ * multiple sources, and `customizer` functions.
+ *
+ * @private
+ * @param {Object} object The destination object.
+ * @param {Object} source The source object.
+ * @returns {Object} Returns `object`.
+ */
+function baseAssign(object, source) {
+  return source == null
+    ? object
+    : baseCopy(source, keys(source), object);
+}
+
+module.exports = baseAssign;
+
+},{"../object/keys":149,"./baseCopy":69}],67:[function(require,module,exports){
+var baseMatches = require('./baseMatches'),
+    baseMatchesProperty = require('./baseMatchesProperty'),
+    bindCallback = require('./bindCallback'),
+    identity = require('../utility/identity'),
+    property = require('../utility/property');
+
+/**
+ * The base implementation of `_.callback` which supports specifying the
+ * number of arguments to provide to `func`.
+ *
+ * @private
+ * @param {*} [func=_.identity] The value to convert to a callback.
+ * @param {*} [thisArg] The `this` binding of `func`.
+ * @param {number} [argCount] The number of arguments to provide to `func`.
+ * @returns {Function} Returns the callback.
+ */
+function baseCallback(func, thisArg, argCount) {
+  var type = typeof func;
+  if (type == 'function') {
+    return thisArg === undefined
+      ? func
+      : bindCallback(func, thisArg, argCount);
+  }
+  if (func == null) {
+    return identity;
+  }
+  if (type == 'object') {
+    return baseMatches(func);
+  }
+  return thisArg === undefined
+    ? property(func)
+    : baseMatchesProperty(func, thisArg);
+}
+
+module.exports = baseCallback;
+
+},{"../utility/identity":154,"../utility/property":156,"./baseMatches":84,"./baseMatchesProperty":85,"./bindCallback":94}],68:[function(require,module,exports){
+var arrayCopy = require('./arrayCopy'),
+    arrayEach = require('./arrayEach'),
+    baseAssign = require('./baseAssign'),
+    baseForOwn = require('./baseForOwn'),
+    initCloneArray = require('./initCloneArray'),
+    initCloneByTag = require('./initCloneByTag'),
+    initCloneObject = require('./initCloneObject'),
+    isArray = require('../lang/isArray'),
+    isHostObject = require('./isHostObject'),
+    isObject = require('../lang/isObject');
+
+/** `Object#toString` result references. */
+var argsTag = '[object Arguments]',
+    arrayTag = '[object Array]',
+    boolTag = '[object Boolean]',
+    dateTag = '[object Date]',
+    errorTag = '[object Error]',
+    funcTag = '[object Function]',
+    mapTag = '[object Map]',
+    numberTag = '[object Number]',
+    objectTag = '[object Object]',
+    regexpTag = '[object RegExp]',
+    setTag = '[object Set]',
+    stringTag = '[object String]',
+    weakMapTag = '[object WeakMap]';
+
+var arrayBufferTag = '[object ArrayBuffer]',
+    float32Tag = '[object Float32Array]',
+    float64Tag = '[object Float64Array]',
+    int8Tag = '[object Int8Array]',
+    int16Tag = '[object Int16Array]',
+    int32Tag = '[object Int32Array]',
+    uint8Tag = '[object Uint8Array]',
+    uint8ClampedTag = '[object Uint8ClampedArray]',
+    uint16Tag = '[object Uint16Array]',
+    uint32Tag = '[object Uint32Array]';
+
+/** Used to identify `toStringTag` values supported by `_.clone`. */
+var cloneableTags = {};
+cloneableTags[argsTag] = cloneableTags[arrayTag] =
+cloneableTags[arrayBufferTag] = cloneableTags[boolTag] =
+cloneableTags[dateTag] = cloneableTags[float32Tag] =
+cloneableTags[float64Tag] = cloneableTags[int8Tag] =
+cloneableTags[int16Tag] = cloneableTags[int32Tag] =
+cloneableTags[numberTag] = cloneableTags[objectTag] =
+cloneableTags[regexpTag] = cloneableTags[stringTag] =
+cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
+cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
+cloneableTags[errorTag] = cloneableTags[funcTag] =
+cloneableTags[mapTag] = cloneableTags[setTag] =
+cloneableTags[weakMapTag] = false;
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+var objToString = objectProto.toString;
+
+/**
+ * The base implementation of `_.clone` without support for argument juggling
+ * and `this` binding `customizer` functions.
+ *
+ * @private
+ * @param {*} value The value to clone.
+ * @param {boolean} [isDeep] Specify a deep clone.
+ * @param {Function} [customizer] The function to customize cloning values.
+ * @param {string} [key] The key of `value`.
+ * @param {Object} [object] The object `value` belongs to.
+ * @param {Array} [stackA=[]] Tracks traversed source objects.
+ * @param {Array} [stackB=[]] Associates clones with source counterparts.
+ * @returns {*} Returns the cloned value.
+ */
+function baseClone(value, isDeep, customizer, key, object, stackA, stackB) {
+  var result;
+  if (customizer) {
+    result = object ? customizer(value, key, object) : customizer(value);
+  }
+  if (result !== undefined) {
+    return result;
+  }
+  if (!isObject(value)) {
+    return value;
+  }
+  var isArr = isArray(value);
+  if (isArr) {
+    result = initCloneArray(value);
+    if (!isDeep) {
+      return arrayCopy(value, result);
+    }
+  } else {
+    var tag = objToString.call(value),
+        isFunc = tag == funcTag;
+
+    if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
+      if (isHostObject(value)) {
+        return object ? value : {};
+      }
+      result = initCloneObject(isFunc ? {} : value);
+      if (!isDeep) {
+        return baseAssign(result, value);
+      }
+    } else {
+      return cloneableTags[tag]
+        ? initCloneByTag(value, tag, isDeep)
+        : (object ? value : {});
+    }
+  }
+  // Check for circular references and return its corresponding clone.
+  stackA || (stackA = []);
+  stackB || (stackB = []);
+
+  var length = stackA.length;
+  while (length--) {
+    if (stackA[length] == value) {
+      return stackB[length];
+    }
+  }
+  // Add the source value to the stack of traversed objects and associate it with its clone.
+  stackA.push(value);
+  stackB.push(result);
+
+  // Recursively populate clone (susceptible to call stack limits).
+  (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) {
+    result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB);
+  });
+  return result;
+}
+
+module.exports = baseClone;
+
+},{"../lang/isArray":140,"../lang/isObject":144,"./arrayCopy":62,"./arrayEach":63,"./baseAssign":66,"./baseForOwn":76,"./initCloneArray":116,"./initCloneByTag":117,"./initCloneObject":118,"./isHostObject":120}],69:[function(require,module,exports){
+/**
+ * Copies properties of `source` to `object`.
+ *
+ * @private
+ * @param {Object} source The object to copy properties from.
+ * @param {Array} props The property names to copy.
+ * @param {Object} [object={}] The object to copy properties to.
+ * @returns {Object} Returns `object`.
+ */
+function baseCopy(source, props, object) {
+  object || (object = {});
+
+  var index = -1,
+      length = props.length;
+
+  while (++index < length) {
+    var key = props[index];
+    object[key] = source[key];
+  }
+  return object;
+}
+
+module.exports = baseCopy;
+
+},{}],70:[function(require,module,exports){
+var isObject = require('../lang/isObject');
+
+/**
+ * The base implementation of `_.create` without support for assigning
+ * properties to the created object.
+ *
+ * @private
+ * @param {Object} prototype The object to inherit from.
+ * @returns {Object} Returns the new object.
+ */
+var baseCreate = (function() {
+  function object() {}
+  return function(prototype) {
+    if (isObject(prototype)) {
+      object.prototype = prototype;
+      var result = new object;
+      object.prototype = undefined;
+    }
+    return result || {};
+  };
+}());
+
+module.exports = baseCreate;
+
+},{"../lang/isObject":144}],71:[function(require,module,exports){
+var baseForOwn = require('./baseForOwn'),
+    createBaseEach = require('./createBaseEach');
+
+/**
+ * The base implementation of `_.forEach` without support for callback
+ * shorthands and `this` binding.
+ *
+ * @private
+ * @param {Array|Object|string} collection The collection to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array|Object|string} Returns `collection`.
+ */
+var baseEach = createBaseEach(baseForOwn);
+
+module.exports = baseEach;
+
+},{"./baseForOwn":76,"./createBaseEach":98}],72:[function(require,module,exports){
+/**
+ * The base implementation of `_.find`, `_.findLast`, `_.findKey`, and `_.findLastKey`,
+ * without support for callback shorthands and `this` binding, which iterates
+ * over `collection` using the provided `eachFunc`.
+ *
+ * @private
+ * @param {Array|Object|string} collection The collection to search.
+ * @param {Function} predicate The function invoked per iteration.
+ * @param {Function} eachFunc The function to iterate over `collection`.
+ * @param {boolean} [retKey] Specify returning the key of the found element
+ *  instead of the element itself.
+ * @returns {*} Returns the found element or its key, else `undefined`.
+ */
+function baseFind(collection, predicate, eachFunc, retKey) {
+  var result;
+  eachFunc(collection, function(value, key, collection) {
+    if (predicate(value, key, collection)) {
+      result = retKey ? key : value;
+      return false;
+    }
+  });
+  return result;
+}
+
+module.exports = baseFind;
+
+},{}],73:[function(require,module,exports){
+/**
+ * The base implementation of `_.findIndex` and `_.findLastIndex` without
+ * support for callback shorthands and `this` binding.
+ *
+ * @private
+ * @param {Array} array The array to search.
+ * @param {Function} predicate The function invoked per iteration.
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ */
+function baseFindIndex(array, predicate, fromRight) {
+  var length = array.length,
+      index = fromRight ? length : -1;
+
+  while ((fromRight ? index-- : ++index < length)) {
+    if (predicate(array[index], index, array)) {
+      return index;
+    }
+  }
+  return -1;
+}
+
+module.exports = baseFindIndex;
+
+},{}],74:[function(require,module,exports){
+var createBaseFor = require('./createBaseFor');
+
+/**
+ * The base implementation of `baseForIn` and `baseForOwn` which iterates
+ * over `object` properties returned by `keysFunc` invoking `iteratee` for
+ * each property. Iteratee functions may exit iteration early by explicitly
+ * returning `false`.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @param {Function} keysFunc The function to get the keys of `object`.
+ * @returns {Object} Returns `object`.
+ */
+var baseFor = createBaseFor();
+
+module.exports = baseFor;
+
+},{"./createBaseFor":99}],75:[function(require,module,exports){
+var baseFor = require('./baseFor'),
+    keysIn = require('../object/keysIn');
+
+/**
+ * The base implementation of `_.forIn` without support for callback
+ * shorthands and `this` binding.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Object} Returns `object`.
+ */
+function baseForIn(object, iteratee) {
+  return baseFor(object, iteratee, keysIn);
+}
+
+module.exports = baseForIn;
+
+},{"../object/keysIn":150,"./baseFor":74}],76:[function(require,module,exports){
+var baseFor = require('./baseFor'),
+    keys = require('../object/keys');
+
+/**
+ * The base implementation of `_.forOwn` without support for callback
+ * shorthands and `this` binding.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Object} Returns `object`.
+ */
+function baseForOwn(object, iteratee) {
+  return baseFor(object, iteratee, keys);
+}
+
+module.exports = baseForOwn;
+
+},{"../object/keys":149,"./baseFor":74}],77:[function(require,module,exports){
+var toObject = require('./toObject');
+
+/**
+ * The base implementation of `get` without support for string paths
+ * and default values.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array} path The path of the property to get.
+ * @param {string} [pathKey] The key representation of path.
+ * @returns {*} Returns the resolved value.
+ */
+function baseGet(object, path, pathKey) {
+  if (object == null) {
+    return;
+  }
+  object = toObject(object);
+  if (pathKey !== undefined && pathKey in object) {
+    path = [pathKey];
+  }
+  var index = 0,
+      length = path.length;
+
+  while (object != null && index < length) {
+    object = toObject(object)[path[index++]];
+  }
+  return (index && index == length) ? object : undefined;
+}
+
+module.exports = baseGet;
+
+},{"./toObject":135}],78:[function(require,module,exports){
+var indexOfNaN = require('./indexOfNaN');
+
+/**
+ * The base implementation of `_.indexOf` without support for binary searches.
+ *
+ * @private
+ * @param {Array} array The array to search.
+ * @param {*} value The value to search for.
+ * @param {number} fromIndex The index to search from.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ */
+function baseIndexOf(array, value, fromIndex) {
+  if (value !== value) {
+    return indexOfNaN(array, fromIndex);
+  }
+  var index = fromIndex - 1,
+      length = array.length;
+
+  while (++index < length) {
+    if (array[index] === value) {
+      return index;
+    }
+  }
+  return -1;
+}
+
+module.exports = baseIndexOf;
+
+},{"./indexOfNaN":115}],79:[function(require,module,exports){
+var baseIsEqualDeep = require('./baseIsEqualDeep'),
+    isObject = require('../lang/isObject'),
+    isObjectLike = require('./isObjectLike');
+
+/**
+ * The base implementation of `_.isEqual` without support for `this` binding
+ * `customizer` functions.
+ *
+ * @private
+ * @param {*} value The value to compare.
+ * @param {*} other The other value to compare.
+ * @param {Function} [customizer] The function to customize comparing values.
+ * @param {boolean} [isLoose] Specify performing partial comparisons.
+ * @param {Array} [stackA] Tracks traversed `value` objects.
+ * @param {Array} [stackB] Tracks traversed `other` objects.
+ * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+ */
+function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) {
+  if (value === other) {
+    return true;
+  }
+  if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
+    return value !== value && other !== other;
+  }
+  return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB);
+}
+
+module.exports = baseIsEqual;
+
+},{"../lang/isObject":144,"./baseIsEqualDeep":80,"./isObjectLike":126}],80:[function(require,module,exports){
+var equalArrays = require('./equalArrays'),
+    equalByTag = require('./equalByTag'),
+    equalObjects = require('./equalObjects'),
+    isArray = require('../lang/isArray'),
+    isHostObject = require('./isHostObject'),
+    isTypedArray = require('../lang/isTypedArray');
+
+/** `Object#toString` result references. */
+var argsTag = '[object Arguments]',
+    arrayTag = '[object Array]',
+    objectTag = '[object Object]';
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+var objToString = objectProto.toString;
+
+/**
+ * A specialized version of `baseIsEqual` for arrays and objects which performs
+ * deep comparisons and tracks traversed objects enabling objects with circular
+ * references to be compared.
+ *
+ * @private
+ * @param {Object} object The object to compare.
+ * @param {Object} other The other object to compare.
+ * @param {Function} equalFunc The function to determine equivalents of values.
+ * @param {Function} [customizer] The function to customize comparing objects.
+ * @param {boolean} [isLoose] Specify performing partial comparisons.
+ * @param {Array} [stackA=[]] Tracks traversed `value` objects.
+ * @param {Array} [stackB=[]] Tracks traversed `other` objects.
+ * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
+ */
+function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) {
+  var objIsArr = isArray(object),
+      othIsArr = isArray(other),
+      objTag = arrayTag,
+      othTag = arrayTag;
+
+  if (!objIsArr) {
+    objTag = objToString.call(object);
+    if (objTag == argsTag) {
+      objTag = objectTag;
+    } else if (objTag != objectTag) {
+      objIsArr = isTypedArray(object);
+    }
+  }
+  if (!othIsArr) {
+    othTag = objToString.call(other);
+    if (othTag == argsTag) {
+      othTag = objectTag;
+    } else if (othTag != objectTag) {
+      othIsArr = isTypedArray(other);
+    }
+  }
+  var objIsObj = objTag == objectTag && !isHostObject(object),
+      othIsObj = othTag == objectTag && !isHostObject(other),
+      isSameTag = objTag == othTag;
+
+  if (isSameTag && !(objIsArr || objIsObj)) {
+    return equalByTag(object, other, objTag);
+  }
+  if (!isLoose) {
+    var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
+        othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
+
+    if (objIsWrapped || othIsWrapped) {
+      return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, isLoose, stackA, stackB);
+    }
+  }
+  if (!isSameTag) {
+    return false;
+  }
+  // Assume cyclic values are equal.
+  // For more information on detecting circular references see https://es5.github.io/#JO.
+  stackA || (stackA = []);
+  stackB || (stackB = []);
+
+  var length = stackA.length;
+  while (length--) {
+    if (stackA[length] == object) {
+      return stackB[length] == other;
+    }
+  }
+  // Add `object` and `other` to the stack of traversed objects.
+  stackA.push(object);
+  stackB.push(other);
+
+  var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB);
+
+  stackA.pop();
+  stackB.pop();
+
+  return result;
+}
+
+module.exports = baseIsEqualDeep;
+
+},{"../lang/isArray":140,"../lang/isTypedArray":147,"./equalArrays":107,"./equalByTag":108,"./equalObjects":109,"./isHostObject":120}],81:[function(require,module,exports){
+var baseIsEqual = require('./baseIsEqual'),
+    toObject = require('./toObject');
+
+/**
+ * The base implementation of `_.isMatch` without support for callback
+ * shorthands and `this` binding.
+ *
+ * @private
+ * @param {Object} object The object to inspect.
+ * @param {Array} matchData The propery names, values, and compare flags to match.
+ * @param {Function} [customizer] The function to customize comparing objects.
+ * @returns {boolean} Returns `true` if `object` is a match, else `false`.
+ */
+function baseIsMatch(object, matchData, customizer) {
+  var index = matchData.length,
+      length = index,
+      noCustomizer = !customizer;
+
+  if (object == null) {
+    return !length;
+  }
+  object = toObject(object);
+  while (index--) {
+    var data = matchData[index];
+    if ((noCustomizer && data[2])
+          ? data[1] !== object[data[0]]
+          : !(data[0] in object)
+        ) {
+      return false;
+    }
+  }
+  while (++index < length) {
+    data = matchData[index];
+    var key = data[0],
+        objValue = object[key],
+        srcValue = data[1];
+
+    if (noCustomizer && data[2]) {
+      if (objValue === undefined && !(key in object)) {
+        return false;
+      }
+    } else {
+      var result = customizer ? customizer(objValue, srcValue, key) : undefined;
+      if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, true) : result)) {
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
+module.exports = baseIsMatch;
+
+},{"./baseIsEqual":79,"./toObject":135}],82:[function(require,module,exports){
+/**
+ * The function whose prototype all chaining wrappers inherit from.
+ *
+ * @private
+ */
+function baseLodash() {
+  // No operation performed.
+}
+
+module.exports = baseLodash;
+
+},{}],83:[function(require,module,exports){
+var baseEach = require('./baseEach'),
+    isArrayLike = require('./isArrayLike');
+
+/**
+ * The base implementation of `_.map` without support for callback shorthands
+ * and `this` binding.
+ *
+ * @private
+ * @param {Array|Object|string} collection The collection to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Array} Returns the new mapped array.
+ */
+function baseMap(collection, iteratee) {
+  var index = -1,
+      result = isArrayLike(collection) ? Array(collection.length) : [];
+
+  baseEach(collection, function(value, key, collection) {
+    result[++index] = iteratee(value, key, collection);
+  });
+  return result;
+}
+
+module.exports = baseMap;
+
+},{"./baseEach":71,"./isArrayLike":119}],84:[function(require,module,exports){
+var baseIsMatch = require('./baseIsMatch'),
+    getMatchData = require('./getMatchData'),
+    toObject = require('./toObject');
+
+/**
+ * The base implementation of `_.matches` which does not clone `source`.
+ *
+ * @private
+ * @param {Object} source The object of property values to match.
+ * @returns {Function} Returns the new function.
+ */
+function baseMatches(source) {
+  var matchData = getMatchData(source);
+  if (matchData.length == 1 && matchData[0][2]) {
+    var key = matchData[0][0],
+        value = matchData[0][1];
+
+    return function(object) {
+      if (object == null) {
+        return false;
+      }
+      object = toObject(object);
+      return object[key] === value && (value !== undefined || (key in object));
+    };
+  }
+  return function(object) {
+    return baseIsMatch(object, matchData);
+  };
+}
+
+module.exports = baseMatches;
+
+},{"./baseIsMatch":81,"./getMatchData":113,"./toObject":135}],85:[function(require,module,exports){
+var baseGet = require('./baseGet'),
+    baseIsEqual = require('./baseIsEqual'),
+    baseSlice = require('./baseSlice'),
+    isArray = require('../lang/isArray'),
+    isKey = require('./isKey'),
+    isStrictComparable = require('./isStrictComparable'),
+    last = require('../array/last'),
+    toObject = require('./toObject'),
+    toPath = require('./toPath');
+
+/**
+ * The base implementation of `_.matchesProperty` which does not clone `srcValue`.
+ *
+ * @private
+ * @param {string} path The path of the property to get.
+ * @param {*} srcValue The value to compare.
+ * @returns {Function} Returns the new function.
+ */
+function baseMatchesProperty(path, srcValue) {
+  var isArr = isArray(path),
+      isCommon = isKey(path) && isStrictComparable(srcValue),
+      pathKey = (path + '');
+
+  path = toPath(path);
+  return function(object) {
+    if (object == null) {
+      return false;
+    }
+    var key = pathKey;
+    object = toObject(object);
+    if ((isArr || !isCommon) && !(key in object)) {
+      object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
+      if (object == null) {
+        return false;
+      }
+      key = last(path);
+      object = toObject(object);
+    }
+    return object[key] === srcValue
+      ? (srcValue !== undefined || (key in object))
+      : baseIsEqual(srcValue, object[key], undefined, true);
+  };
+}
+
+module.exports = baseMatchesProperty;
+
+},{"../array/last":50,"../lang/isArray":140,"./baseGet":77,"./baseIsEqual":79,"./baseSlice":89,"./isKey":123,"./isStrictComparable":127,"./toObject":135,"./toPath":136}],86:[function(require,module,exports){
+var toObject = require('./toObject');
+
+/**
+ * The base implementation of `_.property` without support for deep paths.
+ *
+ * @private
+ * @param {string} key The key of the property to get.
+ * @returns {Function} Returns the new function.
+ */
+function baseProperty(key) {
+  return function(object) {
+    return object == null ? undefined : toObject(object)[key];
+  };
+}
+
+module.exports = baseProperty;
+
+},{"./toObject":135}],87:[function(require,module,exports){
+var baseGet = require('./baseGet'),
+    toPath = require('./toPath');
+
+/**
+ * A specialized version of `baseProperty` which supports deep paths.
+ *
+ * @private
+ * @param {Array|string} path The path of the property to get.
+ * @returns {Function} Returns the new function.
+ */
+function basePropertyDeep(path) {
+  var pathKey = (path + '');
+  path = toPath(path);
+  return function(object) {
+    return baseGet(object, path, pathKey);
+  };
+}
+
+module.exports = basePropertyDeep;
+
+},{"./baseGet":77,"./toPath":136}],88:[function(require,module,exports){
+var identity = require('../utility/identity'),
+    metaMap = require('./metaMap');
+
+/**
+ * The base implementation of `setData` without support for hot loop detection.
+ *
+ * @private
+ * @param {Function} func The function to associate metadata with.
+ * @param {*} data The metadata.
+ * @returns {Function} Returns `func`.
+ */
+var baseSetData = !metaMap ? identity : function(func, data) {
+  metaMap.set(func, data);
+  return func;
+};
+
+module.exports = baseSetData;
+
+},{"../utility/identity":154,"./metaMap":129}],89:[function(require,module,exports){
+/**
+ * The base implementation of `_.slice` without an iteratee call guard.
+ *
+ * @private
+ * @param {Array} array The array to slice.
+ * @param {number} [start=0] The start position.
+ * @param {number} [end=array.length] The end position.
+ * @returns {Array} Returns the slice of `array`.
+ */
+function baseSlice(array, start, end) {
+  var index = -1,
+      length = array.length;
+
+  start = start == null ? 0 : (+start || 0);
+  if (start < 0) {
+    start = -start > length ? 0 : (length + start);
+  }
+  end = (end === undefined || end > length) ? length : (+end || 0);
+  if (end < 0) {
+    end += length;
+  }
+  length = start > end ? 0 : ((end - start) >>> 0);
+  start >>>= 0;
+
+  var result = Array(length);
+  while (++index < length) {
+    result[index] = array[index + start];
+  }
+  return result;
+}
+
+module.exports = baseSlice;
+
+},{}],90:[function(require,module,exports){
+/**
+ * Converts `value` to a string if it's not one. An empty string is returned
+ * for `null` or `undefined` values.
+ *
+ * @private
+ * @param {*} value The value to process.
+ * @returns {string} Returns the string.
+ */
+function baseToString(value) {
+  return value == null ? '' : (value + '');
+}
+
+module.exports = baseToString;
+
+},{}],91:[function(require,module,exports){
+/**
+ * The base implementation of `_.values` and `_.valuesIn` which creates an
+ * array of `object` property values corresponding to the property names
+ * of `props`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {Array} props The property names to get values for.
+ * @returns {Object} Returns the array of property values.
+ */
+function baseValues(object, props) {
+  var index = -1,
+      length = props.length,
+      result = Array(length);
+
+  while (++index < length) {
+    result[index] = object[props[index]];
+  }
+  return result;
+}
+
+module.exports = baseValues;
+
+},{}],92:[function(require,module,exports){
+var binaryIndexBy = require('./binaryIndexBy'),
+    identity = require('../utility/identity');
+
+/** Used as references for the maximum length and index of an array. */
+var MAX_ARRAY_LENGTH = 4294967295,
+    HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
+
+/**
+ * Performs a binary search of `array` to determine the index at which `value`
+ * should be inserted into `array` in order to maintain its sort order.
+ *
+ * @private
+ * @param {Array} array The sorted array to inspect.
+ * @param {*} value The value to evaluate.
+ * @param {boolean} [retHighest] Specify returning the highest qualified index.
+ * @returns {number} Returns the index at which `value` should be inserted
+ *  into `array`.
+ */
+function binaryIndex(array, value, retHighest) {
+  var low = 0,
+      high = array ? array.length : low;
+
+  if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
+    while (low < high) {
+      var mid = (low + high) >>> 1,
+          computed = array[mid];
+
+      if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) {
+        low = mid + 1;
+      } else {
+        high = mid;
+      }
+    }
+    return high;
+  }
+  return binaryIndexBy(array, value, identity, retHighest);
+}
+
+module.exports = binaryIndex;
+
+},{"../utility/identity":154,"./binaryIndexBy":93}],93:[function(require,module,exports){
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeFloor = Math.floor,
+    nativeMin = Math.min;
+
+/** Used as references for the maximum length and index of an array. */
+var MAX_ARRAY_LENGTH = 4294967295,
+    MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1;
+
+/**
+ * This function is like `binaryIndex` except that it invokes `iteratee` for
+ * `value` and each element of `array` to compute their sort ranking. The
+ * iteratee is invoked with one argument; (value).
+ *
+ * @private
+ * @param {Array} array The sorted array to inspect.
+ * @param {*} value The value to evaluate.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @param {boolean} [retHighest] Specify returning the highest qualified index.
+ * @returns {number} Returns the index at which `value` should be inserted
+ *  into `array`.
+ */
+function binaryIndexBy(array, value, iteratee, retHighest) {
+  value = iteratee(value);
+
+  var low = 0,
+      high = array ? array.length : 0,
+      valIsNaN = value !== value,
+      valIsNull = value === null,
+      valIsUndef = value === undefined;
+
+  while (low < high) {
+    var mid = nativeFloor((low + high) / 2),
+        computed = iteratee(array[mid]),
+        isDef = computed !== undefined,
+        isReflexive = computed === computed;
+
+    if (valIsNaN) {
+      var setLow = isReflexive || retHighest;
+    } else if (valIsNull) {
+      setLow = isReflexive && isDef && (retHighest || computed != null);
+    } else if (valIsUndef) {
+      setLow = isReflexive && (retHighest || isDef);
+    } else if (computed == null) {
+      setLow = false;
+    } else {
+      setLow = retHighest ? (computed <= value) : (computed < value);
+    }
+    if (setLow) {
+      low = mid + 1;
+    } else {
+      high = mid;
+    }
+  }
+  return nativeMin(high, MAX_ARRAY_INDEX);
+}
+
+module.exports = binaryIndexBy;
+
+},{}],94:[function(require,module,exports){
+var identity = require('../utility/identity');
+
+/**
+ * A specialized version of `baseCallback` which only supports `this` binding
+ * and specifying the number of arguments to provide to `func`.
+ *
+ * @private
+ * @param {Function} func The function to bind.
+ * @param {*} thisArg The `this` binding of `func`.
+ * @param {number} [argCount] The number of arguments to provide to `func`.
+ * @returns {Function} Returns the callback.
+ */
+function bindCallback(func, thisArg, argCount) {
+  if (typeof func != 'function') {
+    return identity;
+  }
+  if (thisArg === undefined) {
+    return func;
+  }
+  switch (argCount) {
+    case 1: return function(value) {
+      return func.call(thisArg, value);
+    };
+    case 3: return function(value, index, collection) {
+      return func.call(thisArg, value, index, collection);
+    };
+    case 4: return function(accumulator, value, index, collection) {
+      return func.call(thisArg, accumulator, value, index, collection);
+    };
+    case 5: return function(value, other, key, object, source) {
+      return func.call(thisArg, value, other, key, object, source);
+    };
+  }
+  return function() {
+    return func.apply(thisArg, arguments);
+  };
+}
+
+module.exports = bindCallback;
+
+},{"../utility/identity":154}],95:[function(require,module,exports){
+(function (global){
+/** Native method references. */
+var ArrayBuffer = global.ArrayBuffer,
+    Uint8Array = global.Uint8Array;
+
+/**
+ * Creates a clone of the given array buffer.
+ *
+ * @private
+ * @param {ArrayBuffer} buffer The array buffer to clone.
+ * @returns {ArrayBuffer} Returns the cloned array buffer.
+ */
+function bufferClone(buffer) {
+  var result = new ArrayBuffer(buffer.byteLength),
+      view = new Uint8Array(result);
+
+  view.set(new Uint8Array(buffer));
+  return result;
+}
+
+module.exports = bufferClone;
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+
+},{}],96:[function(require,module,exports){
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeMax = Math.max;
+
+/**
+ * Creates an array that is the composition of partially applied arguments,
+ * placeholders, and provided arguments into a single array of arguments.
+ *
+ * @private
+ * @param {Array|Object} args The provided arguments.
+ * @param {Array} partials The arguments to prepend to those provided.
+ * @param {Array} holders The `partials` placeholder indexes.
+ * @returns {Array} Returns the new array of composed arguments.
+ */
+function composeArgs(args, partials, holders) {
+  var holdersLength = holders.length,
+      argsIndex = -1,
+      argsLength = nativeMax(args.length - holdersLength, 0),
+      leftIndex = -1,
+      leftLength = partials.length,
+      result = Array(leftLength + argsLength);
+
+  while (++leftIndex < leftLength) {
+    result[leftIndex] = partials[leftIndex];
+  }
+  while (++argsIndex < holdersLength) {
+    result[holders[argsIndex]] = args[argsIndex];
+  }
+  while (argsLength--) {
+    result[leftIndex++] = args[argsIndex++];
+  }
+  return result;
+}
+
+module.exports = composeArgs;
+
+},{}],97:[function(require,module,exports){
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeMax = Math.max;
+
+/**
+ * This function is like `composeArgs` except that the arguments composition
+ * is tailored for `_.partialRight`.
+ *
+ * @private
+ * @param {Array|Object} args The provided arguments.
+ * @param {Array} partials The arguments to append to those provided.
+ * @param {Array} holders The `partials` placeholder indexes.
+ * @returns {Array} Returns the new array of composed arguments.
+ */
+function composeArgsRight(args, partials, holders) {
+  var holdersIndex = -1,
+      holdersLength = holders.length,
+      argsIndex = -1,
+      argsLength = nativeMax(args.length - holdersLength, 0),
+      rightIndex = -1,
+      rightLength = partials.length,
+      result = Array(argsLength + rightLength);
+
+  while (++argsIndex < argsLength) {
+    result[argsIndex] = args[argsIndex];
+  }
+  var offset = argsIndex;
+  while (++rightIndex < rightLength) {
+    result[offset + rightIndex] = partials[rightIndex];
+  }
+  while (++holdersIndex < holdersLength) {
+    result[offset + holders[holdersIndex]] = args[argsIndex++];
+  }
+  return result;
+}
+
+module.exports = composeArgsRight;
+
+},{}],98:[function(require,module,exports){
+var getLength = require('./getLength'),
+    isLength = require('./isLength'),
+    toObject = require('./toObject');
+
+/**
+ * Creates a `baseEach` or `baseEachRight` function.
+ *
+ * @private
+ * @param {Function} eachFunc The function to iterate over a collection.
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Function} Returns the new base function.
+ */
+function createBaseEach(eachFunc, fromRight) {
+  return function(collection, iteratee) {
+    var length = collection ? getLength(collection) : 0;
+    if (!isLength(length)) {
+      return eachFunc(collection, iteratee);
+    }
+    var index = fromRight ? length : -1,
+        iterable = toObject(collection);
+
+    while ((fromRight ? index-- : ++index < length)) {
+      if (iteratee(iterable[index], index, iterable) === false) {
+        break;
+      }
+    }
+    return collection;
+  };
+}
+
+module.exports = createBaseEach;
+
+},{"./getLength":112,"./isLength":125,"./toObject":135}],99:[function(require,module,exports){
+var toObject = require('./toObject');
+
+/**
+ * Creates a base function for `_.forIn` or `_.forInRight`.
+ *
+ * @private
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Function} Returns the new base function.
+ */
+function createBaseFor(fromRight) {
+  return function(object, iteratee, keysFunc) {
+    var iterable = toObject(object),
+        props = keysFunc(object),
+        length = props.length,
+        index = fromRight ? length : -1;
+
+    while ((fromRight ? index-- : ++index < length)) {
+      var key = props[index];
+      if (iteratee(iterable[key], key, iterable) === false) {
+        break;
+      }
+    }
+    return object;
+  };
+}
+
+module.exports = createBaseFor;
+
+},{"./toObject":135}],100:[function(require,module,exports){
+(function (global){
+var createCtorWrapper = require('./createCtorWrapper');
+
+/**
+ * Creates a function that wraps `func` and invokes it with the `this`
+ * binding of `thisArg`.
+ *
+ * @private
+ * @param {Function} func The function to bind.
+ * @param {*} [thisArg] The `this` binding of `func`.
+ * @returns {Function} Returns the new bound function.
+ */
+function createBindWrapper(func, thisArg) {
+  var Ctor = createCtorWrapper(func);
+
+  function wrapper() {
+    var fn = (this && this !== global && this instanceof wrapper) ? Ctor : func;
+    return fn.apply(thisArg, arguments);
+  }
+  return wrapper;
+}
+
+module.exports = createBindWrapper;
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+
+},{"./createCtorWrapper":101}],101:[function(require,module,exports){
+var baseCreate = require('./baseCreate'),
+    isObject = require('../lang/isObject');
+
+/**
+ * Creates a function that produces an instance of `Ctor` regardless of
+ * whether it was invoked as part of a `new` expression or by `call` or `apply`.
+ *
+ * @private
+ * @param {Function} Ctor The constructor to wrap.
+ * @returns {Function} Returns the new wrapped function.
+ */
+function createCtorWrapper(Ctor) {
+  return function() {
+    // Use a `switch` statement to work with class constructors.
+    // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
+    // for more details.
+    var args = arguments;
+    switch (args.length) {
+      case 0: return new Ctor;
+      case 1: return new Ctor(args[0]);
+      case 2: return new Ctor(args[0], args[1]);
+      case 3: return new Ctor(args[0], args[1], args[2]);
+      case 4: return new Ctor(args[0], args[1], args[2], args[3]);
+      case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
+      case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
+      case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
+    }
+    var thisBinding = baseCreate(Ctor.prototype),
+        result = Ctor.apply(thisBinding, args);
+
+    // Mimic the constructor's `return` behavior.
+    // See https://es5.github.io/#x13.2.2 for more details.
+    return isObject(result) ? result : thisBinding;
+  };
+}
+
+module.exports = createCtorWrapper;
+
+},{"../lang/isObject":144,"./baseCreate":70}],102:[function(require,module,exports){
+var baseCallback = require('./baseCallback'),
+    baseFind = require('./baseFind'),
+    baseFindIndex = require('./baseFindIndex'),
+    isArray = require('../lang/isArray');
+
+/**
+ * Creates a `_.find` or `_.findLast` function.
+ *
+ * @private
+ * @param {Function} eachFunc The function to iterate over a collection.
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Function} Returns the new find function.
+ */
+function createFind(eachFunc, fromRight) {
+  return function(collection, predicate, thisArg) {
+    predicate = baseCallback(predicate, thisArg, 3);
+    if (isArray(collection)) {
+      var index = baseFindIndex(collection, predicate, fromRight);
+      return index > -1 ? collection[index] : undefined;
+    }
+    return baseFind(collection, predicate, eachFunc);
+  };
+}
+
+module.exports = createFind;
+
+},{"../lang/isArray":140,"./baseCallback":67,"./baseFind":72,"./baseFindIndex":73}],103:[function(require,module,exports){
+var bindCallback = require('./bindCallback'),
+    isArray = require('../lang/isArray');
+
+/**
+ * Creates a function for `_.forEach` or `_.forEachRight`.
+ *
+ * @private
+ * @param {Function} arrayFunc The function to iterate over an array.
+ * @param {Function} eachFunc The function to iterate over a collection.
+ * @returns {Function} Returns the new each function.
+ */
+function createForEach(arrayFunc, eachFunc) {
+  return function(collection, iteratee, thisArg) {
+    return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection))
+      ? arrayFunc(collection, iteratee)
+      : eachFunc(collection, bindCallback(iteratee, thisArg, 3));
+  };
+}
+
+module.exports = createForEach;
+
+},{"../lang/isArray":140,"./bindCallback":94}],104:[function(require,module,exports){
+(function (global){
+var arrayCopy = require('./arrayCopy'),
+    composeArgs = require('./composeArgs'),
+    composeArgsRight = require('./composeArgsRight'),
+    createCtorWrapper = require('./createCtorWrapper'),
+    isLaziable = require('./isLaziable'),
+    reorder = require('./reorder'),
+    replaceHolders = require('./replaceHolders'),
+    setData = require('./setData');
+
+/** Used to compose bitmasks for wrapper metadata. */
+var BIND_FLAG = 1,
+    BIND_KEY_FLAG = 2,
+    CURRY_BOUND_FLAG = 4,
+    CURRY_FLAG = 8,
+    CURRY_RIGHT_FLAG = 16,
+    PARTIAL_FLAG = 32,
+    PARTIAL_RIGHT_FLAG = 64,
+    ARY_FLAG = 128;
+
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeMax = Math.max;
+
+/**
+ * Creates a function that wraps `func` and invokes it with optional `this`
+ * binding of, partial application, and currying.
+ *
+ * @private
+ * @param {Function|string} func The function or method name to reference.
+ * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details.
+ * @param {*} [thisArg] The `this` binding of `func`.
+ * @param {Array} [partials] The arguments to prepend to those provided to the new function.
+ * @param {Array} [holders] The `partials` placeholder indexes.
+ * @param {Array} [partialsRight] The arguments to append to those provided to the new function.
+ * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
+ * @param {Array} [argPos] The argument positions of the new function.
+ * @param {number} [ary] The arity cap of `func`.
+ * @param {number} [arity] The arity of `func`.
+ * @returns {Function} Returns the new wrapped function.
+ */
+function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
+  var isAry = bitmask & ARY_FLAG,
+      isBind = bitmask & BIND_FLAG,
+      isBindKey = bitmask & BIND_KEY_FLAG,
+      isCurry = bitmask & CURRY_FLAG,
+      isCurryBound = bitmask & CURRY_BOUND_FLAG,
+      isCurryRight = bitmask & CURRY_RIGHT_FLAG,
+      Ctor = isBindKey ? undefined : createCtorWrapper(func);
+
+  function wrapper() {
+    // Avoid `arguments` object use disqualifying optimizations by
+    // converting it to an array before providing it to other functions.
+    var length = arguments.length,
+        index = length,
+        args = Array(length);
+
+    while (index--) {
+      args[index] = arguments[index];
+    }
+    if (partials) {
+      args = composeArgs(args, partials, holders);
+    }
+    if (partialsRight) {
+      args = composeArgsRight(args, partialsRight, holdersRight);
+    }
+    if (isCurry || isCurryRight) {
+      var placeholder = wrapper.placeholder,
+          argsHolders = replaceHolders(args, placeholder);
+
+      length -= argsHolders.length;
+      if (length < arity) {
+        var newArgPos = argPos ? arrayCopy(argPos) : undefined,
+            newArity = nativeMax(arity - length, 0),
+            newsHolders = isCurry ? argsHolders : undefined,
+            newHoldersRight = isCurry ? undefined : argsHolders,
+            newPartials = isCurry ? args : undefined,
+            newPartialsRight = isCurry ? undefined : args;
+
+        bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG);
+        bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG);
+
+        if (!isCurryBound) {
+          bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG);
+        }
+        var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity],
+            result = createHybridWrapper.apply(undefined, newData);
+
+        if (isLaziable(func)) {
+          setData(result, newData);
+        }
+        result.placeholder = placeholder;
+        return result;
+      }
+    }
+    var thisBinding = isBind ? thisArg : this,
+        fn = isBindKey ? thisBinding[func] : func;
+
+    if (argPos) {
+      args = reorder(args, argPos);
+    }
+    if (isAry && ary < args.length) {
+      args.length = ary;
+    }
+    if (this && this !== global && this instanceof wrapper) {
+      fn = Ctor || createCtorWrapper(func);
+    }
+    return fn.apply(thisBinding, args);
+  }
+  return wrapper;
+}
+
+module.exports = createHybridWrapper;
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+
+},{"./arrayCopy":62,"./composeArgs":96,"./composeArgsRight":97,"./createCtorWrapper":101,"./isLaziable":124,"./reorder":131,"./replaceHolders":132,"./setData":133}],105:[function(require,module,exports){
+(function (global){
+var createCtorWrapper = require('./createCtorWrapper');
+
+/** Used to compose bitmasks for wrapper metadata. */
+var BIND_FLAG = 1;
+
+/**
+ * Creates a function that wraps `func` and invokes it with the optional `this`
+ * binding of `thisArg` and the `partials` prepended to those provided to
+ * the wrapper.
+ *
+ * @private
+ * @param {Function} func The function to partially apply arguments to.
+ * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details.
+ * @param {*} thisArg The `this` binding of `func`.
+ * @param {Array} partials The arguments to prepend to those provided to the new function.
+ * @returns {Function} Returns the new bound function.
+ */
+function createPartialWrapper(func, bitmask, thisArg, partials) {
+  var isBind = bitmask & BIND_FLAG,
+      Ctor = createCtorWrapper(func);
+
+  function wrapper() {
+    // Avoid `arguments` object use disqualifying optimizations by
+    // converting it to an array before providing it `func`.
+    var argsIndex = -1,
+        argsLength = arguments.length,
+        leftIndex = -1,
+        leftLength = partials.length,
+        args = Array(leftLength + argsLength);
+
+    while (++leftIndex < leftLength) {
+      args[leftIndex] = partials[leftIndex];
+    }
+    while (argsLength--) {
+      args[leftIndex++] = arguments[++argsIndex];
+    }
+    var fn = (this && this !== global && this instanceof wrapper) ? Ctor : func;
+    return fn.apply(isBind ? thisArg : this, args);
+  }
+  return wrapper;
+}
+
+module.exports = createPartialWrapper;
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+
+},{"./createCtorWrapper":101}],106:[function(require,module,exports){
+var baseSetData = require('./baseSetData'),
+    createBindWrapper = require('./createBindWrapper'),
+    createHybridWrapper = require('./createHybridWrapper'),
+    createPartialWrapper = require('./createPartialWrapper'),
+    getData = require('./getData'),
+    mergeData = require('./mergeData'),
+    setData = require('./setData');
+
+/** Used to compose bitmasks for wrapper metadata. */
+var BIND_FLAG = 1,
+    BIND_KEY_FLAG = 2,
+    PARTIAL_FLAG = 32,
+    PARTIAL_RIGHT_FLAG = 64;
+
+/** Used as the `TypeError` message for "Functions" methods. */
+var FUNC_ERROR_TEXT = 'Expected a function';
+
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeMax = Math.max;
+
+/**
+ * Creates a function that either curries or invokes `func` with optional
+ * `this` binding and partially applied arguments.
+ *
+ * @private
+ * @param {Function|string} func The function or method name to reference.
+ * @param {number} bitmask The bitmask of flags.
+ *  The bitmask may be composed of the following flags:
+ *     1 - `_.bind`
+ *     2 - `_.bindKey`
+ *     4 - `_.curry` or `_.curryRight` of a bound function
+ *     8 - `_.curry`
+ *    16 - `_.curryRight`
+ *    32 - `_.partial`
+ *    64 - `_.partialRight`
+ *   128 - `_.rearg`
+ *   256 - `_.ary`
+ * @param {*} [thisArg] The `this` binding of `func`.
+ * @param {Array} [partials] The arguments to be partially applied.
+ * @param {Array} [holders] The `partials` placeholder indexes.
+ * @param {Array} [argPos] The argument positions of the new function.
+ * @param {number} [ary] The arity cap of `func`.
+ * @param {number} [arity] The arity of `func`.
+ * @returns {Function} Returns the new wrapped function.
+ */
+function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
+  var isBindKey = bitmask & BIND_KEY_FLAG;
+  if (!isBindKey && typeof func != 'function') {
+    throw new TypeError(FUNC_ERROR_TEXT);
+  }
+  var length = partials ? partials.length : 0;
+  if (!length) {
+    bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG);
+    partials = holders = undefined;
+  }
+  length -= (holders ? holders.length : 0);
+  if (bitmask & PARTIAL_RIGHT_FLAG) {
+    var partialsRight = partials,
+        holdersRight = holders;
+
+    partials = holders = undefined;
+  }
+  var data = isBindKey ? undefined : getData(func),
+      newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity];
+
+  if (data) {
+    mergeData(newData, data);
+    bitmask = newData[1];
+    arity = newData[9];
+  }
+  newData[9] = arity == null
+    ? (isBindKey ? 0 : func.length)
+    : (nativeMax(arity - length, 0) || 0);
+
+  if (bitmask == BIND_FLAG) {
+    var result = createBindWrapper(newData[0], newData[2]);
+  } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !newData[4].length) {
+    result = createPartialWrapper.apply(undefined, newData);
+  } else {
+    result = createHybridWrapper.apply(undefined, newData);
+  }
+  var setter = data ? baseSetData : setData;
+  return setter(result, newData);
+}
+
+module.exports = createWrapper;
+
+},{"./baseSetData":88,"./createBindWrapper":100,"./createHybridWrapper":104,"./createPartialWrapper":105,"./getData":110,"./mergeData":128,"./setData":133}],107:[function(require,module,exports){
+var arraySome = require('./arraySome');
+
+/**
+ * A specialized version of `baseIsEqualDeep` for arrays with support for
+ * partial deep comparisons.
+ *
+ * @private
+ * @param {Array} array The array to compare.
+ * @param {Array} other The other array to compare.
+ * @param {Function} equalFunc The function to determine equivalents of values.
+ * @param {Function} [customizer] The function to customize comparing arrays.
+ * @param {boolean} [isLoose] Specify performing partial comparisons.
+ * @param {Array} [stackA] Tracks traversed `value` objects.
+ * @param {Array} [stackB] Tracks traversed `other` objects.
+ * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
+ */
+function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) {
+  var index = -1,
+      arrLength = array.length,
+      othLength = other.length;
+
+  if (arrLength != othLength && !(isLoose && othLength > arrLength)) {
+    return false;
+  }
+  // Ignore non-index properties.
+  while (++index < arrLength) {
+    var arrValue = array[index],
+        othValue = other[index],
+        result = customizer ? customizer(isLoose ? othValue : arrValue, isLoose ? arrValue : othValue, index) : undefined;
+
+    if (result !== undefined) {
+      if (result) {
+        continue;
+      }
+      return false;
+    }
+    // Recursively compare arrays (susceptible to call stack limits).
+    if (isLoose) {
+      if (!arraySome(other, function(othValue) {
+            return arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB);
+          })) {
+        return false;
+      }
+    } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB))) {
+      return false;
+    }
+  }
+  return true;
+}
+
+module.exports = equalArrays;
+
+},{"./arraySome":65}],108:[function(require,module,exports){
+/** `Object#toString` result references. */
+var boolTag = '[object Boolean]',
+    dateTag = '[object Date]',
+    errorTag = '[object Error]',
+    numberTag = '[object Number]',
+    regexpTag = '[object RegExp]',
+    stringTag = '[object String]';
+
+/**
+ * A specialized version of `baseIsEqualDeep` for comparing objects of
+ * the same `toStringTag`.
+ *
+ * **Note:** This function only supports comparing values with tags of
+ * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
+ *
+ * @private
+ * @param {Object} object The object to compare.
+ * @param {Object} other The other object to compare.
+ * @param {string} tag The `toStringTag` of the objects to compare.
+ * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
+ */
+function equalByTag(object, other, tag) {
+  switch (tag) {
+    case boolTag:
+    case dateTag:
+      // Coerce dates and booleans to numbers, dates to milliseconds and booleans
+      // to `1` or `0` treating invalid dates coerced to `NaN` as not equal.
+      return +object == +other;
+
+    case errorTag:
+      return object.name == other.name && object.message == other.message;
+
+    case numberTag:
+      // Treat `NaN` vs. `NaN` as equal.
+      return (object != +object)
+        ? other != +other
+        : object == +other;
+
+    case regexpTag:
+    case stringTag:
+      // Coerce regexes to strings and treat strings primitives and string
+      // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details.
+      return object == (other + '');
+  }
+  return false;
+}
+
+module.exports = equalByTag;
+
+},{}],109:[function(require,module,exports){
+var keys = require('../object/keys');
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/**
+ * A specialized version of `baseIsEqualDeep` for objects with support for
+ * partial deep comparisons.
+ *
+ * @private
+ * @param {Object} object The object to compare.
+ * @param {Object} other The other object to compare.
+ * @param {Function} equalFunc The function to determine equivalents of values.
+ * @param {Function} [customizer] The function to customize comparing values.
+ * @param {boolean} [isLoose] Specify performing partial comparisons.
+ * @param {Array} [stackA] Tracks traversed `value` objects.
+ * @param {Array} [stackB] Tracks traversed `other` objects.
+ * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
+ */
+function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) {
+  var objProps = keys(object),
+      objLength = objProps.length,
+      othProps = keys(other),
+      othLength = othProps.length;
+
+  if (objLength != othLength && !isLoose) {
+    return false;
+  }
+  var index = objLength;
+  while (index--) {
+    var key = objProps[index];
+    if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) {
+      return false;
+    }
+  }
+  var skipCtor = isLoose;
+  while (++index < objLength) {
+    key = objProps[index];
+    var objValue = object[key],
+        othValue = other[key],
+        result = customizer ? customizer(isLoose ? othValue : objValue, isLoose? objValue : othValue, key) : undefined;
+
+    // Recursively compare objects (susceptible to call stack limits).
+    if (!(result === undefined ? equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB) : result)) {
+      return false;
+    }
+    skipCtor || (skipCtor = key == 'constructor');
+  }
+  if (!skipCtor) {
+    var objCtor = object.constructor,
+        othCtor = other.constructor;
+
+    // Non `Object` object instances with different constructors are not equal.
+    if (objCtor != othCtor &&
+        ('constructor' in object && 'constructor' in other) &&
+        !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
+          typeof othCtor == 'function' && othCtor instanceof othCtor)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+module.exports = equalObjects;
+
+},{"../object/keys":149}],110:[function(require,module,exports){
+var metaMap = require('./metaMap'),
+    noop = require('../utility/noop');
+
+/**
+ * Gets metadata for `func`.
+ *
+ * @private
+ * @param {Function} func The function to query.
+ * @returns {*} Returns the metadata for `func`.
+ */
+var getData = !metaMap ? noop : function(func) {
+  return metaMap.get(func);
+};
+
+module.exports = getData;
+
+},{"../utility/noop":155,"./metaMap":129}],111:[function(require,module,exports){
+var realNames = require('./realNames');
+
+/**
+ * Gets the name of `func`.
+ *
+ * @private
+ * @param {Function} func The function to query.
+ * @returns {string} Returns the function name.
+ */
+function getFuncName(func) {
+  var result = (func.name + ''),
+      array = realNames[result],
+      length = array ? array.length : 0;
+
+  while (length--) {
+    var data = array[length],
+        otherFunc = data.func;
+    if (otherFunc == null || otherFunc == func) {
+      return data.name;
+    }
+  }
+  return result;
+}
+
+module.exports = getFuncName;
+
+},{"./realNames":130}],112:[function(require,module,exports){
+var baseProperty = require('./baseProperty');
+
+/**
+ * Gets the "length" property value of `object`.
+ *
+ * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
+ * that affects Safari on at least iOS 8.1-8.3 ARM64.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {*} Returns the "length" value.
+ */
+var getLength = baseProperty('length');
+
+module.exports = getLength;
+
+},{"./baseProperty":86}],113:[function(require,module,exports){
+var isStrictComparable = require('./isStrictComparable'),
+    pairs = require('../object/pairs');
+
+/**
+ * Gets the propery names, values, and compare flags of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the match data of `object`.
+ */
+function getMatchData(object) {
+  var result = pairs(object),
+      length = result.length;
+
+  while (length--) {
+    result[length][2] = isStrictComparable(result[length][1]);
+  }
+  return result;
+}
+
+module.exports = getMatchData;
+
+},{"../object/pairs":151,"./isStrictComparable":127}],114:[function(require,module,exports){
+var isNative = require('../lang/isNative');
+
+/**
+ * Gets the native function at `key` of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {string} key The key of the method to get.
+ * @returns {*} Returns the function if it's native, else `undefined`.
+ */
+function getNative(object, key) {
+  var value = object == null ? undefined : object[key];
+  return isNative(value) ? value : undefined;
+}
+
+module.exports = getNative;
+
+},{"../lang/isNative":143}],115:[function(require,module,exports){
+/**
+ * Gets the index at which the first occurrence of `NaN` is found in `array`.
+ *
+ * @private
+ * @param {Array} array The array to search.
+ * @param {number} fromIndex The index to search from.
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {number} Returns the index of the matched `NaN`, else `-1`.
+ */
+function indexOfNaN(array, fromIndex, fromRight) {
+  var length = array.length,
+      index = fromIndex + (fromRight ? 0 : -1);
+
+  while ((fromRight ? index-- : ++index < length)) {
+    var other = array[index];
+    if (other !== other) {
+      return index;
+    }
+  }
+  return -1;
+}
+
+module.exports = indexOfNaN;
+
+},{}],116:[function(require,module,exports){
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/**
+ * Initializes an array clone.
+ *
+ * @private
+ * @param {Array} array The array to clone.
+ * @returns {Array} Returns the initialized clone.
+ */
+function initCloneArray(array) {
+  var length = array.length,
+      result = new array.constructor(length);
+
+  // Add array properties assigned by `RegExp#exec`.
+  if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
+    result.index = array.index;
+    result.input = array.input;
+  }
+  return result;
+}
+
+module.exports = initCloneArray;
+
+},{}],117:[function(require,module,exports){
+(function (global){
+var bufferClone = require('./bufferClone');
+
+/** `Object#toString` result references. */
+var boolTag = '[object Boolean]',
+    dateTag = '[object Date]',
+    numberTag = '[object Number]',
+    regexpTag = '[object RegExp]',
+    stringTag = '[object String]';
+
+var arrayBufferTag = '[object ArrayBuffer]',
+    float32Tag = '[object Float32Array]',
+    float64Tag = '[object Float64Array]',
+    int8Tag = '[object Int8Array]',
+    int16Tag = '[object Int16Array]',
+    int32Tag = '[object Int32Array]',
+    uint8Tag = '[object Uint8Array]',
+    uint8ClampedTag = '[object Uint8ClampedArray]',
+    uint16Tag = '[object Uint16Array]',
+    uint32Tag = '[object Uint32Array]';
+
+/** Used to match `RegExp` flags from their coerced string values. */
+var reFlags = /\w*$/;
+
+/** Native method references. */
+var Uint8Array = global.Uint8Array;
+
+/** Used to lookup a type array constructors by `toStringTag`. */
+var ctorByTag = {};
+ctorByTag[float32Tag] = global.Float32Array;
+ctorByTag[float64Tag] = global.Float64Array;
+ctorByTag[int8Tag] = global.Int8Array;
+ctorByTag[int16Tag] = global.Int16Array;
+ctorByTag[int32Tag] = global.Int32Array;
+ctorByTag[uint8Tag] = Uint8Array;
+ctorByTag[uint8ClampedTag] = global.Uint8ClampedArray;
+ctorByTag[uint16Tag] = global.Uint16Array;
+ctorByTag[uint32Tag] = global.Uint32Array;
+
+/**
+ * Initializes an object clone based on its `toStringTag`.
+ *
+ * **Note:** This function only supports cloning values with tags of
+ * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
+ *
+ * @private
+ * @param {Object} object The object to clone.
+ * @param {string} tag The `toStringTag` of the object to clone.
+ * @param {boolean} [isDeep] Specify a deep clone.
+ * @returns {Object} Returns the initialized clone.
+ */
+function initCloneByTag(object, tag, isDeep) {
+  var Ctor = object.constructor;
+  switch (tag) {
+    case arrayBufferTag:
+      return bufferClone(object);
+
+    case boolTag:
+    case dateTag:
+      return new Ctor(+object);
+
+    case float32Tag: case float64Tag:
+    case int8Tag: case int16Tag: case int32Tag:
+    case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
+      // Safari 5 mobile incorrectly has `Object` as the constructor of typed arrays.
+      if (Ctor instanceof Ctor) {
+        Ctor = ctorByTag[tag];
+      }
+      var buffer = object.buffer;
+      return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length);
+
+    case numberTag:
+    case stringTag:
+      return new Ctor(object);
+
+    case regexpTag:
+      var result = new Ctor(object.source, reFlags.exec(object));
+      result.lastIndex = object.lastIndex;
+  }
+  return result;
+}
+
+module.exports = initCloneByTag;
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+
+},{"./bufferClone":95}],118:[function(require,module,exports){
+/**
+ * Initializes an object clone.
+ *
+ * @private
+ * @param {Object} object The object to clone.
+ * @returns {Object} Returns the initialized clone.
+ */
+function initCloneObject(object) {
+  var Ctor = object.constructor;
+  if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) {
+    Ctor = Object;
+  }
+  return new Ctor;
+}
+
+module.exports = initCloneObject;
+
+},{}],119:[function(require,module,exports){
+var getLength = require('./getLength'),
+    isLength = require('./isLength');
+
+/**
+ * Checks if `value` is array-like.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
+ */
+function isArrayLike(value) {
+  return value != null && isLength(getLength(value));
+}
+
+module.exports = isArrayLike;
+
+},{"./getLength":112,"./isLength":125}],120:[function(require,module,exports){
+/**
+ * Checks if `value` is a host object in IE < 9.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
+ */
+var isHostObject = (function() {
+  try {
+    Object({ 'toString': 0 } + '');
+  } catch(e) {
+    return function() { return false; };
+  }
+  return function(value) {
+    // IE < 9 presents many host objects as `Object` objects that can coerce
+    // to strings despite having improperly defined `toString` methods.
+    return typeof value.toString != 'function' && typeof (value + '') == 'string';
+  };
+}());
+
+module.exports = isHostObject;
+
+},{}],121:[function(require,module,exports){
+/** Used to detect unsigned integer values. */
+var reIsUint = /^\d+$/;
+
+/**
+ * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
+ * of an array-like value.
+ */
+var MAX_SAFE_INTEGER = 9007199254740991;
+
+/**
+ * Checks if `value` is a valid array-like index.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
+ * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
+ */
+function isIndex(value, length) {
+  value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
+  length = length == null ? MAX_SAFE_INTEGER : length;
+  return value > -1 && value % 1 == 0 && value < length;
+}
+
+module.exports = isIndex;
+
+},{}],122:[function(require,module,exports){
+var isArrayLike = require('./isArrayLike'),
+    isIndex = require('./isIndex'),
+    isObject = require('../lang/isObject');
+
+/**
+ * Checks if the provided arguments are from an iteratee call.
+ *
+ * @private
+ * @param {*} value The potential iteratee value argument.
+ * @param {*} index The potential iteratee index or key argument.
+ * @param {*} object The potential iteratee object argument.
+ * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.
+ */
+function isIterateeCall(value, index, object) {
+  if (!isObject(object)) {
+    return false;
+  }
+  var type = typeof index;
+  if (type == 'number'
+      ? (isArrayLike(object) && isIndex(index, object.length))
+      : (type == 'string' && index in object)) {
+    var other = object[index];
+    return value === value ? (value === other) : (other !== other);
+  }
+  return false;
+}
+
+module.exports = isIterateeCall;
+
+},{"../lang/isObject":144,"./isArrayLike":119,"./isIndex":121}],123:[function(require,module,exports){
+var isArray = require('../lang/isArray'),
+    toObject = require('./toObject');
+
+/** Used to match property names within property paths. */
+var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/,
+    reIsPlainProp = /^\w*$/;
+
+/**
+ * Checks if `value` is a property name and not a property path.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @param {Object} [object] The object to query keys on.
+ * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
+ */
+function isKey(value, object) {
+  var type = typeof value;
+  if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') {
+    return true;
+  }
+  if (isArray(value)) {
+    return false;
+  }
+  var result = !reIsDeepProp.test(value);
+  return result || (object != null && value in toObject(object));
+}
+
+module.exports = isKey;
+
+},{"../lang/isArray":140,"./toObject":135}],124:[function(require,module,exports){
+var LazyWrapper = require('./LazyWrapper'),
+    getData = require('./getData'),
+    getFuncName = require('./getFuncName'),
+    lodash = require('../chain/lodash');
+
+/**
+ * Checks if `func` has a lazy counterpart.
+ *
+ * @private
+ * @param {Function} func The function to check.
+ * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`.
+ */
+function isLaziable(func) {
+  var funcName = getFuncName(func),
+      other = lodash[funcName];
+
+  if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
+    return false;
+  }
+  if (func === other) {
+    return true;
+  }
+  var data = getData(other);
+  return !!data && func === data[0];
+}
+
+module.exports = isLaziable;
+
+},{"../chain/lodash":51,"./LazyWrapper":60,"./getData":110,"./getFuncName":111}],125:[function(require,module,exports){
+/**
+ * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
+ * of an array-like value.
+ */
+var MAX_SAFE_INTEGER = 9007199254740991;
+
+/**
+ * Checks if `value` is a valid array-like length.
+ *
+ * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
+ */
+function isLength(value) {
+  return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
+}
+
+module.exports = isLength;
+
+},{}],126:[function(require,module,exports){
+/**
+ * Checks if `value` is object-like.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
+ */
+function isObjectLike(value) {
+  return !!value && typeof value == 'object';
+}
+
+module.exports = isObjectLike;
+
+},{}],127:[function(require,module,exports){
+var isObject = require('../lang/isObject');
+
+/**
+ * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` if suitable for strict
+ *  equality comparisons, else `false`.
+ */
+function isStrictComparable(value) {
+  return value === value && !isObject(value);
+}
+
+module.exports = isStrictComparable;
+
+},{"../lang/isObject":144}],128:[function(require,module,exports){
+var arrayCopy = require('./arrayCopy'),
+    composeArgs = require('./composeArgs'),
+    composeArgsRight = require('./composeArgsRight'),
+    replaceHolders = require('./replaceHolders');
+
+/** Used to compose bitmasks for wrapper metadata. */
+var BIND_FLAG = 1,
+    CURRY_BOUND_FLAG = 4,
+    CURRY_FLAG = 8,
+    ARY_FLAG = 128,
+    REARG_FLAG = 256;
+
+/** Used as the internal argument placeholder. */
+var PLACEHOLDER = '__lodash_placeholder__';
+
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeMin = Math.min;
+
+/**
+ * Merges the function metadata of `source` into `data`.
+ *
+ * Merging metadata reduces the number of wrappers required to invoke a function.
+ * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
+ * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg`
+ * augment function arguments, making the order in which they are executed important,
+ * preventing the merging of metadata. However, we make an exception for a safe
+ * common case where curried functions have `_.ary` and or `_.rearg` applied.
+ *
+ * @private
+ * @param {Array} data The destination metadata.
+ * @param {Array} source The source metadata.
+ * @returns {Array} Returns `data`.
+ */
+function mergeData(data, source) {
+  var bitmask = data[1],
+      srcBitmask = source[1],
+      newBitmask = bitmask | srcBitmask,
+      isCommon = newBitmask < ARY_FLAG;
+
+  var isCombo =
+    (srcBitmask == ARY_FLAG && bitmask == CURRY_FLAG) ||
+    (srcBitmask == ARY_FLAG && bitmask == REARG_FLAG && data[7].length <= source[8]) ||
+    (srcBitmask == (ARY_FLAG | REARG_FLAG) && bitmask == CURRY_FLAG);
+
+  // Exit early if metadata can't be merged.
+  if (!(isCommon || isCombo)) {
+    return data;
+  }
+  // Use source `thisArg` if available.
+  if (srcBitmask & BIND_FLAG) {
+    data[2] = source[2];
+    // Set when currying a bound function.
+    newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG;
+  }
+  // Compose partial arguments.
+  var value = source[3];
+  if (value) {
+    var partials = data[3];
+    data[3] = partials ? composeArgs(partials, value, source[4]) : arrayCopy(value);
+    data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : arrayCopy(source[4]);
+  }
+  // Compose partial right arguments.
+  value = source[5];
+  if (value) {
+    partials = data[5];
+    data[5] = partials ? composeArgsRight(partials, value, source[6]) : arrayCopy(value);
+    data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : arrayCopy(source[6]);
+  }
+  // Use source `argPos` if available.
+  value = source[7];
+  if (value) {
+    data[7] = arrayCopy(value);
+  }
+  // Use source `ary` if it's smaller.
+  if (srcBitmask & ARY_FLAG) {
+    data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
+  }
+  // Use source `arity` if one is not provided.
+  if (data[9] == null) {
+    data[9] = source[9];
+  }
+  // Use source `func` and merge bitmasks.
+  data[0] = source[0];
+  data[1] = newBitmask;
+
+  return data;
+}
+
+module.exports = mergeData;
+
+},{"./arrayCopy":62,"./composeArgs":96,"./composeArgsRight":97,"./replaceHolders":132}],129:[function(require,module,exports){
+(function (global){
+var getNative = require('./getNative');
+
+/** Native method references. */
+var WeakMap = getNative(global, 'WeakMap');
+
+/** Used to store function metadata. */
+var metaMap = WeakMap && new WeakMap;
+
+module.exports = metaMap;
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+
+},{"./getNative":114}],130:[function(require,module,exports){
+/** Used to lookup unminified function names. */
+var realNames = {};
+
+module.exports = realNames;
+
+},{}],131:[function(require,module,exports){
+var arrayCopy = require('./arrayCopy'),
+    isIndex = require('./isIndex');
+
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeMin = Math.min;
+
+/**
+ * Reorder `array` according to the specified indexes where the element at
+ * the first index is assigned as the first element, the element at
+ * the second index is assigned as the second element, and so on.
+ *
+ * @private
+ * @param {Array} array The array to reorder.
+ * @param {Array} indexes The arranged array indexes.
+ * @returns {Array} Returns `array`.
+ */
+function reorder(array, indexes) {
+  var arrLength = array.length,
+      length = nativeMin(indexes.length, arrLength),
+      oldArray = arrayCopy(array);
+
+  while (length--) {
+    var index = indexes[length];
+    array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
+  }
+  return array;
+}
+
+module.exports = reorder;
+
+},{"./arrayCopy":62,"./isIndex":121}],132:[function(require,module,exports){
+/** Used as the internal argument placeholder. */
+var PLACEHOLDER = '__lodash_placeholder__';
+
+/**
+ * Replaces all `placeholder` elements in `array` with an internal placeholder
+ * and returns an array of their indexes.
+ *
+ * @private
+ * @param {Array} array The array to modify.
+ * @param {*} placeholder The placeholder to replace.
+ * @returns {Array} Returns the new array of placeholder indexes.
+ */
+function replaceHolders(array, placeholder) {
+  var index = -1,
+      length = array.length,
+      resIndex = -1,
+      result = [];
+
+  while (++index < length) {
+    if (array[index] === placeholder) {
+      array[index] = PLACEHOLDER;
+      result[++resIndex] = index;
+    }
+  }
+  return result;
+}
+
+module.exports = replaceHolders;
+
+},{}],133:[function(require,module,exports){
+var baseSetData = require('./baseSetData'),
+    now = require('../date/now');
+
+/** Used to detect when a function becomes hot. */
+var HOT_COUNT = 150,
+    HOT_SPAN = 16;
+
+/**
+ * Sets metadata for `func`.
+ *
+ * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
+ * period of time, it will trip its breaker and transition to an identity function
+ * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070)
+ * for more details.
+ *
+ * @private
+ * @param {Function} func The function to associate metadata with.
+ * @param {*} data The metadata.
+ * @returns {Function} Returns `func`.
+ */
+var setData = (function() {
+  var count = 0,
+      lastCalled = 0;
+
+  return function(key, value) {
+    var stamp = now(),
+        remaining = HOT_SPAN - (stamp - lastCalled);
+
+    lastCalled = stamp;
+    if (remaining > 0) {
+      if (++count >= HOT_COUNT) {
+        return key;
+      }
+    } else {
+      count = 0;
+    }
+    return baseSetData(key, value);
+  };
+}());
+
+module.exports = setData;
+
+},{"../date/now":57,"./baseSetData":88}],134:[function(require,module,exports){
+var isArguments = require('../lang/isArguments'),
+    isArray = require('../lang/isArray'),
+    isIndex = require('./isIndex'),
+    isLength = require('./isLength'),
+    isString = require('../lang/isString'),
+    keysIn = require('../object/keysIn');
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/**
+ * A fallback implementation of `Object.keys` which creates an array of the
+ * own enumerable property names of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ */
+function shimKeys(object) {
+  var props = keysIn(object),
+      propsLength = props.length,
+      length = propsLength && object.length;
+
+  var allowIndexes = !!length && isLength(length) &&
+    (isArray(object) || isArguments(object) || isString(object));
+
+  var index = -1,
+      result = [];
+
+  while (++index < propsLength) {
+    var key = props[index];
+    if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) {
+      result.push(key);
+    }
+  }
+  return result;
+}
+
+module.exports = shimKeys;
+
+},{"../lang/isArguments":139,"../lang/isArray":140,"../lang/isString":146,"../object/keysIn":150,"./isIndex":121,"./isLength":125}],135:[function(require,module,exports){
+var isObject = require('../lang/isObject'),
+    isString = require('../lang/isString'),
+    support = require('../support');
+
+/**
+ * Converts `value` to an object if it's not one.
+ *
+ * @private
+ * @param {*} value The value to process.
+ * @returns {Object} Returns the object.
+ */
+function toObject(value) {
+  if (support.unindexedChars && isString(value)) {
+    var index = -1,
+        length = value.length,
+        result = Object(value);
+
+    while (++index < length) {
+      result[index] = value.charAt(index);
+    }
+    return result;
+  }
+  return isObject(value) ? value : Object(value);
+}
+
+module.exports = toObject;
+
+},{"../lang/isObject":144,"../lang/isString":146,"../support":153}],136:[function(require,module,exports){
+var baseToString = require('./baseToString'),
+    isArray = require('../lang/isArray');
+
+/** Used to match property names within property paths. */
+var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g;
+
+/** Used to match backslashes in property paths. */
+var reEscapeChar = /\\(\\)?/g;
+
+/**
+ * Converts `value` to property path array if it's not one.
+ *
+ * @private
+ * @param {*} value The value to process.
+ * @returns {Array} Returns the property path array.
+ */
+function toPath(value) {
+  if (isArray(value)) {
+    return value;
+  }
+  var result = [];
+  baseToString(value).replace(rePropName, function(match, number, quote, string) {
+    result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
+  });
+  return result;
+}
+
+module.exports = toPath;
+
+},{"../lang/isArray":140,"./baseToString":90}],137:[function(require,module,exports){
+var LazyWrapper = require('./LazyWrapper'),
+    LodashWrapper = require('./LodashWrapper'),
+    arrayCopy = require('./arrayCopy');
+
+/**
+ * Creates a clone of `wrapper`.
+ *
+ * @private
+ * @param {Object} wrapper The wrapper to clone.
+ * @returns {Object} Returns the cloned wrapper.
+ */
+function wrapperClone(wrapper) {
+  return wrapper instanceof LazyWrapper
+    ? wrapper.clone()
+    : new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__, arrayCopy(wrapper.__actions__));
+}
+
+module.exports = wrapperClone;
+
+},{"./LazyWrapper":60,"./LodashWrapper":61,"./arrayCopy":62}],138:[function(require,module,exports){
+var baseClone = require('../internal/baseClone'),
+    bindCallback = require('../internal/bindCallback');
+
+/**
+ * Creates a deep clone of `value`. If `customizer` is provided it's invoked
+ * to produce the cloned values. If `customizer` returns `undefined` cloning
+ * is handled by the method instead. The `customizer` is bound to `thisArg`
+ * and invoked with up to three argument; (value [, index|key, object]).
+ *
+ * **Note:** This method is loosely based on the
+ * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm).
+ * The enumerable properties of `arguments` objects and objects created by
+ * constructors other than `Object` are cloned to plain `Object` objects. An
+ * empty object is returned for uncloneable values such as functions, DOM nodes,
+ * Maps, Sets, and WeakMaps.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to deep clone.
+ * @param {Function} [customizer] The function to customize cloning values.
+ * @param {*} [thisArg] The `this` binding of `customizer`.
+ * @returns {*} Returns the deep cloned value.
+ * @example
+ *
+ * var users = [
+ *   { 'user': 'barney' },
+ *   { 'user': 'fred' }
+ * ];
+ *
+ * var deep = _.cloneDeep(users);
+ * deep[0] === users[0];
+ * // => false
+ *
+ * // using a customizer callback
+ * var el = _.cloneDeep(document.body, function(value) {
+ *   if (_.isElement(value)) {
+ *     return value.cloneNode(true);
+ *   }
+ * });
+ *
+ * el === document.body
+ * // => false
+ * el.nodeName
+ * // => BODY
+ * el.childNodes.length;
+ * // => 20
+ */
+function cloneDeep(value, customizer, thisArg) {
+  return typeof customizer == 'function'
+    ? baseClone(value, true, bindCallback(customizer, thisArg, 3))
+    : baseClone(value, true);
+}
+
+module.exports = cloneDeep;
+
+},{"../internal/baseClone":68,"../internal/bindCallback":94}],139:[function(require,module,exports){
+var isArrayLike = require('../internal/isArrayLike'),
+    isObjectLike = require('../internal/isObjectLike');
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/** Native method references. */
+var propertyIsEnumerable = objectProto.propertyIsEnumerable;
+
+/**
+ * Checks if `value` is classified as an `arguments` object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isArguments(function() { return arguments; }());
+ * // => true
+ *
+ * _.isArguments([1, 2, 3]);
+ * // => false
+ */
+function isArguments(value) {
+  return isObjectLike(value) && isArrayLike(value) &&
+    hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee');
+}
+
+module.exports = isArguments;
+
+},{"../internal/isArrayLike":119,"../internal/isObjectLike":126}],140:[function(require,module,exports){
+var getNative = require('../internal/getNative'),
+    isLength = require('../internal/isLength'),
+    isObjectLike = require('../internal/isObjectLike');
+
+/** `Object#toString` result references. */
+var arrayTag = '[object Array]';
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+var objToString = objectProto.toString;
+
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeIsArray = getNative(Array, 'isArray');
+
+/**
+ * Checks if `value` is classified as an `Array` object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isArray([1, 2, 3]);
+ * // => true
+ *
+ * _.isArray(function() { return arguments; }());
+ * // => false
+ */
+var isArray = nativeIsArray || function(value) {
+  return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag;
+};
+
+module.exports = isArray;
+
+},{"../internal/getNative":114,"../internal/isLength":125,"../internal/isObjectLike":126}],141:[function(require,module,exports){
+var isArguments = require('./isArguments'),
+    isArray = require('./isArray'),
+    isArrayLike = require('../internal/isArrayLike'),
+    isFunction = require('./isFunction'),
+    isObjectLike = require('../internal/isObjectLike'),
+    isString = require('./isString'),
+    keys = require('../object/keys');
+
+/**
+ * Checks if `value` is empty. A value is considered empty unless it's an
+ * `arguments` object, array, string, or jQuery-like collection with a length
+ * greater than `0` or an object with own enumerable properties.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {Array|Object|string} value The value to inspect.
+ * @returns {boolean} Returns `true` if `value` is empty, else `false`.
+ * @example
+ *
+ * _.isEmpty(null);
+ * // => true
+ *
+ * _.isEmpty(true);
+ * // => true
+ *
+ * _.isEmpty(1);
+ * // => true
+ *
+ * _.isEmpty([1, 2, 3]);
+ * // => false
+ *
+ * _.isEmpty({ 'a': 1 });
+ * // => false
+ */
+function isEmpty(value) {
+  if (value == null) {
+    return true;
+  }
+  if (isArrayLike(value) && (isArray(value) || isString(value) || isArguments(value) ||
+      (isObjectLike(value) && isFunction(value.splice)))) {
+    return !value.length;
+  }
+  return !keys(value).length;
+}
+
+module.exports = isEmpty;
+
+},{"../internal/isArrayLike":119,"../internal/isObjectLike":126,"../object/keys":149,"./isArguments":139,"./isArray":140,"./isFunction":142,"./isString":146}],142:[function(require,module,exports){
+var isObject = require('./isObject');
+
+/** `Object#toString` result references. */
+var funcTag = '[object Function]';
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+var objToString = objectProto.toString;
+
+/**
+ * Checks if `value` is classified as a `Function` object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isFunction(_);
+ * // => true
+ *
+ * _.isFunction(/abc/);
+ * // => false
+ */
+function isFunction(value) {
+  // The use of `Object#toString` avoids issues with the `typeof` operator
+  // in older versions of Chrome and Safari which return 'function' for regexes
+  // and Safari 8 which returns 'object' for typed array constructors.
+  return isObject(value) && objToString.call(value) == funcTag;
+}
+
+module.exports = isFunction;
+
+},{"./isObject":144}],143:[function(require,module,exports){
+var isFunction = require('./isFunction'),
+    isHostObject = require('../internal/isHostObject'),
+    isObjectLike = require('../internal/isObjectLike');
+
+/** Used to detect host constructors (Safari > 5). */
+var reIsHostCtor = /^\[object .+?Constructor\]$/;
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/** Used to resolve the decompiled source of functions. */
+var fnToString = Function.prototype.toString;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/** Used to detect if a method is native. */
+var reIsNative = RegExp('^' +
+  fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&')
+  .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
+);
+
+/**
+ * Checks if `value` is a native function.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a native function, else `false`.
+ * @example
+ *
+ * _.isNative(Array.prototype.push);
+ * // => true
+ *
+ * _.isNative(_);
+ * // => false
+ */
+function isNative(value) {
+  if (value == null) {
+    return false;
+  }
+  if (isFunction(value)) {
+    return reIsNative.test(fnToString.call(value));
+  }
+  return isObjectLike(value) && (isHostObject(value) ? reIsNative : reIsHostCtor).test(value);
+}
+
+module.exports = isNative;
+
+},{"../internal/isHostObject":120,"../internal/isObjectLike":126,"./isFunction":142}],144:[function(require,module,exports){
+/**
+ * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
+ * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an object, else `false`.
+ * @example
+ *
+ * _.isObject({});
+ * // => true
+ *
+ * _.isObject([1, 2, 3]);
+ * // => true
+ *
+ * _.isObject(1);
+ * // => false
+ */
+function isObject(value) {
+  // Avoid a V8 JIT bug in Chrome 19-20.
+  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
+  var type = typeof value;
+  return !!value && (type == 'object' || type == 'function');
+}
+
+module.exports = isObject;
+
+},{}],145:[function(require,module,exports){
+var baseForIn = require('../internal/baseForIn'),
+    isArguments = require('./isArguments'),
+    isHostObject = require('../internal/isHostObject'),
+    isObjectLike = require('../internal/isObjectLike'),
+    support = require('../support');
+
+/** `Object#toString` result references. */
+var objectTag = '[object Object]';
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+var objToString = objectProto.toString;
+
+/**
+ * Checks if `value` is a plain object, that is, an object created by the
+ * `Object` constructor or one with a `[[Prototype]]` of `null`.
+ *
+ * **Note:** This method assumes objects created by the `Object` constructor
+ * have no inherited enumerable properties.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
+ * @example
+ *
+ * function Foo() {
+ *   this.a = 1;
+ * }
+ *
+ * _.isPlainObject(new Foo);
+ * // => false
+ *
+ * _.isPlainObject([1, 2, 3]);
+ * // => false
+ *
+ * _.isPlainObject({ 'x': 0, 'y': 0 });
+ * // => true
+ *
+ * _.isPlainObject(Object.create(null));
+ * // => true
+ */
+function isPlainObject(value) {
+  var Ctor;
+
+  // Exit early for non `Object` objects.
+  if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isHostObject(value) && !isArguments(value)) ||
+      (!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) {
+    return false;
+  }
+  // IE < 9 iterates inherited properties before own properties. If the first
+  // iterated property is an object's own property then there are no inherited
+  // enumerable properties.
+  var result;
+  if (support.ownLast) {
+    baseForIn(value, function(subValue, key, object) {
+      result = hasOwnProperty.call(object, key);
+      return false;
+    });
+    return result !== false;
+  }
+  // In most environments an object's own properties are iterated before
+  // its inherited properties. If the last iterated property is an object's
+  // own property then there are no inherited enumerable properties.
+  baseForIn(value, function(subValue, key) {
+    result = key;
+  });
+  return result === undefined || hasOwnProperty.call(value, result);
+}
+
+module.exports = isPlainObject;
+
+},{"../internal/baseForIn":75,"../internal/isHostObject":120,"../internal/isObjectLike":126,"../support":153,"./isArguments":139}],146:[function(require,module,exports){
+var isObjectLike = require('../internal/isObjectLike');
+
+/** `Object#toString` result references. */
+var stringTag = '[object String]';
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+var objToString = objectProto.toString;
+
+/**
+ * Checks if `value` is classified as a `String` primitive or object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isString('abc');
+ * // => true
+ *
+ * _.isString(1);
+ * // => false
+ */
+function isString(value) {
+  return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag);
+}
+
+module.exports = isString;
+
+},{"../internal/isObjectLike":126}],147:[function(require,module,exports){
+var isLength = require('../internal/isLength'),
+    isObjectLike = require('../internal/isObjectLike');
+
+/** `Object#toString` result references. */
+var argsTag = '[object Arguments]',
+    arrayTag = '[object Array]',
+    boolTag = '[object Boolean]',
+    dateTag = '[object Date]',
+    errorTag = '[object Error]',
+    funcTag = '[object Function]',
+    mapTag = '[object Map]',
+    numberTag = '[object Number]',
+    objectTag = '[object Object]',
+    regexpTag = '[object RegExp]',
+    setTag = '[object Set]',
+    stringTag = '[object String]',
+    weakMapTag = '[object WeakMap]';
+
+var arrayBufferTag = '[object ArrayBuffer]',
+    float32Tag = '[object Float32Array]',
+    float64Tag = '[object Float64Array]',
+    int8Tag = '[object Int8Array]',
+    int16Tag = '[object Int16Array]',
+    int32Tag = '[object Int32Array]',
+    uint8Tag = '[object Uint8Array]',
+    uint8ClampedTag = '[object Uint8ClampedArray]',
+    uint16Tag = '[object Uint16Array]',
+    uint32Tag = '[object Uint32Array]';
+
+/** Used to identify `toStringTag` values of typed arrays. */
+var typedArrayTags = {};
+typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
+typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
+typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
+typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
+typedArrayTags[uint32Tag] = true;
+typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
+typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
+typedArrayTags[dateTag] = typedArrayTags[errorTag] =
+typedArrayTags[funcTag] = typedArrayTags[mapTag] =
+typedArrayTags[numberTag] = typedArrayTags[objectTag] =
+typedArrayTags[regexpTag] = typedArrayTags[setTag] =
+typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+var objToString = objectProto.toString;
+
+/**
+ * Checks if `value` is classified as a typed array.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isTypedArray(new Uint8Array);
+ * // => true
+ *
+ * _.isTypedArray([]);
+ * // => false
+ */
+function isTypedArray(value) {
+  return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];
+}
+
+module.exports = isTypedArray;
+
+},{"../internal/isLength":125,"../internal/isObjectLike":126}],148:[function(require,module,exports){
+/**
+ * Checks if `value` is `undefined`.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
+ * @example
+ *
+ * _.isUndefined(void 0);
+ * // => true
+ *
+ * _.isUndefined(null);
+ * // => false
+ */
+function isUndefined(value) {
+  return value === undefined;
+}
+
+module.exports = isUndefined;
+
+},{}],149:[function(require,module,exports){
+var getNative = require('../internal/getNative'),
+    isArrayLike = require('../internal/isArrayLike'),
+    isObject = require('../lang/isObject'),
+    shimKeys = require('../internal/shimKeys'),
+    support = require('../support');
+
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeKeys = getNative(Object, 'keys');
+
+/**
+ * Creates an array of the own enumerable property names of `object`.
+ *
+ * **Note:** Non-object values are coerced to objects. See the
+ * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
+ * for more details.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ * @example
+ *
+ * function Foo() {
+ *   this.a = 1;
+ *   this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.keys(new Foo);
+ * // => ['a', 'b'] (iteration order is not guaranteed)
+ *
+ * _.keys('hi');
+ * // => ['0', '1']
+ */
+var keys = !nativeKeys ? shimKeys : function(object) {
+  var Ctor = object == null ? undefined : object.constructor;
+  if ((typeof Ctor == 'function' && Ctor.prototype === object) ||
+      (typeof object == 'function' ? support.enumPrototypes : isArrayLike(object))) {
+    return shimKeys(object);
+  }
+  return isObject(object) ? nativeKeys(object) : [];
+};
+
+module.exports = keys;
+
+},{"../internal/getNative":114,"../internal/isArrayLike":119,"../internal/shimKeys":134,"../lang/isObject":144,"../support":153}],150:[function(require,module,exports){
+var arrayEach = require('../internal/arrayEach'),
+    isArguments = require('../lang/isArguments'),
+    isArray = require('../lang/isArray'),
+    isFunction = require('../lang/isFunction'),
+    isIndex = require('../internal/isIndex'),
+    isLength = require('../internal/isLength'),
+    isObject = require('../lang/isObject'),
+    isString = require('../lang/isString'),
+    support = require('../support');
+
+/** `Object#toString` result references. */
+var arrayTag = '[object Array]',
+    boolTag = '[object Boolean]',
+    dateTag = '[object Date]',
+    errorTag = '[object Error]',
+    funcTag = '[object Function]',
+    numberTag = '[object Number]',
+    objectTag = '[object Object]',
+    regexpTag = '[object RegExp]',
+    stringTag = '[object String]';
+
+/** Used to fix the JScript `[[DontEnum]]` bug. */
+var shadowProps = [
+  'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',
+  'toLocaleString', 'toString', 'valueOf'
+];
+
+/** Used for native method references. */
+var errorProto = Error.prototype,
+    objectProto = Object.prototype,
+    stringProto = String.prototype;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+var objToString = objectProto.toString;
+
+/** Used to avoid iterating over non-enumerable properties in IE < 9. */
+var nonEnumProps = {};
+nonEnumProps[arrayTag] = nonEnumProps[dateTag] = nonEnumProps[numberTag] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true };
+nonEnumProps[boolTag] = nonEnumProps[stringTag] = { 'constructor': true, 'toString': true, 'valueOf': true };
+nonEnumProps[errorTag] = nonEnumProps[funcTag] = nonEnumProps[regexpTag] = { 'constructor': true, 'toString': true };
+nonEnumProps[objectTag] = { 'constructor': true };
+
+arrayEach(shadowProps, function(key) {
+  for (var tag in nonEnumProps) {
+    if (hasOwnProperty.call(nonEnumProps, tag)) {
+      var props = nonEnumProps[tag];
+      props[key] = hasOwnProperty.call(props, key);
+    }
+  }
+});
+
+/**
+ * Creates an array of the own and inherited enumerable property names of `object`.
+ *
+ * **Note:** Non-object values are coerced to objects.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ * @example
+ *
+ * function Foo() {
+ *   this.a = 1;
+ *   this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.keysIn(new Foo);
+ * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
+ */
+function keysIn(object) {
+  if (object == null) {
+    return [];
+  }
+  if (!isObject(object)) {
+    object = Object(object);
+  }
+  var length = object.length;
+
+  length = (length && isLength(length) &&
+    (isArray(object) || isArguments(object) || isString(object)) && length) || 0;
+
+  var Ctor = object.constructor,
+      index = -1,
+      proto = (isFunction(Ctor) && Ctor.prototype) || objectProto,
+      isProto = proto === object,
+      result = Array(length),
+      skipIndexes = length > 0,
+      skipErrorProps = support.enumErrorProps && (object === errorProto || object instanceof Error),
+      skipProto = support.enumPrototypes && isFunction(object);
+
+  while (++index < length) {
+    result[index] = (index + '');
+  }
+  // lodash skips the `constructor` property when it infers it's iterating
+  // over a `prototype` object because IE < 9 can't set the `[[Enumerable]]`
+  // attribute of an existing property and the `constructor` property of a
+  // prototype defaults to non-enumerable.
+  for (var key in object) {
+    if (!(skipProto && key == 'prototype') &&
+        !(skipErrorProps && (key == 'message' || key == 'name')) &&
+        !(skipIndexes && isIndex(key, length)) &&
+        !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
+      result.push(key);
+    }
+  }
+  if (support.nonEnumShadows && object !== objectProto) {
+    var tag = object === stringProto ? stringTag : (object === errorProto ? errorTag : objToString.call(object)),
+        nonEnums = nonEnumProps[tag] || nonEnumProps[objectTag];
+
+    if (tag == objectTag) {
+      proto = objectProto;
+    }
+    length = shadowProps.length;
+    while (length--) {
+      key = shadowProps[length];
+      var nonEnum = nonEnums[key];
+      if (!(isProto && nonEnum) &&
+          (nonEnum ? hasOwnProperty.call(object, key) : object[key] !== proto[key])) {
+        result.push(key);
+      }
+    }
+  }
+  return result;
+}
+
+module.exports = keysIn;
+
+},{"../internal/arrayEach":63,"../internal/isIndex":121,"../internal/isLength":125,"../lang/isArguments":139,"../lang/isArray":140,"../lang/isFunction":142,"../lang/isObject":144,"../lang/isString":146,"../support":153}],151:[function(require,module,exports){
+var keys = require('./keys'),
+    toObject = require('../internal/toObject');
+
+/**
+ * Creates a two dimensional array of the key-value pairs for `object`,
+ * e.g. `[[key1, value1], [key2, value2]]`.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the new array of key-value pairs.
+ * @example
+ *
+ * _.pairs({ 'barney': 36, 'fred': 40 });
+ * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed)
+ */
+function pairs(object) {
+  object = toObject(object);
+
+  var index = -1,
+      props = keys(object),
+      length = props.length,
+      result = Array(length);
+
+  while (++index < length) {
+    var key = props[index];
+    result[index] = [key, object[key]];
+  }
+  return result;
+}
+
+module.exports = pairs;
+
+},{"../internal/toObject":135,"./keys":149}],152:[function(require,module,exports){
+var baseValues = require('../internal/baseValues'),
+    keys = require('./keys');
+
+/**
+ * Creates an array of the own enumerable property values of `object`.
+ *
+ * **Note:** Non-object values are coerced to objects.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property values.
+ * @example
+ *
+ * function Foo() {
+ *   this.a = 1;
+ *   this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.values(new Foo);
+ * // => [1, 2] (iteration order is not guaranteed)
+ *
+ * _.values('hi');
+ * // => ['h', 'i']
+ */
+function values(object) {
+  return baseValues(object, keys(object));
+}
+
+module.exports = values;
+
+},{"../internal/baseValues":91,"./keys":149}],153:[function(require,module,exports){
+/** Used for native method references. */
+var arrayProto = Array.prototype,
+    errorProto = Error.prototype,
+    objectProto = Object.prototype;
+
+/** Native method references. */
+var propertyIsEnumerable = objectProto.propertyIsEnumerable,
+    splice = arrayProto.splice;
+
+/**
+ * An object environment feature flags.
+ *
+ * @static
+ * @memberOf _
+ * @type Object
+ */
+var support = {};
+
+(function(x) {
+  var Ctor = function() { this.x = x; },
+      object = { '0': x, 'length': x },
+      props = [];
+
+  Ctor.prototype = { 'valueOf': x, 'y': x };
+  for (var key in new Ctor) { props.push(key); }
+
+  /**
+   * Detect if `name` or `message` properties of `Error.prototype` are
+   * enumerable by default (IE < 9, Safari < 5.1).
+   *
+   * @memberOf _.support
+   * @type boolean
+   */
+  support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') ||
+    propertyIsEnumerable.call(errorProto, 'name');
+
+  /**
+   * Detect if `prototype` properties are enumerable by default.
+   *
+   * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1
+   * (if the prototype or a property on the prototype has been set)
+   * incorrectly set the `[[Enumerable]]` value of a function's `prototype`
+   * property to `true`.
+   *
+   * @memberOf _.support
+   * @type boolean
+   */
+  support.enumPrototypes = propertyIsEnumerable.call(Ctor, 'prototype');
+
+  /**
+   * Detect if properties shadowing those on `Object.prototype` are non-enumerable.
+   *
+   * In IE < 9 an object's own properties, shadowing non-enumerable ones,
+   * are made non-enumerable as well (a.k.a the JScript `[[DontEnum]]` bug).
+   *
+   * @memberOf _.support
+   * @type boolean
+   */
+  support.nonEnumShadows = !/valueOf/.test(props);
+
+  /**
+   * Detect if own properties are iterated after inherited properties (IE < 9).
+   *
+   * @memberOf _.support
+   * @type boolean
+   */
+  support.ownLast = props[0] != 'x';
+
+  /**
+   * Detect if `Array#shift` and `Array#splice` augment array-like objects
+   * correctly.
+   *
+   * Firefox < 10, compatibility modes of IE 8, and IE < 9 have buggy Array
+   * `shift()` and `splice()` functions that fail to remove the last element,
+   * `value[0]`, of array-like objects even though the "length" property is
+   * set to `0`. The `shift()` method is buggy in compatibility modes of IE 8,
+   * while `splice()` is buggy regardless of mode in IE < 9.
+   *
+   * @memberOf _.support
+   * @type boolean
+   */
+  support.spliceObjects = (splice.call(object, 0, 1), !object[0]);
+
+  /**
+   * Detect lack of support for accessing string characters by index.
+   *
+   * IE < 8 can't access characters by index. IE 8 can only access characters
+   * by index on string literals, not string objects.
+   *
+   * @memberOf _.support
+   * @type boolean
+   */
+  support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx';
+}(1, 0));
+
+module.exports = support;
+
+},{}],154:[function(require,module,exports){
+/**
+ * This method returns the first argument provided to it.
+ *
+ * @static
+ * @memberOf _
+ * @category Utility
+ * @param {*} value Any value.
+ * @returns {*} Returns `value`.
+ * @example
+ *
+ * var object = { 'user': 'fred' };
+ *
+ * _.identity(object) === object;
+ * // => true
+ */
+function identity(value) {
+  return value;
+}
+
+module.exports = identity;
+
+},{}],155:[function(require,module,exports){
+/**
+ * A no-operation function that returns `undefined` regardless of the
+ * arguments it receives.
+ *
+ * @static
+ * @memberOf _
+ * @category Utility
+ * @example
+ *
+ * var object = { 'user': 'fred' };
+ *
+ * _.noop(object) === undefined;
+ * // => true
+ */
+function noop() {
+  // No operation performed.
+}
+
+module.exports = noop;
+
+},{}],156:[function(require,module,exports){
+var baseProperty = require('../internal/baseProperty'),
+    basePropertyDeep = require('../internal/basePropertyDeep'),
+    isKey = require('../internal/isKey');
+
+/**
+ * Creates a function that returns the property value at `path` on a
+ * given object.
+ *
+ * @static
+ * @memberOf _
+ * @category Utility
+ * @param {Array|string} path The path of the property to get.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var objects = [
+ *   { 'a': { 'b': { 'c': 2 } } },
+ *   { 'a': { 'b': { 'c': 1 } } }
+ * ];
+ *
+ * _.map(objects, _.property('a.b.c'));
+ * // => [2, 1]
+ *
+ * _.pluck(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c');
+ * // => [1, 2]
+ */
+function property(path) {
+  return isKey(path) ? baseProperty(path) : basePropertyDeep(path);
+}
+
+module.exports = property;
+
+},{"../internal/baseProperty":86,"../internal/basePropertyDeep":87,"../internal/isKey":123}],157:[function(require,module,exports){
+(function (process){
+// vim:ts=4:sts=4:sw=4:
+/*!
+ *
+ * Copyright 2009-2012 Kris Kowal under the terms of the MIT
+ * license found at http://github.com/kriskowal/q/raw/master/LICENSE
+ *
+ * With parts by Tyler Close
+ * Copyright 2007-2009 Tyler Close under the terms of the MIT X license found
+ * at http://www.opensource.org/licenses/mit-license.html
+ * Forked at ref_send.js version: 2009-05-11
+ *
+ * With parts by Mark Miller
+ * Copyright (C) 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+(function (definition) {
+    "use strict";
+
+    // This file will function properly as a <script> tag, or a module
+    // using CommonJS and NodeJS or RequireJS module formats.  In
+    // Common/Node/RequireJS, the module exports the Q API and when
+    // executed as a simple <script>, it creates a Q global instead.
+
+    // Montage Require
+    if (typeof bootstrap === "function") {
+        bootstrap("promise", definition);
+
+    // CommonJS
+    } else if (typeof exports === "object" && typeof module === "object") {
+        module.exports = definition();
+
+    // RequireJS
+    } else if (typeof define === "function" && define.amd) {
+        define(definition);
+
+    // SES (Secure EcmaScript)
+    } else if (typeof ses !== "undefined") {
+        if (!ses.ok()) {
+            return;
+        } else {
+            ses.makeQ = definition;
+        }
+
+    // <script>
+    } else if (typeof window !== "undefined" || typeof self !== "undefined") {
+        // Prefer window over self for add-on scripts. Use self for
+        // non-windowed contexts.
+        var global = typeof window !== "undefined" ? window : self;
+
+        // Get the `window` object, save the previous Q global
+        // and initialize Q as a global.
+        var previousQ = global.Q;
+        global.Q = definition();
+
+        // Add a noConflict function so Q can be removed from the
+        // global namespace.
+        global.Q.noConflict = function () {
+            global.Q = previousQ;
+            return this;
+        };
+
+    } else {
+        throw new Error("This environment was not anticipated by Q. Please file a bug.");
+    }
+
+})(function () {
+"use strict";
+
+var hasStacks = false;
+try {
+    throw new Error();
+} catch (e) {
+    hasStacks = !!e.stack;
+}
+
+// All code after this point will be filtered from stack traces reported
+// by Q.
+var qStartingLine = captureLine();
+var qFileName;
+
+// shims
+
+// used for fallback in "allResolved"
+var noop = function () {};
+
+// Use the fastest possible means to execute a task in a future turn
+// of the event loop.
+var nextTick =(function () {
+    // linked list of tasks (single, with head node)
+    var head = {task: void 0, next: null};
+    var tail = head;
+    var flushing = false;
+    var requestTick = void 0;
+    var isNodeJS = false;
+    // queue for late tasks, used by unhandled rejection tracking
+    var laterQueue = [];
+
+    function flush() {
+        /* jshint loopfunc: true */
+        var task, domain;
+
+        while (head.next) {
+            head = head.next;
+            task = head.task;
+            head.task = void 0;
+            domain = head.domain;
+
+            if (domain) {
+                head.domain = void 0;
+                domain.enter();
+            }
+            runSingle(task, domain);
+
+        }
+        while (laterQueue.length) {
+            task = laterQueue.pop();
+            runSingle(task);
+        }
+        flushing = false;
+    }
+    // runs a single function in the async queue
+    function runSingle(task, domain) {
+        try {
+            task();
+
+        } catch (e) {
+            if (isNodeJS) {
+                // In node, uncaught exceptions are considered fatal errors.
+                // Re-throw them synchronously to interrupt flushing!
+
+                // Ensure continuation if the uncaught exception is suppressed
+                // listening "uncaughtException" events (as domains does).
+                // Continue in next event to avoid tick recursion.
+                if (domain) {
+                    domain.exit();
+                }
+                setTimeout(flush, 0);
+                if (domain) {
+                    domain.enter();
+                }
+
+                throw e;
+
+            } else {
+                // In browsers, uncaught exceptions are not fatal.
+                // Re-throw them asynchronously to avoid slow-downs.
+                setTimeout(function () {
+                    throw e;
+                }, 0);
+            }
+        }
+
+        if (domain) {
+            domain.exit();
+        }
+    }
+
+    nextTick = function (task) {
+        tail = tail.next = {
+            task: task,
+            domain: isNodeJS && process.domain,
+            next: null
+        };
+
+        if (!flushing) {
+            flushing = true;
+            requestTick();
+        }
+    };
+
+    if (typeof process === "object" &&
+        process.toString() === "[object process]" && process.nextTick) {
+        // Ensure Q is in a real Node environment, with a `process.nextTick`.
+        // To see through fake Node environments:
+        // * Mocha test runner - exposes a `process` global without a `nextTick`
+        // * Browserify - exposes a `process.nexTick` function that uses
+        //   `setTimeout`. In this case `setImmediate` is preferred because
+        //    it is faster. Browserify's `process.toString()` yields
+        //   "[object Object]", while in a real Node environment
+        //   `process.nextTick()` yields "[object process]".
+        isNodeJS = true;
+
+        requestTick = function () {
+            process.nextTick(flush);
+        };
+
+    } else if (typeof setImmediate === "function") {
+        // In IE10, Node.js 0.9+, or https://github.com/NobleJS/setImmediate
+        if (typeof window !== "undefined") {
+            requestTick = setImmediate.bind(window, flush);
+        } else {
+            requestTick = function () {
+                setImmediate(flush);
+            };
+        }
+
+    } else if (typeof MessageChannel !== "undefined") {
+        // modern browsers
+        // http://www.nonblocking.io/2011/06/windownexttick.html
+        var channel = new MessageChannel();
+        // At least Safari Version 6.0.5 (8536.30.1) intermittently cannot create
+        // working message ports the first time a page loads.
+        channel.port1.onmessage = function () {
+            requestTick = requestPortTick;
+            channel.port1.onmessage = flush;
+            flush();
+        };
+        var requestPortTick = function () {
+            // Opera requires us to provide a message payload, regardless of
+            // whether we use it.
+            channel.port2.postMessage(0);
+        };
+        requestTick = function () {
+            setTimeout(flush, 0);
+            requestPortTick();
+        };
+
+    } else {
+        // old browsers
+        requestTick = function () {
+            setTimeout(flush, 0);
+        };
+    }
+    // runs a task after all other tasks have been run
+    // this is useful for unhandled rejection tracking that needs to happen
+    // after all `then`d tasks have been run.
+    nextTick.runAfter = function (task) {
+        laterQueue.push(task);
+        if (!flushing) {
+            flushing = true;
+            requestTick();
+        }
+    };
+    return nextTick;
+})();
+
+// Attempt to make generics safe in the face of downstream
+// modifications.
+// There is no situation where this is necessary.
+// If you need a security guarantee, these primordials need to be
+// deeply frozen anyway, and if you don’t need a security guarantee,
+// this is just plain paranoid.
+// However, this **might** have the nice side-effect of reducing the size of
+// the minified code by reducing x.call() to merely x()
+// See Mark Miller’s explanation of what this does.
+// http://wiki.ecmascript.org/doku.php?id=conventions:safe_meta_programming
+var call = Function.call;
+function uncurryThis(f) {
+    return function () {
+        return call.apply(f, arguments);
+    };
+}
+// This is equivalent, but slower:
+// uncurryThis = Function_bind.bind(Function_bind.call);
+// http://jsperf.com/uncurrythis
+
+var array_slice = uncurryThis(Array.prototype.slice);
+
+var array_reduce = uncurryThis(
+    Array.prototype.reduce || function (callback, basis) {
+        var index = 0,
+            length = this.length;
+        // concerning the initial value, if one is not provided
+        if (arguments.length === 1) {
+            // seek to the first value in the array, accounting
+            // for the possibility that is is a sparse array
+            do {
+                if (index in this) {
+                    basis = this[index++];
+                    break;
+                }
+                if (++index >= length) {
+                    throw new TypeError();
+                }
+            } while (1);
+        }
+        // reduce
+        for (; index < length; index++) {
+            // account for the possibility that the array is sparse
+            if (index in this) {
+                basis = callback(basis, this[index], index);
+            }
+        }
+        return basis;
+    }
+);
+
+var array_indexOf = uncurryThis(
+    Array.prototype.indexOf || function (value) {
+        // not a very good shim, but good enough for our one use of it
+        for (var i = 0; i < this.length; i++) {
+            if (this[i] === value) {
+                return i;
+            }
+        }
+        return -1;
+    }
+);
+
+var array_map = uncurryThis(
+    Array.prototype.map || function (callback, thisp) {
+        var self = this;
+        var collect = [];
+        array_reduce(self, function (undefined, value, index) {
+            collect.push(callback.call(thisp, value, index, self));
+        }, void 0);
+        return collect;
+    }
+);
+
+var object_create = Object.create || function (prototype) {
+    function Type() { }
+    Type.prototype = prototype;
+    return new Type();
+};
+
+var object_hasOwnProperty = uncurryThis(Object.prototype.hasOwnProperty);
+
+var object_keys = Object.keys || function (object) {
+    var keys = [];
+    for (var key in object) {
+        if (object_hasOwnProperty(object, key)) {
+            keys.push(key);
+        }
+    }
+    return keys;
+};
+
+var object_toString = uncurryThis(Object.prototype.toString);
+
+function isObject(value) {
+    return value === Object(value);
+}
+
+// generator related shims
+
+// FIXME: Remove this function once ES6 generators are in SpiderMonkey.
+function isStopIteration(exception) {
+    return (
+        object_toString(exception) === "[object StopIteration]" ||
+        exception instanceof QReturnValue
+    );
+}
+
+// FIXME: Remove this helper and Q.return once ES6 generators are in
+// SpiderMonkey.
+var QReturnValue;
+if (typeof ReturnValue !== "undefined") {
+    QReturnValue = ReturnValue;
+} else {
+    QReturnValue = function (value) {
+        this.value = value;
+    };
+}
+
+// long stack traces
+
+var STACK_JUMP_SEPARATOR = "From previous event:";
+
+function makeStackTraceLong(error, promise) {
+    // If possible, transform the error stack trace by removing Node and Q
+    // cruft, then concatenating with the stack trace of `promise`. See #57.
+    if (hasStacks &&
+        promise.stack &&
+        typeof error === "object" &&
+        error !== null &&
+        error.stack &&
+        error.stack.indexOf(STACK_JUMP_SEPARATOR) === -1
+    ) {
+        var stacks = [];
+        for (var p = promise; !!p; p = p.source) {
+            if (p.stack) {
+                stacks.unshift(p.stack);
+            }
+        }
+        stacks.unshift(error.stack);
+
+        var concatedStacks = stacks.join("\n" + STACK_JUMP_SEPARATOR + "\n");
+        error.stack = filterStackString(concatedStacks);
+    }
+}
+
+function filterStackString(stackString) {
+    var lines = stackString.split("\n");
+    var desiredLines = [];
+    for (var i = 0; i < lines.length; ++i) {
+        var line = lines[i];
+
+        if (!isInternalFrame(line) && !isNodeFrame(line) && line) {
+            desiredLines.push(line);
+        }
+    }
+    return desiredLines.join("\n");
+}
+
+function isNodeFrame(stackLine) {
+    return stackLine.indexOf("(module.js:") !== -1 ||
+           stackLine.indexOf("(node.js:") !== -1;
+}
+
+function getFileNameAndLineNumber(stackLine) {
+    // Named functions: "at functionName (filename:lineNumber:columnNumber)"
+    // In IE10 function name can have spaces ("Anonymous function") O_o
+    var attempt1 = /at .+ \((.+):(\d+):(?:\d+)\)$/.exec(stackLine);
+    if (attempt1) {
+        return [attempt1[1], Number(attempt1[2])];
+    }
+
+    // Anonymous functions: "at filename:lineNumber:columnNumber"
+    var attempt2 = /at ([^ ]+):(\d+):(?:\d+)$/.exec(stackLine);
+    if (attempt2) {
+        return [attempt2[1], Number(attempt2[2])];
+    }
+
+    // Firefox style: "function@filename:lineNumber or @filename:lineNumber"
+    var attempt3 = /.*@(.+):(\d+)$/.exec(stackLine);
+    if (attempt3) {
+        return [attempt3[1], Number(attempt3[2])];
+    }
+}
+
+function isInternalFrame(stackLine) {
+    var fileNameAndLineNumber = getFileNameAndLineNumber(stackLine);
+
+    if (!fileNameAndLineNumber) {
+        return false;
+    }
+
+    var fileName = fileNameAndLineNumber[0];
+    var lineNumber = fileNameAndLineNumber[1];
+
+    return fileName === qFileName &&
+        lineNumber >= qStartingLine &&
+        lineNumber <= qEndingLine;
+}
+
+// discover own file name and line number range for filtering stack
+// traces
+function captureLine() {
+    if (!hasStacks) {
+        return;
+    }
+
+    try {
+        throw new Error();
+    } catch (e) {
+        var lines = e.stack.split("\n");
+        var firstLine = lines[0].indexOf("@") > 0 ? lines[1] : lines[2];
+        var fileNameAndLineNumber = getFileNameAndLineNumber(firstLine);
+        if (!fileNameAndLineNumber) {
+            return;
+        }
+
+        qFileName = fileNameAndLineNumber[0];
+        return fileNameAndLineNumber[1];
+    }
+}
+
+function deprecate(callback, name, alternative) {
+    return function () {
+        if (typeof console !== "undefined" &&
+            typeof console.warn === "function") {
+            console.warn(name + " is deprecated, use " + alternative +
+                         " instead.", new Error("").stack);
+        }
+        return callback.apply(callback, arguments);
+    };
+}
+
+// end of shims
+// beginning of real work
+
+/**
+ * Constructs a promise for an immediate reference, passes promises through, or
+ * coerces promises from different systems.
+ * @param value immediate reference or promise
+ */
+function Q(value) {
+    // If the object is already a Promise, return it directly.  This enables
+    // the resolve function to both be used to created references from objects,
+    // but to tolerably coerce non-promises to promises.
+    if (value instanceof Promise) {
+        return value;
+    }
+
+    // assimilate thenables
+    if (isPromiseAlike(value)) {
+        return coerce(value);
+    } else {
+        return fulfill(value);
+    }
+}
+Q.resolve = Q;
+
+/**
+ * Performs a task in a future turn of the event loop.
+ * @param {Function} task
+ */
+Q.nextTick = nextTick;
+
+/**
+ * Controls whether or not long stack traces will be on
+ */
+Q.longStackSupport = false;
+
+// enable long stacks if Q_DEBUG is set
+if (typeof process === "object" && process && process.env && process.env.Q_DEBUG) {
+    Q.longStackSupport = true;
+}
+
+/**
+ * Constructs a {promise, resolve, reject} object.
+ *
+ * `resolve` is a callback to invoke with a more resolved value for the
+ * promise. To fulfill the promise, invoke `resolve` with any value that is
+ * not a thenable. To reject the promise, invoke `resolve` with a rejected
+ * thenable, or invoke `reject` with the reason directly. To resolve the
+ * promise to another thenable, thus putting it in the same state, invoke
+ * `resolve` with that other thenable.
+ */
+Q.defer = defer;
+function defer() {
+    // if "messages" is an "Array", that indicates that the promise has not yet
+    // been resolved.  If it is "undefined", it has been resolved.  Each
+    // element of the messages array is itself an array of complete arguments to
+    // forward to the resolved promise.  We coerce the resolution value to a
+    // promise using the `resolve` function because it handles both fully
+    // non-thenable values and other thenables gracefully.
+    var messages = [], progressListeners = [], resolvedPromise;
+
+    var deferred = object_create(defer.prototype);
+    var promise = object_create(Promise.prototype);
+
+    promise.promiseDispatch = function (resolve, op, operands) {
+        var args = array_slice(arguments);
+        if (messages) {
+            messages.push(args);
+            if (op === "when" && operands[1]) { // progress operand
+                progressListeners.push(operands[1]);
+            }
+        } else {
+            Q.nextTick(function () {
+                resolvedPromise.promiseDispatch.apply(resolvedPromise, args);
+            });
+        }
+    };
+
+    // XXX deprecated
+    promise.valueOf = function () {
+        if (messages) {
+            return promise;
+        }
+        var nearerValue = nearer(resolvedPromise);
+        if (isPromise(nearerValue)) {
+            resolvedPromise = nearerValue; // shorten chain
+        }
+        return nearerValue;
+    };
+
+    promise.inspect = function () {
+        if (!resolvedPromise) {
+            return { state: "pending" };
+        }
+        return resolvedPromise.inspect();
+    };
+
+    if (Q.longStackSupport && hasStacks) {
+        try {
+            throw new Error();
+        } catch (e) {
+            // NOTE: don't try to use `Error.captureStackTrace` or transfer the
+            // accessor around; that causes memory leaks as per GH-111. Just
+            // reify the stack trace as a string ASAP.
+            //
+            // At the same time, cut off the first line; it's always just
+            // "[object Promise]\n", as per the `toString`.
+            promise.stack = e.stack.substring(e.stack.indexOf("\n") + 1);
+        }
+    }
+
+    // NOTE: we do the checks for `resolvedPromise` in each method, instead of
+    // consolidating them into `become`, since otherwise we'd create new
+    // promises with the lines `become(whatever(value))`. See e.g. GH-252.
+
+    function become(newPromise) {
+        resolvedPromise = newPromise;
+        promise.source = newPromise;
+
+        array_reduce(messages, function (undefined, message) {
+            Q.nextTick(function () {
+                newPromise.promiseDispatch.apply(newPromise, message);
+            });
+        }, void 0);
+
+        messages = void 0;
+        progressListeners = void 0;
+    }
+
+    deferred.promise = promise;
+    deferred.resolve = function (value) {
+        if (resolvedPromise) {
+            return;
+        }
+
+        become(Q(value));
+    };
+
+    deferred.fulfill = function (value) {
+        if (resolvedPromise) {
+            return;
+        }
+
+        become(fulfill(value));
+    };
+    deferred.reject = function (reason) {
+        if (resolvedPromise) {
+            return;
+        }
+
+        become(reject(reason));
+    };
+    deferred.notify = function (progress) {
+        if (resolvedPromise) {
+            return;
+        }
+
+        array_reduce(progressListeners, function (undefined, progressListener) {
+            Q.nextTick(function () {
+                progressListener(progress);
+            });
+        }, void 0);
+    };
+
+    return deferred;
+}
+
+/**
+ * Creates a Node-style callback that will resolve or reject the deferred
+ * promise.
+ * @returns a nodeback
+ */
+defer.prototype.makeNodeResolver = function () {
+    var self = this;
+    return function (error, value) {
+        if (error) {
+            self.reject(error);
+        } else if (arguments.length > 2) {
+            self.resolve(array_slice(arguments, 1));
+        } else {
+            self.resolve(value);
+        }
+    };
+};
+
+/**
+ * @param resolver {Function} a function that returns nothing and accepts
+ * the resolve, reject, and notify functions for a deferred.
+ * @returns a promise that may be resolved with the given resolve and reject
+ * functions, or rejected by a thrown exception in resolver
+ */
+Q.Promise = promise; // ES6
+Q.promise = promise;
+function promise(resolver) {
+    if (typeof resolver !== "function") {
+        throw new TypeError("resolver must be a function.");
+    }
+    var deferred = defer();
+    try {
+        resolver(deferred.resolve, deferred.reject, deferred.notify);
+    } catch (reason) {
+        deferred.reject(reason);
+    }
+    return deferred.promise;
+}
+
+promise.race = race; // ES6
+promise.all = all; // ES6
+promise.reject = reject; // ES6
+promise.resolve = Q; // ES6
+
+// XXX experimental.  This method is a way to denote that a local value is
+// serializable and should be immediately dispatched to a remote upon request,
+// instead of passing a reference.
+Q.passByCopy = function (object) {
+    //freeze(object);
+    //passByCopies.set(object, true);
+    return object;
+};
+
+Promise.prototype.passByCopy = function () {
+    //freeze(object);
+    //passByCopies.set(object, true);
+    return this;
+};
+
+/**
+ * If two promises eventually fulfill to the same value, promises that value,
+ * but otherwise rejects.
+ * @param x {Any*}
+ * @param y {Any*}
+ * @returns {Any*} a promise for x and y if they are the same, but a rejection
+ * otherwise.
+ *
+ */
+Q.join = function (x, y) {
+    return Q(x).join(y);
+};
+
+Promise.prototype.join = function (that) {
+    return Q([this, that]).spread(function (x, y) {
+        if (x === y) {
+            // TODO: "===" should be Object.is or equiv
+            return x;
+        } else {
+            throw new Error("Can't join: not the same: " + x + " " + y);
+        }
+    });
+};
+
+/**
+ * Returns a promise for the first of an array of promises to become settled.
+ * @param answers {Array[Any*]} promises to race
+ * @returns {Any*} the first promise to be settled
+ */
+Q.race = race;
+function race(answerPs) {
+    return promise(function (resolve, reject) {
+        // Switch to this once we can assume at least ES5
+        // answerPs.forEach(function (answerP) {
+        //     Q(answerP).then(resolve, reject);
+        // });
+        // Use this in the meantime
+        for (var i = 0, len = answerPs.length; i < len; i++) {
+            Q(answerPs[i]).then(resolve, reject);
+        }
+    });
+}
+
+Promise.prototype.race = function () {
+    return this.then(Q.race);
+};
+
+/**
+ * Constructs a Promise with a promise descriptor object and optional fallback
+ * function.  The descriptor contains methods like when(rejected), get(name),
+ * set(name, value), post(name, args), and delete(name), which all
+ * return either a value, a promise for a value, or a rejection.  The fallback
+ * accepts the operation name, a resolver, and any further arguments that would
+ * have been forwarded to the appropriate method above had a method been
+ * provided with the proper name.  The API makes no guarantees about the nature
+ * of the returned object, apart from that it is usable whereever promises are
+ * bought and sold.
+ */
+Q.makePromise = Promise;
+function Promise(descriptor, fallback, inspect) {
+    if (fallback === void 0) {
+        fallback = function (op) {
+            return reject(new Error(
+                "Promise does not support operation: " + op
+            ));
+        };
+    }
+    if (inspect === void 0) {
+        inspect = function () {
+            return {state: "unknown"};
+        };
+    }
+
+    var promise = object_create(Promise.prototype);
+
+    promise.promiseDispatch = function (resolve, op, args) {
+        var result;
+        try {
+            if (descriptor[op]) {
+                result = descriptor[op].apply(promise, args);
+            } else {
+                result = fallback.call(promise, op, args);
+            }
+        } catch (exception) {
+            result = reject(exception);
+        }
+        if (resolve) {
+            resolve(result);
+        }
+    };
+
+    promise.inspect = inspect;
+
+    // XXX deprecated `valueOf` and `exception` support
+    if (inspect) {
+        var inspected = inspect();
+        if (inspected.state === "rejected") {
+            promise.exception = inspected.reason;
+        }
+
+        promise.valueOf = function () {
+            var inspected = inspect();
+            if (inspected.state === "pending" ||
+                inspected.state === "rejected") {
+                return promise;
+            }
+            return inspected.value;
+        };
+    }
+
+    return promise;
+}
+
+Promise.prototype.toString = function () {
+    return "[object Promise]";
+};
+
+Promise.prototype.then = function (fulfilled, rejected, progressed) {
+    var self = this;
+    var deferred = defer();
+    var done = false;   // ensure the untrusted promise makes at most a
+                        // single call to one of the callbacks
+
+    function _fulfilled(value) {
+        try {
+            return typeof fulfilled === "function" ? fulfilled(value) : value;
+        } catch (exception) {
+            return reject(exception);
+        }
+    }
+
+    function _rejected(exception) {
+        if (typeof rejected === "function") {
+            makeStackTraceLong(exception, self);
+            try {
+                return rejected(exception);
+            } catch (newException) {
+                return reject(newException);
+            }
+        }
+        return reject(exception);
+    }
+
+    function _progressed(value) {
+        return typeof progressed === "function" ? progressed(value) : value;
+    }
+
+    Q.nextTick(function () {
+        self.promiseDispatch(function (value) {
+            if (done) {
+                return;
+            }
+            done = true;
+
+            deferred.resolve(_fulfilled(value));
+        }, "when", [function (exception) {
+            if (done) {
+                return;
+            }
+            done = true;
+
+            deferred.resolve(_rejected(exception));
+        }]);
+    });
+
+    // Progress propagator need to be attached in the current tick.
+    self.promiseDispatch(void 0, "when", [void 0, function (value) {
+        var newValue;
+        var threw = false;
+        try {
+            newValue = _progressed(value);
+        } catch (e) {
+            threw = true;
+            if (Q.onerror) {
+                Q.onerror(e);
+            } else {
+                throw e;
+            }
+        }
+
+        if (!threw) {
+            deferred.notify(newValue);
+        }
+    }]);
+
+    return deferred.promise;
+};
+
+Q.tap = function (promise, callback) {
+    return Q(promise).tap(callback);
+};
+
+/**
+ * Works almost like "finally", but not called for rejections.
+ * Original resolution value is passed through callback unaffected.
+ * Callback may return a promise that will be awaited for.
+ * @param {Function} callback
+ * @returns {Q.Promise}
+ * @example
+ * doSomething()
+ *   .then(...)
+ *   .tap(console.log)
+ *   .then(...);
+ */
+Promise.prototype.tap = function (callback) {
+    callback = Q(callback);
+
+    return this.then(function (value) {
+        return callback.fcall(value).thenResolve(value);
+    });
+};
+
+/**
+ * Registers an observer on a promise.
+ *
+ * Guarantees:
+ *
+ * 1. that fulfilled and rejected will be called only once.
+ * 2. that either the fulfilled callback or the rejected callback will be
+ *    called, but not both.
+ * 3. that fulfilled and rejected will not be called in this turn.
+ *
+ * @param value      promise or immediate reference to observe
+ * @param fulfilled  function to be called with the fulfilled value
+ * @param rejected   function to be called with the rejection exception
+ * @param progressed function to be called on any progress notifications
+ * @return promise for the return value from the invoked callback
+ */
+Q.when = when;
+function when(value, fulfilled, rejected, progressed) {
+    return Q(value).then(fulfilled, rejected, progressed);
+}
+
+Promise.prototype.thenResolve = function (value) {
+    return this.then(function () { return value; });
+};
+
+Q.thenResolve = function (promise, value) {
+    return Q(promise).thenResolve(value);
+};
+
+Promise.prototype.thenReject = function (reason) {
+    return this.then(function () { throw reason; });
+};
+
+Q.thenReject = function (promise, reason) {
+    return Q(promise).thenReject(reason);
+};
+
+/**
+ * If an object is not a promise, it is as "near" as possible.
+ * If a promise is rejected, it is as "near" as possible too.
+ * If it’s a fulfilled promise, the fulfillment value is nearer.
+ * If it’s a deferred promise and the deferred has been resolved, the
+ * resolution is "nearer".
+ * @param object
+ * @returns most resolved (nearest) form of the object
+ */
+
+// XXX should we re-do this?
+Q.nearer = nearer;
+function nearer(value) {
+    if (isPromise(value)) {
+        var inspected = value.inspect();
+        if (inspected.state === "fulfilled") {
+            return inspected.value;
+        }
+    }
+    return value;
+}
+
+/**
+ * @returns whether the given object is a promise.
+ * Otherwise it is a fulfilled value.
+ */
+Q.isPromise = isPromise;
+function isPromise(object) {
+    return object instanceof Promise;
+}
+
+Q.isPromiseAlike = isPromiseAlike;
+function isPromiseAlike(object) {
+    return isObject(object) && typeof object.then === "function";
+}
+
+/**
+ * @returns whether the given object is a pending promise, meaning not
+ * fulfilled or rejected.
+ */
+Q.isPending = isPending;
+function isPending(object) {
+    return isPromise(object) && object.inspect().state === "pending";
+}
+
+Promise.prototype.isPending = function () {
+    return this.inspect().state === "pending";
+};
+
+/**
+ * @returns whether the given object is a value or fulfilled
+ * promise.
+ */
+Q.isFulfilled = isFulfilled;
+function isFulfilled(object) {
+    return !isPromise(object) || object.inspect().state === "fulfilled";
+}
+
+Promise.prototype.isFulfilled = function () {
+    return this.inspect().state === "fulfilled";
+};
+
+/**
+ * @returns whether the given object is a rejected promise.
+ */
+Q.isRejected = isRejected;
+function isRejected(object) {
+    return isPromise(object) && object.inspect().state === "rejected";
+}
+
+Promise.prototype.isRejected = function () {
+    return this.inspect().state === "rejected";
+};
+
+//// BEGIN UNHANDLED REJECTION TRACKING
+
+// This promise library consumes exceptions thrown in handlers so they can be
+// handled by a subsequent promise.  The exceptions get added to this array when
+// they are created, and removed when they are handled.  Note that in ES6 or
+// shimmed environments, this would naturally be a `Set`.
+var unhandledReasons = [];
+var unhandledRejections = [];
+var reportedUnhandledRejections = [];
+var trackUnhandledRejections = true;
+
+function resetUnhandledRejections() {
+    unhandledReasons.length = 0;
+    unhandledRejections.length = 0;
+
+    if (!trackUnhandledRejections) {
+        trackUnhandledRejections = true;
+    }
+}
+
+function trackRejection(promise, reason) {
+    if (!trackUnhandledRejections) {
+        return;
+    }
+    if (typeof process === "object" && typeof process.emit === "function") {
+        Q.nextTick.runAfter(function () {
+            if (array_indexOf(unhandledRejections, promise) !== -1) {
+                process.emit("unhandledRejection", reason, promise);
+                reportedUnhandledRejections.push(promise);
+            }
+        });
+    }
+
+    unhandledRejections.push(promise);
+    if (reason && typeof reason.stack !== "undefined") {
+        unhandledReasons.push(reason.stack);
+    } else {
+        unhandledReasons.push("(no stack) " + reason);
+    }
+}
+
+function untrackRejection(promise) {
+    if (!trackUnhandledRejections) {
+        return;
+    }
+
+    var at = array_indexOf(unhandledRejections, promise);
+    if (at !== -1) {
+        if (typeof process === "object" && typeof process.emit === "function") {
+            Q.nextTick.runAfter(function () {
+                var atReport = array_indexOf(reportedUnhandledRejections, promise);
+                if (atReport !== -1) {
+                    process.emit("rejectionHandled", unhandledReasons[at], promise);
+                    reportedUnhandledRejections.splice(atReport, 1);
+                }
+            });
+        }
+        unhandledRejections.splice(at, 1);
+        unhandledReasons.splice(at, 1);
+    }
+}
+
+Q.resetUnhandledRejections = resetUnhandledRejections;
+
+Q.getUnhandledReasons = function () {
+    // Make a copy so that consumers can't interfere with our internal state.
+    return unhandledReasons.slice();
+};
+
+Q.stopUnhandledRejectionTracking = function () {
+    resetUnhandledRejections();
+    trackUnhandledRejections = false;
+};
+
+resetUnhandledRejections();
+
+//// END UNHANDLED REJECTION TRACKING
+
+/**
+ * Constructs a rejected promise.
+ * @param reason value describing the failure
+ */
+Q.reject = reject;
+function reject(reason) {
+    var rejection = Promise({
+        "when": function (rejected) {
+            // note that the error has been handled
+            if (rejected) {
+                untrackRejection(this);
+            }
+            return rejected ? rejected(reason) : this;
+        }
+    }, function fallback() {
+        return this;
+    }, function inspect() {
+        return { state: "rejected", reason: reason };
+    });
+
+    // Note that the reason has not been handled.
+    trackRejection(rejection, reason);
+
+    return rejection;
+}
+
+/**
+ * Constructs a fulfilled promise for an immediate reference.
+ * @param value immediate reference
+ */
+Q.fulfill = fulfill;
+function fulfill(value) {
+    return Promise({
+        "when": function () {
+            return value;
+        },
+        "get": function (name) {
+            return value[name];
+        },
+        "set": function (name, rhs) {
+            value[name] = rhs;
+        },
+        "delete": function (name) {
+            delete value[name];
+        },
+        "post": function (name, args) {
+            // Mark Miller proposes that post with no name should apply a
+            // promised function.
+            if (name === null || name === void 0) {
+                return value.apply(void 0, args);
+            } else {
+                return value[name].apply(value, args);
+            }
+        },
+        "apply": function (thisp, args) {
+            return value.apply(thisp, args);
+        },
+        "keys": function () {
+            return object_keys(value);
+        }
+    }, void 0, function inspect() {
+        return { state: "fulfilled", value: value };
+    });
+}
+
+/**
+ * Converts thenables to Q promises.
+ * @param promise thenable promise
+ * @returns a Q promise
+ */
+function coerce(promise) {
+    var deferred = defer();
+    Q.nextTick(function () {
+        try {
+            promise.then(deferred.resolve, deferred.reject, deferred.notify);
+        } catch (exception) {
+            deferred.reject(exception);
+        }
+    });
+    return deferred.promise;
+}
+
+/**
+ * Annotates an object such that it will never be
+ * transferred away from this process over any promise
+ * communication channel.
+ * @param object
+ * @returns promise a wrapping of that object that
+ * additionally responds to the "isDef" message
+ * without a rejection.
+ */
+Q.master = master;
+function master(object) {
+    return Promise({
+        "isDef": function () {}
+    }, function fallback(op, args) {
+        return dispatch(object, op, args);
+    }, function () {
+        return Q(object).inspect();
+    });
+}
+
+/**
+ * Spreads the values of a promised array of arguments into the
+ * fulfillment callback.
+ * @param fulfilled callback that receives variadic arguments from the
+ * promised array
+ * @param rejected callback that receives the exception if the promise
+ * is rejected.
+ * @returns a promise for the return value or thrown exception of
+ * either callback.
+ */
+Q.spread = spread;
+function spread(value, fulfilled, rejected) {
+    return Q(value).spread(fulfilled, rejected);
+}
+
+Promise.prototype.spread = function (fulfilled, rejected) {
+    return this.all().then(function (array) {
+        return fulfilled.apply(void 0, array);
+    }, rejected);
+};
+
+/**
+ * The async function is a decorator for generator functions, turning
+ * them into asynchronous generators.  Although generators are only part
+ * of the newest ECMAScript 6 drafts, this code does not cause syntax
+ * errors in older engines.  This code should continue to work and will
+ * in fact improve over time as the language improves.
+ *
+ * ES6 generators are currently part of V8 version 3.19 with the
+ * --harmony-generators runtime flag enabled.  SpiderMonkey has had them
+ * for longer, but under an older Python-inspired form.  This function
+ * works on both kinds of generators.
+ *
+ * Decorates a generator function such that:
+ *  - it may yield promises
+ *  - execution will continue when that promise is fulfilled
+ *  - the value of the yield expression will be the fulfilled value
+ *  - it returns a promise for the return value (when the generator
+ *    stops iterating)
+ *  - the decorated function returns a promise for the return value
+ *    of the generator or the first rejected promise among those
+ *    yielded.
+ *  - if an error is thrown in the generator, it propagates through
+ *    every following yield until it is caught, or until it escapes
+ *    the generator function altogether, and is translated into a
+ *    rejection for the promise returned by the decorated generator.
+ */
+Q.async = async;
+function async(makeGenerator) {
+    return function () {
+        // when verb is "send", arg is a value
+        // when verb is "throw", arg is an exception
+        function continuer(verb, arg) {
+            var result;
+
+            // Until V8 3.19 / Chromium 29 is released, SpiderMonkey is the only
+            // engine that has a deployed base of browsers that support generators.
+            // However, SM's generators use the Python-inspired semantics of
+            // outdated ES6 drafts.  We would like to support ES6, but we'd also
+            // like to make it possible to use generators in deployed browsers, so
+            // we also support Python-style generators.  At some point we can remove
+            // this block.
+
+            if (typeof StopIteration === "undefined") {
+                // ES6 Generators
+                try {
+                    result = generator[verb](arg);
+                } catch (exception) {
+                    return reject(exception);
+                }
+                if (result.done) {
+                    return Q(result.value);
+                } else {
+                    return when(result.value, callback, errback);
+                }
+            } else {
+                // SpiderMonkey Generators
+                // FIXME: Remove this case when SM does ES6 generators.
+                try {
+                    result = generator[verb](arg);
+                } catch (exception) {
+                    if (isStopIteration(exception)) {
+                        return Q(exception.value);
+                    } else {
+                        return reject(exception);
+                    }
+                }
+                return when(result, callback, errback);
+            }
+        }
+        var generator = makeGenerator.apply(this, arguments);
+        var callback = continuer.bind(continuer, "next");
+        var errback = continuer.bind(continuer, "throw");
+        return callback();
+    };
+}
+
+/**
+ * The spawn function is a small wrapper around async that immediately
+ * calls the generator and also ends the promise chain, so that any
+ * unhandled errors are thrown instead of forwarded to the error
+ * handler. This is useful because it's extremely common to run
+ * generators at the top-level to work with libraries.
+ */
+Q.spawn = spawn;
+function spawn(makeGenerator) {
+    Q.done(Q.async(makeGenerator)());
+}
+
+// FIXME: Remove this interface once ES6 generators are in SpiderMonkey.
+/**
+ * Throws a ReturnValue exception to stop an asynchronous generator.
+ *
+ * This interface is a stop-gap measure to support generator return
+ * values in older Firefox/SpiderMonkey.  In browsers that support ES6
+ * generators like Chromium 29, just use "return" in your generator
+ * functions.
+ *
+ * @param value the return value for the surrounding generator
+ * @throws ReturnValue exception with the value.
+ * @example
+ * // ES6 style
+ * Q.async(function* () {
+ *      var foo = yield getFooPromise();
+ *      var bar = yield getBarPromise();
+ *      return foo + bar;
+ * })
+ * // Older SpiderMonkey style
+ * Q.async(function () {
+ *      var foo = yield getFooPromise();
+ *      var bar = yield getBarPromise();
+ *      Q.return(foo + bar);
+ * })
+ */
+Q["return"] = _return;
+function _return(value) {
+    throw new QReturnValue(value);
+}
+
+/**
+ * The promised function decorator ensures that any promise arguments
+ * are settled and passed as values (`this` is also settled and passed
+ * as a value).  It will also ensure that the result of a function is
+ * always a promise.
+ *
+ * @example
+ * var add = Q.promised(function (a, b) {
+ *     return a + b;
+ * });
+ * add(Q(a), Q(B));
+ *
+ * @param {function} callback The function to decorate
+ * @returns {function} a function that has been decorated.
+ */
+Q.promised = promised;
+function promised(callback) {
+    return function () {
+        return spread([this, all(arguments)], function (self, args) {
+            return callback.apply(self, args);
+        });
+    };
+}
+
+/**
+ * sends a message to a value in a future turn
+ * @param object* the recipient
+ * @param op the name of the message operation, e.g., "when",
+ * @param args further arguments to be forwarded to the operation
+ * @returns result {Promise} a promise for the result of the operation
+ */
+Q.dispatch = dispatch;
+function dispatch(object, op, args) {
+    return Q(object).dispatch(op, args);
+}
+
+Promise.prototype.dispatch = function (op, args) {
+    var self = this;
+    var deferred = defer();
+    Q.nextTick(function () {
+        self.promiseDispatch(deferred.resolve, op, args);
+    });
+    return deferred.promise;
+};
+
+/**
+ * Gets the value of a property in a future turn.
+ * @param object    promise or immediate reference for target object
+ * @param name      name of property to get
+ * @return promise for the property value
+ */
+Q.get = function (object, key) {
+    return Q(object).dispatch("get", [key]);
+};
+
+Promise.prototype.get = function (key) {
+    return this.dispatch("get", [key]);
+};
+
+/**
+ * Sets the value of a property in a future turn.
+ * @param object    promise or immediate reference for object object
+ * @param name      name of property to set
+ * @param value     new value of property
+ * @return promise for the return value
+ */
+Q.set = function (object, key, value) {
+    return Q(object).dispatch("set", [key, value]);
+};
+
+Promise.prototype.set = function (key, value) {
+    return this.dispatch("set", [key, value]);
+};
+
+/**
+ * Deletes a property in a future turn.
+ * @param object    promise or immediate reference for target object
+ * @param name      name of property to delete
+ * @return promise for the return value
+ */
+Q.del = // XXX legacy
+Q["delete"] = function (object, key) {
+    return Q(object).dispatch("delete", [key]);
+};
+
+Promise.prototype.del = // XXX legacy
+Promise.prototype["delete"] = function (key) {
+    return this.dispatch("delete", [key]);
+};
+
+/**
+ * Invokes a method in a future turn.
+ * @param object    promise or immediate reference for target object
+ * @param name      name of method to invoke
+ * @param value     a value to post, typically an array of
+ *                  invocation arguments for promises that
+ *                  are ultimately backed with `resolve` values,
+ *                  as opposed to those backed with URLs
+ *                  wherein the posted value can be any
+ *                  JSON serializable object.
+ * @return promise for the return value
+ */
+// bound locally because it is used by other methods
+Q.mapply = // XXX As proposed by "Redsandro"
+Q.post = function (object, name, args) {
+    return Q(object).dispatch("post", [name, args]);
+};
+
+Promise.prototype.mapply = // XXX As proposed by "Redsandro"
+Promise.prototype.post = function (name, args) {
+    return this.dispatch("post", [name, args]);
+};
+
+/**
+ * Invokes a method in a future turn.
+ * @param object    promise or immediate reference for target object
+ * @param name      name of method to invoke
+ * @param ...args   array of invocation arguments
+ * @return promise for the return value
+ */
+Q.send = // XXX Mark Miller's proposed parlance
+Q.mcall = // XXX As proposed by "Redsandro"
+Q.invoke = function (object, name /*...args*/) {
+    return Q(object).dispatch("post", [name, array_slice(arguments, 2)]);
+};
+
+Promise.prototype.send = // XXX Mark Miller's proposed parlance
+Promise.prototype.mcall = // XXX As proposed by "Redsandro"
+Promise.prototype.invoke = function (name /*...args*/) {
+    return this.dispatch("post", [name, array_slice(arguments, 1)]);
+};
+
+/**
+ * Applies the promised function in a future turn.
+ * @param object    promise or immediate reference for target function
+ * @param args      array of application arguments
+ */
+Q.fapply = function (object, args) {
+    return Q(object).dispatch("apply", [void 0, args]);
+};
+
+Promise.prototype.fapply = function (args) {
+    return this.dispatch("apply", [void 0, args]);
+};
+
+/**
+ * Calls the promised function in a future turn.
+ * @param object    promise or immediate reference for target function
+ * @param ...args   array of application arguments
+ */
+Q["try"] =
+Q.fcall = function (object /* ...args*/) {
+    return Q(object).dispatch("apply", [void 0, array_slice(arguments, 1)]);
+};
+
+Promise.prototype.fcall = function (/*...args*/) {
+    return this.dispatch("apply", [void 0, array_slice(arguments)]);
+};
+
+/**
+ * Binds the promised function, transforming return values into a fulfilled
+ * promise and thrown errors into a rejected one.
+ * @param object    promise or immediate reference for target function
+ * @param ...args   array of application arguments
+ */
+Q.fbind = function (object /*...args*/) {
+    var promise = Q(object);
+    var args = array_slice(arguments, 1);
+    return function fbound() {
+        return promise.dispatch("apply", [
+            this,
+            args.concat(array_slice(arguments))
+        ]);
+    };
+};
+Promise.prototype.fbind = function (/*...args*/) {
+    var promise = this;
+    var args = array_slice(arguments);
+    return function fbound() {
+        return promise.dispatch("apply", [
+            this,
+            args.concat(array_slice(arguments))
+        ]);
+    };
+};
+
+/**
+ * Requests the names of the owned properties of a promised
+ * object in a future turn.
+ * @param object    promise or immediate reference for target object
+ * @return promise for the keys of the eventually settled object
+ */
+Q.keys = function (object) {
+    return Q(object).dispatch("keys", []);
+};
+
+Promise.prototype.keys = function () {
+    return this.dispatch("keys", []);
+};
+
+/**
+ * Turns an array of promises into a promise for an array.  If any of
+ * the promises gets rejected, the whole array is rejected immediately.
+ * @param {Array*} an array (or promise for an array) of values (or
+ * promises for values)
+ * @returns a promise for an array of the corresponding values
+ */
+// By Mark Miller
+// http://wiki.ecmascript.org/doku.php?id=strawman:concurrency&rev=1308776521#allfulfilled
+Q.all = all;
+function all(promises) {
+    return when(promises, function (promises) {
+        var pendingCount = 0;
+        var deferred = defer();
+        array_reduce(promises, function (undefined, promise, index) {
+            var snapshot;
+            if (
+                isPromise(promise) &&
+                (snapshot = promise.inspect()).state === "fulfilled"
+            ) {
+                promises[index] = snapshot.value;
+            } else {
+                ++pendingCount;
+                when(
+                    promise,
+                    function (value) {
+                        promises[index] = value;
+                        if (--pendingCount === 0) {
+                            deferred.resolve(promises);
+                        }
+                    },
+                    deferred.reject,
+                    function (progress) {
+                        deferred.notify({ index: index, value: progress });
+                    }
+                );
+            }
+        }, void 0);
+        if (pendingCount === 0) {
+            deferred.resolve(promises);
+        }
+        return deferred.promise;
+    });
+}
+
+Promise.prototype.all = function () {
+    return all(this);
+};
+
+/**
+ * Returns the first resolved promise of an array. Prior rejected promises are
+ * ignored.  Rejects only if all promises are rejected.
+ * @param {Array*} an array containing values or promises for values
+ * @returns a promise fulfilled with the value of the first resolved promise,
+ * or a rejected promise if all promises are rejected.
+ */
+Q.any = any;
+
+function any(promises) {
+    if (promises.length === 0) {
+        return Q.resolve();
+    }
+
+    var deferred = Q.defer();
+    var pendingCount = 0;
+    array_reduce(promises, function (prev, current, index) {
+        var promise = promises[index];
+
+        pendingCount++;
+
+        when(promise, onFulfilled, onRejected, onProgress);
+        function onFulfilled(result) {
+            deferred.resolve(result);
+        }
+        function onRejected() {
+            pendingCount--;
+            if (pendingCount === 0) {
+                deferred.reject(new Error(
+                    "Can't get fulfillment value from any promise, all " +
+                    "promises were rejected."
+                ));
+            }
+        }
+        function onProgress(progress) {
+            deferred.notify({
+                index: index,
+                value: progress
+            });
+        }
+    }, undefined);
+
+    return deferred.promise;
+}
+
+Promise.prototype.any = function () {
+    return any(this);
+};
+
+/**
+ * Waits for all promises to be settled, either fulfilled or
+ * rejected.  This is distinct from `all` since that would stop
+ * waiting at the first rejection.  The promise returned by
+ * `allResolved` will never be rejected.
+ * @param promises a promise for an array (or an array) of promises
+ * (or values)
+ * @return a promise for an array of promises
+ */
+Q.allResolved = deprecate(allResolved, "allResolved", "allSettled");
+function allResolved(promises) {
+    return when(promises, function (promises) {
+        promises = array_map(promises, Q);
+        return when(all(array_map(promises, function (promise) {
+            return when(promise, noop, noop);
+        })), function () {
+            return promises;
+        });
+    });
+}
+
+Promise.prototype.allResolved = function () {
+    return allResolved(this);
+};
+
+/**
+ * @see Promise#allSettled
+ */
+Q.allSettled = allSettled;
+function allSettled(promises) {
+    return Q(promises).allSettled();
+}
+
+/**
+ * Turns an array of promises into a promise for an array of their states (as
+ * returned by `inspect`) when they have all settled.
+ * @param {Array[Any*]} values an array (or promise for an array) of values (or
+ * promises for values)
+ * @returns {Array[State]} an array of states for the respective values.
+ */
+Promise.prototype.allSettled = function () {
+    return this.then(function (promises) {
+        return all(array_map(promises, function (promise) {
+            promise = Q(promise);
+            function regardless() {
+                return promise.inspect();
+            }
+            return promise.then(regardless, regardless);
+        }));
+    });
+};
+
+/**
+ * Captures the failure of a promise, giving an oportunity to recover
+ * with a callback.  If the given promise is fulfilled, the returned
+ * promise is fulfilled.
+ * @param {Any*} promise for something
+ * @param {Function} callback to fulfill the returned promise if the
+ * given promise is rejected
+ * @returns a promise for the return value of the callback
+ */
+Q.fail = // XXX legacy
+Q["catch"] = function (object, rejected) {
+    return Q(object).then(void 0, rejected);
+};
+
+Promise.prototype.fail = // XXX legacy
+Promise.prototype["catch"] = function (rejected) {
+    return this.then(void 0, rejected);
+};
+
+/**
+ * Attaches a listener that can respond to progress notifications from a
+ * promise's originating deferred. This listener receives the exact arguments
+ * passed to ``deferred.notify``.
+ * @param {Any*} promise for something
+ * @param {Function} callback to receive any progress notifications
+ * @returns the given promise, unchanged
+ */
+Q.progress = progress;
+function progress(object, progressed) {
+    return Q(object).then(void 0, void 0, progressed);
+}
+
+Promise.prototype.progress = function (progressed) {
+    return this.then(void 0, void 0, progressed);
+};
+
+/**
+ * Provides an opportunity to observe the settling of a promise,
+ * regardless of whether the promise is fulfilled or rejected.  Forwards
+ * the resolution to the returned promise when the callback is done.
+ * The callback can return a promise to defer completion.
+ * @param {Any*} promise
+ * @param {Function} callback to observe the resolution of the given
+ * promise, takes no arguments.
+ * @returns a promise for the resolution of the given promise when
+ * ``fin`` is done.
+ */
+Q.fin = // XXX legacy
+Q["finally"] = function (object, callback) {
+    return Q(object)["finally"](callback);
+};
+
+Promise.prototype.fin = // XXX legacy
+Promise.prototype["finally"] = function (callback) {
+    callback = Q(callback);
+    return this.then(function (value) {
+        return callback.fcall().then(function () {
+            return value;
+        });
+    }, function (reason) {
+        // TODO attempt to recycle the rejection with "this".
+        return callback.fcall().then(function () {
+            throw reason;
+        });
+    });
+};
+
+/**
+ * Terminates a chain of promises, forcing rejections to be
+ * thrown as exceptions.
+ * @param {Any*} promise at the end of a chain of promises
+ * @returns nothing
+ */
+Q.done = function (object, fulfilled, rejected, progress) {
+    return Q(object).done(fulfilled, rejected, progress);
+};
+
+Promise.prototype.done = function (fulfilled, rejected, progress) {
+    var onUnhandledError = function (error) {
+        // forward to a future turn so that ``when``
+        // does not catch it and turn it into a rejection.
+        Q.nextTick(function () {
+            makeStackTraceLong(error, promise);
+            if (Q.onerror) {
+                Q.onerror(error);
+            } else {
+                throw error;
+            }
+        });
+    };
+
+    // Avoid unnecessary `nextTick`ing via an unnecessary `when`.
+    var promise = fulfilled || rejected || progress ?
+        this.then(fulfilled, rejected, progress) :
+        this;
+
+    if (typeof process === "object" && process && process.domain) {
+        onUnhandledError = process.domain.bind(onUnhandledError);
+    }
+
+    promise.then(void 0, onUnhandledError);
+};
+
+/**
+ * Causes a promise to be rejected if it does not get fulfilled before
+ * some milliseconds time out.
+ * @param {Any*} promise
+ * @param {Number} milliseconds timeout
+ * @param {Any*} custom error message or Error object (optional)
+ * @returns a promise for the resolution of the given promise if it is
+ * fulfilled before the timeout, otherwise rejected.
+ */
+Q.timeout = function (object, ms, error) {
+    return Q(object).timeout(ms, error);
+};
+
+Promise.prototype.timeout = function (ms, error) {
+    var deferred = defer();
+    var timeoutId = setTimeout(function () {
+        if (!error || "string" === typeof error) {
+            error = new Error(error || "Timed out after " + ms + " ms");
+            error.code = "ETIMEDOUT";
+        }
+        deferred.reject(error);
+    }, ms);
+
+    this.then(function (value) {
+        clearTimeout(timeoutId);
+        deferred.resolve(value);
+    }, function (exception) {
+        clearTimeout(timeoutId);
+        deferred.reject(exception);
+    }, deferred.notify);
+
+    return deferred.promise;
+};
+
+/**
+ * Returns a promise for the given value (or promised value), some
+ * milliseconds after it resolved. Passes rejections immediately.
+ * @param {Any*} promise
+ * @param {Number} milliseconds
+ * @returns a promise for the resolution of the given promise after milliseconds
+ * time has elapsed since the resolution of the given promise.
+ * If the given promise rejects, that is passed immediately.
+ */
+Q.delay = function (object, timeout) {
+    if (timeout === void 0) {
+        timeout = object;
+        object = void 0;
+    }
+    return Q(object).delay(timeout);
+};
+
+Promise.prototype.delay = function (timeout) {
+    return this.then(function (value) {
+        var deferred = defer();
+        setTimeout(function () {
+            deferred.resolve(value);
+        }, timeout);
+        return deferred.promise;
+    });
+};
+
+/**
+ * Passes a continuation to a Node function, which is called with the given
+ * arguments provided as an array, and returns a promise.
+ *
+ *      Q.nfapply(FS.readFile, [__filename])
+ *      .then(function (content) {
+ *      })
+ *
+ */
+Q.nfapply = function (callback, args) {
+    return Q(callback).nfapply(args);
+};
+
+Promise.prototype.nfapply = function (args) {
+    var deferred = defer();
+    var nodeArgs = array_slice(args);
+    nodeArgs.push(deferred.makeNodeResolver());
+    this.fapply(nodeArgs).fail(deferred.reject);
+    return deferred.promise;
+};
+
+/**
+ * Passes a continuation to a Node function, which is called with the given
+ * arguments provided individually, and returns a promise.
+ * @example
+ * Q.nfcall(FS.readFile, __filename)
+ * .then(function (content) {
+ * })
+ *
+ */
+Q.nfcall = function (callback /*...args*/) {
+    var args = array_slice(arguments, 1);
+    return Q(callback).nfapply(args);
+};
+
+Promise.prototype.nfcall = function (/*...args*/) {
+    var nodeArgs = array_slice(arguments);
+    var deferred = defer();
+    nodeArgs.push(deferred.makeNodeResolver());
+    this.fapply(nodeArgs).fail(deferred.reject);
+    return deferred.promise;
+};
+
+/**
+ * Wraps a NodeJS continuation passing function and returns an equivalent
+ * version that returns a promise.
+ * @example
+ * Q.nfbind(FS.readFile, __filename)("utf-8")
+ * .then(console.log)
+ * .done()
+ */
+Q.nfbind =
+Q.denodeify = function (callback /*...args*/) {
+    var baseArgs = array_slice(arguments, 1);
+    return function () {
+        var nodeArgs = baseArgs.concat(array_slice(arguments));
+        var deferred = defer();
+        nodeArgs.push(deferred.makeNodeResolver());
+        Q(callback).fapply(nodeArgs).fail(deferred.reject);
+        return deferred.promise;
+    };
+};
+
+Promise.prototype.nfbind =
+Promise.prototype.denodeify = function (/*...args*/) {
+    var args = array_slice(arguments);
+    args.unshift(this);
+    return Q.denodeify.apply(void 0, args);
+};
+
+Q.nbind = function (callback, thisp /*...args*/) {
+    var baseArgs = array_slice(arguments, 2);
+    return function () {
+        var nodeArgs = baseArgs.concat(array_slice(arguments));
+        var deferred = defer();
+        nodeArgs.push(deferred.makeNodeResolver());
+        function bound() {
+            return callback.apply(thisp, arguments);
+        }
+        Q(bound).fapply(nodeArgs).fail(deferred.reject);
+        return deferred.promise;
+    };
+};
+
+Promise.prototype.nbind = function (/*thisp, ...args*/) {
+    var args = array_slice(arguments, 0);
+    args.unshift(this);
+    return Q.nbind.apply(void 0, args);
+};
+
+/**
+ * Calls a method of a Node-style object that accepts a Node-style
+ * callback with a given array of arguments, plus a provided callback.
+ * @param object an object that has the named method
+ * @param {String} name name of the method of object
+ * @param {Array} args arguments to pass to the method; the callback
+ * will be provided by Q and appended to these arguments.
+ * @returns a promise for the value or error
+ */
+Q.nmapply = // XXX As proposed by "Redsandro"
+Q.npost = function (object, name, args) {
+    return Q(object).npost(name, args);
+};
+
+Promise.prototype.nmapply = // XXX As proposed by "Redsandro"
+Promise.prototype.npost = function (name, args) {
+    var nodeArgs = array_slice(args || []);
+    var deferred = defer();
+    nodeArgs.push(deferred.makeNodeResolver());
+    this.dispatch("post", [name, nodeArgs]).fail(deferred.reject);
+    return deferred.promise;
+};
+
+/**
+ * Calls a method of a Node-style object that accepts a Node-style
+ * callback, forwarding the given variadic arguments, plus a provided
+ * callback argument.
+ * @param object an object that has the named method
+ * @param {String} name name of the method of object
+ * @param ...args arguments to pass to the method; the callback will
+ * be provided by Q and appended to these arguments.
+ * @returns a promise for the value or error
+ */
+Q.nsend = // XXX Based on Mark Miller's proposed "send"
+Q.nmcall = // XXX Based on "Redsandro's" proposal
+Q.ninvoke = function (object, name /*...args*/) {
+    var nodeArgs = array_slice(arguments, 2);
+    var deferred = defer();
+    nodeArgs.push(deferred.makeNodeResolver());
+    Q(object).dispatch("post", [name, nodeArgs]).fail(deferred.reject);
+    return deferred.promise;
+};
+
+Promise.prototype.nsend = // XXX Based on Mark Miller's proposed "send"
+Promise.prototype.nmcall = // XXX Based on "Redsandro's" proposal
+Promise.prototype.ninvoke = function (name /*...args*/) {
+    var nodeArgs = array_slice(arguments, 1);
+    var deferred = defer();
+    nodeArgs.push(deferred.makeNodeResolver());
+    this.dispatch("post", [name, nodeArgs]).fail(deferred.reject);
+    return deferred.promise;
+};
+
+/**
+ * If a function would like to support both Node continuation-passing-style and
+ * promise-returning-style, it can end its internal promise chain with
+ * `nodeify(nodeback)`, forwarding the optional nodeback argument.  If the user
+ * elects to use a nodeback, the result will be sent there.  If they do not
+ * pass a nodeback, they will receive the result promise.
+ * @param object a result (or a promise for a result)
+ * @param {Function} nodeback a Node.js-style callback
+ * @returns either the promise or nothing
+ */
+Q.nodeify = nodeify;
+function nodeify(object, nodeback) {
+    return Q(object).nodeify(nodeback);
+}
+
+Promise.prototype.nodeify = function (nodeback) {
+    if (nodeback) {
+        this.then(function (value) {
+            Q.nextTick(function () {
+                nodeback(null, value);
+            });
+        }, function (error) {
+            Q.nextTick(function () {
+                nodeback(error);
+            });
+        });
+    } else {
+        return this;
+    }
+};
+
+Q.noConflict = function() {
+    throw new Error("Q.noConflict only works when Q is used as a global");
+};
+
+// All code before this point will be filtered from stack traces.
+var qEndingLine = captureLine();
+
+return Q;
+
+});
+
+}).call(this,require('_process'))
+
+},{"_process":12}],158:[function(require,module,exports){
+/**
+ * Root reference for iframes.
+ */
+
+var root;
+if (typeof window !== 'undefined') { // Browser window
+  root = window;
+} else if (typeof self !== 'undefined') { // Web Worker
+  root = self;
+} else { // Other environments
+  console.warn("Using browser-only version of superagent in non-browser environment");
+  root = this;
+}
+
+var Emitter = require('emitter');
+var requestBase = require('./request-base');
+var isObject = require('./is-object');
+
+/**
+ * Noop.
+ */
+
+function noop(){};
+
+/**
+ * Expose `request`.
+ */
+
+var request = module.exports = require('./request').bind(null, Request);
+
+/**
+ * Determine XHR.
+ */
+
+request.getXHR = function () {
+  if (root.XMLHttpRequest
+      && (!root.location || 'file:' != root.location.protocol
+          || !root.ActiveXObject)) {
+    return new XMLHttpRequest;
+  } else {
+    try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {}
+    try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {}
+    try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {}
+    try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {}
+  }
+  throw Error("Browser-only verison of superagent could not find XHR");
+};
+
+/**
+ * Removes leading and trailing whitespace, added to support IE.
+ *
+ * @param {String} s
+ * @return {String}
+ * @api private
+ */
+
+var trim = ''.trim
+  ? function(s) { return s.trim(); }
+  : function(s) { return s.replace(/(^\s*|\s*$)/g, ''); };
+
+/**
+ * Serialize the given `obj`.
+ *
+ * @param {Object} obj
+ * @return {String}
+ * @api private
+ */
+
+function serialize(obj) {
+  if (!isObject(obj)) return obj;
+  var pairs = [];
+  for (var key in obj) {
+    pushEncodedKeyValuePair(pairs, key, obj[key]);
+  }
+  return pairs.join('&');
+}
+
+/**
+ * Helps 'serialize' with serializing arrays.
+ * Mutates the pairs array.
+ *
+ * @param {Array} pairs
+ * @param {String} key
+ * @param {Mixed} val
+ */
+
+function pushEncodedKeyValuePair(pairs, key, val) {
+  if (val != null) {
+    if (Array.isArray(val)) {
+      val.forEach(function(v) {
+        pushEncodedKeyValuePair(pairs, key, v);
+      });
+    } else if (isObject(val)) {
+      for(var subkey in val) {
+        pushEncodedKeyValuePair(pairs, key + '[' + subkey + ']', val[subkey]);
+      }
+    } else {
+      pairs.push(encodeURIComponent(key)
+        + '=' + encodeURIComponent(val));
+    }
+  } else if (val === null) {
+    pairs.push(encodeURIComponent(key));
+  }
+}
+
+/**
+ * Expose serialization method.
+ */
+
+ request.serializeObject = serialize;
+
+ /**
+  * Parse the given x-www-form-urlencoded `str`.
+  *
+  * @param {String} str
+  * @return {Object}
+  * @api private
+  */
+
+function parseString(str) {
+  var obj = {};
+  var pairs = str.split('&');
+  var pair;
+  var pos;
+
+  for (var i = 0, len = pairs.length; i < len; ++i) {
+    pair = pairs[i];
+    pos = pair.indexOf('=');
+    if (pos == -1) {
+      obj[decodeURIComponent(pair)] = '';
+    } else {
+      obj[decodeURIComponent(pair.slice(0, pos))] =
+        decodeURIComponent(pair.slice(pos + 1));
+    }
+  }
+
+  return obj;
+}
+
+/**
+ * Expose parser.
+ */
+
+request.parseString = parseString;
+
+/**
+ * Default MIME type map.
+ *
+ *     superagent.types.xml = 'application/xml';
+ *
+ */
+
+request.types = {
+  html: 'text/html',
+  json: 'application/json',
+  xml: 'application/xml',
+  urlencoded: 'application/x-www-form-urlencoded',
+  'form': 'application/x-www-form-urlencoded',
+  'form-data': 'application/x-www-form-urlencoded'
+};
+
+/**
+ * Default serialization map.
+ *
+ *     superagent.serialize['application/xml'] = function(obj){
+ *       return 'generated xml here';
+ *     };
+ *
+ */
+
+ request.serialize = {
+   'application/x-www-form-urlencoded': serialize,
+   'application/json': JSON.stringify
+ };
+
+ /**
+  * Default parsers.
+  *
+  *     superagent.parse['application/xml'] = function(str){
+  *       return { object parsed from str };
+  *     };
+  *
+  */
+
+request.parse = {
+  'application/x-www-form-urlencoded': parseString,
+  'application/json': JSON.parse
+};
+
+/**
+ * Parse the given header `str` into
+ * an object containing the mapped fields.
+ *
+ * @param {String} str
+ * @return {Object}
+ * @api private
+ */
+
+function parseHeader(str) {
+  var lines = str.split(/\r?\n/);
+  var fields = {};
+  var index;
+  var line;
+  var field;
+  var val;
+
+  lines.pop(); // trailing CRLF
+
+  for (var i = 0, len = lines.length; i < len; ++i) {
+    line = lines[i];
+    index = line.indexOf(':');
+    field = line.slice(0, index).toLowerCase();
+    val = trim(line.slice(index + 1));
+    fields[field] = val;
+  }
+
+  return fields;
+}
+
+/**
+ * Check if `mime` is json or has +json structured syntax suffix.
+ *
+ * @param {String} mime
+ * @return {Boolean}
+ * @api private
+ */
+
+function isJSON(mime) {
+  return /[\/+]json\b/.test(mime);
+}
+
+/**
+ * Return the mime type for the given `str`.
+ *
+ * @param {String} str
+ * @return {String}
+ * @api private
+ */
+
+function type(str){
+  return str.split(/ *; */).shift();
+};
+
+/**
+ * Return header field parameters.
+ *
+ * @param {String} str
+ * @return {Object}
+ * @api private
+ */
+
+function params(str){
+  return str.split(/ *; */).reduce(function(obj, str){
+    var parts = str.split(/ *= */),
+        key = parts.shift(),
+        val = parts.shift();
+
+    if (key && val) obj[key] = val;
+    return obj;
+  }, {});
+};
+
+/**
+ * Initialize a new `Response` with the given `xhr`.
+ *
+ *  - set flags (.ok, .error, etc)
+ *  - parse header
+ *
+ * Examples:
+ *
+ *  Aliasing `superagent` as `request` is nice:
+ *
+ *      request = superagent;
+ *
+ *  We can use the promise-like API, or pass callbacks:
+ *
+ *      request.get('/').end(function(res){});
+ *      request.get('/', function(res){});
+ *
+ *  Sending data can be chained:
+ *
+ *      request
+ *        .post('/user')
+ *        .send({ name: 'tj' })
+ *        .end(function(res){});
+ *
+ *  Or passed to `.send()`:
+ *
+ *      request
+ *        .post('/user')
+ *        .send({ name: 'tj' }, function(res){});
+ *
+ *  Or passed to `.post()`:
+ *
+ *      request
+ *        .post('/user', { name: 'tj' })
+ *        .end(function(res){});
+ *
+ * Or further reduced to a single call for simple cases:
+ *
+ *      request
+ *        .post('/user', { name: 'tj' }, function(res){});
+ *
+ * @param {XMLHTTPRequest} xhr
+ * @param {Object} options
+ * @api private
+ */
+
+function Response(req, options) {
+  options = options || {};
+  this.req = req;
+  this.xhr = this.req.xhr;
+  // responseText is accessible only if responseType is '' or 'text' and on older browsers
+  this.text = ((this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || typeof this.xhr.responseType === 'undefined')
+     ? this.xhr.responseText
+     : null;
+  this.statusText = this.req.xhr.statusText;
+  this._setStatusProperties(this.xhr.status);
+  this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders());
+  // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but
+  // getResponseHeader still works. so we get content-type even if getting
+  // other headers fails.
+  this.header['content-type'] = this.xhr.getResponseHeader('content-type');
+  this._setHeaderProperties(this.header);
+  this.body = this.req.method != 'HEAD'
+    ? this._parseBody(this.text ? this.text : this.xhr.response)
+    : null;
+}
+
+/**
+ * Get case-insensitive `field` value.
+ *
+ * @param {String} field
+ * @return {String}
+ * @api public
+ */
+
+Response.prototype.get = function(field){
+  return this.header[field.toLowerCase()];
+};
+
+/**
+ * Set header related properties:
+ *
+ *   - `.type` the content type without params
+ *
+ * A response of "Content-Type: text/plain; charset=utf-8"
+ * will provide you with a `.type` of "text/plain".
+ *
+ * @param {Object} header
+ * @api private
+ */
+
+Response.prototype._setHeaderProperties = function(header){
+  // content-type
+  var ct = this.header['content-type'] || '';
+  this.type = type(ct);
+
+  // params
+  var obj = params(ct);
+  for (var key in obj) this[key] = obj[key];
+};
+
+/**
+ * Parse the given body `str`.
+ *
+ * Used for auto-parsing of bodies. Parsers
+ * are defined on the `superagent.parse` object.
+ *
+ * @param {String} str
+ * @return {Mixed}
+ * @api private
+ */
+
+Response.prototype._parseBody = function(str){
+  var parse = request.parse[this.type];
+  if (!parse && isJSON(this.type)) {
+    parse = request.parse['application/json'];
+  }
+  return parse && str && (str.length || str instanceof Object)
+    ? parse(str)
+    : null;
+};
+
+/**
+ * Set flags such as `.ok` based on `status`.
+ *
+ * For example a 2xx response will give you a `.ok` of __true__
+ * whereas 5xx will be __false__ and `.error` will be __true__. The
+ * `.clientError` and `.serverError` are also available to be more
+ * specific, and `.statusType` is the class of error ranging from 1..5
+ * sometimes useful for mapping respond colors etc.
+ *
+ * "sugar" properties are also defined for common cases. Currently providing:
+ *
+ *   - .noContent
+ *   - .badRequest
+ *   - .unauthorized
+ *   - .notAcceptable
+ *   - .notFound
+ *
+ * @param {Number} status
+ * @api private
+ */
+
+Response.prototype._setStatusProperties = function(status){
+  // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request
+  if (status === 1223) {
+    status = 204;
+  }
+
+  var type = status / 100 | 0;
+
+  // status / class
+  this.status = this.statusCode = status;
+  this.statusType = type;
+
+  // basics
+  this.info = 1 == type;
+  this.ok = 2 == type;
+  this.clientError = 4 == type;
+  this.serverError = 5 == type;
+  this.error = (4 == type || 5 == type)
+    ? this.toError()
+    : false;
+
+  // sugar
+  this.accepted = 202 == status;
+  this.noContent = 204 == status;
+  this.badRequest = 400 == status;
+  this.unauthorized = 401 == status;
+  this.notAcceptable = 406 == status;
+  this.notFound = 404 == status;
+  this.forbidden = 403 == status;
+};
+
+/**
+ * Return an `Error` representative of this response.
+ *
+ * @return {Error}
+ * @api public
+ */
+
+Response.prototype.toError = function(){
+  var req = this.req;
+  var method = req.method;
+  var url = req.url;
+
+  var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')';
+  var err = new Error(msg);
+  err.status = this.status;
+  err.method = method;
+  err.url = url;
+
+  return err;
+};
+
+/**
+ * Expose `Response`.
+ */
+
+request.Response = Response;
+
+/**
+ * Initialize a new `Request` with the given `method` and `url`.
+ *
+ * @param {String} method
+ * @param {String} url
+ * @api public
+ */
+
+function Request(method, url) {
+  var self = this;
+  this._query = this._query || [];
+  this.method = method;
+  this.url = url;
+  this.header = {}; // preserves header name case
+  this._header = {}; // coerces header names to lowercase
+  this.on('end', function(){
+    var err = null;
+    var res = null;
+
+    try {
+      res = new Response(self);
+    } catch(e) {
+      err = new Error('Parser is unable to parse the response');
+      err.parse = true;
+      err.original = e;
+      // issue #675: return the raw response if the response parsing fails
+      err.rawResponse = self.xhr && self.xhr.responseText ? self.xhr.responseText : null;
+      // issue #876: return the http status code if the response parsing fails
+      err.statusCode = self.xhr && self.xhr.status ? self.xhr.status : null;
+      return self.callback(err);
+    }
+
+    self.emit('response', res);
+
+    var new_err;
+    try {
+      if (res.status < 200 || res.status >= 300) {
+        new_err = new Error(res.statusText || 'Unsuccessful HTTP response');
+        new_err.original = err;
+        new_err.response = res;
+        new_err.status = res.status;
+      }
+    } catch(e) {
+      new_err = e; // #985 touching res may cause INVALID_STATE_ERR on old Android
+    }
+
+    // #1000 don't catch errors from the callback to avoid double calling it
+    if (new_err) {
+      self.callback(new_err, res);
+    } else {
+      self.callback(null, res);
+    }
+  });
+}
+
+/**
+ * Mixin `Emitter` and `requestBase`.
+ */
+
+Emitter(Request.prototype);
+for (var key in requestBase) {
+  Request.prototype[key] = requestBase[key];
+}
+
+/**
+ * Set Content-Type to `type`, mapping values from `request.types`.
+ *
+ * Examples:
+ *
+ *      superagent.types.xml = 'application/xml';
+ *
+ *      request.post('/')
+ *        .type('xml')
+ *        .send(xmlstring)
+ *        .end(callback);
+ *
+ *      request.post('/')
+ *        .type('application/xml')
+ *        .send(xmlstring)
+ *        .end(callback);
+ *
+ * @param {String} type
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.type = function(type){
+  this.set('Content-Type', request.types[type] || type);
+  return this;
+};
+
+/**
+ * Set responseType to `val`. Presently valid responseTypes are 'blob' and
+ * 'arraybuffer'.
+ *
+ * Examples:
+ *
+ *      req.get('/')
+ *        .responseType('blob')
+ *        .end(callback);
+ *
+ * @param {String} val
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.responseType = function(val){
+  this._responseType = val;
+  return this;
+};
+
+/**
+ * Set Accept to `type`, mapping values from `request.types`.
+ *
+ * Examples:
+ *
+ *      superagent.types.json = 'application/json';
+ *
+ *      request.get('/agent')
+ *        .accept('json')
+ *        .end(callback);
+ *
+ *      request.get('/agent')
+ *        .accept('application/json')
+ *        .end(callback);
+ *
+ * @param {String} accept
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.accept = function(type){
+  this.set('Accept', request.types[type] || type);
+  return this;
+};
+
+/**
+ * Set Authorization field value with `user` and `pass`.
+ *
+ * @param {String} user
+ * @param {String} pass
+ * @param {Object} options with 'type' property 'auto' or 'basic' (default 'basic')
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.auth = function(user, pass, options){
+  if (!options) {
+    options = {
+      type: 'basic'
+    }
+  }
+
+  switch (options.type) {
+    case 'basic':
+      var str = btoa(user + ':' + pass);
+      this.set('Authorization', 'Basic ' + str);
+    break;
+
+    case 'auto':
+      this.username = user;
+      this.password = pass;
+    break;
+  }
+  return this;
+};
+
+/**
+* Add query-string `val`.
+*
+* Examples:
+*
+*   request.get('/shoes')
+*     .query('size=10')
+*     .query({ color: 'blue' })
+*
+* @param {Object|String} val
+* @return {Request} for chaining
+* @api public
+*/
+
+Request.prototype.query = function(val){
+  if ('string' != typeof val) val = serialize(val);
+  if (val) this._query.push(val);
+  return this;
+};
+
+/**
+ * Queue the given `file` as an attachment to the specified `field`,
+ * with optional `filename`.
+ *
+ * ``` js
+ * request.post('/upload')
+ *   .attach('content', new Blob(['<a id="a"><b id="b">hey!</b></a>'], { type: "text/html"}))
+ *   .end(callback);
+ * ```
+ *
+ * @param {String} field
+ * @param {Blob|File} file
+ * @param {String} filename
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.attach = function(field, file, filename){
+  this._getFormData().append(field, file, filename || file.name);
+  return this;
+};
+
+Request.prototype._getFormData = function(){
+  if (!this._formData) {
+    this._formData = new root.FormData();
+  }
+  return this._formData;
+};
+
+/**
+ * Invoke the callback with `err` and `res`
+ * and handle arity check.
+ *
+ * @param {Error} err
+ * @param {Response} res
+ * @api private
+ */
+
+Request.prototype.callback = function(err, res){
+  var fn = this._callback;
+  this.clearTimeout();
+  fn(err, res);
+};
+
+/**
+ * Invoke callback with x-domain error.
+ *
+ * @api private
+ */
+
+Request.prototype.crossDomainError = function(){
+  var err = new Error('Request has been terminated\nPossible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.');
+  err.crossDomain = true;
+
+  err.status = this.status;
+  err.method = this.method;
+  err.url = this.url;
+
+  this.callback(err);
+};
+
+/**
+ * Invoke callback with timeout error.
+ *
+ * @api private
+ */
+
+Request.prototype._timeoutError = function(){
+  var timeout = this._timeout;
+  var err = new Error('timeout of ' + timeout + 'ms exceeded');
+  err.timeout = timeout;
+  this.callback(err);
+};
+
+/**
+ * Compose querystring to append to req.url
+ *
+ * @api private
+ */
+
+Request.prototype._appendQueryString = function(){
+  var query = this._query.join('&');
+  if (query) {
+    this.url += ~this.url.indexOf('?')
+      ? '&' + query
+      : '?' + query;
+  }
+};
+
+/**
+ * Initiate request, invoking callback `fn(res)`
+ * with an instanceof `Response`.
+ *
+ * @param {Function} fn
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.end = function(fn){
+  var self = this;
+  var xhr = this.xhr = request.getXHR();
+  var timeout = this._timeout;
+  var data = this._formData || this._data;
+
+  // store callback
+  this._callback = fn || noop;
+
+  // state change
+  xhr.onreadystatechange = function(){
+    if (4 != xhr.readyState) return;
+
+    // In IE9, reads to any property (e.g. status) off of an aborted XHR will
+    // result in the error "Could not complete the operation due to error c00c023f"
+    var status;
+    try { status = xhr.status } catch(e) { status = 0; }
+
+    if (0 == status) {
+      if (self.timedout) return self._timeoutError();
+      if (self._aborted) return;
+      return self.crossDomainError();
+    }
+    self.emit('end');
+  };
+
+  // progress
+  var handleProgress = function(e){
+    if (e.total > 0) {
+      e.percent = e.loaded / e.total * 100;
+    }
+    e.direction = 'download';
+    self.emit('progress', e);
+  };
+  if (this.hasListeners('progress')) {
+    xhr.onprogress = handleProgress;
+  }
+  try {
+    if (xhr.upload && this.hasListeners('progress')) {
+      xhr.upload.onprogress = handleProgress;
+    }
+  } catch(e) {
+    // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist.
+    // Reported here:
+    // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context
+  }
+
+  // timeout
+  if (timeout && !this._timer) {
+    this._timer = setTimeout(function(){
+      self.timedout = true;
+      self.abort();
+    }, timeout);
+  }
+
+  // querystring
+  this._appendQueryString();
+
+  // initiate request
+  if (this.username && this.password) {
+    xhr.open(this.method, this.url, true, this.username, this.password);
+  } else {
+    xhr.open(this.method, this.url, true);
+  }
+
+  // CORS
+  if (this._withCredentials) xhr.withCredentials = true;
+
+  // body
+  if ('GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !this._isHost(data)) {
+    // serialize stuff
+    var contentType = this._header['content-type'];
+    var serialize = this._serializer || request.serialize[contentType ? contentType.split(';')[0] : ''];
+    if (!serialize && isJSON(contentType)) serialize = request.serialize['application/json'];
+    if (serialize) data = serialize(data);
+  }
+
+  // set header fields
+  for (var field in this.header) {
+    if (null == this.header[field]) continue;
+    xhr.setRequestHeader(field, this.header[field]);
+  }
+
+  if (this._responseType) {
+    xhr.responseType = this._responseType;
+  }
+
+  // send stuff
+  this.emit('request', this);
+
+  // IE11 xhr.send(undefined) sends 'undefined' string as POST payload (instead of nothing)
+  // We need null here if data is undefined
+  xhr.send(typeof data !== 'undefined' ? data : null);
+  return this;
+};
+
+
+/**
+ * Expose `Request`.
+ */
+
+request.Request = Request;
+
+/**
+ * GET `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} [data] or fn
+ * @param {Function} [fn]
+ * @return {Request}
+ * @api public
+ */
+
+request.get = function(url, data, fn){
+  var req = request('GET', url);
+  if ('function' == typeof data) fn = data, data = null;
+  if (data) req.query(data);
+  if (fn) req.end(fn);
+  return req;
+};
+
+/**
+ * HEAD `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} [data] or fn
+ * @param {Function} [fn]
+ * @return {Request}
+ * @api public
+ */
+
+request.head = function(url, data, fn){
+  var req = request('HEAD', url);
+  if ('function' == typeof data) fn = data, data = null;
+  if (data) req.send(data);
+  if (fn) req.end(fn);
+  return req;
+};
+
+/**
+ * OPTIONS query to `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} [data] or fn
+ * @param {Function} [fn]
+ * @return {Request}
+ * @api public
+ */
+
+request.options = function(url, data, fn){
+  var req = request('OPTIONS', url);
+  if ('function' == typeof data) fn = data, data = null;
+  if (data) req.send(data);
+  if (fn) req.end(fn);
+  return req;
+};
+
+/**
+ * DELETE `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Function} [fn]
+ * @return {Request}
+ * @api public
+ */
+
+function del(url, fn){
+  var req = request('DELETE', url);
+  if (fn) req.end(fn);
+  return req;
+};
+
+request['del'] = del;
+request['delete'] = del;
+
+/**
+ * PATCH `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed} [data]
+ * @param {Function} [fn]
+ * @return {Request}
+ * @api public
+ */
+
+request.patch = function(url, data, fn){
+  var req = request('PATCH', url);
+  if ('function' == typeof data) fn = data, data = null;
+  if (data) req.send(data);
+  if (fn) req.end(fn);
+  return req;
+};
+
+/**
+ * POST `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed} [data]
+ * @param {Function} [fn]
+ * @return {Request}
+ * @api public
+ */
+
+request.post = function(url, data, fn){
+  var req = request('POST', url);
+  if ('function' == typeof data) fn = data, data = null;
+  if (data) req.send(data);
+  if (fn) req.end(fn);
+  return req;
+};
+
+/**
+ * PUT `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} [data] or fn
+ * @param {Function} [fn]
+ * @return {Request}
+ * @api public
+ */
+
+request.put = function(url, data, fn){
+  var req = request('PUT', url);
+  if ('function' == typeof data) fn = data, data = null;
+  if (data) req.send(data);
+  if (fn) req.end(fn);
+  return req;
+};
+
+},{"./is-object":159,"./request":161,"./request-base":160,"emitter":162}],159:[function(require,module,exports){
+/**
+ * Check if `obj` is an object.
+ *
+ * @param {Object} obj
+ * @return {Boolean}
+ * @api private
+ */
+
+function isObject(obj) {
+  return null !== obj && 'object' === typeof obj;
+}
+
+module.exports = isObject;
+
+},{}],160:[function(require,module,exports){
+/**
+ * Module of mixed-in functions shared between node and client code
+ */
+var isObject = require('./is-object');
+
+/**
+ * Clear previous timeout.
+ *
+ * @return {Request} for chaining
+ * @api public
+ */
+
+exports.clearTimeout = function _clearTimeout(){
+  this._timeout = 0;
+  clearTimeout(this._timer);
+  return this;
+};
+
+/**
+ * Override default response body parser
+ *
+ * This function will be called to convert incoming data into request.body
+ *
+ * @param {Function}
+ * @api public
+ */
+
+exports.parse = function parse(fn){
+  this._parser = fn;
+  return this;
+};
+
+/**
+ * Override default request body serializer
+ *
+ * This function will be called to convert data set via .send or .attach into payload to send
+ *
+ * @param {Function}
+ * @api public
+ */
+
+exports.serialize = function serialize(fn){
+  this._serializer = fn;
+  return this;
+};
+
+/**
+ * Set timeout to `ms`.
+ *
+ * @param {Number} ms
+ * @return {Request} for chaining
+ * @api public
+ */
+
+exports.timeout = function timeout(ms){
+  this._timeout = ms;
+  return this;
+};
+
+/**
+ * Promise support
+ *
+ * @param {Function} resolve
+ * @param {Function} reject
+ * @return {Request}
+ */
+
+exports.then = function then(resolve, reject) {
+  if (!this._fullfilledPromise) {
+    var self = this;
+    this._fullfilledPromise = new Promise(function(innerResolve, innerReject){
+      self.end(function(err, res){
+        if (err) innerReject(err); else innerResolve(res);
+      });
+    });
+  }
+  return this._fullfilledPromise.then(resolve, reject);
+}
+
+/**
+ * Allow for extension
+ */
+
+exports.use = function use(fn) {
+  fn(this);
+  return this;
+}
+
+
+/**
+ * Get request header `field`.
+ * Case-insensitive.
+ *
+ * @param {String} field
+ * @return {String}
+ * @api public
+ */
+
+exports.get = function(field){
+  return this._header[field.toLowerCase()];
+};
+
+/**
+ * Get case-insensitive header `field` value.
+ * This is a deprecated internal API. Use `.get(field)` instead.
+ *
+ * (getHeader is no longer used internally by the superagent code base)
+ *
+ * @param {String} field
+ * @return {String}
+ * @api private
+ * @deprecated
+ */
+
+exports.getHeader = exports.get;
+
+/**
+ * Set header `field` to `val`, or multiple fields with one object.
+ * Case-insensitive.
+ *
+ * Examples:
+ *
+ *      req.get('/')
+ *        .set('Accept', 'application/json')
+ *        .set('X-API-Key', 'foobar')
+ *        .end(callback);
+ *
+ *      req.get('/')
+ *        .set({ Accept: 'application/json', 'X-API-Key': 'foobar' })
+ *        .end(callback);
+ *
+ * @param {String|Object} field
+ * @param {String} val
+ * @return {Request} for chaining
+ * @api public
+ */
+
+exports.set = function(field, val){
+  if (isObject(field)) {
+    for (var key in field) {
+      this.set(key, field[key]);
+    }
+    return this;
+  }
+  this._header[field.toLowerCase()] = val;
+  this.header[field] = val;
+  return this;
+};
+
+/**
+ * Remove header `field`.
+ * Case-insensitive.
+ *
+ * Example:
+ *
+ *      req.get('/')
+ *        .unset('User-Agent')
+ *        .end(callback);
+ *
+ * @param {String} field
+ */
+exports.unset = function(field){
+  delete this._header[field.toLowerCase()];
+  delete this.header[field];
+  return this;
+};
+
+/**
+ * Write the field `name` and `val` for "multipart/form-data"
+ * request bodies.
+ *
+ * ``` js
+ * request.post('/upload')
+ *   .field('foo', 'bar')
+ *   .end(callback);
+ * ```
+ *
+ * @param {String} name
+ * @param {String|Blob|File|Buffer|fs.ReadStream} val
+ * @return {Request} for chaining
+ * @api public
+ */
+exports.field = function(name, val) {
+  this._getFormData().append(name, val);
+  return this;
+};
+
+/**
+ * Abort the request, and clear potential timeout.
+ *
+ * @return {Request}
+ * @api public
+ */
+exports.abort = function(){
+  if (this._aborted) {
+    return this;
+  }
+  this._aborted = true;
+  this.xhr && this.xhr.abort(); // browser
+  this.req && this.req.abort(); // node
+  this.clearTimeout();
+  this.emit('abort');
+  return this;
+};
+
+/**
+ * Enable transmission of cookies with x-domain requests.
+ *
+ * Note that for this to work the origin must not be
+ * using "Access-Control-Allow-Origin" with a wildcard,
+ * and also must set "Access-Control-Allow-Credentials"
+ * to "true".
+ *
+ * @api public
+ */
+
+exports.withCredentials = function(){
+  // This is browser-only functionality. Node side is no-op.
+  this._withCredentials = true;
+  return this;
+};
+
+/**
+ * Set the max redirects to `n`. Does noting in browser XHR implementation.
+ *
+ * @param {Number} n
+ * @return {Request} for chaining
+ * @api public
+ */
+
+exports.redirects = function(n){
+  this._maxRedirects = n;
+  return this;
+};
+
+/**
+ * Convert to a plain javascript object (not JSON string) of scalar properties.
+ * Note as this method is designed to return a useful non-this value,
+ * it cannot be chained.
+ *
+ * @return {Object} describing method, url, and data of this request
+ * @api public
+ */
+
+exports.toJSON = function(){
+  return {
+    method: this.method,
+    url: this.url,
+    data: this._data,
+    headers: this._header
+  };
+};
+
+/**
+ * Check if `obj` is a host object,
+ * we don't want to serialize these :)
+ *
+ * TODO: future proof, move to compoent land
+ *
+ * @param {Object} obj
+ * @return {Boolean}
+ * @api private
+ */
+
+exports._isHost = function _isHost(obj) {
+  var str = {}.toString.call(obj);
+
+  switch (str) {
+    case '[object File]':
+    case '[object Blob]':
+    case '[object FormData]':
+      return true;
+    default:
+      return false;
+  }
+}
+
+/**
+ * Send `data` as the request body, defaulting the `.type()` to "json" when
+ * an object is given.
+ *
+ * Examples:
+ *
+ *       // manual json
+ *       request.post('/user')
+ *         .type('json')
+ *         .send('{"name":"tj"}')
+ *         .end(callback)
+ *
+ *       // auto json
+ *       request.post('/user')
+ *         .send({ name: 'tj' })
+ *         .end(callback)
+ *
+ *       // manual x-www-form-urlencoded
+ *       request.post('/user')
+ *         .type('form')
+ *         .send('name=tj')
+ *         .end(callback)
+ *
+ *       // auto x-www-form-urlencoded
+ *       request.post('/user')
+ *         .type('form')
+ *         .send({ name: 'tj' })
+ *         .end(callback)
+ *
+ *       // defaults to x-www-form-urlencoded
+ *      request.post('/user')
+ *        .send('name=tobi')
+ *        .send('species=ferret')
+ *        .end(callback)
+ *
+ * @param {String|Object} data
+ * @return {Request} for chaining
+ * @api public
+ */
+
+exports.send = function(data){
+  var obj = isObject(data);
+  var type = this._header['content-type'];
+
+  // merge
+  if (obj && isObject(this._data)) {
+    for (var key in data) {
+      this._data[key] = data[key];
+    }
+  } else if ('string' == typeof data) {
+    // default to x-www-form-urlencoded
+    if (!type) this.type('form');
+    type = this._header['content-type'];
+    if ('application/x-www-form-urlencoded' == type) {
+      this._data = this._data
+        ? this._data + '&' + data
+        : data;
+    } else {
+      this._data = (this._data || '') + data;
+    }
+  } else {
+    this._data = data;
+  }
+
+  if (!obj || this._isHost(data)) return this;
+
+  // default to json
+  if (!type) this.type('json');
+  return this;
+};
+
+},{"./is-object":159}],161:[function(require,module,exports){
+// The node and browser modules expose versions of this with the
+// appropriate constructor function bound as first argument
+/**
+ * Issue a request:
+ *
+ * Examples:
+ *
+ *    request('GET', '/users').end(callback)
+ *    request('/users').end(callback)
+ *    request('/users', callback)
+ *
+ * @param {String} method
+ * @param {String|Function} url or callback
+ * @return {Request}
+ * @api public
+ */
+
+function request(RequestConstructor, method, url) {
+  // callback
+  if ('function' == typeof url) {
+    return new RequestConstructor('GET', method).end(url);
+  }
+
+  // url first
+  if (2 == arguments.length) {
+    return new RequestConstructor('GET', method);
+  }
+
+  return new RequestConstructor(method, url);
+}
+
+module.exports = request;
+
+},{}],162:[function(require,module,exports){
+\r
+/**\r
+ * Expose `Emitter`.\r
+ */\r
+\r
+if (typeof module !== 'undefined') {\r
+  module.exports = Emitter;\r
+}\r
+\r
+/**\r
+ * Initialize a new `Emitter`.\r
+ *\r
+ * @api public\r
+ */\r
+\r
+function Emitter(obj) {\r
+  if (obj) return mixin(obj);\r
+};\r
+\r
+/**\r
+ * Mixin the emitter properties.\r
+ *\r
+ * @param {Object} obj\r
+ * @return {Object}\r
+ * @api private\r
+ */\r
+\r
+function mixin(obj) {\r
+  for (var key in Emitter.prototype) {\r
+    obj[key] = Emitter.prototype[key];\r
+  }\r
+  return obj;\r
+}\r
+\r
+/**\r
+ * Listen on the given `event` with `fn`.\r
+ *\r
+ * @param {String} event\r
+ * @param {Function} fn\r
+ * @return {Emitter}\r
+ * @api public\r
+ */\r
+\r
+Emitter.prototype.on =\r
+Emitter.prototype.addEventListener = function(event, fn){\r
+  this._callbacks = this._callbacks || {};\r
+  (this._callbacks['$' + event] = this._callbacks['$' + event] || [])\r
+    .push(fn);\r
+  return this;\r
+};\r
+\r
+/**\r
+ * Adds an `event` listener that will be invoked a single\r
+ * time then automatically removed.\r
+ *\r
+ * @param {String} event\r
+ * @param {Function} fn\r
+ * @return {Emitter}\r
+ * @api public\r
+ */\r
+\r
+Emitter.prototype.once = function(event, fn){\r
+  function on() {\r
+    this.off(event, on);\r
+    fn.apply(this, arguments);\r
+  }\r
+\r
+  on.fn = fn;\r
+  this.on(event, on);\r
+  return this;\r
+};\r
+\r
+/**\r
+ * Remove the given callback for `event` or all\r
+ * registered callbacks.\r
+ *\r
+ * @param {String} event\r
+ * @param {Function} fn\r
+ * @return {Emitter}\r
+ * @api public\r
+ */\r
+\r
+Emitter.prototype.off =\r
+Emitter.prototype.removeListener =\r
+Emitter.prototype.removeAllListeners =\r
+Emitter.prototype.removeEventListener = function(event, fn){\r
+  this._callbacks = this._callbacks || {};\r
+\r
+  // all\r
+  if (0 == arguments.length) {\r
+    this._callbacks = {};\r
+    return this;\r
+  }\r
+\r
+  // specific event\r
+  var callbacks = this._callbacks['$' + event];\r
+  if (!callbacks) return this;\r
+\r
+  // remove all handlers\r
+  if (1 == arguments.length) {\r
+    delete this._callbacks['$' + event];\r
+    return this;\r
+  }\r
+\r
+  // remove specific handler\r
+  var cb;\r
+  for (var i = 0; i < callbacks.length; i++) {\r
+    cb = callbacks[i];\r
+    if (cb === fn || cb.fn === fn) {\r
+      callbacks.splice(i, 1);\r
+      break;\r
+    }\r
+  }\r
+  return this;\r
+};\r
+\r
+/**\r
+ * Emit `event` with the given args.\r
+ *\r
+ * @param {String} event\r
+ * @param {Mixed} ...\r
+ * @return {Emitter}\r
+ */\r
+\r
+Emitter.prototype.emit = function(event){\r
+  this._callbacks = this._callbacks || {};\r
+  var args = [].slice.call(arguments, 1)\r
+    , callbacks = this._callbacks['$' + event];\r
+\r
+  if (callbacks) {\r
+    callbacks = callbacks.slice(0);\r
+    for (var i = 0, len = callbacks.length; i < len; ++i) {\r
+      callbacks[i].apply(this, args);\r
+    }\r
+  }\r
+\r
+  return this;\r
+};\r
+\r
+/**\r
+ * Return array of callbacks for `event`.\r
+ *\r
+ * @param {String} event\r
+ * @return {Array}\r
+ * @api public\r
+ */\r
+\r
+Emitter.prototype.listeners = function(event){\r
+  this._callbacks = this._callbacks || {};\r
+  return this._callbacks['$' + event] || [];\r
+};\r
+\r
+/**\r
+ * Check if this emitter has `event` handlers.\r
+ *\r
+ * @param {String} event\r
+ * @return {Boolean}\r
+ * @api public\r
+ */\r
+\r
+Emitter.prototype.hasListeners = function(event){\r
+  return !! this.listeners(event).length;\r
+};\r
+
+},{}]},{},[1])(1)
+});
+
+
+ /*global JSONEditor*/
+'use strict';
+
+window.SwaggerUi = Backbone.Router.extend({
+
+  dom_id: 'swagger_ui',
+
+  // Attributes
+  options: null,
+  api: null,
+  headerView: null,
+  mainView: null,
+
+  // SwaggerUi accepts all the same options as SwaggerApi
+  initialize: function(options) {
+    options = options || {};
+
+    if (options.defaultModelRendering !== 'model') {
+      options.defaultModelRendering = 'schema';
+    }
+
+    if (!options.highlightSizeThreshold) {
+      options.highlightSizeThreshold = 100000;
+    }
+
+    // Allow dom_id to be overridden
+    if (options.dom_id) {
+      this.dom_id = options.dom_id;
+      delete options.dom_id;
+    }
+
+    if (!options.supportedSubmitMethods){
+      options.supportedSubmitMethods = [
+        'get',
+        'put',
+        'post',
+        'delete',
+        'head',
+        'options',
+        'patch'
+      ];
+    }
+
+    if (typeof options.oauth2RedirectUrl === 'string') {
+      window.oAuthRedirectUrl = options.oauth2RedirectUrl;
+    }
+
+    // Create an empty div which contains the dom_id
+    if (! $('#' + this.dom_id).length){
+      $('body').append('<div id="' + this.dom_id + '"></div>') ;
+    }
+
+    this.options = options;
+
+    // set marked options
+    marked.setOptions({gfm: true});
+
+    // Set the callbacks
+    var that = this;
+    this.options.success = function() { return that.render(); };
+    this.options.progress = function(d) { return that.showMessage(d); };
+    this.options.failure = function(d) { return that.onLoadFailure(d); };
+
+    // Create view to handle the header inputs
+    this.headerView = new SwaggerUi.Views.HeaderView({el: $('#header')});
+
+    // Event handler for when the baseUrl/apiKey is entered by user
+    this.headerView.on('update-swagger-ui', function(data) {
+      return that.updateSwaggerUi(data);
+    });
+
+    // JSon Editor custom theming
+     JSONEditor.defaults.iconlibs.swagger = JSONEditor.AbstractIconLib.extend({
+      mapping: {
+        collapse: 'collapse',
+        expand: 'expand'
+        },
+      icon_prefix: 'swagger-'
+      });
+
+  },
+
+  // Set an option after initializing
+  setOption: function(option, value) {
+    this.options[option] = value;
+  },
+
+  // Get the value of a previously set option
+  getOption: function(option) {
+    return this.options[option];
+  },
+
+  // Event handler for when url/key is received from user
+  updateSwaggerUi: function(data){
+    this.options.url = data.url;
+    this.load();
+  },
+
+  // Create an api and render
+  load: function(){
+    // Initialize the API object
+    if (this.mainView) {
+      this.mainView.clear();
+    }
+
+    if (this.authView) {
+      this.authView.remove();
+    }
+    var url = this.options.url;
+    if (url && url.indexOf('http') !== 0) {
+      url = this.buildUrl(window.location.href.toString(), url);
+    }
+    if(this.api) {
+      this.options.authorizations = this.api.clientAuthorizations.authz;
+    }
+    this.options.url = url;
+    this.headerView.update(url);
+
+    this.api = new SwaggerClient(this.options);
+  },
+
+  // collapse all sections
+  collapseAll: function(){
+    Docs.collapseEndpointListForResource('');
+  },
+
+  // list operations for all sections
+  listAll: function(){
+    Docs.collapseOperationsForResource('');
+  },
+
+  // expand operations for all sections
+  expandAll: function(){
+    Docs.expandOperationsForResource('');
+  },
+
+  // This is bound to success handler for SwaggerApi
+  //  so it gets called when SwaggerApi completes loading
+  render: function(){
+    var authsModel;
+    this.showMessage('Finished Loading Resource Information. Rendering Swagger UI...');
+    this.mainView = new SwaggerUi.Views.MainView({
+      model: this.api,
+      el: $('#' + this.dom_id),
+      swaggerOptions: this.options,
+      router: this
+    }).render();
+    if (!_.isEmpty(this.api.securityDefinitions)){
+      authsModel = _.map(this.api.securityDefinitions, function (auth, name) {
+        var result = {};
+        result[name] = auth;
+        return result;
+      });
+      this.authView = new SwaggerUi.Views.AuthButtonView({
+        data: SwaggerUi.utils.parseSecurityDefinitions(authsModel),
+        router: this
+      });
+      $('#auth_container').append(this.authView.render().el);
+    }
+    this.showMessage();
+    switch (this.options.docExpansion) {
+      case 'full':
+        this.expandAll(); break;
+      case 'list':
+        this.listAll(); break;
+      default:
+        break;
+    }
+    this.renderGFM();
+
+    if (this.options.onComplete){
+      this.options.onComplete(this.api, this);
+    }
+
+    setTimeout(Docs.shebang.bind(this), 100);
+  },
+
+  buildUrl: function(base, url){
+    if (url.indexOf('/') === 0) {
+      var parts = base.split('/');
+      base = parts[0] + '//' + parts[2];
+      return base + url;
+    } else {
+      var endOfPath = base.length;
+
+      if (base.indexOf('?') > -1){
+        endOfPath = Math.min(endOfPath, base.indexOf('?'));
+      }
+
+      if (base.indexOf('#') > -1){
+        endOfPath = Math.min(endOfPath, base.indexOf('#'));
+      }
+
+      base = base.substring(0, endOfPath);
+
+      if (base.indexOf('/', base.length - 1 ) !== -1){
+        return base + url;
+      }
+
+      return base + '/' + url;
+    }
+  },
+
+  // Shows message on topbar of the ui
+  showMessage: function(data){
+    if (data === undefined) {
+      data = '';
+    }
+    var $msgbar = $('#message-bar');
+    $msgbar.removeClass('message-fail');
+    $msgbar.addClass('message-success');
+    $msgbar.text(data);
+    if(window.SwaggerTranslator) {
+      window.SwaggerTranslator.translate($msgbar);
+    }
+  },
+
+  // shows message in red
+  onLoadFailure: function(data){
+    if (data === undefined) {
+      data = '';
+    }
+    $('#message-bar').removeClass('message-success');
+    $('#message-bar').addClass('message-fail');
+
+    var val = $('#message-bar').text(data);
+
+    if (this.options.onFailure) {
+      this.options.onFailure(data);
+    }
+
+    return val;
+  },
+
+  // Renders GFM for elements with 'markdown' class
+  renderGFM: function(){
+    $('.markdown').each(function(){
+      $(this).html(marked($(this).html()));
+    });
+
+    $('.propDesc', '.model-signature .description').each(function () {
+      $(this).html(marked($(this).html())).addClass('markdown');
+    });
+  }
+
+});
+
+window.SwaggerUi.Views = {};
+window.SwaggerUi.Models = {};
+window.SwaggerUi.Collections = {};
+window.SwaggerUi.partials = {};
+window.SwaggerUi.utils = {};
+
+// don't break backward compatibility with previous versions and warn users to upgrade their code
+(function(){
+  window.authorizations = {
+    add: function() {
+      warn('Using window.authorizations is deprecated. Please use SwaggerUi.api.clientAuthorizations.add().');
+
+      if (typeof window.swaggerUi === 'undefined') {
+        throw new TypeError('window.swaggerUi is not defined');
+      }
+
+      if (window.swaggerUi instanceof SwaggerUi) {
+        window.swaggerUi.api.clientAuthorizations.add.apply(window.swaggerUi.api.clientAuthorizations, arguments);
+      }
+    }
+  };
+
+  window.ApiKeyAuthorization = function() {
+    warn('window.ApiKeyAuthorization is deprecated. Please use SwaggerClient.ApiKeyAuthorization.');
+    SwaggerClient.ApiKeyAuthorization.apply(window, arguments);
+  };
+
+  window.PasswordAuthorization = function() {
+    warn('window.PasswordAuthorization is deprecated. Please use SwaggerClient.PasswordAuthorization.');
+    SwaggerClient.PasswordAuthorization.apply(window, arguments);
+  };
+
+  function warn(message) {
+    if ('console' in window && typeof window.console.warn === 'function') {
+      console.warn(message);
+    }
+  }
+})();
+
+
+// UMD
+(function (root, factory) {
+    if (typeof define === 'function' && define.amd) {
+        // AMD. Register as an anonymous module.
+        define(['b'], function (b) {
+            return (root.SwaggerUi = factory(b));
+        });
+    } else if (typeof exports === 'object') {
+        // Node. Does not work with strict CommonJS, but
+        // only CommonJS-like environments that support module.exports,
+        // like Node.
+        module.exports = factory(require('b'));
+    } else {
+        // Browser globals
+        root.SwaggerUi = factory(root.b);
+    }
+}(this, function () {
+    return SwaggerUi;
+}));
+
+'use strict';
+
+window.SwaggerUi.utils = {
+    parseSecurityDefinitions: function (security, securityDefinitions) {
+        var auths = Object.assign({}, securityDefinitions);
+        var oauth2Arr = [];
+        var authsArr = [];
+        var scopes = [];
+        var utils = window.SwaggerUi.utils;
+
+        if (!Array.isArray(security)) { return null; }
+
+        security.forEach(function (item) {
+            var singleSecurity = {};
+            var singleOauth2Security = {};
+
+            for (var key in item) {
+                if (Array.isArray(item[key])) {
+                    if (!auths[key]) { continue; }
+                    auths[key] = auths[key] || {};
+                    if (auths[key].type === 'oauth2') {
+                        singleOauth2Security[key] = Object.assign({}, auths[key]);
+                        singleOauth2Security[key].scopes = Object.assign({}, auths[key].scopes);
+                        for (var i in singleOauth2Security[key].scopes) {
+                            if (item[key].indexOf(i) < 0) {
+                                delete singleOauth2Security[key].scopes[i];
+                            }
+                        }
+                        singleOauth2Security[key].scopes = utils.parseOauth2Scopes(singleOauth2Security[key].scopes);
+                        scopes = _.merge(scopes, singleOauth2Security[key].scopes);
+                    } else {
+                        singleSecurity[key] = Object.assign({}, auths[key]);
+                    }
+                } else {
+                    if (item[key].type === 'oauth2') {
+                        singleOauth2Security[key] = Object.assign({}, item[key]);
+                        singleOauth2Security[key].scopes = utils.parseOauth2Scopes(singleOauth2Security[key].scopes);
+                        scopes = _.merge(scopes, singleOauth2Security[key].scopes);
+                    } else {
+                        singleSecurity[key] = item[key];
+                    }
+                }
+            }
+
+            if (!_.isEmpty(singleSecurity)) {
+                authsArr.push(singleSecurity);
+            }
+
+            if (!_.isEmpty(singleOauth2Security)){
+                oauth2Arr.push(singleOauth2Security);
+            }
+        });
+
+        return {
+            auths : authsArr,
+            oauth2: oauth2Arr,
+            scopes: scopes
+        };
+    },
+
+    parseOauth2Scopes: function (data) {
+        var scopes = Object.assign({}, data);
+        var result = [];
+        var key;
+
+        for (key in scopes) {
+            result.push({scope: key, description: scopes[key]});
+        }
+
+        return result;
+    },
+
+    sanitize: function(html) {
+        // Strip the script tags from the html and inline evenhandlers
+        html = html.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');
+        html = html.replace(/(on\w+="[^"]*")*(on\w+='[^']*')*(on\w+=\w*\(\w*\))*/gi, '');
+
+        return html;
+    }
+};
+'use strict';
+
+SwaggerUi.Models.ApiKeyAuthModel = Backbone.Model.extend({
+    defaults: {
+        'in': '',
+        name: '',
+        title: '',
+        value: ''
+    },
+
+    initialize: function () {
+        this.on('change', this.validate);
+    },
+
+    validate: function () {
+        var valid = !!this.get('value');
+
+        this.set('valid', valid);
+
+        return valid;
+    }
+});
+'use strict';
+
+SwaggerUi.Views.ApiKeyAuthView = Backbone.View.extend({ // TODO: append this to global SwaggerUi
+
+    events: {
+        'change .input_apiKey_entry': 'apiKeyChange'
+    },
+
+    selectors: {
+        apikeyInput: '.input_apiKey_entry'
+    },
+
+    template: Handlebars.templates.apikey_auth,
+
+    initialize: function(opts) {
+        this.options = opts || {};
+        this.router = this.options.router;
+    },
+
+    render: function (){
+        this.$el.html(this.template(this.model.toJSON()));
+
+        return this;
+    },
+
+    apiKeyChange: function (e) {
+        var val = $(e.target).val();
+        if (val) {
+            this.$(this.selectors.apikeyInput).removeClass('error');
+        }
+
+        this.model.set('value', val);
+    },
+
+    isValid: function () {
+        return this.model.validate();
+    },
+
+    highlightInvalid: function () {
+        if (!this.isValid()) {
+            this.$(this.selectors.apikeyInput).addClass('error');
+        }
+    }
+
+});
+'use strict';
+
+SwaggerUi.Views.AuthButtonView = Backbone.View.extend({
+    events: {
+        'click .authorize__btn': 'authorizeBtnClick'
+    },
+
+    tpls: {
+        popup: Handlebars.templates.popup,
+        authBtn: Handlebars.templates.auth_button,
+        authBtnOperation: Handlebars.templates.auth_button_operation
+    },
+
+    initialize: function(opts) {
+        this.options = opts || {};
+        this.options.data = this.options.data || {};
+        this.isOperation = this.options.isOperation;
+        this.model = this.model || {};
+        this.router = this.options.router;
+        this.auths = this.options.data.oauth2.concat(this.options.data.auths);
+    },
+
+    render: function () {
+        var tplName = this.isOperation ? 'authBtnOperation' : 'authBtn';
+
+        this.$authEl = this.renderAuths(this.auths);
+        this.$el.html(this.tpls[tplName](this.model));
+
+        return this;
+    },
+
+    authorizeBtnClick: function (e) {
+        var authsModel;
+
+        e.preventDefault();
+
+        authsModel = {
+            title: 'Available authorizations',
+            content: this.$authEl
+        };
+
+        // The content of the popup is removed and all events unbound after clicking the 'Cancel' button of the popup.
+        // We'll have to re-render the contents before creating a new popup view.
+        this.render();
+
+        this.popup = new SwaggerUi.Views.PopupView({model: authsModel});
+        this.popup.render();
+    },
+
+    renderAuths: function (auths) {
+        var $el = $('<div>');
+        var isLogout = false;
+
+        auths.forEach(function (auth) {
+            var authView = new SwaggerUi.Views.AuthView({data: auth, router: this.router});
+            var authEl = authView.render().el;
+            $el.append(authEl);
+            if (authView.isLogout) {
+                isLogout = true;
+            }
+        }, this);
+
+        this.model.isLogout = isLogout;
+
+        return $el;
+    }
+
+});
+
+'use strict';
+
+SwaggerUi.Collections.AuthsCollection = Backbone.Collection.extend({
+    constructor: function() {
+        var args = Array.prototype.slice.call(arguments);
+
+        args[0] = this.parse(args[0]);
+
+        Backbone.Collection.apply(this, args);
+    },
+
+    add: function (model) {
+        var args = Array.prototype.slice.call(arguments);
+
+        if (Array.isArray(model)) {
+            args[0] = _.map(model, function(val) {
+                return this.handleOne(val);
+            }, this);
+        } else {
+            args[0] = this.handleOne(model);
+        }
+
+        Backbone.Collection.prototype.add.apply(this, args);
+    },
+
+    handleOne: function (model) {
+        var result = model;
+
+        if (! (model instanceof Backbone.Model) ) {
+            switch (model.type) {
+                case 'oauth2':
+                    result = new SwaggerUi.Models.Oauth2Model(model);
+                    break;
+                case 'basic':
+                    result = new SwaggerUi.Models.BasicAuthModel(model);
+                    break;
+                case 'apiKey':
+                    result = new SwaggerUi.Models.ApiKeyAuthModel(model);
+                    break;
+                default:
+                    result = new Backbone.Model(model);
+            }
+        }
+
+        return result;
+    },
+
+    isValid: function () {
+        var valid = true;
+
+        this.models.forEach(function(model) {
+            if (!model.validate()) {
+                valid = false;
+            }
+        });
+
+        return valid;
+    },
+
+    isAuthorized: function () {
+        return this.length === this.where({ isLogout: true }).length;
+    },
+
+    isPartiallyAuthorized: function () {
+        return this.where({ isLogout: true }).length > 0;
+    },
+
+    parse: function (data) {
+        var authz = {};
+
+        if(typeof window.swaggerUi !== 'undefined') {
+            authz = Object.assign({}, window.swaggerUi.api.clientAuthorizations.authz);
+        }
+
+        return _.map(data, function (auth, name) {
+            var isBasic = authz[name] && auth.type === 'basic' && authz[name].username && authz[name].password;
+
+            _.extend(auth, {
+                title: name
+            });
+
+            if (authz[name] || isBasic) {
+                _.extend(auth, {
+                    isLogout: true,
+                    value: isBasic ? undefined : authz[name].value,
+                    username: isBasic ? authz[name].username : undefined,
+                    password: isBasic ? authz[name].password : undefined,
+                    valid: true
+                });
+            }
+
+            return auth;
+        });
+    }
+});
+'use strict';
+
+SwaggerUi.Views.AuthsCollectionView = Backbone.View.extend({
+
+    initialize: function(opts) {
+        this.options = opts || {};
+        this.options.data = this.options.data || {};
+        this.router = this.options.router;
+
+        this.collection = new SwaggerUi.Collections.AuthsCollection(opts.data);
+
+        this.$innerEl = $('<div>');
+        this.authViews = [];
+    },
+
+    render: function () {
+        this.collection.each(function (auth) {
+            this.renderOneAuth(auth);
+        }, this);
+
+        this.$el.html(this.$innerEl.html() ? this.$innerEl : '');
+
+        return this;
+    },
+
+    renderOneAuth: function (authModel) {
+        var authViewEl, authView, authViewName;
+        var type = authModel.get('type');
+
+        if (type === 'apiKey') {
+            authViewName = 'ApiKeyAuthView';
+        } else if (type === 'basic' && this.$innerEl.find('.basic_auth_container').length === 0) {
+            authViewName = 'BasicAuthView';
+        } else if (type === 'oauth2') {
+            authViewName = 'Oauth2View';
+        }
+
+        if (authViewName) {
+            authView = new SwaggerUi.Views[authViewName]({model: authModel, router: this.router});
+            authViewEl = authView.render().el;
+            this.authViews.push(authView);
+        }
+
+        this.$innerEl.append(authViewEl);
+    },
+
+    highlightInvalid: function () {
+        this.authViews.forEach(function (view) {
+            view.highlightInvalid();
+        }, this);
+    }
+
+});
+
+'use strict';
+
+/* global redirect_uri:true */
+/* global clientId */
+/* global scopeSeparator */
+/* global additionalQueryStringParams */
+/* global clientSecret */
+/* global onOAuthComplete */
+/* global realm */
+/*jshint unused:false*/
+
+SwaggerUi.Views.AuthView = Backbone.View.extend({
+    events: {
+        'click .auth_submit__button': 'authorizeClick',
+        'click .auth_logout__button': 'logoutClick'
+    },
+
+    tpls: {
+        main: Handlebars.templates.auth_view
+    },
+
+    selectors: {
+        innerEl: '.auth_inner',
+        authBtn: '.auth_submit__button'
+    },
+
+    initialize: function(opts) {
+        this.options = opts || {};
+        opts.data = opts.data || {};
+        this.router = this.options.router;
+
+        this.authsCollectionView = new SwaggerUi.Views.AuthsCollectionView({data: opts.data});
+
+        this.$el.html(this.tpls.main({
+            isLogout: this.authsCollectionView.collection.isAuthorized(),
+            isAuthorized: this.authsCollectionView.collection.isPartiallyAuthorized()
+        }));
+        this.$innerEl = this.$(this.selectors.innerEl);
+        this.isLogout = this.authsCollectionView.collection.isPartiallyAuthorized();
+    },
+
+    render: function () {
+        this.$innerEl.html(this.authsCollectionView.render().el);
+
+        return this;
+    },
+
+    authorizeClick: function (e) {
+        e.preventDefault();
+        e.stopPropagation();
+
+        if (this.authsCollectionView.collection.isValid()) {
+            this.authorize();
+        } else {
+            this.authsCollectionView.highlightInvalid();
+        }
+    },
+
+    authorize: function () {
+        this.authsCollectionView.collection.forEach(function (auth) {
+            var keyAuth, basicAuth;
+            var type = auth.get('type');
+
+            if (type === 'apiKey') {
+                keyAuth = new SwaggerClient.ApiKeyAuthorization(
+                    auth.get('name'),
+                    auth.get('value'),
+                    auth.get('in')
+                );
+
+                this.router.api.clientAuthorizations.add(auth.get('title'), keyAuth);
+            } else if (type === 'basic') {
+                basicAuth = new SwaggerClient.PasswordAuthorization(auth.get('username'), auth.get('password'));
+                this.router.api.clientAuthorizations.add(auth.get('title'), basicAuth);
+            } else if (type === 'oauth2') {
+                this.handleOauth2Login(auth);
+            }
+        }, this);
+
+        this.router.load();
+    },
+
+    logoutClick: function (e) {
+        e.preventDefault();
+
+        this.authsCollectionView.collection.forEach(function (auth) {
+            window.swaggerUi.api.clientAuthorizations.remove(auth.get('title'));
+        });
+
+        this.router.load();
+    },
+
+    // taken from lib/swagger-oauth.js
+    handleOauth2Login: function (auth) {
+        var host = window.location;
+        var pathname = location.pathname.substring(0, location.pathname.lastIndexOf('/'));
+        var defaultRedirectUrl = host.protocol + '//' + host.host + pathname + '/o2c.html';
+        var redirectUrl = window.oAuthRedirectUrl || defaultRedirectUrl;
+        var url = null;
+        var scopes = _.map(auth.get('scopes'), function (scope) {
+            if(scope.checked) {
+                return scope.scope;
+            }
+        });
+        var container = window.swaggerUiAuth || (window.swaggerUiAuth = {});
+        var state, dets, ep;
+        container.OAuthSchemeKey = auth.get('title');
+
+        window.enabledScopes = scopes;
+        var flow = auth.get('flow');
+
+        /**
+         * Returns the name of the access token parameter returned by the server.
+         *
+         * @param dets
+         *     The authorisation scheme configuration.
+         * @return the name of the access token parameter
+         */
+        function getTokenName(dets) {
+            return dets.vendorExtensions['x-tokenName'] || dets.tokenName;
+        }
+
+        if(auth.get('type') === 'oauth2' && flow && (flow === 'implicit' || flow === 'accessCode')) {
+            dets = auth.attributes;
+            url = dets.authorizationUrl + '?response_type=' + (flow === 'implicit' ? 'token' : 'code');
+            container.tokenName = getTokenName(dets) || 'access_token';
+            container.tokenUrl = (flow === 'accessCode' ? dets.tokenUrl : null);
+            state = container.OAuthSchemeKey;
+        }
+        else if(auth.get('type') === 'oauth2' && flow && (flow === 'application')) {
+            dets = auth.attributes;
+            container.tokenName = getTokenName(dets) || 'access_token';
+            this.clientCredentialsFlow(scopes, dets, container.OAuthSchemeKey);
+            return;
+        }
+        else if(auth.get('type') === 'oauth2' && flow && (flow === 'password')) {
+            dets = auth.attributes;
+            container.tokenName = getTokenName(dets) || 'access_token';
+            this.passwordFlow(scopes, dets, container.OAuthSchemeKey);
+            return;
+        }
+        else if(auth.get('grantTypes')) {
+            // 1.2 support
+            var o = auth.get('grantTypes');
+            for(var t in o) {
+                if(o.hasOwnProperty(t) && t === 'implicit') {
+                    dets = o[t];
+                    ep = dets.loginEndpoint.url;
+                    url = dets.loginEndpoint.url + '?response_type=token';
+                    container.tokenName = getTokenName(dets);
+                }
+                else if (o.hasOwnProperty(t) && t === 'accessCode') {
+                    dets = o[t];
+                    ep = dets.tokenRequestEndpoint.url;
+                    url = dets.tokenRequestEndpoint.url + '?response_type=code';
+                    container.tokenName = getTokenName(dets);
+                }
+            }
+        }
+
+        redirect_uri = redirectUrl;
+
+        url += '&redirect_uri=' + encodeURIComponent(redirectUrl);
+        url += '&realm=' + encodeURIComponent(realm);
+        url += '&client_id=' + encodeURIComponent(clientId);
+        url += '&scope=' + encodeURIComponent(scopes.join(scopeSeparator));
+        url += '&state=' + encodeURIComponent(state);
+        for (var key in additionalQueryStringParams) {
+            url += '&' + key + '=' + encodeURIComponent(additionalQueryStringParams[key]);
+        }
+
+        window.open(url);
+    },
+
+    // taken from lib/swagger-oauth.js
+    clientCredentialsFlow: function (scopes, oauth, OAuthSchemeKey) {
+        this.accessTokenRequest(scopes, oauth, OAuthSchemeKey, 'client_credentials');
+    },
+
+    passwordFlow: function (scopes, oauth, OAuthSchemeKey) {
+        this.accessTokenRequest(scopes, oauth, OAuthSchemeKey, 'password', {
+            'username': oauth.username,
+            'password': oauth.password
+        });
+    },
+
+    accessTokenRequest: function (scopes, oauth, OAuthSchemeKey, grantType, params) {
+        params = $.extend({}, {
+            'scope': scopes.join(' '),
+            'grant_type': grantType
+        }, params);
+
+        var headers= {};
+
+        switch (oauth.clientAuthenticationType) {
+            case 'basic':
+                headers.Authorization = 'Basic ' + btoa(oauth.clientId + ':' + oauth.clientSecret);
+                break;
+            case 'request-body':
+                params.client_id = oauth.clientId;
+                params.client_secret = oauth.clientSecret;
+                break;
+        }
+
+        $.ajax({
+            url : oauth.tokenUrl,
+            type: 'POST',
+            data: params,
+            headers: headers,
+            success: function (data)
+            {
+                onOAuthComplete(data, OAuthSchemeKey);
+            },
+            error: function ()
+            {
+                onOAuthComplete('');
+            }
+        });
+    }
+});
+
+'use strict';
+
+SwaggerUi.Models.BasicAuthModel = Backbone.Model.extend({
+    defaults: {
+        username: '',
+        password: '',
+        title: 'basic'
+    },
+
+    initialize: function () {
+        this.on('change', this.validate);
+    },
+
+    validate: function () {
+        var valid = !!this.get('password') && !!this.get('username');
+
+        this.set('valid', valid);
+
+        return valid;
+    }
+});
+'use strict';
+
+SwaggerUi.Views.BasicAuthView = Backbone.View.extend({
+
+    initialize: function (opts) {
+        this.options = opts || {};
+        this.router = this.options.router;
+    },
+
+    events: {
+        'change .auth_input': 'inputChange'
+    },
+
+    selectors: {
+        usernameInput: '.basic_auth__username',
+        passwordInput: '.basic_auth__password'
+    },
+
+    cls: {
+        error: 'error'
+    },
+
+    template: Handlebars.templates.basic_auth,
+
+    render: function(){
+        $(this.el).html(this.template(this.model.toJSON()));
+
+        return this;
+    },
+
+    inputChange: function (e) {
+        var $el = $(e.target);
+        var val = $el.val();
+        var attr = $el.prop('name');
+
+        if (val) {
+            $el.removeClass(this.cls.error);
+        }
+
+        this.model.set(attr, val);
+    },
+
+    isValid: function () {
+        return this.model.validate();
+    },
+
+    highlightInvalid: function () {
+        if (!this.model.get('username')) {
+            this.$(this.selectors.usernameInput).addClass(this.cls.error);
+        }
+    }
+});
+
+'use strict';
+
+SwaggerUi.Views.ContentTypeView = Backbone.View.extend({
+  initialize: function() {},
+
+  render: function(){
+       this.model.contentTypeId = 'ct' + Math.random();
+    $(this.el).html(Handlebars.templates.content_type(this.model));
+    return this;
+  }
+});
+'use strict';
+
+SwaggerUi.Views.HeaderView = Backbone.View.extend({
+  events: {
+    'click #show-pet-store-icon'    : 'showPetStore',
+    'click #explore'                : 'showCustom',
+    'submit #api_selector'          : 'showCustom',
+    'keyup #input_baseUrl'          : 'showCustomOnKeyup',
+    'keyup #input_apiKey'           : 'showCustomOnKeyup'
+  },
+
+  initialize: function(){},
+
+  showPetStore: function(){
+    this.trigger('update-swagger-ui', {
+      url:'http://petstore.swagger.io/v2/swagger.json'
+    });
+  },
+
+  showCustomOnKeyup: function(e){
+    if (e.keyCode === 13) {
+      this.showCustom();
+    }
+  },
+
+  showCustom: function(e){
+    if (e) {
+      e.preventDefault();
+    }
+
+    this.trigger('update-swagger-ui', {
+      url: $('#input_baseUrl').val()
+    });
+  },
+
+  update: function(url, apiKey, trigger){
+    if (trigger === undefined) {
+      trigger = false;
+    }
+
+    $('#input_baseUrl').val(url);
+
+    if (trigger) {
+      this.trigger('update-swagger-ui', {url:url});
+    }
+  }
+});
+
+'use strict';
+
+SwaggerUi.Views.MainView = Backbone.View.extend({
+  apisSorter : {
+    alpha   : function(a,b){ return a.name.localeCompare(b.name); }
+  },
+  operationsSorters : {
+    alpha   : function(a,b){ return a.path.localeCompare(b.path); },
+    method  : function(a,b){ return a.method.localeCompare(b.method); }
+  },
+  initialize: function(opts){
+    var sorterOption, sorterFn, key, value;
+    opts = opts || {};
+
+    this.router = opts.router;
+
+    // Sort APIs
+    if (opts.swaggerOptions.apisSorter) {
+      sorterOption = opts.swaggerOptions.apisSorter;
+      if (_.isFunction(sorterOption)) {
+        sorterFn = sorterOption;
+      } else {
+        sorterFn = this.apisSorter[sorterOption];
+      }
+      if (_.isFunction(sorterFn)) {
+        this.model.apisArray.sort(sorterFn);
+      }
+    }
+    // Sort operations of each API
+    if (opts.swaggerOptions.operationsSorter) {
+      sorterOption = opts.swaggerOptions.operationsSorter;
+      if (_.isFunction(sorterOption)) {
+        sorterFn = sorterOption;
+      } else {
+        sorterFn = this.operationsSorters[sorterOption];
+      }
+      if (_.isFunction(sorterFn)) {
+        for (key in this.model.apisArray) {
+          this.model.apisArray[key].operationsArray.sort(sorterFn);
+        }
+      }
+    }
+
+    // set up the UI for input
+    this.model.auths = [];
+
+    for (key in this.model.securityDefinitions) {
+      value = this.model.securityDefinitions[key];
+
+      this.model.auths.push({
+        name: key,
+        type: value.type,
+        value: value
+      });
+    }
+
+    if ('validatorUrl' in opts.swaggerOptions) {
+      // Validator URL specified explicitly
+      this.model.validatorUrl = opts.swaggerOptions.validatorUrl;
+    } else if (this.model.url.indexOf('localhost') > 0 || this.model.url.indexOf('127.0.0.1') > 0) {
+      // Localhost override
+      this.model.validatorUrl = null;
+    } else {
+      this.model.validatorUrl = '//online.swagger.io/validator';
+    }
+
+    // JSonEditor requires type='object' to be present on defined types, we add it if it's missing
+    // is there any valid case were it should not be added ?
+    var def;
+    for(def in this.model.definitions){
+      if (!this.model.definitions[def].type){
+        this.model.definitions[def].type = 'object';
+      }
+    }
+
+  },
+
+  render: function () {
+    $(this.el).html(Handlebars.templates.main(this.model));
+    this.info = this.$('.info')[0];
+
+    if (this.info) {
+      this.info.addEventListener('click', this.onLinkClick, true);
+    }
+
+    this.model.securityDefinitions = this.model.securityDefinitions || {};
+
+    // Render each resource
+
+    var resources = {};
+    var counter = 0;
+    for (var i = 0; i < this.model.apisArray.length; i++) {
+      var resource = this.model.apisArray[i];
+      var id = resource.name;
+      while (typeof resources[id] !== 'undefined') {
+        id = id + '_' + counter;
+        counter += 1;
+      }
+      resource.id = sanitizeHtml(id);
+      resources[id] = resource;
+      this.addResource(resource, this.model.auths);
+    }
+
+    $('.propWrap').hover(function onHover(){
+      $('.optionsWrapper', $(this)).show();
+    }, function offhover(){
+      $('.optionsWrapper', $(this)).hide();
+    });
+    return this;
+  },
+
+  addResource: function(resource, auths){
+    // Render a resource and add it to resources li
+    resource.id = resource.id.replace(/[^a-zA-Z\d]/g, function(str) { return str.charCodeAt(0); });
+
+    // Make all definitions available at the root of the resource so that they can
+    // be loaded by the JSonEditor
+    resource.definitions = this.model.definitions;
+
+    var resourceView = new SwaggerUi.Views.ResourceView({
+      model: resource,
+      router: this.router,
+      tagName: 'li',
+      id: 'resource_' + resource.id,
+      className: 'resource',
+      auths: auths,
+      swaggerOptions: this.options.swaggerOptions
+    });
+    $('#resources', this.el).append(resourceView.render().el);
+  },
+
+  clear: function(){
+    $(this.el).html('');
+  },
+
+  onLinkClick: function (e) {
+    var el = e.target;
+
+    if (el.tagName === 'A' && el.href && !el.target) {
+        e.preventDefault();
+        window.open(el.href, '_blank');
+    }
+  }
+});
+
+'use strict';
+
+SwaggerUi.Models.Oauth2Model = Backbone.Model.extend({
+    defaults: {
+        scopes: {},
+        isPasswordFlow: false,
+        clientAuthenticationType: 'none'
+    },
+
+    initialize: function () {
+        if(this.attributes && this.attributes.scopes) {
+            var attributes = _.cloneDeep(this.attributes);
+            var i, scopes = [];
+            for(i in attributes.scopes) {
+                var scope = attributes.scopes[i];
+                if(typeof scope.description === 'string') {
+                    scopes[scope] = attributes.scopes[i];
+                    scopes.push(attributes.scopes[i]);
+                }
+            }
+            attributes.scopes = scopes;
+            this.attributes = attributes;
+        }
+
+        if (this.attributes && this.attributes.flow) {
+            var flow = this.attributes.flow;
+            this.set('isPasswordFlow', flow === 'password');
+            this.set('requireClientAuthentication', flow === 'application');
+            this.set('clientAuthentication', flow === 'password' || flow === 'application');
+        }
+        this.on('change', this.validate);
+    },
+
+    setScopes: function (name, val) {
+        var auth = _.extend({}, this.attributes);
+        var index = _.findIndex(auth.scopes, function(o) {
+            return o.scope === name;
+        });
+        auth.scopes[index].checked = val;
+
+        this.set(auth);
+        this.validate();
+    },
+
+    validate: function () {
+      var valid = false;
+      if (this.get('isPasswordFlow') &&
+          (!this.get('username'))) {
+          return false;
+      }
+
+      if (this.get('clientAuthenticationType') in ['basic', 'request-body'] &&
+          (!this.get('clientId'))) {
+          return false;
+      }
+
+      var scp = this.get('scopes');
+      var idx =  _.findIndex(scp, function (o) {
+         return o.checked === true;
+      });
+
+      if(scp.length > 0 && idx >= 0) {
+          valid = true;
+      }
+
+      if(scp.length === 0) {
+          valid = true;
+      }
+
+      this.set('valid', valid);
+
+      return valid;
+    }
+});
+
+'use strict';
+
+SwaggerUi.Views.Oauth2View = Backbone.View.extend({
+    events: {
+        'change .oauth-scope': 'scopeChange',
+        'change .oauth-username': 'setUsername',
+        'change .oauth-password': 'setPassword',
+        'change .oauth-client-authentication-type': 'setClientAuthenticationType',
+        'change .oauth-client-id': 'setClientId',
+        'change .oauth-client-secret': 'setClientSecret'
+    },
+
+    template: Handlebars.templates.oauth2,
+
+    cls: {
+        error: 'error'
+    },
+
+    render: function () {
+        this.$el.html(this.template(this.model.toJSON()));
+
+        return this;
+    },
+
+    scopeChange: function (e) {
+        var val = $(e.target).prop('checked');
+        var scope = $(e.target).data('scope');
+
+        this.model.setScopes(scope, val);
+    },
+
+    setUsername: function (e) {
+        var val= $(e.target).val();
+        this.model.set('username', val);
+        if (val) {
+            $(e.target).removeClass(this.cls.error);
+        }
+    },
+
+    setPassword: function (e) {
+        this.model.set('password', $(e.target).val());
+    },
+
+    setClientAuthenticationType: function (e) {
+        var type = $(e.target).val();
+        var $el = this.$el;
+        this.model.set('clientAuthenticationType', type);
+
+        switch(type) {
+            case 'none':
+                $el.find('.oauth-client-authentication').hide();
+                break;
+            case 'basic':
+            case 'request-body':
+                $el.find('.oauth-client-id').removeClass(this.cls.error);
+                $el.find('.oauth-client-authentication').show();
+                break;
+        }
+    },
+
+    setClientId: function (e) {
+        var val = $(e.target).val();
+        this.model.set('clientId', val);
+        if (val) {
+            $(e.target).removeClass(this.cls.error);
+        }
+    },
+
+    setClientSecret: function (e) {
+        this.model.set('clientSecret', $(e.target).val());
+        $(e.target).removeClass('error');
+    },
+
+    highlightInvalid: function () {
+        if (!this.model.get('username')) {
+            this.$el.find('.oauth-username').addClass(this.cls.error);
+        }
+
+        if (!this.model.get('clientId')) {
+            this.$el.find('.oauth-client-id').addClass(this.cls.error);
+        }
+    }
+});
+'use strict';
+
+SwaggerUi.Views.OperationView = Backbone.View.extend({
+  invocationUrl: null,
+
+  events: {
+    'submit .sandbox'         : 'submitOperation',
+    'click .submit'           : 'submitOperation',
+    'click .response_hider'   : 'hideResponse',
+    'click .toggleOperation'  : 'toggleOperationContent',
+    'mouseenter .api-ic'      : 'mouseEnter',
+    'dblclick .curl'          : 'selectText',
+    'change [name=responseContentType]' : 'showSnippet'
+  },
+
+  initialize: function(opts) {
+    opts = opts || {};
+    this.router = opts.router;
+    this.auths = opts.auths;
+    this.parentId = this.model.parentId;
+    this.nickname = this.model.nickname;
+    this.model.encodedParentId = encodeURIComponent(this.parentId);
+
+    if (opts.swaggerOptions) {
+      this.model.defaultRendering = opts.swaggerOptions.defaultModelRendering;
+
+      if (opts.swaggerOptions.showRequestHeaders) {
+        this.model.showRequestHeaders = true;
+      }
+
+      if (opts.swaggerOptions.showOperationIds) {
+        this.model.showOperationIds = true;
+      }
+    }
+    return this;
+  },
+
+  selectText: function(event) {
+    var doc = document,
+        text = event.target.firstChild,
+        range,
+        selection;
+    if (doc.body.createTextRange) {
+      range = document.body.createTextRange();
+      range.moveToElementText(text);
+      range.select();
+    } else if (window.getSelection) {
+      selection = window.getSelection();
+      range = document.createRange();
+      range.selectNodeContents(text);
+      selection.removeAllRanges();
+      selection.addRange(range);
+    }
+  },
+
+  mouseEnter: function(e) {
+    var elem = $(this.el).find('.content');
+    var x = e.pageX;
+    var y = e.pageY;
+    var scX = $(window).scrollLeft();
+    var scY = $(window).scrollTop();
+    var scMaxX = scX + $(window).width();
+    var scMaxY = scY + $(window).height();
+    var wd = elem.width();
+    var hgh = elem.height();
+
+    if (x + wd > scMaxX) {
+      x = scMaxX - wd;
+    }
+
+    if (x < scX) {
+      x = scX;
+    }
+
+    if (y + hgh > scMaxY) {
+      y = scMaxY - hgh;
+    }
+
+    if (y < scY) {
+      y = scY;
+    }
+
+    var pos = {};
+    pos.top = y;
+    pos.left = x;
+    elem.css(pos);
+  },
+
+  // Note: copied from CoffeeScript compiled file
+  // TODO: refactor
+  render: function() {
+    var a, auth, auths, code, contentTypeModel, isMethodSubmissionSupported, k, key, l, len, len1, len2, len3, len4, m, modelAuths, n, o, p, param, q, ref, ref1, ref2, ref3, ref4, ref5, responseContentTypeView, responseSignatureView, schema, schemaObj, scopeIndex, signatureModel, statusCode, successResponse, type, v, value, produces, isXML, isJSON;
+    isMethodSubmissionSupported = jQuery.inArray(this.model.method, this.model.supportedSubmitMethods()) >= 0;
+    if (!isMethodSubmissionSupported) {
+      this.model.isReadOnly = true;
+    }
+    this.model.description = this.model.description || this.model.notes;
+    this.model.oauth = null;
+    modelAuths = this.model.authorizations || this.model.security;
+    if (modelAuths) {
+      if (Array.isArray(modelAuths)) {
+        for (l = 0, len = modelAuths.length; l < len; l++) {
+          auths = modelAuths[l];
+          for (key in auths) {
+            for (a in this.auths) {
+              auth = this.auths[a];
+              if (key === auth.name) {
+                if (auth.type === 'oauth2') {
+                  this.model.oauth = {};
+                  this.model.oauth.scopes = [];
+                  ref1 = auth.value.scopes;
+                  for (k in ref1) {
+                    v = ref1[k];
+                    scopeIndex = auths[key].indexOf(k);
+                    if (scopeIndex >= 0) {
+                      o = {
+                        scope: k,
+                        description: v
+                      };
+                      this.model.oauth.scopes.push(o);
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      } else {
+        for (k in modelAuths) {
+          v = modelAuths[k];
+          if (k === 'oauth2') {
+            if (this.model.oauth === null) {
+              this.model.oauth = {};
+            }
+            if (this.model.oauth.scopes === void 0) {
+              this.model.oauth.scopes = [];
+            }
+            for (m = 0, len1 = v.length; m < len1; m++) {
+              o = v[m];
+              this.model.oauth.scopes.push(o);
+            }
+          }
+        }
+      }
+    }
+    if (typeof this.model.responses !== 'undefined') {
+      this.model.responseMessages = [];
+      ref2 = this.model.responses;
+      for (code in ref2) {
+        value = ref2[code];
+        schema = null;
+        schemaObj = this.model.responses[code].schema;
+        if (schemaObj && schemaObj.$ref) {
+          schema = schemaObj.$ref;
+          if (schema.indexOf('#/definitions/') !== -1) {
+            schema = schema.replace(/^.*#\/definitions\//, '');
+          }
+        }
+        this.model.responseMessages.push({
+          code: code,
+          message: value.description,
+          responseModel: schema,
+          headers: value.headers,
+          schema: schemaObj
+        });
+      }
+    }
+    if (typeof this.model.responseMessages === 'undefined') {
+      this.model.responseMessages = [];
+    }
+    signatureModel = null;
+    produces = this.model.produces;
+    isXML = this.contains(produces, 'xml');
+    isJSON = isXML ? this.contains(produces, 'json') : true;
+
+    if (this.model.successResponse) {
+      successResponse = this.model.successResponse;
+      for (key in successResponse) {
+        value = successResponse[key];
+        this.model.successCode = key;
+        if (typeof value === 'object' && typeof value.createJSONSample === 'function') {
+          this.model.successDescription = value.description;
+          this.model.headers = this.parseResponseHeaders(value.headers);
+          signatureModel = {
+            sampleJSON: isJSON ? JSON.stringify(SwaggerUi.partials.signature.createJSONSample(value), void 0, 2) : false,
+            isParam: false,
+            sampleXML: isXML ? SwaggerUi.partials.signature.createXMLSample(value.name, value.definition, value.models) : false,
+            signature: SwaggerUi.partials.signature.getModelSignature(value.name, value.definition, value.models, value.modelPropertyMacro)
+          };
+        } else {
+          signatureModel = {
+            signature: SwaggerUi.partials.signature.getPrimitiveSignature(value)
+          };
+        }
+      }
+    } else if (this.model.responseClassSignature && this.model.responseClassSignature !== 'string') {
+      signatureModel = {
+        sampleJSON: this.model.responseSampleJSON,
+        isParam: false,
+        signature: this.model.responseClassSignature
+      };
+    }
+    $(this.el).html(Handlebars.templates.operation(this.model));
+    if (signatureModel) {
+      signatureModel.defaultRendering = this.model.defaultRendering;
+      responseSignatureView = new SwaggerUi.Views.SignatureView({
+        model: signatureModel,
+        router: this.router,
+        tagName: 'div'
+      });
+      $('.model-signature', $(this.el)).append(responseSignatureView.render().el);
+    } else {
+      this.model.responseClassSignature = 'string';
+      $('.model-signature', $(this.el)).html(this.model.type);
+    }
+    contentTypeModel = {
+      isParam: false
+    };
+    contentTypeModel.consumes = this.model.consumes;
+    contentTypeModel.produces = this.model.produces;
+    ref3 = this.model.parameters;
+    for (n = 0, len2 = ref3.length; n < len2; n++) {
+      param = ref3[n];
+      type = param.type || param.dataType || '';
+      if (typeof type === 'undefined') {
+        schema = param.schema;
+        if (schema && schema.$ref) {
+          ref = schema.$ref;
+          if (ref.indexOf('#/definitions/') === 0) {
+            type = ref.substring('#/definitions/'.length);
+          } else {
+            type = ref;
+          }
+        }
+      }
+      if (type && type.toLowerCase() === 'file') {
+        if (!contentTypeModel.consumes) {
+          contentTypeModel.consumes = 'multipart/form-data';
+        }
+      }
+      param.type = type;
+    }
+    responseContentTypeView = new SwaggerUi.Views.ResponseContentTypeView({
+      model: contentTypeModel,
+      router: this.router
+    });
+    $('.response-content-type', $(this.el)).append(responseContentTypeView.render().el);
+    ref4 = this.model.parameters;
+    for (p = 0, len3 = ref4.length; p < len3; p++) {
+      param = ref4[p];
+      this.addParameter(param, contentTypeModel.consumes);
+    }
+    ref5 = this.model.responseMessages;
+    for (q = 0, len4 = ref5.length; q < len4; q++) {
+      statusCode = ref5[q];
+      statusCode.isXML = isXML;
+      statusCode.isJSON = isJSON;
+      if (!_.isUndefined(statusCode.headers)) {
+        statusCode.headers = this.parseHeadersType(statusCode.headers);
+      }
+      this.addStatusCode(statusCode);
+    }
+
+    if (Array.isArray(this.model.security)) {
+      var authsModel = SwaggerUi.utils.parseSecurityDefinitions(this.model.security, this.model.parent.securityDefinitions);
+
+      authsModel.isLogout = !_.isEmpty(this.model.clientAuthorizations.authz);
+      this.authView = new SwaggerUi.Views.AuthButtonView({
+        data: authsModel,
+        router: this.router,
+        isOperation: true,
+        model: {
+          scopes: authsModel.scopes
+        }
+      });
+      this.$('.authorize-wrapper').append(this.authView.render().el);
+    }
+
+    this.showSnippet();
+    return this;
+  },
+
+  parseHeadersType: function (headers) {
+    var map = {
+      'string': {
+        'date-time': 'dateTime',
+        'date'     : 'date'
+      }
+    };
+
+    _.forEach(headers, function (header) {
+      var value;
+      header = header || {};
+      value = map[header.type] && map[header.type][header.format];
+      if (!_.isUndefined(value)) {
+        header.type = value;
+      }
+    });
+
+    return headers;
+  },
+
+  contains: function (produces, type) {
+    return produces.filter(function (val) {
+      if (val.indexOf(type) > -1) {
+        return true;
+      }
+    }).length;
+  },
+
+  parseResponseHeaders: function (data) {
+    var HEADERS_SEPARATOR = '; ';
+    var headers = _.clone(data);
+
+    _.forEach(headers, function (header) {
+      var other = [];
+      _.forEach(header, function (value, key) {
+        var properties = ['type', 'description'];
+        if (properties.indexOf(key.toLowerCase()) === -1) {
+          other.push(key + ': ' + value);
+        }
+      });
+
+      other.join(HEADERS_SEPARATOR);
+      header.other = other;
+    });
+
+    return headers;
+  },
+
+  addParameter: function(param, consumes) {
+    // Render a parameter
+    param.consumes = consumes;
+    param.defaultRendering = this.model.defaultRendering;
+
+    // Copy this param JSON spec so that it will be available for JsonEditor
+    if(param.schema){
+      $.extend(true, param.schema, this.model.definitions[param.type]);
+      param.schema.definitions = this.model.definitions;
+      // This is required for JsonEditor to display the root properly
+      if(!param.schema.type){
+        param.schema.type = 'object';
+      }
+      // This is the title that will be used by JsonEditor for the root
+      // Since we already display the parameter's name in the Parameter column
+      // We set this to space, we can't set it to null or space otherwise JsonEditor
+      // will replace it with the text "root" which won't look good on screen
+      if(!param.schema.title){
+        param.schema.title = ' ';
+      }
+    }
+
+    var paramView = new SwaggerUi.Views.ParameterView({
+      model: param,
+      tagName: 'tr',
+      readOnly: this.model.isReadOnly,
+      swaggerOptions: this.options.swaggerOptions
+    });
+    $('.operation-params', $(this.el)).append(paramView.render().el);
+  },
+
+  addStatusCode: function(statusCode) {
+    // Render status codes
+    statusCode.defaultRendering = this.model.defaultRendering;
+    var statusCodeView = new SwaggerUi.Views.StatusCodeView({
+      model: statusCode,
+      tagName: 'tr',
+      router: this.router
+    });
+    $('.operation-status', $(this.el)).append(statusCodeView.render().el);
+  },
+
+  // Note: copied from CoffeeScript compiled file
+  // TODO: redactor
+  submitOperation: function(e) {
+    var error_free, form, isFileUpload, map, opts;
+    if (e !== null) {
+      e.preventDefault();
+    }
+    form = $('.sandbox', $(this.el));
+    error_free = true;
+    form.find('input.required').each(function() {
+      $(this).removeClass('error');
+      if (jQuery.trim($(this).val()) === '') {
+        $(this).addClass('error');
+        $(this).wiggle({
+          callback: (function(_this) {
+            return function() {
+              $(_this).focus();
+            };
+          })(this)
+        });
+        error_free = false;
+      }
+    });
+    form.find('textarea.required:visible').each(function() {
+      $(this).removeClass('error');
+      if (jQuery.trim($(this).val()) === '') {
+        $(this).addClass('error');
+        $(this).wiggle({
+          callback: (function(_this) {
+            return function() {
+              return $(_this).focus();
+            };
+          })(this)
+        });
+        error_free = false;
+      }
+    });
+    form.find('select.required').each(function() {
+      $(this).removeClass('error');
+      if (this.selectedIndex === -1) {
+        $(this).addClass('error');
+        $(this).wiggle({
+          callback: (function(_this) {
+            return function() {
+              $(_this).focus();
+            };
+          })(this)
+        });
+        error_free = false;
+      }
+    });
+    if (error_free) {
+      map = this.getInputMap(form);
+      isFileUpload = this.isFileUpload(form);
+      opts = {
+        parent: this
+      };
+      if (this.options.swaggerOptions) {
+        for(var key in this.options.swaggerOptions) {
+          opts[key] = this.options.swaggerOptions[key];
+        }
+      }
+
+      var pi;
+      for(pi = 0; pi < this.model.parameters.length; pi++){
+        var p = this.model.parameters[pi];
+        if( p.jsonEditor && p.jsonEditor.isEnabled()){
+          var json = p.jsonEditor.getValue();
+          map[p.name] = JSON.stringify(json);
+        }
+      }
+
+      opts.responseContentType = $('div select[name=responseContentType]', $(this.el)).val();
+      opts.requestContentType = $('div select[name=parameterContentType]', $(this.el)).val();
+      $('.response_throbber', $(this.el)).show();
+      if (isFileUpload) {
+        $('.request_url', $(this.el)).html('<pre></pre>');
+        $('.request_url pre', $(this.el)).text(this.invocationUrl);
+
+        opts.useJQuery = true;
+        map.parameterContentType = 'multipart/form-data';
+        this.map = map;
+        return this.model.execute(map, opts, this.showCompleteStatus, this.showErrorStatus, this);
+      } else {
+        this.map = map;
+        return this.model.execute(map, opts, this.showCompleteStatus, this.showErrorStatus, this);
+      }
+    }
+  },
+
+  getInputMap: function (form) {
+    var map, ref1, l, len, o, ref2, m, len1, val, ref3, n, len2;
+    map = {};
+    ref1 = form.find('input');
+    for (l = 0, len = ref1.length; l < len; l++) {
+      o = ref1[l];
+      if ((o.value !== null) && jQuery.trim(o.value).length > 0) {
+        map[o.name] = o.value;
+      }
+      if (o.type === 'file') {
+        map[o.name] = o.files[0];
+      }
+    }
+    ref2 = form.find('textarea');
+    for (m = 0, len1 = ref2.length; m < len1; m++) {
+      o = ref2[m];
+      val = this.getTextAreaValue(o);
+      if ((val !== null) && jQuery.trim(val).length > 0) {
+        map[o.name] = val;
+      }
+    }
+    ref3 = form.find('select');
+    for (n = 0, len2 = ref3.length; n < len2; n++) {
+      o = ref3[n];
+      val = this.getSelectedValue(o);
+      if ((val !== null) && jQuery.trim(val).length > 0) {
+        map[o.name] = val;
+      }
+    }
+    return map;
+  },
+
+  isFileUpload: function (form) {
+    var ref1, l, len, o;
+    var isFileUpload = false;
+    ref1 = form.find('input');
+    for (l = 0, len = ref1.length; l < len; l++) {
+      o = ref1[l];
+      if (o.type === 'file') {
+        isFileUpload = true;
+      }
+    }
+    return isFileUpload;
+  },
+
+  success: function(response, parent) {
+    parent.showCompleteStatus(response);
+  },
+
+  // wraps a jquery response as a shred response
+  wrap: function(data) {
+    var h, headerArray, headers, i, l, len, o;
+    headers = {};
+    headerArray = data.getAllResponseHeaders().split('\r');
+    for (l = 0, len = headerArray.length; l < len; l++) {
+      i = headerArray[l];
+      h = i.match(/^([^:]*?):(.*)$/);
+      if (!h) {
+        h = [];
+      }
+      h.shift();
+      if (h[0] !== void 0 && h[1] !== void 0) {
+        headers[h[0].trim()] = h[1].trim();
+      }
+    }
+    o = {};
+    o.content = {};
+    o.content.data = data.responseText;
+    o.headers = headers;
+    o.request = {};
+    o.request.url = this.invocationUrl;
+    o.status = data.status;
+    return o;
+  },
+
+  getSelectedValue: function(select) {
+    if (!select.multiple) {
+      return select.value;
+    } else {
+      var options = [];
+      for (var l = 0, len = select.options.length; l < len; l++) {
+        var opt = select.options[l];
+        if (opt.selected) {
+          options.push(opt.value);
+        }
+      }
+      if (options.length > 0) {
+        return options;
+      } else {
+        return null;
+      }
+    }
+  },
+
+  // handler for hide response link
+  hideResponse: function(e) {
+    if (e) { e.preventDefault(); }
+    $('.response', $(this.el)).slideUp();
+    $('.response_hider', $(this.el)).fadeOut();
+  },
+
+  // Show response from server
+  showResponse: function(response) {
+    var prettyJson = JSON.stringify(response, null, '\t').replace(/\n/g, '<br>');
+    $('.response_body', $(this.el)).html(_.escape(prettyJson));
+  },
+
+  // Show error from server
+  showErrorStatus: function(data, parent) {
+    parent.showStatus(data);
+  },
+
+  // show the status codes
+  showCompleteStatus: function(data, parent){
+    parent.showStatus(data);
+  },
+
+  // Adapted from http://stackoverflow.com/a/2893259/454004
+  // Note: directly ported from CoffeeScript
+  // TODO: Cleanup CoffeeScript artifacts
+  formatXml: function(xml) {
+    var contexp, fn, formatted, indent, l, lastType, len, lines, ln, pad, reg, transitions, wsexp;
+    reg = /(>)(<)(\/*)/g;
+    wsexp = /[ ]*(.*)[ ]+\n/g;
+    contexp = /(<.+>)(.+\n)/g;
+    xml = xml.replace(/\r\n/g, '\n').replace(reg, '$1\n$2$3').replace(wsexp, '$1\n').replace(contexp, '$1\n$2');
+    pad = 0;
+    formatted = '';
+    lines = xml.split('\n');
+    indent = 0;
+    lastType = 'other';
+    transitions = {
+      'single->single': 0,
+      'single->closing': -1,
+      'single->opening': 0,
+      'single->other': 0,
+      'closing->single': 0,
+      'closing->closing': -1,
+      'closing->opening': 0,
+      'closing->other': 0,
+      'opening->single': 1,
+      'opening->closing': 0,
+      'opening->opening': 1,
+      'opening->other': 1,
+      'other->single': 0,
+      'other->closing': -1,
+      'other->opening': 0,
+      'other->other': 0
+    };
+    fn = function(ln) {
+      var fromTo, j, key, padding, type, types, value;
+      types = {
+        single: Boolean(ln.match(/<.+\/>/)),
+        closing: Boolean(ln.match(/<\/.+>/)),
+        opening: Boolean(ln.match(/<[^!?].*>/))
+      };
+      type = ((function() {
+        var results;
+        results = [];
+        for (key in types) {
+          value = types[key];
+          if (value) {
+            results.push(key);
+          }
+        }
+        return results;
+      })())[0];
+      type = type === void 0 ? 'other' : type;
+      fromTo = lastType + '->' + type;
+      lastType = type;
+      padding = '';
+      indent += transitions[fromTo];
+      padding = ((function() {
+        var m, ref1, results;
+        results = [];
+        for (j = m = 0, ref1 = indent; 0 <= ref1 ? m < ref1 : m > ref1; j = 0 <= ref1 ? ++m : --m) {
+          results.push('  ');
+        }
+        return results;
+      })()).join('');
+      if (fromTo === 'opening->closing') {
+        formatted = formatted.substr(0, formatted.length - 1) + ln + '\n';
+      } else {
+        formatted += padding + ln + '\n';
+      }
+    };
+    for (l = 0, len = lines.length; l < len; l++) {
+      ln = lines[l];
+      fn(ln);
+    }
+    return formatted;
+  },
+
+  // puts the response data in UI
+  showStatus: function(response) {
+    var url, content;
+    if (response.content === undefined) {
+      content = response.data;
+      url = response.url;
+    } else {
+      content = response.content.data;
+      url = response.request.url;
+    }
+    var headers = response.headers;
+    if(typeof content === 'string') {
+      content = jQuery.trim(content);
+    }
+
+    // if server is nice, and sends content-type back, we can use it
+    var contentType = null;
+    if (headers) {
+      contentType = headers['Content-Type'] || headers['content-type'];
+      if (contentType) {
+        contentType = contentType.split(';')[0].trim();
+      }
+    }
+
+    $('.response_body', $(this.el)).removeClass('json');
+    $('.response_body', $(this.el)).removeClass('xml');
+
+    var supportsAudioPlayback = function(contentType){
+      var audioElement = document.createElement('audio');
+      return !!(audioElement.canPlayType && audioElement.canPlayType(contentType).replace(/no/, ''));
+    };
+
+    var pre;
+    var code;
+    var skipHighlight = false;
+    if (!content) {
+      code = $('<code />').text('no content');
+      pre = $('<pre class="json" />').append(code);
+
+      // JSON
+    } else if (
+        contentType === 'application/octet-stream' ||
+        headers['Content-Disposition'] && (/attachment/).test(headers['Content-Disposition']) ||
+        headers['content-disposition'] && (/attachment/).test(headers['content-disposition']) ||
+        headers['Content-Description'] && (/File Transfer/).test(headers['Content-Description']) ||
+        headers['content-description'] && (/File Transfer/).test(headers['content-description'])) {
+
+      if ('Blob' in window) {
+        var type = contentType || 'text/html';
+        var a = document.createElement('a');
+        var href;
+
+        if({}.toString.apply(content) === '[object Blob]') {
+          href = window.URL.createObjectURL(content);
+        }
+        else {
+          var binaryData = [];
+          binaryData.push(content);
+          href = window.URL.createObjectURL(new Blob(binaryData, {type: type}));
+        }
+        var fileName = response.url.substr(response.url.lastIndexOf('/') + 1);
+        var download = [type, fileName, href].join(':');
+
+        // Use filename from response header
+        var disposition = headers['content-disposition'] || headers['Content-Disposition'];
+        if(typeof disposition !== 'undefined') {
+          var responseFilename = /filename=([^;]*);?/.exec(disposition);
+          if(responseFilename !== null && responseFilename.length > 1) {
+            download = responseFilename[1];
+            fileName = download;
+          }
+        }
+
+        a.setAttribute('href', href);
+        a.setAttribute('download', download);
+        a.innerText = 'Download ' + fileName;
+
+        pre = $('<div/>').append(a);
+        skipHighlight = true;
+      } else {
+        pre = $('<pre class="json" />').append('Download headers detected but your browser does not support downloading binary via XHR (Blob).');
+      }
+    } else if (contentType === 'application/json' || /\+json$/.test(contentType)) {
+      var json = null;
+      try {
+        json = JSON.stringify(JSON.parse(content), null, '  ');
+      } catch (_error) {
+        json = 'can\'t parse JSON.  Raw result:\n\n' + content;
+      }
+      code = $('<code />').text(json);
+      pre = $('<pre class="json" />').append(code);
+
+      // XML
+    } else if (contentType === 'application/xml' || /\+xml$/.test(contentType)) {
+      code = $('<code />').text(this.formatXml(content));
+      pre = $('<pre class="xml" />').append(code);
+
+      // HTML
+    } else if (contentType === 'text/html') {
+      code = $('<code />').html(_.escape(content));
+      pre = $('<pre class="xml" />').append(code);
+
+      // Plain Text
+    } else if (/text\/plain/.test(contentType)) {
+      code = $('<code />').text(content);
+      pre = $('<pre class="plain" />').append(code);
+
+      // Image
+    } else if (/^image\//.test(contentType)) {
+      var urlCreator = window.URL || window.webkitURL;
+      var imageUrl = urlCreator.createObjectURL(content);
+
+      pre = $('<img>').attr( 'src', imageUrl);
+      // Audio
+    } else if (/^audio\//.test(contentType) && supportsAudioPlayback(contentType)) {
+      pre = $('<audio controls>').append($('<source>').attr('src', url).attr('type', contentType));
+    } else if(headers.location || headers.Location) {
+      // Location header based redirect download
+      window.location = response.url;
+
+      // Anything else (CORS)
+    } else {
+      code = $('<code />').text(content);
+      pre = $('<pre class="json" />').append(code);
+    }
+    var response_body = pre;
+    $('.request_url', $(this.el)).html('<pre></pre>');
+    $('.request_url pre', $(this.el)).text(url);
+    $('.response_code', $(this.el)).html('<pre>' + response.status + '</pre>');
+    $('.response_body', $(this.el)).html(response_body);
+    $('.response_headers', $(this.el)).html('<pre>' + _.escape(JSON.stringify(response.headers, null, '  ')).replace(/\n/g, '<br>') + '</pre>');
+    $('.response', $(this.el)).slideDown();
+    $('.response_hider', $(this.el)).show();
+    $('.response_throbber', $(this.el)).hide();
+
+
+    // adds curl output
+    var curlCommand = this.model.asCurl(this.map, {responseContentType: contentType});
+    curlCommand = curlCommand.replace('!', '&#33;');
+    $( 'div.curl', $(this.el)).html('<pre>' + _.escape(curlCommand) + '</pre>');
+
+    // only highlight the response if response is less than threshold, default state is highlight response
+    var opts = this.options.swaggerOptions;
+
+    if (opts.showRequestHeaders) {
+      var form = $('.sandbox', $(this.el)),
+          map = this.getInputMap(form),
+          requestHeaders = this.model.getHeaderParams(map);
+      delete requestHeaders['Content-Type'];
+      $('.request_headers', $(this.el)).html('<pre>' + _.escape(JSON.stringify(requestHeaders, null, '  ')).replace(/\n/g, '<br>') + '</pre>');
+    }
+
+    // Call user-defined hook
+    if (opts.responseHooks && opts.responseHooks[this.nickname]) {
+      opts.responseHooks[this.nickname](response, this);
+    }
+
+    var response_body_el = $('.response_body', $(this.el))[0];
+    // only highlight the response if response is less than threshold, default state is highlight response
+    if (opts.highlightSizeThreshold && typeof response.data !== 'undefined' && response.data.length > opts.highlightSizeThreshold || skipHighlight) {
+      return response_body_el;
+    } else {
+      return hljs.highlightBlock(response_body_el);
+    }
+  },
+
+  toggleOperationContent: function (event) {
+    var elem = $('#' + Docs.escapeResourceName(this.parentId + '_' + this.nickname + '_content'));
+    if (elem.is(':visible')){
+      $.bbq.pushState('#/', 2);
+      event.preventDefault();
+      Docs.collapseOperation(elem);
+    } else {
+      Docs.expandOperation(elem);
+    }
+  },
+
+  getTextAreaValue: function(textArea) {
+    var param, parsed, result, i;
+    if (textArea.value === null || jQuery.trim(textArea.value).length === 0) {
+      return null;
+    }
+    param = this.getParamByName(textArea.name);
+    if (param && param.type && param.type.toLowerCase() === 'array') {
+      parsed = textArea.value.split('\n');
+      result = [];
+      for (i = 0; i < parsed.length; i++) {
+        if (parsed[i] !== null && jQuery.trim(parsed[i]).length > 0) {
+          result.push(parsed[i]);
+        }
+      }
+      return result.length > 0 ? result : null;
+    } else {
+      return textArea.value;
+    }
+  },
+
+  showSnippet: function () {
+    var contentTypeEl = this.$('[name=responseContentType]');
+    var xmlSnippetEl = this.$('.operation-status .snippet_xml, .response-class .snippet_xml');
+    var jsonSnippetEl = this.$('.operation-status .snippet_json, .response-class .snippet_json');
+    var contentType;
+
+    if (!contentTypeEl.length) { return; }
+    contentType = contentTypeEl.val();
+
+    if (contentType.indexOf('xml') > -1) {
+      xmlSnippetEl.show();
+      jsonSnippetEl.hide();
+    } else {
+      jsonSnippetEl.show();
+      xmlSnippetEl.hide();
+    }
+  },
+
+  getParamByName: function(name) {
+    var i;
+    if (this.model.parameters) {
+      for(i = 0; i < this.model.parameters.length; i++) {
+        if (this.model.parameters[i].name === name) {
+          return this.model.parameters[i];
+        }
+      }
+    }
+    return null;
+  }
+
+});
+
+'use strict';
+
+SwaggerUi.Views.ParameterContentTypeView = Backbone.View.extend({
+  initialize: function  () {},
+
+  render: function(){
+    this.model.parameterContentTypeId = 'pct' + Math.random();
+    $(this.el).html(Handlebars.templates.parameter_content_type(this.model));
+    return this;
+  }
+
+});
+'use strict';
+
+SwaggerUi.Views.ParameterView = Backbone.View.extend({
+  events: {
+    'change [name=parameterContentType]' : 'toggleParameterSnippet'
+  },
+
+  initialize: function(){
+    Handlebars.registerHelper('isArray', function(param, opts) {
+      var paramType = param.type && param.type.toLowerCase();
+      if (paramType === 'array' || param.allowMultiple) {
+        return opts.fn(this);
+      } else {
+        return opts.inverse(this);
+      }
+    });
+  },
+
+  render: function() {
+    var type = this.model.type || this.model.dataType;
+    var modelType = this.model.modelSignature.type;
+    var modelDefinitions = this.model.modelSignature.definitions;
+    var schema = this.model.schema || {};
+    var consumes = this.model.consumes || [];
+    var sampleJSON, signatureView;
+
+    if (typeof type === 'undefined') {
+      if (schema.$ref) {
+        var ref = schema.$ref;
+        if (ref.indexOf('#/definitions/') === 0) {
+          type = ref.substring('#/definitions/'.length);
+        } else {
+          type = ref;
+        }
+      }
+    }
+
+    this.model.type = type;
+    this.model.paramType = this.model.in || this.model.paramType;
+    this.model.isBody = this.model.paramType === 'body' || this.model.in === 'body';
+    this.model.isFile = type && type.toLowerCase() === 'file';
+
+    // Allow for default === false
+    if(typeof this.model.default === 'undefined') {
+      this.model.default = this.model.defaultValue;
+    }
+
+    this.model.hasDefault = (typeof this.model.default !== 'undefined');
+    this.model.valueId = 'm' + this.model.name + Math.random();
+
+    if (this.model.allowableValues) {
+      this.model.isList = true;
+    }
+
+    var isXML = this.contains(consumes, 'xml');
+    var isJSON = isXML ? this.contains(consumes, 'json') : true;
+    sampleJSON = SwaggerUi.partials.signature.createParameterJSONSample(modelType, modelDefinitions);
+
+    var template = this.template();
+    $(this.el).html(template(this.model));
+
+    var signatureModel = {
+      sampleJSON: isJSON ? sampleJSON : false,
+      sampleXML: sampleJSON && isXML ? SwaggerUi.partials.signature.createXMLSample('', schema, modelDefinitions, true) : false,
+      isParam: true,
+      signature: SwaggerUi.partials.signature.getParameterModelSignature(modelType, modelDefinitions),
+      defaultRendering: this.model.defaultRendering
+    };
+
+    if (sampleJSON) {
+      signatureView = new SwaggerUi.Views.SignatureView({model: signatureModel, tagName: 'div'});
+      $('.model-signature', $(this.el)).append(signatureView.render().el);
+    }
+    else {
+      $('.model-signature', $(this.el)).html(this.model.signature);
+    }
+
+    var isParam = false;
+
+    if( this.options.swaggerOptions.jsonEditor && this.model.isBody && this.model.schema){
+      var $self = $(this.el);
+      this.model.jsonEditor =
+        /* global JSONEditor */
+        new JSONEditor($('.editor_holder', $self)[0],
+                       {schema: this.model.schema, startval : this.model.default,
+                        ajax:true,
+                        disable_properties:true,
+                        disable_edit_json:true,
+                        iconlib: 'swagger' });
+      // This is so that the signature can send back the sample to the json editor
+      // TODO: SignatureView should expose an event "onSampleClicked" instead
+      signatureModel.jsonEditor = this.model.jsonEditor;
+      $('.body-textarea', $self).hide();
+      $('.editor_holder', $self).show();
+      $('.parameter-content-type', $self)
+        .change(function(e){
+            if(e.target.value === 'application/xml'){
+              $('.body-textarea', $self).show();
+              $('.editor_holder', $self).hide();
+              this.model.jsonEditor.disable();
+            }
+            else {
+              $('.body-textarea', $self).hide();
+              $('.editor_holder', $self).show();
+              this.model.jsonEditor.enable();
+            }
+        });
+      }
+
+
+    if (this.model.isBody) {
+      isParam = true;
+    }
+
+    var contentTypeModel = {
+      isParam: isParam
+    };
+
+    contentTypeModel.consumes = this.model.consumes;
+
+    if (isParam) {
+      var parameterContentTypeView = new SwaggerUi.Views.ParameterContentTypeView({model: contentTypeModel});
+      $('.parameter-content-type', $(this.el)).append(parameterContentTypeView.render().el);
+      this.toggleParameterSnippet();
+    }
+
+    else {
+      var responseContentTypeView = new SwaggerUi.Views.ResponseContentTypeView({model: contentTypeModel});
+      $('.response-content-type', $(this.el)).append(responseContentTypeView.render().el);
+      this.toggleResponseSnippet();
+    }
+
+    return this;
+  },
+
+  contains: function (consumes, type) {
+    return consumes.filter(function (val) {
+      if (val.indexOf(type) > -1) {
+        return true;
+      }
+    }).length;
+  },
+
+  toggleParameterSnippet: function () {
+    var contentType = this.$('[name=parameterContentType]').val();
+
+    this.toggleSnippet(contentType);
+  },
+
+  toggleResponseSnippet: function () {
+    var contentEl = this.$('[name=responseContentType]');
+
+    if (!contentEl.length) { return; }
+
+    this.toggleSnippet(contentEl.val());
+  },
+
+  toggleSnippet: function (type) {
+    type = type || '';
+    if (type.indexOf('xml') > -1) {
+      this.$('.snippet_xml').show();
+      this.$('.snippet_json').hide();
+    } else {
+      this.$('.snippet_json').show();
+      this.$('.snippet_xml').hide();
+    }
+  },
+
+  // Return an appropriate template based on if the parameter is a list, readonly, required
+  template: function(){
+    if (this.model.isList) {
+      return Handlebars.templates.param_list;
+    } else {
+      if (this.options.readOnly) {
+        if (this.model.required) {
+          return Handlebars.templates.param_readonly_required;
+        } else {
+          return Handlebars.templates.param_readonly;
+        }
+      } else {
+        if (this.model.required) {
+          return Handlebars.templates.param_required;
+        } else {
+          return Handlebars.templates.param;
+        }
+      }
+    }
+  }
+});
+
+'use strict';
+
+/* jshint -W122 */
+SwaggerUi.partials.signature = (function () {
+  // copy-pasted from swagger-js
+  var resolveSchema = function (schema) {
+    if (_.isPlainObject(schema.schema)) {
+      schema = resolveSchema(schema.schema);
+    }
+
+    return schema;
+  };
+
+  // copy-pasted from swagger-js
+  var simpleRef = function (name) {
+    if (typeof name === 'undefined') {
+      return null;
+    }
+
+    if (name.indexOf('#/definitions/') === 0) {
+      return name.substring('#/definitions/'.length);
+    } else {
+      return name;
+    }
+  };
+
+  // copy-pasted from swagger-js
+  var getInlineModel = function(inlineStr) {
+    if(/^Inline Model \d+$/.test(inlineStr) && this.inlineModels) {
+      var id = parseInt(inlineStr.substr('Inline Model'.length).trim(),10); //
+      var model = this.inlineModels[id];
+      return model;
+    }
+    // I'm returning null here, should I rather throw an error?
+    return null;
+  };
+
+  // copy-pasted from swagger-js
+  var formatXml = function(xml) {
+    var contexp, fn, formatted, indent, l, lastType, len, lines, ln, pad, reg, transitions, wsexp;
+    reg = /(>)(<)(\/*)/g;
+    wsexp = /[ ]*(.*)[ ]+\n/g;
+    contexp = /(<.+>)(.+\n)/g;
+    xml = xml.replace(reg, '$1\n$2$3').replace(wsexp, '$1\n').replace(contexp, '$1\n$2');
+    pad = 0;
+    formatted = '';
+    lines = xml.split('\n');
+    indent = 0;
+    lastType = 'other';
+    transitions = {
+      'single->single': 0,
+      'single->closing': -1,
+      'single->opening': 0,
+      'single->other': 0,
+      'closing->single': 0,
+      'closing->closing': -1,
+      'closing->opening': 0,
+      'closing->other': 0,
+      'opening->single': 1,
+      'opening->closing': 0,
+      'opening->opening': 1,
+      'opening->other': 1,
+      'other->single': 0,
+      'other->closing': -1,
+      'other->opening': 0,
+      'other->other': 0
+    };
+    fn = function(ln) {
+      var fromTo, j, key, padding, type, types, value;
+      types = {
+        single: Boolean(ln.match(/<.+\/>/)),
+        closing: Boolean(ln.match(/<\/.+>/)),
+        opening: Boolean(ln.match(/<[^!?].*>/))
+      };
+      type = ((function() {
+        var results;
+        results = [];
+        for (key in types) {
+          value = types[key];
+          if (value) {
+            results.push(key);
+          }
+        }
+        return results;
+      })())[0];
+      type = type === void 0 ? 'other' : type;
+      fromTo = lastType + '->' + type;
+      lastType = type;
+      padding = '';
+      indent += transitions[fromTo];
+      padding = ((function() {
+        var m, ref1, results;
+        results = [];
+        for (j = m = 0, ref1 = indent; 0 <= ref1 ? m < ref1 : m > ref1; j = 0 <= ref1 ? ++m : --m) {
+          results.push('  ');
+        }
+        return results;
+      })()).join('');
+      if (fromTo === 'opening->closing') {
+        formatted = formatted.substr(0, formatted.length - 1) + ln + '\n';
+      } else {
+        formatted += padding + ln + '\n';
+      }
+    };
+    for (l = 0, len = lines.length; l < len; l++) {
+      ln = lines[l];
+      fn(ln);
+    }
+    return formatted;
+  };
+
+  // copy-pasted from swagger-js
+  var getModelSignature = function (name, schema, models, modelPropertyMacro) {
+    var strongOpen = '<span class="strong">';
+    var strongClose = '</span>';
+
+    var optionHtml = function (label, value) {
+      return '<tr><td class="optionName">' + label + ':</td><td>' + value + '</td></tr>';
+    };
+
+
+    // Allow for ignoring the 'name' argument.... shifting the rest
+    if(_.isObject(arguments[0])) {
+      name = void 0;
+      schema = arguments[0];
+      models = arguments[1];
+      modelPropertyMacro = arguments[2];
+    }
+
+    models = models || {};
+
+    // Resolve the schema (Handle nested schemas)
+    schema = resolveSchema(schema);
+
+    // Return for empty object
+    if(_.isEmpty(schema)) {
+      return strongOpen + 'Empty' + strongClose;
+    }
+
+    // Dereference $ref from 'models'
+    if(typeof schema.$ref === 'string') {
+      name = simpleRef(schema.$ref);
+      schema = models[name];
+      if(typeof schema === 'undefined')
+      {
+        return strongOpen + name + ' is not defined!' + strongClose;
+      }
+    }
+
+    if(typeof name !== 'string') {
+      name = schema.title || 'Inline Model';
+    }
+
+    // If we are a Model object... adjust accordingly
+    if(schema.definition) {
+      schema = schema.definition;
+    }
+
+    if(typeof modelPropertyMacro !== 'function') {
+      modelPropertyMacro = function(prop){
+        return (prop || {}).default;
+      };
+    }
+
+    var references = {};
+    var seenModels = [];
+    var inlineModels = 0;
+
+    // Generate current HTML
+    var html = processModel(schema, name);
+
+    // Generate references HTML
+    while (_.keys(references).length > 0) {
+      /* jshint ignore:start */
+      _.forEach(references, function (schema, name) {
+        var seenModel = _.indexOf(seenModels, name) > -1;
+
+        delete references[name];
+
+        if (!seenModel) {
+          seenModels.push(name);
+
+          html += '<br />' + processModel(schema, name);
+        }
+      });
+      /* jshint ignore:end */
+    }
+
+    return html;
+
+
+    function addReference(schema, name, skipRef) {
+      var modelName = name;
+      var model;
+
+      if (schema.$ref) {
+        modelName = schema.title || simpleRef(schema.$ref);
+        model = models[simpleRef(schema.$ref)];
+      } else if (_.isUndefined(name)) {
+        modelName = schema.title || 'Inline Model ' + (++inlineModels);
+        model = {definition: schema};
+      }
+
+      if (skipRef !== true) {
+        references[modelName] = _.isUndefined(model) ? {} : model.definition;
+      }
+
+      return modelName;
+    }
+
+    function primitiveToHTML(schema) {
+      var html = '<span class="propType">';
+      var type = schema.type || 'object';
+
+      if (schema.$ref) {
+        html += addReference(schema, simpleRef(schema.$ref));
+      } else if (type === 'object') {
+        if (!_.isUndefined(schema.properties)) {
+          html += addReference(schema);
+        } else {
+          html += 'object';
+        }
+      } else if (type === 'array') {
+        html += 'Array[';
+
+        if (_.isArray(schema.items)) {
+          html += _.map(schema.items, addReference).join(',');
+        } else if (_.isPlainObject(schema.items)) {
+          if (_.isUndefined(schema.items.$ref)) {
+            if (!_.isUndefined(schema.items.type) && _.indexOf(['array', 'object'], schema.items.type) === -1) {
+              html += schema.items.type;
+            } else {
+              html += addReference(schema.items);
+            }
+          } else {
+            html += addReference(schema.items, simpleRef(schema.items.$ref));
+          }
+        } else {
+          console.log('Array type\'s \'items\' schema is not an array or an object, cannot process');
+          html += 'object';
+        }
+
+        html += ']';
+      } else {
+        html += schema.type;
+      }
+
+      html += '</span>';
+
+      return html;
+    }
+
+    function primitiveToOptionsHTML(schema, html) {
+      var options = '';
+      var type = schema.type || 'object';
+      var isArray = type === 'array';
+
+      if (!_.isUndefined(schema.description)) {
+        html += ': ' + '<span class="propDesc">' + schema.description + '</span>';
+      }
+
+      if (schema.enum) {
+        html += ' = <span class="propVals">[\'' + schema.enum.join('\', \'') + '\']</span>';
+      }
+
+      if (isArray) {
+        if (_.isPlainObject(schema.items) && !_.isUndefined(schema.items.type)) {
+          type = schema.items.type;
+        } else {
+          type = 'object';
+        }
+      }
+
+      if (!_.isUndefined(schema.default)) {
+        options += optionHtml('Default', schema.default);
+      }
+
+      switch (type) {
+      case 'string':
+        if (schema.minLength) {
+          options += optionHtml('Min. Length', schema.minLength);
+        }
+
+        if (schema.maxLength) {
+          options += optionHtml('Max. Length', schema.maxLength);
+        }
+
+        if (schema.pattern) {
+          options += optionHtml('Reg. Exp.', schema.pattern);
+        }
+        break;
+      case 'integer':
+      case 'number':
+        if (schema.minimum) {
+          options += optionHtml('Min. Value', schema.minimum);
+        }
+
+        if (schema.exclusiveMinimum) {
+          options += optionHtml('Exclusive Min.', 'true');
+        }
+
+        if (schema.maximum) {
+          options += optionHtml('Max. Value', schema.maximum);
+        }
+
+        if (schema.exclusiveMaximum) {
+          options += optionHtml('Exclusive Max.', 'true');
+        }
+
+        if (schema.multipleOf) {
+          options += optionHtml('Multiple Of', schema.multipleOf);
+        }
+
+        break;
+      }
+
+      if (isArray) {
+        if (schema.minItems) {
+          options += optionHtml('Min. Items', schema.minItems);
+        }
+
+        if (schema.maxItems) {
+          options += optionHtml('Max. Items', schema.maxItems);
+        }
+
+        if (schema.uniqueItems) {
+          options += optionHtml('Unique Items', 'true');
+        }
+
+        if (schema.collectionFormat) {
+          options += optionHtml('Coll. Format', schema.collectionFormat);
+        }
+      }
+
+      if (_.isUndefined(schema.items)) {
+        if (_.isArray(schema.enum)) {
+          var enumString;
+
+          if (type === 'number' || type === 'integer') {
+            enumString = schema.enum.join(', ');
+          } else {
+            enumString = '"' + schema.enum.join('", "') + '"';
+          }
+
+          options += optionHtml('Enum', enumString);
+        }
+      }
+
+      if (options.length > 0) {
+        html = '<span class="propWrap">' + html + '<table class="optionsWrapper"><tr><th colspan="2">' + type + '</th></tr>' + options + '</table></span>';
+      }
+
+      return html;
+    }
+
+    function processModel(schema, name) {
+      var type = schema.type || 'object';
+      var isArray = schema.type === 'array';
+      var html = strongOpen + name + ' ' + (isArray ? '[' : '{') + strongClose;
+      var contents;
+
+      if (name) {
+        seenModels.push(name);
+      }
+
+      if (isArray) {
+        if (_.isArray(schema.items)) {
+          html += '<div>' + _.map(schema.items, function (item) {
+            var type = item.type || 'object';
+
+            if (_.isUndefined(item.$ref)) {
+              if (_.indexOf(['array', 'object'], type) > -1) {
+                if (type === 'object' && _.isUndefined(item.properties)) {
+                  return 'object';
+                } else {
+                  return addReference(item);
+                }
+              } else {
+                return primitiveToOptionsHTML(item, type);
+              }
+            } else {
+              return addReference(item, simpleRef(item.$ref));
+            }
+          }).join(',</div><div>');
+        } else if (_.isPlainObject(schema.items)) {
+          if (_.isUndefined(schema.items.$ref)) {
+            if (_.indexOf(['array', 'object'], schema.items.type || 'object') > -1) {
+              if ((_.isUndefined(schema.items.type) || schema.items.type === 'object') && _.isUndefined(schema.items.properties)) {
+                html += '<div>object</div>';
+              } else {
+                html += '<div>' + addReference(schema.items) + '</div>';
+              }
+            } else {
+              html += '<div>' + primitiveToOptionsHTML(schema.items, schema.items.type) + '</div>';
+            }
+          } else {
+            html += '<div>' + addReference(schema.items, simpleRef(schema.items.$ref)) + '</div>';
+          }
+        } else {
+          console.log('Array type\'s \'items\' property is not an array or an object, cannot process');
+          html += '<div>object</div>';
+        }
+      } else {
+        if (schema.$ref) {
+          html += '<div>' + addReference(schema, name) + '</div>';
+        } else if (type === 'object') {
+          if (_.isPlainObject(schema.properties)) {
+            contents = _.map(schema.properties, function (property, name) {
+              var propertyIsRequired = (_.indexOf(schema.required, name) >= 0);
+              var cProperty = _.cloneDeep(property);
+
+              var requiredClass = propertyIsRequired ? 'required' : '';
+              var html = '<span class="propName ' + requiredClass + '">' + name + '</span> (';
+              var model;
+
+              // Allow macro to set the default value
+              cProperty.default = modelPropertyMacro(cProperty);
+
+              // Resolve the schema (Handle nested schemas)
+              cProperty = resolveSchema(cProperty);
+
+              // We need to handle property references to primitives (Issue 339)
+              if (!_.isUndefined(cProperty.$ref)) {
+                model = models[simpleRef(cProperty.$ref)];
+
+                if (!_.isUndefined(model) && _.indexOf([undefined, 'array', 'object'], model.definition.type) === -1) {
+                  // Use referenced schema
+                  cProperty = resolveSchema(model.definition);
+                }
+              }
+
+              html += primitiveToHTML(cProperty);
+
+              if(!propertyIsRequired) {
+                html += ', <span class="propOptKey">optional</span>';
+              }
+
+              if(property.readOnly) {
+                  html += ', <span class="propReadOnly">read only</span>';
+              }
+
+              html += ')';
+
+              return '<div' + (property.readOnly ? ' class="readOnly"' : '') + '>' + primitiveToOptionsHTML(cProperty, html);
+            }).join(',</div>');
+          }
+
+          if (contents) {
+            html += contents + '</div>';
+          }
+        } else {
+          html += '<div>' + primitiveToOptionsHTML(schema, type) + '</div>';
+        }
+      }
+
+      return html + strongOpen + (isArray ? ']' : '}') + strongClose;
+    }
+
+  };
+
+  // copy-pasted from swagger-js
+  var schemaToJSON = function (schema, models, modelsToIgnore, modelPropertyMacro) {
+    // Resolve the schema (Handle nested schemas)
+    schema = resolveSchema(schema);
+
+    if(typeof modelPropertyMacro !== 'function') {
+      modelPropertyMacro = function(prop){
+        return (prop || {}).default;
+      };
+    }
+
+    modelsToIgnore= modelsToIgnore || {};
+
+    var type = schema.type || 'object';
+    var format = schema.format;
+    var model;
+    var output;
+
+    if (!_.isUndefined(schema.example)) {
+      output = schema.example;
+    } else if (_.isUndefined(schema.items) && _.isArray(schema.enum)) {
+      output = schema.enum[0];
+    }
+
+    if (_.isUndefined(output)) {
+      if (schema.$ref) {
+        model = models[simpleRef(schema.$ref)];
+
+        if (!_.isUndefined(model)) {
+          if (_.isUndefined(modelsToIgnore[model.name])) {
+            modelsToIgnore[model.name] = model;
+            output = schemaToJSON(model.definition, models, modelsToIgnore, modelPropertyMacro);
+            delete modelsToIgnore[model.name];
+          } else {
+            if (model.type === 'array') {
+              output = [];
+            } else {
+              output = {};
+            }
+          }
+        }
+      } else if (!_.isUndefined(schema.default)) {
+        output = schema.default;
+      } else if (type === 'string') {
+        if (format === 'date-time') {
+          output = new Date().toISOString();
+        } else if (format === 'date') {
+          output = new Date().toISOString().split('T')[0];
+        } else {
+          output = 'string';
+        }
+      } else if (type === 'integer') {
+        output = 0;
+      } else if (type === 'number') {
+        output = 0.0;
+      } else if (type === 'boolean') {
+        output = true;
+      } else if (type === 'object') {
+        output = {};
+
+        _.forEach(schema.properties, function (property, name) {
+          var cProperty = _.cloneDeep(property);
+
+          // Allow macro to set the default value
+          cProperty.default = modelPropertyMacro(property);
+
+          output[name] = schemaToJSON(cProperty, models, modelsToIgnore, modelPropertyMacro);
+        });
+      } else if (type === 'array') {
+        output = [];
+
+        if (_.isArray(schema.items)) {
+          _.forEach(schema.items, function (item) {
+            output.push(schemaToJSON(item, models, modelsToIgnore, modelPropertyMacro));
+          });
+        } else if (_.isPlainObject(schema.items)) {
+          output.push(schemaToJSON(schema.items, models, modelsToIgnore, modelPropertyMacro));
+        } else if (_.isUndefined(schema.items)) {
+          output.push({});
+        } else {
+          console.log('Array type\'s \'items\' property is not an array or an object, cannot process');
+        }
+      }
+    }
+
+    return output;
+  };
+
+  // copy-pasted from swagger-js
+  var createJSONSample = function (value, modelsToIgnore) {
+    modelsToIgnore = modelsToIgnore || {};
+
+    modelsToIgnore[value.name] = value;
+
+    // Response support
+    if (value.examples && _.isPlainObject(value.examples)) {
+      value = _.cloneDeep(value);
+      var keys = Object.keys(value.examples);
+
+      _.forEach(keys, function(key) {
+        if(key.indexOf('application/json') === 0) {
+          var example = value.examples[key];
+          if (_.isString(example)) {
+            example = jsyaml.safeLoad(example);
+          }
+          value.definition.example = example;
+          return schemaToJSON(value.definition, example, modelsToIgnore, value.modelPropertyMacro);
+        }
+      });
+    }
+
+    if (value.examples) {
+      value = _.cloneDeep(value);
+      var example = value.examples;
+      if (_.isString(example)) {
+        example = jsyaml.safeLoad(example);
+      }
+      value.definition.example = example;
+      return schemaToJSON(value.definition, example, modelsToIgnore, value.modelPropertyMacro);
+    }
+
+    return schemaToJSON(value.definition, value.models, modelsToIgnore, value.modelPropertyMacro);
+  };
+
+  // copy-pasted from swagger-js
+  var getParameterModelSignature = function (type, definitions) {
+      var isPrimitive, listType;
+
+      if (type instanceof Array) {
+        listType = true;
+        type = type[0];
+      }
+
+      // Convert undefined to string of 'undefined'
+      if (typeof type === 'undefined') {
+        type = 'undefined';
+        isPrimitive = true;
+
+      } else if (definitions[type]){
+        // a model def exists?
+        type = definitions[type]; /* Model */
+        isPrimitive = false;
+
+      } else if (getInlineModel(type)) {
+        type = getInlineModel(type); /* Model */
+        isPrimitive = false;
+
+      } else {
+        // We default to primitive
+        isPrimitive = true;
+      }
+
+      if (isPrimitive) {
+        if (listType) {
+          return 'Array[' + type + ']';
+        } else {
+          return type.toString();
+        }
+      } else {
+        if (listType) {
+          return 'Array[' + getModelSignature(type.name, type.definition, type.models, type.modelPropertyMacro) + ']';
+        } else {
+          return getModelSignature(type.name, type.definition, type.models, type.modelPropertyMacro);
+        }
+      }
+  };
+
+  // copy-pasted from swagger-js
+  var createParameterJSONSample = function (type, models) {
+    var listType, sampleJson, innerType;
+    models = models || {};
+
+    listType = (type instanceof Array);
+    innerType = listType ? type[0] : type;
+
+    if(models[innerType]) {
+      sampleJson = createJSONSample(models[innerType]);
+    } else if (getInlineModel(innerType)){
+      sampleJson = createJSONSample(getInlineModel(innerType)); // may return null, if type isn't correct
+    }
+
+
+    if (sampleJson) {
+      sampleJson = listType ? [sampleJson] : sampleJson;
+
+      if (typeof sampleJson === 'string') {
+        return sampleJson;
+      } else if (_.isObject(sampleJson)) {
+        var t = sampleJson;
+
+        if (sampleJson instanceof Array && sampleJson.length > 0) {
+          t = sampleJson[0];
+        }
+
+        if (t.nodeName && typeof t === 'Node') {
+          var xmlString = new XMLSerializer().serializeToString(t);
+
+          return formatXml(xmlString);
+        } else {
+          return JSON.stringify(sampleJson, null, 2);
+        }
+      } else {
+        return sampleJson;
+      }
+    }
+  };
+
+  var wrapTag = function (name, value, attrs) {
+    var str, attributes;
+
+    attrs = attrs || [];
+
+    attributes = attrs.map(function (attr) {
+      return ' ' + attr.name + '="' + attr.value + '"';
+    }).join('');
+
+    if (!name) {
+      return getErrorMessage('Node name is not provided');
+    }
+
+    str = [
+      '<', name,
+      attributes,
+      '>',
+      value,
+      '</', name, '>'
+    ];
+
+    return str.join('');
+  };
+
+  // Commenting this funtion as the names are now determined beforehand and the prefix part is exposed as a separate function | https://github.com/swagger-api/swagger-ui/issues/2577
+ /** var getName = function (name, xml) {
+    var result = name || '';
+
+    xml = xml || {};
+
+    if (xml.name) {
+      result = xml.name;
+    }
+
+    if (xml.prefix) {
+      result = xml.prefix + ':' + result;
+    }
+
+    return result;
+  };
+  */
+
+  var getPrefix = function (name, xml) {
+    var result = name || '';
+
+    xml = xml || {};
+
+    if (xml.prefix) {
+      result = xml.prefix + ':' + result;
+    }
+
+    return result;
+  };
+
+  var getNamespace = function (xml) {
+    var namespace = '';
+    var name = 'xmlns';
+
+    xml = xml || {};
+
+    if (xml.namespace) {
+      namespace = xml.namespace;
+    } else {
+      return namespace;
+    }
+
+    if (xml.prefix) {
+      name += ':' + xml.prefix;
+    }
+
+    return {
+      name: name,
+      value: namespace
+    };
+  };
+
+  var createArrayXML = function (descriptor) {
+    var name = descriptor.name;
+    var config = descriptor.config;
+    var definition = descriptor.definition;
+    var models = descriptor.models;
+    var value;
+    var items = definition.items;
+    var xml = definition.xml || {};
+    var namespace = getNamespace(xml);
+    var attributes = [];
+
+    if (!items) { return getErrorMessage(); }
+    var key = name;
+    // If there is a name specified for the array elements, use that for the array elements name | https://github.com/swagger-api/swagger-ui/issues/2577
+    if(items.xml && items.xml.name) {
+        key = items.xml.name;
+    }
+    value = createSchemaXML(key, items, models, config);
+    if (namespace) {
+      attributes.push(namespace);
+    }
+
+    if (xml.wrapped) {
+      value = wrapTag(name, value, attributes);
+    }
+
+    return value;
+  };
+
+  var getPrimitiveSignature = function (schema) {
+    var type, items;
+
+    schema = schema || {};
+    items = schema.items || {};
+    type = schema.type || '';
+
+    switch (type) {
+      case 'object': return 'Object is not a primitive';
+      case 'array' : return 'Array[' + (items.format || items.type) + ']';
+      default: return schema.format || type;
+    }
+  };
+
+  var createPrimitiveXML = function (descriptor) {
+    var name = descriptor.name;
+    var definition = descriptor.definition;
+    var primitivesMap = {
+      'string': {
+        'date': new Date(1).toISOString().split('T')[0],
+        'date-time' : new Date(1).toISOString(),
+        'default': 'string'
+      },
+      'integer': {
+        'default': 1
+      },
+      'number': {
+        'default': 1.1
+      },
+      'boolean': {
+        'default': true
+      }
+    };
+    var type = definition.type;
+    var format = definition.format;
+    var xml = definition.xml || {};
+    var namespace = getNamespace(xml);
+    var attributes = [];
+    var value;
+
+    if (_.keys(primitivesMap).indexOf(type) < 0) { return getErrorMessage(); }
+
+    if (_.isArray(definition.enum)){
+      value = definition.enum[0];
+    } else {
+      value = definition.example || primitivesMap[type][format] || primitivesMap[type].default;
+    }
+
+    if (xml.attribute) {
+      return {name: name, value: value};
+    }
+
+    if (namespace) {
+      attributes.push(namespace);
+    }
+
+    return wrapTag(name, value, attributes);
+  };
+
+  function createObjectXML (descriptor) {
+    var name = descriptor.name;
+    var definition = descriptor.definition;
+    var config = descriptor.config;
+    var models = descriptor.models;
+    var isParam = descriptor.config.isParam;
+    var serializedProperties;
+    var attrs = [];
+    var properties = definition.properties;
+    var additionalProperties = definition.additionalProperties;
+    var xml = definition.xml;
+    var namespace = getNamespace(xml);
+
+    if (namespace) {
+      attrs.push(namespace);
+    }
+
+    if (!properties && !additionalProperties) { return getErrorMessage(); }
+
+    properties = properties || {};
+
+    serializedProperties = _.map(properties, function (prop, key) {
+      var xml, result;
+
+      if (isParam && prop.readOnly) {
+        return '';
+      }
+
+      xml = prop.xml || {};
+      result = createSchemaXML(key, prop, models, config);
+
+      if (xml.attribute) {
+        attrs.push(result);
+        return '';
+      }
+
+      return result;
+    }).join('');
+
+    if (additionalProperties) {
+      serializedProperties += '<!-- additional elements allowed -->';
+    }
+
+    return wrapTag(name, serializedProperties, attrs);
+  }
+
+  function getInfiniteLoopMessage (name, loopTo) {
+    return wrapTag(name, '<!-- Infinite loop $ref:' + loopTo + ' -->');
+  }
+
+  function getErrorMessage (details) {
+    details = details ? ': ' + details : '';
+    return '<!-- invalid XML' + details + ' -->';
+  }
+
+  function createSchemaXML (name, definition, models, config) {
+    var $ref = _.isObject(definition) ? definition.$ref : null;
+    var output, index;
+    config = config || {};
+    config.modelsToIgnore = config.modelsToIgnore || [];
+
+    var descriptor = _.isString($ref) ? getDescriptorByRef($ref, name, models, config)
+        : getDescriptor(name, definition, models, config);
+
+    if (!descriptor) {
+      return getErrorMessage();
+    }
+
+    switch (descriptor.type) {
+      case 'array':
+        output = createArrayXML(descriptor); break;
+      case 'object':
+        output = createObjectXML(descriptor); break;
+      case 'loop':
+        output = getInfiniteLoopMessage(descriptor.name, descriptor.config.loopTo); break;
+      default:
+        output = createPrimitiveXML(descriptor);
+    }
+
+    if ($ref && descriptor.type !== 'loop') {
+      index = config.modelsToIgnore.indexOf($ref);
+      if (index > -1) {
+        config.modelsToIgnore.splice(index, 1);
+      }
+    }
+
+    return output;
+  }
+
+  function Descriptor (name, type, definition, models, config) {
+    if (arguments.length < 4) {
+      throw new Error();
+    }
+    this.config = config || {};
+    this.config.modelsToIgnore = this.config.modelsToIgnore || [];
+    // name is already set by getDescriptorByRef or getDescriptor function depending on the type. Only prefix, if present is needed to be set here | https://github.com/swagger-api/swagger-ui/issues/2577
+    this.name = getPrefix(name, definition.xml);
+    this.definition = definition;
+    this.models = models;
+    this.type = type;
+  }
+
+  function getDescriptorByRef($ref, name, models, config) {
+    var modelType = simpleRef($ref);
+    var model = models[modelType] || {};
+    var type = model.definition && model.definition.type ? model.definition.type : 'object';
+    // If model definition xml name is present, then that will be preferred over model name. This is the case of preferring XmlElement name over XmlRootElement name if XmlElement name is provided | https://github.com/swagger-api/swagger-ui/issues/2577
+    if(model.definition && model.definition.xml && model.definition.xml.name) {
+        name = name || model.definition.xml.name || model.name;
+    }
+    // else only model name will be considered for determination | https://github.com/swagger-api/swagger-ui/issues/2577
+    else {
+        name = name || model.name;
+    }
+
+    if (config.modelsToIgnore.indexOf($ref) > -1) {
+      type = 'loop';
+      config.loopTo = modelType;
+    } else {
+      config.modelsToIgnore.push($ref);
+    }
+
+    if (!model.definition) {
+      return null;
+    }
+    return new Descriptor(name, type, model.definition, models, config);
+  }
+
+  function getDescriptor (name, definition, models, config){
+    var type = definition.type || 'object';
+    // If definition xml name is present, then that will be preferred over name | https://github.com/swagger-api/swagger-ui/issues/2577
+    if(definition.xml && definition.xml.name) {
+        name = definition.xml.name || name;
+    }
+    if (!definition) {
+      return null;
+    }
+
+    return new Descriptor(name, type, definition, models, config);
+  }
+
+  function createXMLSample (name, definition, models, isParam) {
+    var prolog = '<?xml version="1.0"?>';
+
+    return formatXml(prolog + createSchemaXML(name, definition, models, { isParam: isParam } ));
+  }
+
+  return {
+      getModelSignature: getModelSignature,
+      createJSONSample: createJSONSample,
+      getParameterModelSignature: getParameterModelSignature,
+      createParameterJSONSample: createParameterJSONSample,
+      createSchemaXML: createSchemaXML,
+      createXMLSample: createXMLSample,
+      getPrimitiveSignature: getPrimitiveSignature
+  };
+
+})();
+
+'use strict';
+
+SwaggerUi.Views.PopupView = Backbone.View.extend({
+    events: {
+        'click .api-popup-cancel': 'cancelClick'
+    },
+
+    template: Handlebars.templates.popup,
+    className: 'api-popup-dialog',
+
+    selectors: {
+        content: '.api-popup-content',
+        main   : '#swagger-ui-container'
+    },
+
+    initialize: function(){
+        this.$el.html(this.template(this.model));
+    },
+
+    render: function () {
+        this.$(this.selectors.content).append(this.model.content);
+        $(this.selectors.main).first().append(this.el);
+        this.showPopup();
+
+        return this;
+    },
+
+    showPopup: function () {
+        this.$el.show();
+    },
+
+    cancelClick: function () {
+        this.remove();
+    }
+
+});
+
+'use strict';
+
+SwaggerUi.Views.ResourceView = Backbone.View.extend({
+  initialize: function(opts) {
+    opts = opts || {};
+    this.router = opts.router;
+    this.auths = opts.auths;
+    if ('' === this.model.description) {
+      this.model.description = null;
+    }
+    if (this.model.description) {
+      this.model.summary = this.model.description;
+    }
+    this.number = 0;
+  },
+
+  render: function(){
+    var methods = {};
+
+
+    $(this.el).html(Handlebars.templates.resource(this.model));
+
+    // Render each operation
+    for (var i = 0; i < this.model.operationsArray.length; i++) {
+      var operation = this.model.operationsArray[i];
+      var counter = 0;
+      var id = operation.nickname;
+
+      while (typeof methods[id] !== 'undefined') {
+        id = id + '_' + counter;
+        counter += 1;
+      }
+
+      methods[id] = operation;
+
+      operation.nickname = id;
+      operation.parentId = this.model.id;
+      operation.definitions = this.model.definitions; // make Json Schema available for JSonEditor in this operation
+      this.addOperation(operation);
+    }
+
+    $('.toggleEndpointList', this.el).click(this.callDocs.bind(this, 'toggleEndpointListForResource'));
+    $('.collapseResource', this.el).click(this.callDocs.bind(this, 'collapseOperationsForResource'));
+    $('.expandResource', this.el).click(this.callDocs.bind(this, 'expandOperationsForResource'));
+
+    return this;
+  },
+
+  addOperation: function(operation) {
+
+    operation.number = this.number;
+
+    // Render an operation and add it to operations li
+    var operationView = new SwaggerUi.Views.OperationView({
+      model: operation,
+      router: this.router,
+      tagName: 'li',
+      className: 'endpoint',
+      swaggerOptions: this.options.swaggerOptions,
+      auths: this.auths
+    });
+
+    $('.endpoints', $(this.el)).append(operationView.render().el);
+
+    this.number++;
+
+  },
+  // Generic Event handler (`Docs` is global)
+
+
+  callDocs: function(fnName, e) {
+    e.preventDefault();
+    Docs[fnName](e.currentTarget.getAttribute('data-id'));
+  }
+});
+
+'use strict';
+
+SwaggerUi.Views.ResponseContentTypeView = Backbone.View.extend({
+  initialize: function(){},
+
+  render: function(){
+    this.model.responseContentTypeId = 'rct' + Math.random();
+    $(this.el).html(Handlebars.templates.response_content_type(this.model));
+    return this;
+  }
+});
+'use strict';
+
+SwaggerUi.Views.SignatureView = Backbone.View.extend({
+  events: {
+    'click a.description-link'       : 'switchToDescription',
+    'click a.snippet-link'           : 'switchToSnippet',
+    'mousedown .snippet_json'          : 'jsonSnippetMouseDown',
+    'mousedown .snippet_xml'          : 'xmlSnippetMouseDown'
+  },
+
+  initialize: function () {
+  },
+
+  render: function(){
+
+    $(this.el).html(Handlebars.templates.signature(this.model));
+
+    if (this.model.defaultRendering === 'model') {
+      this.switchToDescription();
+    } else {
+      this.switchToSnippet();
+    }
+
+    return this;
+  },
+
+  // handler for show signature
+  switchToDescription: function(e){
+    if (e) { e.preventDefault(); }
+
+    $('.snippet', $(this.el)).hide();
+    $('.description', $(this.el)).show();
+    $('.description-link', $(this.el)).addClass('selected');
+    $('.snippet-link', $(this.el)).removeClass('selected');
+  },
+
+  // handler for show sample
+  switchToSnippet: function(e){
+    if (e) { e.preventDefault(); }
+
+    $('.snippet', $(this.el)).show();
+    $('.description', $(this.el)).hide();
+    $('.snippet-link', $(this.el)).addClass('selected');
+    $('.description-link', $(this.el)).removeClass('selected');
+  },
+
+  // handler for snippet to text area
+  snippetToTextArea: function(val) {
+    var textArea = $('textarea', $(this.el.parentNode.parentNode.parentNode));
+
+    // Fix for bug in IE 10/11 which causes placeholder text to be copied to "value"
+    if ($.trim(textArea.val()) === '' || textArea.prop('placeholder') === textArea.val()) {
+      textArea.val(val);
+      // TODO move this code outside of the view and expose an event instead
+      if( this.model.jsonEditor && this.model.jsonEditor.isEnabled()){
+        this.model.jsonEditor.setValue(JSON.parse(this.model.sampleJSON));
+      }
+    }
+  },
+
+  jsonSnippetMouseDown: function (e) {
+    if (this.model.isParam) {
+      if (e) { e.preventDefault(); }
+
+      this.snippetToTextArea(this.model.sampleJSON);
+    }
+  },
+
+  xmlSnippetMouseDown: function (e) {
+    if (this.model.isParam) {
+      if (e) { e.preventDefault(); }
+
+      this.snippetToTextArea(this.model.sampleXML);
+    }
+  }
+});
+'use strict';
+
+SwaggerUi.Views.StatusCodeView = Backbone.View.extend({
+  initialize: function (opts) {
+    this.options = opts || {};
+    this.router = this.options.router;
+  },
+
+  render: function(){
+    var responseModel, responseModelView;
+    var value = this.router.api.models[this.model.responseModel];
+    $(this.el).html(Handlebars.templates.status_code(this.model));
+
+    if (this.router.api.models.hasOwnProperty(this.model.responseModel)) {
+      responseModel = {
+        sampleJSON: JSON.stringify(SwaggerUi.partials.signature.createJSONSample(value), void 0, 2),
+        sampleXML: this.model.isXML ? SwaggerUi.partials.signature.createXMLSample('', this.model.schema, this.router.api.models) : false,
+        isParam: false,
+        signature: SwaggerUi.partials.signature.getModelSignature(this.model.responseModel, value, this.router.api.models),
+        defaultRendering: this.model.defaultRendering
+      };
+    } else {
+      responseModel = {
+        signature: SwaggerUi.partials.signature.getPrimitiveSignature(this.model.schema)
+      };
+    }
+
+    responseModelView = new SwaggerUi.Views.SignatureView({model: responseModel, tagName: 'div'});
+    $('.model-signature', this.$el).append(responseModelView.render().el);
+    return this;
+  }
+});}).call(this);
+//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlbXBsYXRlcy5qcyIsImRvYy5qcyIsImVzNS1zaGltLmpzIiwiaGVscGVycy9oYW5kbGViYXJzLmpzIiwic2FuaXRpemUtaHRtbC5taW4uanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1wYWNrL19wcmVsdWRlLmpzIiwiaW5kZXguanMiLCJsaWIvYXV0aC5qcyIsImxpYi9jbGllbnQuanMiLCJsaWIvaGVscGVycy5qcyIsImxpYi9odHRwLmpzIiwibGliL3Jlc29sdmVyLmpzIiwibGliL3NjaGVtYS1tYXJrdXAuanMiLCJsaWIvc3BlYy1jb252ZXJ0ZXIuanMiLCJsaWIvdHlwZXMvbW9kZWwuanMiLCJsaWIvdHlwZXMvb3BlcmF0aW9uLmpzIiwibGliL3R5cGVzL29wZXJhdGlvbkdyb3VwLmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3Byb2Nlc3MvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9idG9hL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2J1ZmZlci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9idWZmZXIvbm9kZV9tb2R1bGVzL2Jhc2U2NC1qcy9saWIvYjY0LmpzIiwibm9kZV9tb2R1bGVzL2J1ZmZlci9ub2RlX21vZHVsZXMvaWVlZTc1NC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9idWZmZXIvbm9kZV9tb2R1bGVzL2lzLWFycmF5L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Nvb2tpZWphci9jb29raWVqYXIuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvY29tbW9uLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvZHVtcGVyLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvZXhjZXB0aW9uLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvbG9hZGVyLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvbWFyay5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3NjaGVtYS5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3NjaGVtYS9jb3JlLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvc2NoZW1hL2RlZmF1bHRfZnVsbC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3NjaGVtYS9kZWZhdWx0X3NhZmUuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC9zY2hlbWEvZmFpbHNhZmUuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC9zY2hlbWEvanNvbi5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL2JpbmFyeS5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvYm9vbC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvZmxvYXQuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL2ludC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvanMvZnVuY3Rpb24uanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL2pzL3JlZ2V4cC5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvanMvdW5kZWZpbmVkLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9tYXAuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL21lcmdlLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9udWxsLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9vbWFwLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9wYWlycy5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvc2VxLmpzIiwibm9kZV9tb2R1bGVzL2pzLXlhbWwvbGliL2pzLXlhbWwvdHlwZS9zZXQuanMiLCJub2RlX21vZHVsZXMvanMteWFtbC9saWIvanMteWFtbC90eXBlL3N0ci5qcyIsIm5vZGVfbW9kdWxlcy9qcy15YW1sL2xpYi9qcy15YW1sL3R5cGUvdGltZXN0YW1wLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvYXJyYXkvaW5kZXhPZi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2FycmF5L2xhc3QuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jaGFpbi9sb2Rhc2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2VhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2ZpbmQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2ZvckVhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2luY2x1ZGVzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvY29sbGVjdGlvbi9tYXAuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9kYXRlL25vdy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2Z1bmN0aW9uL2JpbmQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9mdW5jdGlvbi9yZXN0UGFyYW0uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9MYXp5V3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL0xvZGFzaFdyYXBwZXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9hcnJheUNvcHkuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9hcnJheUVhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9hcnJheU1hcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2FycmF5U29tZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VBc3NpZ24uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlQ2FsbGJhY2suanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlQ2xvbmUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlQ29weS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VDcmVhdGUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlRWFjaC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VGaW5kLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZUZpbmRJbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VGb3IuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlRm9ySW4uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlRm9yT3duLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZUdldC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VJbmRleE9mLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZUlzRXF1YWwuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlSXNFcXVhbERlZXAuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlSXNNYXRjaC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VMb2Rhc2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlTWFwLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZU1hdGNoZXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9iYXNlTWF0Y2hlc1Byb3BlcnR5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVByb3BlcnR5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVByb3BlcnR5RGVlcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2Jhc2VTZXREYXRhLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVNsaWNlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVRvU3RyaW5nLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmFzZVZhbHVlcy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2JpbmFyeUluZGV4LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvYmluYXJ5SW5kZXhCeS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2JpbmRDYWxsYmFjay5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2J1ZmZlckNsb25lLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY29tcG9zZUFyZ3MuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jb21wb3NlQXJnc1JpZ2h0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY3JlYXRlQmFzZUVhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jcmVhdGVCYXNlRm9yLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY3JlYXRlQmluZFdyYXBwZXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jcmVhdGVDdG9yV3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2NyZWF0ZUZpbmQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9jcmVhdGVGb3JFYWNoLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY3JlYXRlSHlicmlkV3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2NyZWF0ZVBhcnRpYWxXcmFwcGVyLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvY3JlYXRlV3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2VxdWFsQXJyYXlzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvZXF1YWxCeVRhZy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2VxdWFsT2JqZWN0cy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2dldERhdGEuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9nZXRGdW5jTmFtZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2dldExlbmd0aC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2dldE1hdGNoRGF0YS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2dldE5hdGl2ZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2luZGV4T2ZOYU4uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pbml0Q2xvbmVBcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2luaXRDbG9uZUJ5VGFnLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvaW5pdENsb25lT2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvaXNBcnJheUxpa2UuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pc0hvc3RPYmplY3QuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pc0luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvaXNJdGVyYXRlZUNhbGwuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pc0tleS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2lzTGF6aWFibGUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9pc0xlbmd0aC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2lzT2JqZWN0TGlrZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL2lzU3RyaWN0Q29tcGFyYWJsZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL21lcmdlRGF0YS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL21ldGFNYXAuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9yZWFsTmFtZXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9yZW9yZGVyLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvcmVwbGFjZUhvbGRlcnMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC9zZXREYXRhLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvaW50ZXJuYWwvc2hpbUtleXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9pbnRlcm5hbC90b09iamVjdC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL3RvUGF0aC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2ludGVybmFsL3dyYXBwZXJDbG9uZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvY2xvbmVEZWVwLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc0FyZ3VtZW50cy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNBcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNFbXB0eS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNGdW5jdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNOYXRpdmUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9sYW5nL2lzT2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc1BsYWluT2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc1N0cmluZy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L2xhbmcvaXNUeXBlZEFycmF5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvbGFuZy9pc1VuZGVmaW5lZC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L29iamVjdC9rZXlzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvb2JqZWN0L2tleXNJbi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L29iamVjdC9wYWlycy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L29iamVjdC92YWx1ZXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoLWNvbXBhdC9zdXBwb3J0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC1jb21wYXQvdXRpbGl0eS9pZGVudGl0eS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L3V0aWxpdHkvbm9vcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gtY29tcGF0L3V0aWxpdHkvcHJvcGVydHkuanMiLCJub2RlX21vZHVsZXMvcS9xLmpzIiwibm9kZV9tb2R1bGVzL3N1cGVyYWdlbnQvbGliL2NsaWVudC5qcyIsIm5vZGVfbW9kdWxlcy9zdXBlcmFnZW50L2xpYi9pcy1vYmplY3QuanMiLCJub2RlX21vZHVsZXMvc3VwZXJhZ2VudC9saWIvcmVxdWVzdC1iYXNlLmpzIiwibm9kZV9tb2R1bGVzL3N1cGVyYWdlbnQvbGliL3JlcXVlc3QuanMiLCJub2RlX21vZHVsZXMvc3VwZXJhZ2VudC9ub2RlX21vZHVsZXMvY29tcG9uZW50LWVtaXR0ZXIvaW5kZXguanMiLCJTd2FnZ2VyVWkuanMiLCJ1dGlscy91dGlscy5qcyIsInZpZXcvQXBpS2V5QXV0aE1vZGVsLmpzIiwidmlldy9BcGlLZXlBdXRoVmlldy5qcyIsInZpZXcvQXV0aEJ1dHRvblZpZXcuanMiLCJ2aWV3L0F1dGhzQ29sbGVjdGlvbi5qcyIsInZpZXcvQXV0aHNDb2xsZWN0aW9uVmlldy5qcyIsInZpZXcvQXV0aFZpZXcuanMiLCJ2aWV3L0Jhc2ljQXV0aE1vZGVsLmpzIiwidmlldy9CYXNpY0F1dGhWaWV3LmpzIiwidmlldy9Db250ZW50VHlwZVZpZXcuanMiLCJ2aWV3L0hlYWRlclZpZXcuanMiLCJ2aWV3L01haW5WaWV3LmpzIiwidmlldy9PYXV0aDJNb2RlbC5qcyIsInZpZXcvT2F1dGgyVmlldy5qcyIsInZpZXcvT3BlcmF0aW9uVmlldy5qcyIsInZpZXcvUGFyYW1ldGVyQ29udGVudFR5cGVWaWV3LmpzIiwidmlldy9QYXJhbWV0ZXJWaWV3LmpzIiwidmlldy9wYXJ0aWFscy9zaWduYXR1cmUuanMiLCJ2aWV3L1BvcHVwVmlldy5qcyIsInZpZXcvUmVzb3VyY2VWaWV3LmpzIiwidmlldy9SZXNwb25zZUNvbnRlbnRUeXBlVmlldy5qcyIsInZpZXcvU2lnbmF0dXJlVmlldy5qcyIsInZpZXcvU3RhdHVzQ29kZVZpZXcuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDMXhCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUN4TUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ2poRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNuR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNOQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNySkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4WEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5NEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdnQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM29CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDanZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNy9DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbHlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbGpEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4S0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3SEE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25EQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbmdFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2g5QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNiQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNuS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNsVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQy9FQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUM1Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDcEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUM5RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDckRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUM1TkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNwREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQy9DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ2hKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUMxRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ2xGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDbjNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQzdMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUM3OUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDcENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDM0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQzNFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6InN3YWdnZXItdWkuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovIFxuIHsoZnVuY3Rpb24oKSB7XG4gIHZhciB0ZW1wbGF0ZSA9IEhhbmRsZWJhcnMudGVtcGxhdGUsIHRlbXBsYXRlcyA9IEhhbmRsZWJhcnMudGVtcGxhdGVzID0gSGFuZGxlYmFycy50ZW1wbGF0ZXMgfHwge307XG50ZW1wbGF0ZXNbJ2FwaWtleV9hdXRoJ10gPSB0ZW1wbGF0ZSh7XCIxXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiBcIiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cXFwia2V5X2F1dGhfX3ZhbHVlXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnZhbHVlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvc3Bhbj5cXG5cIjtcbn0sXCIzXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgICAgICAgICAgICAgICAgPGlucHV0IHBsYWNlaG9sZGVyPVxcXCJhcGlfa2V5XFxcIiBjbGFzcz1cXFwiYXV0aF9pbnB1dCBpbnB1dF9hcGlLZXlfZW50cnlcXFwiIG5hbWU9XFxcImFwaUtleVxcXCIgdHlwZT1cXFwidGV4dFxcXCIvPlxcblwiO1xufSxcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIjxkaXYgY2xhc3M9XFxcImtleV9pbnB1dF9jb250YWluZXJcXFwiPlxcbiAgICA8aDMgY2xhc3M9XFxcImF1dGhfX3RpdGxlXFxcIj5BcGkga2V5IGF1dGhvcml6YXRpb248L2gzPlxcbiAgICA8ZGl2IGNsYXNzPVxcXCJhdXRoX19kZXNjcmlwdGlvblxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmRlc2NyaXB0aW9uIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvZGl2PlxcbiAgICA8ZGl2PlxcbiAgICAgICAgPGRpdiBjbGFzcz1cXFwia2V5X2F1dGhfX2ZpZWxkXFxcIj5cXG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cXFwia2V5X2F1dGhfX2xhYmVsXFxcIj5uYW1lOjwvc3Bhbj5cXG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cXFwia2V5X2F1dGhfX3ZhbHVlXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3NwYW4+XFxuICAgICAgICA8L2Rpdj5cXG4gICAgICAgIDxkaXYgY2xhc3M9XFxcImtleV9hdXRoX19maWVsZFxcXCI+XFxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XFxcImtleV9hdXRoX19sYWJlbFxcXCI+aW46PC9zcGFuPlxcbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVxcXCJrZXlfYXV0aF9fdmFsdWVcXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwW1wiaW5cIl0gOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvc3Bhbj5cXG4gICAgICAgIDwvZGl2PlxcbiAgICAgICAgPGRpdiBjbGFzcz1cXFwia2V5X2F1dGhfX2ZpZWxkXFxcIj5cXG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cXFwia2V5X2F1dGhfX2xhYmVsXFxcIj52YWx1ZTo8L3NwYW4+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pc0xvZ291dCA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLnByb2dyYW0oMywgZGF0YSwgMCksXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiICAgICAgICA8L2Rpdj5cXG4gICAgPC9kaXY+XFxuPC9kaXY+XFxuXCI7XG59LFwidXNlRGF0YVwiOnRydWV9KTtcbnRlbXBsYXRlc1snYXV0aF9idXR0b24nXSA9IHRlbXBsYXRlKHtcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIjxhIGNsYXNzPSdhdXRob3JpemVfX2J0bicgaHJlZj1cXFwiI1xcXCI+QXV0aG9yaXplPC9hPlxcblwiO1xufSxcInVzZURhdGFcIjp0cnVlfSk7XG50ZW1wbGF0ZXNbJ2F1dGhfYnV0dG9uX29wZXJhdGlvbiddID0gdGVtcGxhdGUoe1wiMVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiICAgICAgICBhdXRob3JpemVfX2J0bl9vcGVyYXRpb25fbG9naW5cXG5cIjtcbn0sXCIzXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgICAgICAgIGF1dGhvcml6ZV9fYnRuX29wZXJhdGlvbl9sb2dvdXRcXG5cIjtcbn0sXCI1XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiBcIiAgICAgICAgPHVsIGNsYXNzPVxcXCJhdXRob3JpemUtc2NvcGVzXFxcIj5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzLmVhY2guY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zY29wZXMgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVhY2hcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oNiwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiICAgICAgICA8L3VsPlxcblwiO1xufSxcIjZcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIiAgICAgICAgICAgICAgICA8bGkgY2xhc3M9XFxcImF1dGhvcml6ZV9fc2NvcGVcXFwiIHRpdGxlPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5kZXNjcmlwdGlvbiA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zY29wZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9saT5cXG5cIjtcbn0sXCJjb21waWxlclwiOls3LFwiPj0gNC4wLjBcIl0sXCJtYWluXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fTtcblxuICByZXR1cm4gXCI8ZGl2IGNsYXNzPVxcXCJhdXRob3JpemVfX2J0biBhdXRob3JpemVfX2J0bl9vcGVyYXRpb25cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzTG9nb3V0IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIucHJvZ3JhbSgzLCBkYXRhLCAwKSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiPlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc2NvcGVzIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSg1LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2Rpdj5cXG5cIjtcbn0sXCJ1c2VEYXRhXCI6dHJ1ZX0pO1xudGVtcGxhdGVzWydhdXRoX3ZpZXcnXSA9IHRlbXBsYXRlKHtcIjFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cXFwiYnV0dG9uXFxcIiBjbGFzcz1cXFwiYXV0aF9fYnV0dG9uIGF1dGhfc3VibWl0X19idXR0b25cXFwiIGRhdGEtc3ctdHJhbnNsYXRlPkF1dGhvcml6ZTwvYnV0dG9uPlxcblwiO1xufSxcIjNcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cXFwiYnV0dG9uXFxcIiBjbGFzcz1cXFwiYXV0aF9fYnV0dG9uIGF1dGhfbG9nb3V0X19idXR0b25cXFwiIGRhdGEtc3ctdHJhbnNsYXRlPkxvZ291dDwvYnV0dG9uPlxcblwiO1xufSxcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9O1xuXG4gIHJldHVybiBcIjxkaXYgY2xhc3M9XFxcImF1dGhfY29udGFpbmVyXFxcIj5cXG5cXG4gICAgPGRpdiBjbGFzcz1cXFwiYXV0aF9pbm5lclxcXCI+PC9kaXY+XFxuICAgIDxkaXYgY2xhc3M9XFxcImF1dGhfc3VibWl0XFxcIj5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzLnVubGVzcy5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaXNMb2dvdXQgOiBkZXB0aDApLHtcIm5hbWVcIjpcInVubGVzc1wiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzQXV0aG9yaXplZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMywgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiICAgIDwvZGl2PlxcblxcbjwvZGl2PlxcblwiO1xufSxcInVzZURhdGFcIjp0cnVlfSk7XG50ZW1wbGF0ZXNbJ2Jhc2ljX2F1dGgnXSA9IHRlbXBsYXRlKHtcIjFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAtIGF1dGhvcml6ZWRcIjtcbn0sXCIzXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiBcIiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cXFwiYmFzaWNfYXV0aF9fdmFsdWVcXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC51c2VybmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9zcGFuPlxcblwiO1xufSxcIjVcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAgICAgICAgICAgICAgICA8aW5wdXQgcmVxdWlyZWQgcGxhY2Vob2xkZXI9XFxcInVzZXJuYW1lXFxcIiBjbGFzcz1cXFwiYmFzaWNfYXV0aF9fdXNlcm5hbWUgYXV0aF9pbnB1dFxcXCIgbmFtZT1cXFwidXNlcm5hbWVcXFwiIHR5cGU9XFxcInRleHRcXFwiLz5cXG5cIjtcbn0sXCI3XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgICAgICAgICAgICA8ZGl2IGNsYXNzPVxcXCJhdXRoX2xhYmVsXFxcIj5cXG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XFxcImJhc2ljX2F1dGhfX2xhYmVsXFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT5wYXNzd29yZDo8L3NwYW4+XFxuICAgICAgICAgICAgICAgIDxpbnB1dCByZXF1aXJlZCBwbGFjZWhvbGRlcj1cXFwicGFzc3dvcmRcXFwiIGNsYXNzPVxcXCJiYXNpY19hdXRoX19wYXNzd29yZCBhdXRoX2lucHV0XFxcIiBuYW1lPVxcXCJwYXNzd29yZFxcXCIgdHlwZT1cXFwicGFzc3dvcmRcXFwiLz48L2xhYmVsPlxcbiAgICAgICAgICAgIDwvZGl2PlxcblwiO1xufSxcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9O1xuXG4gIHJldHVybiBcIjxkaXYgY2xhc3M9J2Jhc2ljX2F1dGhfY29udGFpbmVyJz5cXG4gICAgPGgzIGNsYXNzPVxcXCJhdXRoX190aXRsZVxcXCI+QmFzaWMgYXV0aGVudGljYXRpb25cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzTG9nb3V0IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2gzPlxcbiAgICA8Zm9ybSBjbGFzcz1cXFwiYmFzaWNfaW5wdXRfY29udGFpbmVyXFxcIj5cXG4gICAgICAgIDxkaXYgY2xhc3M9XFxcImF1dGhfX2Rlc2NyaXB0aW9uXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZGVzY3JpcHRpb24gOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9kaXY+XFxuICAgICAgICA8ZGl2IGNsYXNzPVxcXCJhdXRoX2xhYmVsXFxcIj5cXG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cXFwiYmFzaWNfYXV0aF9fbGFiZWxcXFwiIGRhdGEtc3ctdHJhbnNsYXRlPnVzZXJuYW1lOjwvc3Bhbj5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzTG9nb3V0IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgzLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIucHJvZ3JhbSg1LCBkYXRhLCAwKSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgICAgICAgIDwvZGl2PlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnMudW5sZXNzLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pc0xvZ291dCA6IGRlcHRoMCkse1wibmFtZVwiOlwidW5sZXNzXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDcsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiAgICA8L2Zvcm0+XFxuPC9kaXY+XFxuXCI7XG59LFwidXNlRGF0YVwiOnRydWV9KTtcbnRlbXBsYXRlc1snY29udGVudF90eXBlJ10gPSB0ZW1wbGF0ZSh7XCIxXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiAoKHN0YWNrMSA9IGhlbHBlcnMuZWFjaC5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnByb2R1Y2VzIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlYWNoXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDIsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpO1xufSxcIjJcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIlx0PG9wdGlvbiB2YWx1ZT1cXFwiXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsZGVwdGgwLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSxkZXB0aDAse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L29wdGlvbj5cXG5cIjtcbn0sXCI0XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgIDxvcHRpb24gdmFsdWU9XFxcImFwcGxpY2F0aW9uL2pzb25cXFwiPmFwcGxpY2F0aW9uL2pzb248L29wdGlvbj5cXG5cIjtcbn0sXCJjb21waWxlclwiOls3LFwiPj0gNC4wLjBcIl0sXCJtYWluXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCI8bGFiZWwgZGF0YS1zdy10cmFuc2xhdGUgZm9yPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5jb250ZW50VHlwZUlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiPlJlc3BvbnNlIENvbnRlbnQgVHlwZTwvbGFiZWw+XFxuPHNlbGVjdCBuYW1lPVxcXCJjb250ZW50VHlwZVxcXCIgaWQ9XFxcIlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmNvbnRlbnRUeXBlSWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCI+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5wcm9kdWNlcyA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLnByb2dyYW0oNCwgZGF0YSwgMCksXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9zZWxlY3Q+XFxuXCI7XG59LFwidXNlRGF0YVwiOnRydWV9KTtcbnRlbXBsYXRlc1snbWFpbiddID0gdGVtcGxhdGUoe1wiMVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiICA8ZGl2IGNsYXNzPVxcXCJpbmZvX3RpdGxlXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pbmZvIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS50aXRsZSA6IHN0YWNrMSkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2Rpdj5cXG4gIDxkaXYgY2xhc3M9XFxcImluZm9fZGVzY3JpcHRpb24gbWFya2Rvd25cXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLCgoc3RhY2sxID0gKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmluZm8gOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLmRlc2NyaXB0aW9uIDogc3RhY2sxKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvZGl2PlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZXh0ZXJuYWxEb2NzIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgyLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgIFwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pbmZvIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS50ZXJtc09mU2VydmljZVVybCA6IHN0YWNrMSkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oNCwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuICBcIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKChzdGFjazEgPSAoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pbmZvIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS5jb250YWN0IDogc3RhY2sxKSkgIT0gbnVsbCA/IHN0YWNrMS5uYW1lIDogc3RhY2sxKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSg2LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG4gIFwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoKHN0YWNrMSA9ICgoc3RhY2sxID0gKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmluZm8gOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLmNvbnRhY3QgOiBzdGFjazEpKSAhPSBudWxsID8gc3RhY2sxLnVybCA6IHN0YWNrMSkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oOCwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuICBcIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKChzdGFjazEgPSAoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pbmZvIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS5jb250YWN0IDogc3RhY2sxKSkgIT0gbnVsbCA/IHN0YWNrMS5lbWFpbCA6IHN0YWNrMSkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMTAsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcbiAgXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLCgoc3RhY2sxID0gKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmluZm8gOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLmxpY2Vuc2UgOiBzdGFjazEpLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEyLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG5cIjtcbn0sXCIyXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCIgIDxwPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLCgoc3RhY2sxID0gKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmV4dGVybmFsRG9jcyA6IGRlcHRoMCkpICE9IG51bGwgPyBzdGFjazEuZGVzY3JpcHRpb24gOiBzdGFjazEpLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9wPlxcbiAgPGEgaHJlZj1cXFwiXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5leHRlcm5hbERvY3MgOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLnVybCA6IHN0YWNrMSkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIiB0YXJnZXQ9XFxcIl9ibGFua1xcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5leHRlcm5hbERvY3MgOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLnVybCA6IHN0YWNrMSkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9hPlxcblwiO1xufSxcIjRcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuIFwiPGRpdiBjbGFzcz1cXFwiaW5mb190b3NcXFwiPjxhIHRhcmdldD1cXFwiX2JsYW5rXFxcIiBocmVmPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pbmZvIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS50ZXJtc09mU2VydmljZVVybCA6IHN0YWNrMSkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT5UZXJtcyBvZiBzZXJ2aWNlPC9hPjwvZGl2PlwiO1xufSxcIjZcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuIFwiPGRpdj48ZGl2IGNsYXNzPSdpbmZvX25hbWUnIHN0eWxlPVxcXCJkaXNwbGF5OiBpbmxpbmVcXFwiIGRhdGEtc3ctdHJhbnNsYXRlPkNyZWF0ZWQgYnkgPC9kaXY+IFwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCgoc3RhY2sxID0gKChzdGFjazEgPSAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaW5mbyA6IGRlcHRoMCkpICE9IG51bGwgPyBzdGFjazEuY29udGFjdCA6IHN0YWNrMSkpICE9IG51bGwgPyBzdGFjazEubmFtZSA6IHN0YWNrMSkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9kaXY+XCI7XG59LFwiOFwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiPGRpdiBjbGFzcz0naW5mb191cmwnIGRhdGEtc3ctdHJhbnNsYXRlPlNlZSBtb3JlIGF0IDxhIGhyZWY9XFxcIlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKChzdGFjazEgPSAoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pbmZvIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS5jb250YWN0IDogc3RhY2sxKSkgIT0gbnVsbCA/IHN0YWNrMS51cmwgOiBzdGFjazEpLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoKHN0YWNrMSA9ICgoc3RhY2sxID0gKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmluZm8gOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLmNvbnRhY3QgOiBzdGFjazEpKSAhPSBudWxsID8gc3RhY2sxLnVybCA6IHN0YWNrMSkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9hPjwvZGl2PlwiO1xufSxcIjEwXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCI8ZGl2IGNsYXNzPSdpbmZvX2VtYWlsJz48YSB0YXJnZXQ9XFxcIl9wYXJlbnRcXFwiIGhyZWY9XFxcIm1haWx0bzpcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLCgoc3RhY2sxID0gKChzdGFjazEgPSAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaW5mbyA6IGRlcHRoMCkpICE9IG51bGwgPyBzdGFjazEuY29udGFjdCA6IHN0YWNrMSkpICE9IG51bGwgPyBzdGFjazEuZW1haWwgOiBzdGFjazEpLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIj9zdWJqZWN0PVwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKChzdGFjazEgPSAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaW5mbyA6IGRlcHRoMCkpICE9IG51bGwgPyBzdGFjazEudGl0bGUgOiBzdGFjazEpLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCIgZGF0YS1zdy10cmFuc2xhdGU+Q29udGFjdCB0aGUgZGV2ZWxvcGVyPC9hPjwvZGl2PlwiO1xufSxcIjEyXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCI8ZGl2IGNsYXNzPSdpbmZvX2xpY2Vuc2UnPjxhIHRhcmdldD1cXFwiX2JsYW5rXFxcIiBocmVmPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLCgoc3RhY2sxID0gKChzdGFjazEgPSAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaW5mbyA6IGRlcHRoMCkpICE9IG51bGwgPyBzdGFjazEubGljZW5zZSA6IHN0YWNrMSkpICE9IG51bGwgPyBzdGFjazEudXJsIDogc3RhY2sxKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKChzdGFjazEgPSAoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pbmZvIDogZGVwdGgwKSkgIT0gbnVsbCA/IHN0YWNrMS5saWNlbnNlIDogc3RhY2sxKSkgIT0gbnVsbCA/IHN0YWNrMS5uYW1lIDogc3RhY2sxKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2E+PC9kaXY+XCI7XG59LFwiMTRcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuIFwiICAsIDxzcGFuIHN0eWxlPVxcXCJmb250LXZhcmlhbnQ6IHNtYWxsLWNhcHNcXFwiIGRhdGEtc3ctdHJhbnNsYXRlPmFwaSB2ZXJzaW9uPC9zcGFuPjogXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKChzdGFjazEgPSAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaW5mbyA6IGRlcHRoMCkpICE9IG51bGwgPyBzdGFjazEudmVyc2lvbiA6IHN0YWNrMSkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuICAgIFwiO1xufSxcIjE2XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCIgICAgPHNwYW4gc3R5bGU9XFxcImZsb2F0OnJpZ2h0XFxcIj48YSB0YXJnZXQ9XFxcIl9ibGFua1xcXCIgaHJlZj1cXFwiXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsaWRhdG9yVXJsIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIvZGVidWc/dXJsPVwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnVybCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIj48aW1nIGlkPVxcXCJ2YWxpZGF0b3JcXFwiIHNyYz1cXFwiXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsaWRhdG9yVXJsIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI/dXJsPVwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnVybCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIj48L2E+XFxuICAgIDwvc3Bhbj5cXG5cIjtcbn0sXCJjb21waWxlclwiOls3LFwiPj0gNC4wLjBcIl0sXCJtYWluXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fTtcblxuICByZXR1cm4gXCI8ZGl2IGNsYXNzPSdpbmZvJyBpZD0nYXBpX2luZm8nPlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaW5mbyA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9kaXY+XFxuPGRpdiBjbGFzcz0nY29udGFpbmVyJyBpZD0ncmVzb3VyY2VzX2NvbnRhaW5lcic+XFxuICA8ZGl2IGNsYXNzPSdhdXRob3JpemUtd3JhcHBlcic+PC9kaXY+XFxuXFxuICA8dWwgaWQ9J3Jlc291cmNlcyc+PC91bD5cXG5cXG4gIDxkaXYgY2xhc3M9XFxcImZvb3RlclxcXCI+XFxuICAgIDxoNCBzdHlsZT1cXFwiY29sb3I6ICM5OTlcXFwiPlsgPHNwYW4gc3R5bGU9XFxcImZvbnQtdmFyaWFudDogc21hbGwtY2Fwc1xcXCI+YmFzZSB1cmw8L3NwYW4+OiBcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5iYXNlUGF0aCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLCgoc3RhY2sxID0gKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmluZm8gOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLnZlcnNpb24gOiBzdGFjazEpLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDE0LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJdXFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC52YWxpZGF0b3JVcmwgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDE2LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgICAgPC9oND5cXG4gICAgPC9kaXY+XFxuPC9kaXY+XFxuXCI7XG59LFwidXNlRGF0YVwiOnRydWV9KTtcbnRlbXBsYXRlc1snb2F1dGgyJ10gPSB0ZW1wbGF0ZSh7XCIxXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiBcIjxwPkF1dGhvcml6YXRpb24gVVJMOiBcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmF1dGhvcml6YXRpb25VcmwgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9wPlwiO1xufSxcIjNcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuIFwiPHA+VG9rZW4gVVJMOiBcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnRva2VuVXJsIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvcD5cIjtcbn0sXCI1XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgICAgICAgIDxwPlBsZWFzZSBpbnB1dCB1c2VybmFtZSBhbmQgcGFzc3dvcmQgZm9yIHBhc3N3b3JkIGZsb3cgYXV0aG9yaXphdGlvbjwvcD5cXG4gICAgICAgIDxmaWVsZHNldD5cXG4gICAgICAgICAgICA8ZGl2PjxsYWJlbD5Vc2VybmFtZTogPGlucHV0IGNsYXNzPVxcXCJvYXV0aC11c2VybmFtZVxcXCIgdHlwZT1cXFwidGV4dFxcXCIgbmFtZT1cXFwidXNlcm5hbWVcXFwiPjwvbGFiZWw+PC9kaXY+XFxuICAgICAgICAgICAgPGRpdj48bGFiZWw+UGFzc3dvcmQ6IDxpbnB1dCBjbGFzcz1cXFwib2F1dGgtcGFzc3dvcmRcXFwiIHR5cGU9XFxcInBhc3N3b3JkXFxcIiBuYW1lPVxcXCJwYXNzd29yZFxcXCI+PC9sYWJlbD48L2Rpdj5cXG4gICAgICAgIDwvZmllbGRzZXQ+XFxuXCI7XG59LFwiN1wiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gXCIgICAgICAgIDxwPlNldHVwIGNsaWVudCBhdXRoZW50aWNhdGlvbi5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5yZXF1aXJlQ2xpZW50QXV0aGVudGljYWl0b24gOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDgsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvcD5cXG4gICAgICAgIDxmaWVsZHNldD5cXG4gICAgICAgICAgICA8ZGl2PjxsYWJlbD5UeXBlOlxcbiAgICAgICAgICAgICAgICA8c2VsZWN0IGNsYXNzPVxcXCJvYXV0aC1jbGllbnQtYXV0aGVudGljYXRpb24tdHlwZVxcXCIgbmFtZT1cXFwiY2xpZW50LWF1dGhlbnRpY2F0aW9uLXR5cGVcXFwiPlxcbiAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cXFwibm9uZVxcXCIgc2VsZWN0ZWQ+Tm9uZSBvciBvdGhlcjwvb3B0aW9uPlxcbiAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cXFwiYmFzaWNcXFwiPkJhc2ljIGF1dGg8L29wdGlvbj5cXG4gICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XFxcInJlcXVlc3QtYm9keVxcXCI+UmVxdWVzdCBib2R5PC9vcHRpb24+XFxuICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxcbiAgICAgICAgICAgIDwvbGFiZWw+PC9kaXY+XFxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cXFwib2F1dGgtY2xpZW50LWF1dGhlbnRpY2F0aW9uXFxcIiBoaWRkZW4+XFxuICAgICAgICAgICAgICAgIDxkaXY+PGxhYmVsPkNsaWVudElkOiA8aW5wdXQgY2xhc3M9XFxcIm9hdXRoLWNsaWVudC1pZFxcXCIgdHlwZT1cXFwidGV4dFxcXCIgbmFtZT1cXFwiY2xpZW50LWlkXFxcIj48L2xhYmVsPjwvZGl2PlxcbiAgICAgICAgICAgICAgICA8ZGl2PjxsYWJlbD5TZWNyZXQ6IDxpbnB1dCBjbGFzcz1cXFwib2F1dGgtY2xpZW50LXNlY3JldFxcXCIgdHlwZT1cXFwidGV4dFxcXCIgbmFtZT1cXFwiY2xpZW50LXNlY3JldFxcXCI+PC9sYWJlbD48L2Rpdj5cXG4gICAgICAgICAgICA8L2Rpdj5cXG4gICAgICAgIDwvZmllbGRzZXQ+XFxuXCI7XG59LFwiOFwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiKFJlcXVpcmVkKVwiO1xufSxcIjEwXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCIgICAgICAgICAgICA8bGk+XFxuICAgICAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cXFwib2F1dGgtc2NvcGVcXFwiIHR5cGU9XFxcImNoZWNrYm94XFxcIiBkYXRhLXNjb3BlPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zY29wZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIiBvYXV0aHR5cGU9XFxcIlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLk9BdXRoU2NoZW1lS2V5IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiLz5cXG4gICAgICAgICAgICAgICAgPGxhYmVsPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnNjb3BlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2xhYmVsPjxici8+XFxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVxcXCJhcGktc2NvcGUtZGVzY1xcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZGVzY3JpcHRpb24gOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuT0F1dGhTY2hlbWVLZXkgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDExLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgICAgICAgICAgICAgICAgPC9zcGFuPlxcbiAgICAgICAgICAgIDwvbGk+XFxuXCI7XG59LFwiMTFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuIFwiICAgICAgICAgICAgICAgICAgICAgICAgKFwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5PQXV0aFNjaGVtZUtleSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiKVxcblwiO1xufSxcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIjxkaXY+XFxuICAgIDxoMyBjbGFzcz1cXFwiYXV0aF9fdGl0bGVcXFwiPk9BdXRoMi4wPC9oMz5cXG4gICAgPHA+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmRlc2NyaXB0aW9uIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvcD5cXG4gICAgXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5hdXRob3JpemF0aW9uVXJsIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG4gICAgXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC50b2tlblVybCA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMywgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuICAgIDxwPmZsb3c6IFwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmZsb3cgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvcD5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzUGFzc3dvcmRGbG93IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSg1LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmNsaWVudEF1dGhlbnRpY2F0aW9uIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSg3LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgICAgPHA+PHN0cm9uZz4gXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuYXBwTmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiIDwvc3Ryb25nPiBBUEkgcmVxdWlyZXMgdGhlIGZvbGxvd2luZyBzY29wZXMuIFNlbGVjdCB3aGljaCBvbmVzIHlvdSB3YW50IHRvIGdyYW50IHRvIFN3YWdnZXIgVUkuPC9wPlxcbiAgICA8cD5TY29wZXMgYXJlIHVzZWQgdG8gZ3JhbnQgYW4gYXBwbGljYXRpb24gZGlmZmVyZW50IGxldmVscyBvZiBhY2Nlc3MgdG8gZGF0YSBvbiBiZWhhbGYgb2YgdGhlIGVuZCB1c2VyLiBFYWNoIEFQSSBtYXkgZGVjbGFyZSBvbmUgb3IgbW9yZSBzY29wZXMuXFxuICAgICAgICA8YSBocmVmPVxcXCIjXFxcIj5MZWFybiBob3cgdG8gdXNlPC9hPlxcbiAgICA8L3A+XFxuICAgIDx1bCBjbGFzcz1cXFwiYXBpLXBvcHVwLXNjb3Blc1xcXCI+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVycy5lYWNoLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zY29wZXMgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVhY2hcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMTAsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiAgICA8L3VsPlxcbjwvZGl2PlwiO1xufSxcInVzZURhdGFcIjp0cnVlfSk7XG50ZW1wbGF0ZXNbJ29wZXJhdGlvbiddID0gdGVtcGxhdGUoe1wiMVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiZGVwcmVjYXRlZFwiO1xufSxcIjNcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAgICAgICAgICAgIDxoND48c3BhbiBkYXRhLXN3LXRyYW5zbGF0ZT5XYXJuaW5nOiBEZXByZWNhdGVkPC9zcGFuPjwvaDQ+XFxuXCI7XG59LFwiNVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gXCIgICAgICAgIDxoND48c3BhbiBkYXRhLXN3LXRyYW5zbGF0ZT5JbXBsZW1lbnRhdGlvbiBOb3Rlczwvc3Bhbj48L2g0PlxcbiAgICAgICAgPGRpdiBjbGFzcz1cXFwibWFya2Rvd25cXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZGVzY3JpcHRpb24gOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9kaXY+XFxuXCI7XG59LFwiN1wiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiICAgICAgICAgICAgPGRpdiBjbGFzcz0nYXV0aG9yaXplLXdyYXBwZXIgYXV0aG9yaXplLXdyYXBwZXJfb3BlcmF0aW9uJz48L2Rpdj5cXG5cIjtcbn0sXCI5XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fTtcblxuICByZXR1cm4gXCIgICAgICAgICAgPGRpdiBjbGFzcz1cXFwicmVzcG9uc2UtY2xhc3NcXFwiPlxcbiAgICAgICAgICAgIDxoND48c3BhbiBkYXRhLXN3LXRyYW5zbGF0ZT5SZXNwb25zZSBDbGFzczwvc3Bhbj4gKDxzcGFuIGRhdGEtc3ctdHJhbnNsYXRlPlN0YXR1czwvc3Bhbj4gXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc3VjY2Vzc0NvZGUgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIik8L2g0PlxcbiAgICAgICAgICAgICAgXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zdWNjZXNzRGVzY3JpcHRpb24gOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEwLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG4gICAgICAgICAgICA8cD48c3BhbiBjbGFzcz1cXFwibW9kZWwtc2lnbmF0dXJlXFxcIiAvPjwvcD5cXG4gICAgICAgICAgICA8YnIvPlxcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XFxcInJlc3BvbnNlLWNvbnRlbnQtdHlwZVxcXCIgLz5cXG4gICAgICAgICAgICA8L2Rpdj5cXG5cIjtcbn0sXCIxMFwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gXCI8ZGl2IGNsYXNzPVxcXCJtYXJrZG93blxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zdWNjZXNzRGVzY3JpcHRpb24gOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9kaXY+XCI7XG59LFwiMTJcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuIFwiICAgICAgICAgIDxoNCBkYXRhLXN3LXRyYW5zbGF0ZT5IZWFkZXJzPC9oND5cXG4gICAgICAgICAgPHRhYmxlIGNsYXNzPVxcXCJoZWFkZXJzXFxcIj5cXG4gICAgICAgICAgICA8dGhlYWQ+XFxuICAgICAgICAgICAgICA8dHI+XFxuICAgICAgICAgICAgICAgIDx0aCBzdHlsZT1cXFwid2lkdGg6IDEwMHB4OyBtYXgtd2lkdGg6IDEwMHB4XFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT5IZWFkZXI8L3RoPlxcbiAgICAgICAgICAgICAgICA8dGggc3R5bGU9XFxcIndpZHRoOiAzMTBweDsgbWF4LXdpZHRoOiAzMTBweFxcXCIgZGF0YS1zdy10cmFuc2xhdGU+RGVzY3JpcHRpb248L3RoPlxcbiAgICAgICAgICAgICAgICA8dGggc3R5bGU9XFxcIndpZHRoOiAyMDBweDsgbWF4LXdpZHRoOiAyMDBweFxcXCIgZGF0YS1zdy10cmFuc2xhdGU+VHlwZTwvdGg+XFxuICAgICAgICAgICAgICAgIDx0aCBzdHlsZT1cXFwid2lkdGg6IDMyMHB4OyBtYXgtd2lkdGg6IDMyMHB4XFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT5PdGhlcjwvdGg+XFxuICAgICAgICAgICAgICA8L3RyPlxcbiAgICAgICAgICAgIDwvdGhlYWQ+XFxuICAgICAgICAgICAgPHRib2R5PlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnMuZWFjaC5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmhlYWRlcnMgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVhY2hcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMTMsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiAgICAgICAgICAgIDwvdGJvZHk+XFxuICAgICAgICAgIDwvdGFibGU+XFxuXCI7XG59LFwiMTNcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGhlbHBlciwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiICAgICAgICAgICAgICA8dHI+XFxuICAgICAgICAgICAgICAgIDx0ZD5cIlxuICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy5rZXkgfHwgKGRhdGEgJiYgZGF0YS5rZXkpKSAhPSBudWxsID8gaGVscGVyIDogYWxpYXMyKSwodHlwZW9mIGhlbHBlciA9PT0gXCJmdW5jdGlvblwiID8gaGVscGVyLmNhbGwoYWxpYXMxLHtcIm5hbWVcIjpcImtleVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSA6IGhlbHBlcikpKVxuICAgICsgXCI8L3RkPlxcbiAgICAgICAgICAgICAgICA8dGQ+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmRlc2NyaXB0aW9uIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvdGQ+XFxuICAgICAgICAgICAgICAgIDx0ZD5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC50eXBlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3RkPlxcbiAgICAgICAgICAgICAgICA8dGQ+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAub3RoZXIgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvdGQ+XFxuICAgICAgICAgICAgICA8L3RyPlxcblwiO1xufSxcIjE1XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgICAgICAgICAgPGg0IGRhdGEtc3ctdHJhbnNsYXRlPlBhcmFtZXRlcnM8L2g0PlxcbiAgICAgICAgICA8dGFibGUgY2xhc3M9J2Z1bGx3aWR0aCBwYXJhbWV0ZXJzJz5cXG4gICAgICAgICAgPHRoZWFkPlxcbiAgICAgICAgICAgIDx0cj5cXG4gICAgICAgICAgICA8dGggc3R5bGU9XFxcIndpZHRoOiAxMDBweDsgbWF4LXdpZHRoOiAxMDBweFxcXCIgZGF0YS1zdy10cmFuc2xhdGU+UGFyYW1ldGVyPC90aD5cXG4gICAgICAgICAgICA8dGggc3R5bGU9XFxcIndpZHRoOiAzMTBweDsgbWF4LXdpZHRoOiAzMTBweFxcXCIgZGF0YS1zdy10cmFuc2xhdGU+VmFsdWU8L3RoPlxcbiAgICAgICAgICAgIDx0aCBzdHlsZT1cXFwid2lkdGg6IDIwMHB4OyBtYXgtd2lkdGg6IDIwMHB4XFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT5EZXNjcmlwdGlvbjwvdGg+XFxuICAgICAgICAgICAgPHRoIHN0eWxlPVxcXCJ3aWR0aDogMTAwcHg7IG1heC13aWR0aDogMTAwcHhcXFwiIGRhdGEtc3ctdHJhbnNsYXRlPlBhcmFtZXRlciBUeXBlPC90aD5cXG4gICAgICAgICAgICA8dGggc3R5bGU9XFxcIndpZHRoOiAyMjBweDsgbWF4LXdpZHRoOiAyMzBweFxcXCIgZGF0YS1zdy10cmFuc2xhdGU+RGF0YSBUeXBlPC90aD5cXG4gICAgICAgICAgICA8L3RyPlxcbiAgICAgICAgICA8L3RoZWFkPlxcbiAgICAgICAgICA8dGJvZHkgY2xhc3M9XFxcIm9wZXJhdGlvbi1wYXJhbXNcXFwiPlxcblxcbiAgICAgICAgICA8L3Rib2R5PlxcbiAgICAgICAgICA8L3RhYmxlPlxcblwiO1xufSxcIjE3XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgICAgICAgICAgPGRpdiBzdHlsZT0nbWFyZ2luOjA7cGFkZGluZzowO2Rpc3BsYXk6aW5saW5lJz48L2Rpdj5cXG4gICAgICAgICAgPGg0IGRhdGEtc3ctdHJhbnNsYXRlPlJlc3BvbnNlIE1lc3NhZ2VzPC9oND5cXG4gICAgICAgICAgPHRhYmxlIGNsYXNzPSdmdWxsd2lkdGggcmVzcG9uc2UtbWVzc2FnZXMnPlxcbiAgICAgICAgICAgIDx0aGVhZD5cXG4gICAgICAgICAgICA8dHI+XFxuICAgICAgICAgICAgICA8dGggZGF0YS1zdy10cmFuc2xhdGU+SFRUUCBTdGF0dXMgQ29kZTwvdGg+XFxuICAgICAgICAgICAgICA8dGggZGF0YS1zdy10cmFuc2xhdGU+UmVhc29uPC90aD5cXG4gICAgICAgICAgICAgIDx0aCBkYXRhLXN3LXRyYW5zbGF0ZT5SZXNwb25zZSBNb2RlbDwvdGg+XFxuICAgICAgICAgICAgICA8dGggZGF0YS1zdy10cmFuc2xhdGU+SGVhZGVyczwvdGg+XFxuICAgICAgICAgICAgPC90cj5cXG4gICAgICAgICAgICA8L3RoZWFkPlxcbiAgICAgICAgICAgIDx0Ym9keSBjbGFzcz1cXFwib3BlcmF0aW9uLXN0YXR1c1xcXCI+XFxuICAgICAgICAgICAgPC90Ym9keT5cXG4gICAgICAgICAgPC90YWJsZT5cXG5cIjtcbn0sXCIxOVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiXCI7XG59LFwiMjFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAgICAgICAgICA8ZGl2IGNsYXNzPSdzYW5kYm94X2hlYWRlcic+XFxuICAgICAgICAgICAgPGlucHV0IGNsYXNzPSdzdWJtaXQnIHR5cGU9J3N1Ym1pdCcgdmFsdWU9J1RyeSBpdCBvdXQhJyBkYXRhLXN3LXRyYW5zbGF0ZS8+XFxuICAgICAgICAgICAgPGEgaHJlZj0nIycgY2xhc3M9J3Jlc3BvbnNlX2hpZGVyJyBzdHlsZT0nZGlzcGxheTpub25lJyBkYXRhLXN3LXRyYW5zbGF0ZT5IaWRlIFJlc3BvbnNlPC9hPlxcbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPSdyZXNwb25zZV90aHJvYmJlcicgc3R5bGU9J2Rpc3BsYXk6bm9uZSc+PC9zcGFuPlxcbiAgICAgICAgICA8L2Rpdj5cXG5cIjtcbn0sXCIyM1wiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiICAgICAgICAgIDxoNCBkYXRhLXN3LXRyYW5zbGF0ZT5SZXF1ZXN0IEhlYWRlcnM8L2g0PlxcbiAgICAgICAgICA8ZGl2IGNsYXNzPSdibG9jayByZXF1ZXN0X2hlYWRlcnMnPjwvZGl2PlxcblwiO1xufSxcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nLCBhbGlhczM9Y29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb247XG5cbiAgcmV0dXJuIFwiICA8dWwgY2xhc3M9J29wZXJhdGlvbnMnID5cXG4gICAgPGxpIGNsYXNzPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5tZXRob2QgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiBvcGVyYXRpb24nIGlkPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5wYXJlbnRJZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiX1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm5pY2tuYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInPlxcbiAgICAgIDxkaXYgY2xhc3M9J2hlYWRpbmcnPlxcbiAgICAgICAgPGgzPlxcbiAgICAgICAgICA8c3BhbiBjbGFzcz0naHR0cF9tZXRob2QnPlxcbiAgICAgICAgICA8YSBocmVmPScjIS9cIlxuICAgICsgYWxpYXMzKChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5lbmNvZGVkUGFyZW50SWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKVxuICAgICsgXCIvXCJcbiAgICArIGFsaWFzMygoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubmlja25hbWUgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKVxuICAgICsgXCInIGNsYXNzPVxcXCJ0b2dnbGVPcGVyYXRpb25cXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm1ldGhvZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9hPlxcbiAgICAgICAgICA8L3NwYW4+XFxuICAgICAgICAgIDxzcGFuIGNsYXNzPSdwYXRoJz5cXG4gICAgICAgICAgPGEgaHJlZj0nIyEvXCJcbiAgICArIGFsaWFzMygoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZW5jb2RlZFBhcmVudElkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSlcbiAgICArIFwiL1wiXG4gICAgKyBhbGlhczMoKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm5pY2tuYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSlcbiAgICArIFwiJyBjbGFzcz1cXFwidG9nZ2xlT3BlcmF0aW9uIFwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZGVwcmVjYXRlZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5wYXRoIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2E+XFxuICAgICAgICAgIDwvc3Bhbj5cXG4gICAgICAgIDwvaDM+XFxuICAgICAgICA8dWwgY2xhc3M9J29wdGlvbnMnPlxcbiAgICAgICAgICA8bGk+XFxuICAgICAgICAgIDxhIGhyZWY9JyMhL1wiXG4gICAgKyBhbGlhczMoKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmVuY29kZWRQYXJlbnRJZCA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpXG4gICAgKyBcIi9cIlxuICAgICsgYWxpYXMzKChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uaWNrbmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpXG4gICAgKyBcIicgY2xhc3M9XFxcInRvZ2dsZU9wZXJhdGlvblxcXCI+PHNwYW4gY2xhc3M9XFxcIm1hcmtkb3duXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zdW1tYXJ5IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3NwYW4+PC9hPlxcbiAgICAgICAgICA8L2xpPlxcbiAgICAgICAgPC91bD5cXG4gICAgICA8L2Rpdj5cXG4gICAgICA8ZGl2IGNsYXNzPSdjb250ZW50JyBpZD0nXCJcbiAgICArIGFsaWFzMygoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZW5jb2RlZFBhcmVudElkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSlcbiAgICArIFwiX1wiXG4gICAgKyBhbGlhczMoKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm5pY2tuYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSlcbiAgICArIFwiX2NvbnRlbnQnIHN0eWxlPSdkaXNwbGF5Om5vbmUnPlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZGVwcmVjYXRlZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMywgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5kZXNjcmlwdGlvbiA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oNSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zZWN1cml0eSA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oNywgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC50eXBlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSg5LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmhlYWRlcnMgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEyLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG4gICAgICAgIDxmb3JtIGFjY2VwdC1jaGFyc2V0PSdVVEYtOCcgY2xhc3M9J3NhbmRib3gnPlxcbiAgICAgICAgICA8ZGl2IHN0eWxlPSdtYXJnaW46MDtwYWRkaW5nOjA7ZGlzcGxheTppbmxpbmUnPjwvZGl2PlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAucGFyYW1ldGVycyA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMTUsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAucmVzcG9uc2VNZXNzYWdlcyA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMTcsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaXNSZWFkT25seSA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMTksIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5wcm9ncmFtKDIxLCBkYXRhLCAwKSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgICAgICAgIDwvZm9ybT5cXG4gICAgICAgIDxkaXYgY2xhc3M9J3Jlc3BvbnNlJyBzdHlsZT0nZGlzcGxheTpub25lJz5cXG4gICAgICAgICAgPGg0IGNsYXNzPSdjdXJsJz5DdXJsPC9oND5cXG4gICAgICAgICAgPGRpdiBjbGFzcz0nYmxvY2sgY3VybCc+PC9kaXY+XFxuICAgICAgICAgIDxoNCBkYXRhLXN3LXRyYW5zbGF0ZT5SZXF1ZXN0IFVSTDwvaDQ+XFxuICAgICAgICAgIDxkaXYgY2xhc3M9J2Jsb2NrIHJlcXVlc3RfdXJsJz48L2Rpdj5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnNob3dSZXF1ZXN0SGVhZGVycyA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMjMsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiAgICAgICAgICA8aDQgZGF0YS1zdy10cmFuc2xhdGU+UmVzcG9uc2UgQm9keTwvaDQ+XFxuICAgICAgICAgIDxkaXYgY2xhc3M9J2Jsb2NrIHJlc3BvbnNlX2JvZHknPjwvZGl2PlxcbiAgICAgICAgICA8aDQgZGF0YS1zdy10cmFuc2xhdGU+UmVzcG9uc2UgQ29kZTwvaDQ+XFxuICAgICAgICAgIDxkaXYgY2xhc3M9J2Jsb2NrIHJlc3BvbnNlX2NvZGUnPjwvZGl2PlxcbiAgICAgICAgICA8aDQgZGF0YS1zdy10cmFuc2xhdGU+UmVzcG9uc2UgSGVhZGVyczwvaDQ+XFxuICAgICAgICAgIDxkaXYgY2xhc3M9J2Jsb2NrIHJlc3BvbnNlX2hlYWRlcnMnPjwvZGl2PlxcbiAgICAgICAgPC9kaXY+XFxuICAgICAgPC9kaXY+XFxuICAgIDwvbGk+XFxuICA8L3VsPlxcblwiO1xufSxcInVzZURhdGFcIjp0cnVlfSk7XG50ZW1wbGF0ZXNbJ3BhcmFtJ10gPSB0ZW1wbGF0ZSh7XCIxXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzRmlsZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMiwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLnByb2dyYW0oNCwgZGF0YSwgMCksXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIik7XG59LFwiMlwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiXHRcdFx0PGlucHV0IHR5cGU9XFxcImZpbGVcXFwiIG5hbWU9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm5hbWUgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIicgaWQ9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnZhbHVlSWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIicvPlxcblx0XHRcdDxkaXYgY2xhc3M9XFxcInBhcmFtZXRlci1jb250ZW50LXR5cGVcXFwiIC8+XFxuXCI7XG59LFwiNFwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMFtcImRlZmF1bHRcIl0gOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDUsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5wcm9ncmFtKDcsIGRhdGEsIDApLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpO1xufSxcIjVcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIlx0XHRcdFx0PGRpdiBjbGFzcz1cXFwiZWRpdG9yX2hvbGRlclxcXCI+PC9kaXY+XFxuXHRcdFx0XHQ8dGV4dGFyZWEgY2xhc3M9J2JvZHktdGV4dGFyZWEnIG5hbWU9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm5hbWUgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIicgaWQ9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnZhbHVlSWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIic+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDBbXCJkZWZhdWx0XCJdIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3RleHRhcmVhPlxcbiAgICAgICAgPGJyIC8+XFxuICAgICAgICA8ZGl2IGNsYXNzPVxcXCJwYXJhbWV0ZXItY29udGVudC10eXBlXFxcIiAvPlxcblwiO1xufSxcIjdcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIlx0XHRcdFx0PHRleHRhcmVhIGNsYXNzPSdib2R5LXRleHRhcmVhJyBuYW1lPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInIGlkPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC52YWx1ZUlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInPjwvdGV4dGFyZWE+XFxuXHRcdFx0XHQ8ZGl2IGNsYXNzPVxcXCJlZGl0b3JfaG9sZGVyXFxcIj48L2Rpdj5cXG5cdFx0XHRcdDxiciAvPlxcblx0XHRcdFx0PGRpdiBjbGFzcz1cXFwicGFyYW1ldGVyLWNvbnRlbnQtdHlwZVxcXCIgLz5cXG5cIjtcbn0sXCI5XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzRmlsZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMiwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLnByb2dyYW0oMTAsIGRhdGEsIDApLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpO1xufSxcIjEwXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiAoKHN0YWNrMSA9IChoZWxwZXJzLnJlbmRlclRleHRQYXJhbSB8fCAoZGVwdGgwICYmIGRlcHRoMC5yZW5kZXJUZXh0UGFyYW0pIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LGRlcHRoMCx7XCJuYW1lXCI6XCJyZW5kZXJUZXh0UGFyYW1cIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMTEsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpO1xufSxcIjExXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCJcIjtcbn0sXCJjb21waWxlclwiOls3LFwiPj0gNC4wLjBcIl0sXCJtYWluXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCI8dGQgY2xhc3M9J2NvZGUnPjxsYWJlbCBmb3I9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnZhbHVlSWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIic+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9sYWJlbD48L3RkPlxcbjx0ZD5cXG5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzQm9keSA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLnByb2dyYW0oOSwgZGF0YSwgMCksXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuPC90ZD5cXG48dGQgY2xhc3M9XFxcIm1hcmtkb3duXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZGVzY3JpcHRpb24gOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC90ZD5cXG48dGQ+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAucGFyYW1UeXBlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3RkPlxcbjx0ZD5cXG5cdDxzcGFuIGNsYXNzPVxcXCJtb2RlbC1zaWduYXR1cmVcXFwiPjwvc3Bhbj5cXG48L3RkPlxcblwiO1xufSxcInVzZURhdGFcIjp0cnVlfSk7XG50ZW1wbGF0ZXNbJ3BhcmFtX2xpc3QnXSA9IHRlbXBsYXRlKHtcIjFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiByZXF1aXJlZFwiO1xufSxcIjNcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiBtdWx0aXBsZT1cXFwibXVsdGlwbGVcXFwiXCI7XG59LFwiNVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiIHJlcXVpcmVkIFwiO1xufSxcIjdcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuIFwiICAgICAgPG9wdGlvbiBcIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzLnVubGVzcy5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmhhc0RlZmF1bHQgOiBkZXB0aDApLHtcIm5hbWVcIjpcInVubGVzc1wiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSg4LCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCIgdmFsdWU9Jyc+PC9vcHRpb24+XFxuXCI7XG59LFwiOFwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiICBzZWxlY3RlZD1cXFwiXFxcIiBcIjtcbn0sXCIxMFwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiXFxuICAgICAgPG9wdGlvbiBcIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlzRGVmYXVsdCA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMTEsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiAgdmFsdWU9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC52YWx1ZSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInPiBcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsdWUgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiIFwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaXNEZWZhdWx0IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxMywgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiIDwvb3B0aW9uPlxcblxcblwiO1xufSxcIjExXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgc2VsZWN0ZWQ9XFxcIlxcXCIgIFwiO1xufSxcIjEzXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgKGRlZmF1bHQpIFwiO1xufSxcIjE1XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCI8c3Ryb25nPlwiO1xufSxcIjE3XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCI8L3N0cm9uZz5cIjtcbn0sXCJjb21waWxlclwiOls3LFwiPj0gNC4wLjBcIl0sXCJtYWluXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBoZWxwZXIsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIjx0ZCBjbGFzcz0nY29kZVwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAucmVxdWlyZWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIic+PGxhYmVsIGZvcj0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsdWVJZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJz5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2xhYmVsPjwvdGQ+XFxuPHRkPlxcbiAgPHNlbGVjdCBcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5pc0FycmF5IHx8IChkZXB0aDAgJiYgZGVwdGgwLmlzQXJyYXkpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsZGVwdGgwLHtcIm5hbWVcIjpcImlzQXJyYXlcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMywgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiIGNsYXNzPVxcXCJwYXJhbWV0ZXIgXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5yZXF1aXJlZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oNSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIiBuYW1lPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiIGlkPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC52YWx1ZUlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiPlxcblxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnMudW5sZXNzLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5yZXF1aXJlZCA6IGRlcHRoMCkse1wibmFtZVwiOlwidW5sZXNzXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDcsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnMuZWFjaC5jYWxsKGFsaWFzMSwoKHN0YWNrMSA9IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5hbGxvd2FibGVWYWx1ZXMgOiBkZXB0aDApKSAhPSBudWxsID8gc3RhY2sxLmRlc2NyaXB0aXZlVmFsdWVzIDogc3RhY2sxKSx7XCJuYW1lXCI6XCJlYWNoXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEwLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG4gIDwvc2VsZWN0PlxcbjwvdGQ+XFxuPHRkIGNsYXNzPVxcXCJtYXJrZG93blxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5yZXF1aXJlZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMTUsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyAoKHN0YWNrMSA9ICgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMuZGVzY3JpcHRpb24gfHwgKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmRlc2NyaXB0aW9uIDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGFsaWFzMiksKHR5cGVvZiBoZWxwZXIgPT09IFwiZnVuY3Rpb25cIiA/IGhlbHBlci5jYWxsKGFsaWFzMSx7XCJuYW1lXCI6XCJkZXNjcmlwdGlvblwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSA6IGhlbHBlcikpKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5yZXF1aXJlZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMTcsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvdGQ+XFxuPHRkPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnBhcmFtVHlwZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC90ZD5cXG48dGQ+PHNwYW4gY2xhc3M9XFxcIm1vZGVsLXNpZ25hdHVyZVxcXCI+PC9zcGFuPjwvdGQ+XFxuXCI7XG59LFwidXNlRGF0YVwiOnRydWV9KTtcbnRlbXBsYXRlc1sncGFyYW1fcmVhZG9ubHknXSA9IHRlbXBsYXRlKHtcIjFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIiAgICAgICAgPHRleHRhcmVhIGNsYXNzPSdib2R5LXRleHRhcmVhJyByZWFkb25seT0ncmVhZG9ubHknIG5hbWU9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIicgaWQ9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnZhbHVlSWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIic+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwW1wiZGVmYXVsdFwiXSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3RleHRhcmVhPlxcbiAgICAgICAgPGRpdiBjbGFzcz1cXFwicGFyYW1ldGVyLWNvbnRlbnQtdHlwZVxcXCIgLz5cXG5cIjtcbn0sXCIzXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwW1wiZGVmYXVsdFwiXSA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oNCwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLnByb2dyYW0oNiwgZGF0YSwgMCksXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIik7XG59LFwiNFwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gXCIgICAgICAgICAgICBcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwW1wiZGVmYXVsdFwiXSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG5cIjtcbn0sXCI2XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgICAgICAgICAgICAoZW1wdHkpXFxuXCI7XG59LFwiY29tcGlsZXJcIjpbNyxcIj49IDQuMC4wXCJdLFwibWFpblwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiPHRkIGNsYXNzPSdjb2RlJz48bGFiZWwgZm9yPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC52YWx1ZUlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvbGFiZWw+PC90ZD5cXG48dGQ+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pc0JvZHkgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5wcm9ncmFtKDMsIGRhdGEsIDApLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvdGQ+XFxuPHRkIGNsYXNzPVxcXCJtYXJrZG93blxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmRlc2NyaXB0aW9uIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvdGQ+XFxuPHRkPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnBhcmFtVHlwZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC90ZD5cXG48dGQ+PHNwYW4gY2xhc3M9XFxcIm1vZGVsLXNpZ25hdHVyZVxcXCI+PC9zcGFuPjwvdGQ+XFxuXCI7XG59LFwidXNlRGF0YVwiOnRydWV9KTtcbnRlbXBsYXRlc1sncGFyYW1fcmVhZG9ubHlfcmVxdWlyZWQnXSA9IHRlbXBsYXRlKHtcIjFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIiAgICAgICAgPHRleHRhcmVhIGNsYXNzPSdib2R5LXRleHRhcmVhJyByZWFkb25seT0ncmVhZG9ubHknIHBsYWNlaG9sZGVyPScocmVxdWlyZWQpJyBuYW1lPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInIGlkPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC52YWx1ZUlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMFtcImRlZmF1bHRcIl0gOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC90ZXh0YXJlYT5cXG5cIjtcbn0sXCIzXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwW1wiZGVmYXVsdFwiXSA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oNCwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLnByb2dyYW0oNiwgZGF0YSwgMCksXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIik7XG59LFwiNFwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gXCIgICAgICAgICAgICBcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwW1wiZGVmYXVsdFwiXSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG5cIjtcbn0sXCI2XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgICAgICAgICAgICAoZW1wdHkpXFxuXCI7XG59LFwiY29tcGlsZXJcIjpbNyxcIj49IDQuMC4wXCJdLFwibWFpblwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiPHRkIGNsYXNzPSdjb2RlIHJlcXVpcmVkJz48bGFiZWwgZm9yPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC52YWx1ZUlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvbGFiZWw+PC90ZD5cXG48dGQ+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pc0JvZHkgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5wcm9ncmFtKDMsIGRhdGEsIDApLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvdGQ+XFxuPHRkIGNsYXNzPVxcXCJtYXJrZG93blxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmRlc2NyaXB0aW9uIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvdGQ+XFxuPHRkPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnBhcmFtVHlwZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC90ZD5cXG48dGQ+PHNwYW4gY2xhc3M9XFxcIm1vZGVsLXNpZ25hdHVyZVxcXCI+PC9zcGFuPjwvdGQ+XFxuXCI7XG59LFwidXNlRGF0YVwiOnRydWV9KTtcbnRlbXBsYXRlc1sncGFyYW1fcmVxdWlyZWQnXSA9IHRlbXBsYXRlKHtcIjFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaXNGaWxlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgyLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIucHJvZ3JhbSg0LCBkYXRhLCAwKSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKTtcbn0sXCIyXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCJcdFx0XHQ8aW5wdXQgdHlwZT1cXFwiZmlsZVxcXCIgbmFtZT0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJyBpZD0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsdWVJZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJy8+XFxuXCI7XG59LFwiNFwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMFtcImRlZmF1bHRcIl0gOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDUsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5wcm9ncmFtKDcsIGRhdGEsIDApLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpO1xufSxcIjVcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIlx0XHRcdFx0PGRpdiBjbGFzcz1cXFwiZWRpdG9yX2hvbGRlclxcXCI+PC9kaXY+XFxuXHRcdFx0XHQ8dGV4dGFyZWEgY2xhc3M9J2JvZHktdGV4dGFyZWEgcmVxdWlyZWQnIHBsYWNlaG9sZGVyPScocmVxdWlyZWQpJyBuYW1lPSdcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAubmFtZSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInIGlkPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC52YWx1ZUlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMFtcImRlZmF1bHRcIl0gOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC90ZXh0YXJlYT5cXG4gICAgICAgIDxiciAvPlxcbiAgICAgICAgPGRpdiBjbGFzcz1cXFwicGFyYW1ldGVyLWNvbnRlbnQtdHlwZVxcXCIgLz5cXG5cIjtcbn0sXCI3XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCJcdFx0XHRcdDx0ZXh0YXJlYSBjbGFzcz0nYm9keS10ZXh0YXJlYSByZXF1aXJlZCcgcGxhY2Vob2xkZXI9JyhyZXF1aXJlZCknIG5hbWU9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIicgaWQ9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnZhbHVlSWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIic+PC90ZXh0YXJlYT5cXG5cdFx0XHRcdDxkaXYgY2xhc3M9XFxcImVkaXRvcl9ob2xkZXJcXFwiPjwvZGl2Plxcblx0XHRcdFx0PGJyIC8+XFxuXHRcdFx0XHQ8ZGl2IGNsYXNzPVxcXCJwYXJhbWV0ZXItY29udGVudC10eXBlXFxcIiAvPlxcblwiO1xufSxcIjlcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaXNGaWxlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxMCwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLnByb2dyYW0oMTIsIGRhdGEsIDApLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpO1xufSxcIjEwXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCJcdFx0XHQ8aW5wdXQgY2xhc3M9J3BhcmFtZXRlciByZXF1aXJlZCcgdHlwZT0nZmlsZScgbmFtZT0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm5hbWUgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJyBpZD0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsdWVJZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJy8+XFxuXCI7XG59LFwiMTJcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuICgoc3RhY2sxID0gKGhlbHBlcnMucmVuZGVyVGV4dFBhcmFtIHx8IChkZXB0aDAgJiYgZGVwdGgwLnJlbmRlclRleHRQYXJhbSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sZGVwdGgwLHtcIm5hbWVcIjpcInJlbmRlclRleHRQYXJhbVwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxMywgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIik7XG59LFwiMTNcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIlwiO1xufSxcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LCBhbGlhczI9aGVscGVycy5oZWxwZXJNaXNzaW5nO1xuXG4gIHJldHVybiBcIjx0ZCBjbGFzcz0nY29kZSByZXF1aXJlZCc+PGxhYmVsIGZvcj0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAudmFsdWVJZCA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJz5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2xhYmVsPjwvdGQ+XFxuPHRkPlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaXNCb2R5IDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIucHJvZ3JhbSg5LCBkYXRhLCAwKSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3RkPlxcbjx0ZD5cXG5cdDxzdHJvbmc+PHNwYW4gY2xhc3M9XFxcIm1hcmtkb3duXFxcIj5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZGVzY3JpcHRpb24gOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9zcGFuPjwvc3Ryb25nPlxcbjwvdGQ+XFxuPHRkPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnBhcmFtVHlwZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC90ZD5cXG48dGQ+PHNwYW4gY2xhc3M9XFxcIm1vZGVsLXNpZ25hdHVyZVxcXCI+PC9zcGFuPjwvdGQ+XFxuXCI7XG59LFwidXNlRGF0YVwiOnRydWV9KTtcbnRlbXBsYXRlc1sncGFyYW1ldGVyX2NvbnRlbnRfdHlwZSddID0gdGVtcGxhdGUoe1wiMVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gKChzdGFjazEgPSBoZWxwZXJzLmVhY2guY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5jb25zdW1lcyA6IGRlcHRoMCkse1wibmFtZVwiOlwiZWFjaFwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgyLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKTtcbn0sXCIyXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCIgIDxvcHRpb24gdmFsdWU9XFxcIlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLGRlcHRoMCx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCI+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsZGVwdGgwLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9vcHRpb24+XFxuXCI7XG59LFwiNFwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgcmV0dXJuIFwiICA8b3B0aW9uIHZhbHVlPVxcXCJhcHBsaWNhdGlvbi9qc29uXFxcIj5hcHBsaWNhdGlvbi9qc29uPC9vcHRpb24+XFxuXCI7XG59LFwiY29tcGlsZXJcIjpbNyxcIj49IDQuMC4wXCJdLFwibWFpblwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgaGVscGVyLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCI8bGFiZWwgZm9yPVxcXCJcIlxuICAgICsgY29udGFpbmVyLmVzY2FwZUV4cHJlc3Npb24oKChoZWxwZXIgPSAoaGVscGVyID0gaGVscGVycy5wYXJhbWV0ZXJDb250ZW50VHlwZUlkIHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5wYXJhbWV0ZXJDb250ZW50VHlwZUlkIDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGFsaWFzMiksKHR5cGVvZiBoZWxwZXIgPT09IFwiZnVuY3Rpb25cIiA/IGhlbHBlci5jYWxsKGFsaWFzMSx7XCJuYW1lXCI6XCJwYXJhbWV0ZXJDb250ZW50VHlwZUlkXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pIDogaGVscGVyKSkpXG4gICAgKyBcIlxcXCIgZGF0YS1zdy10cmFuc2xhdGU+UGFyYW1ldGVyIGNvbnRlbnQgdHlwZTo8L2xhYmVsPlxcbjxzZWxlY3QgbmFtZT1cXFwicGFyYW1ldGVyQ29udGVudFR5cGVcXFwiIGlkPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAucGFyYW1ldGVyQ29udGVudFR5cGVJZCA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiPlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuY29uc3VtZXMgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5wcm9ncmFtKDQsIGRhdGEsIDApLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvc2VsZWN0PlxcblwiO1xufSxcInVzZURhdGFcIjp0cnVlfSk7XG50ZW1wbGF0ZXNbJ3BvcHVwJ10gPSB0ZW1wbGF0ZSh7XCJjb21waWxlclwiOls3LFwiPj0gNC4wLjBcIl0sXCJtYWluXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgaGVscGVyO1xuXG4gIHJldHVybiBcIjxkaXYgY2xhc3M9XFxcImFwaS1wb3B1cC1kaWFsb2ctd3JhcHBlclxcXCI+XFxuICAgIDxkaXYgY2xhc3M9XFxcImFwaS1wb3B1cC10aXRsZVxcXCI+XCJcbiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKCgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMudGl0bGUgfHwgKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnRpdGxlIDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGhlbHBlcnMuaGVscGVyTWlzc2luZyksKHR5cGVvZiBoZWxwZXIgPT09IFwiZnVuY3Rpb25cIiA/IGhlbHBlci5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30se1wibmFtZVwiOlwidGl0bGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkgOiBoZWxwZXIpKSlcbiAgICArIFwiPC9kaXY+XFxuICAgIDxkaXYgY2xhc3M9XFxcImFwaS1wb3B1cC1jb250ZW50XFxcIj48L2Rpdj5cXG4gICAgPHAgY2xhc3M9XFxcImVycm9yLW1zZ1xcXCI+PC9wPlxcbiAgICA8ZGl2IGNsYXNzPVxcXCJhcGktcG9wdXAtYWN0aW9uc1xcXCI+XFxuICAgICAgICA8YnV0dG9uIGNsYXNzPVxcXCJhcGktcG9wdXAtY2FuY2VsIGFwaS1idXR0b24gZ3JheVxcXCIgdHlwZT1cXFwiYnV0dG9uXFxcIj5DYW5jZWw8L2J1dHRvbj5cXG4gICAgPC9kaXY+XFxuPC9kaXY+XFxuPGRpdiBjbGFzcz1cXFwiYXBpLXBvcHVwLWRpYWxvZy1zaGFkb3dcXFwiPjwvZGl2PlwiO1xufSxcInVzZURhdGFcIjp0cnVlfSk7XG50ZW1wbGF0ZXNbJ3Jlc291cmNlJ10gPSB0ZW1wbGF0ZSh7XCIxXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCIgOiBcIjtcbn0sXCIzXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxO1xuXG4gIHJldHVybiBcIiAgICA8bGk+XFxuICAgICAgPGEgaHJlZj0nXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGhlbHBlcnMuaGVscGVyTWlzc2luZykuY2FsbChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9LChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC51cmwgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJyBkYXRhLXN3LXRyYW5zbGF0ZT5SYXc8L2E+XFxuICAgIDwvbGk+XFxuXCI7XG59LFwiY29tcGlsZXJcIjpbNyxcIj49IDQuMC4wXCJdLFwibWFpblwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgaGVscGVyLCBvcHRpb25zLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZywgYnVmZmVyID0gXG4gIFwiPGRpdiBjbGFzcz0naGVhZGluZyc+XFxuICA8aDI+XFxuICAgIDxhIGhyZWY9JyMhL1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pZCA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCInIGNsYXNzPVxcXCJ0b2dnbGVFbmRwb2ludExpc3RcXFwiIGRhdGEtaWQ9XFxcIlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pZCA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5uYW1lIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvYT4gXCI7XG4gIHN0YWNrMSA9ICgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMuc3VtbWFyeSB8fCAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc3VtbWFyeSA6IGRlcHRoMCkpICE9IG51bGwgPyBoZWxwZXIgOiBhbGlhczIpLChvcHRpb25zPXtcIm5hbWVcIjpcInN1bW1hcnlcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMSwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pLCh0eXBlb2YgaGVscGVyID09PSBcImZ1bmN0aW9uXCIgPyBoZWxwZXIuY2FsbChhbGlhczEsb3B0aW9ucykgOiBoZWxwZXIpKTtcbiAgaWYgKCFoZWxwZXJzLnN1bW1hcnkpIHsgc3RhY2sxID0gaGVscGVycy5ibG9ja0hlbHBlck1pc3NpbmcuY2FsbChkZXB0aDAsc3RhY2sxLG9wdGlvbnMpfVxuICBpZiAoc3RhY2sxICE9IG51bGwpIHsgYnVmZmVyICs9IHN0YWNrMTsgfVxuICByZXR1cm4gYnVmZmVyICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc3VtbWFyeSA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG4gIDwvaDI+XFxuICA8dWwgY2xhc3M9J29wdGlvbnMnPlxcbiAgICA8bGk+XFxuICAgICAgPGEgaHJlZj0nIyEvXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIicgaWQ9J2VuZHBvaW50TGlzdFRvZ2dlcl9cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiJyBjbGFzcz1cXFwidG9nZ2xlRW5kcG9pbnRMaXN0XFxcIiBkYXRhLWlkPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuaWQgOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT5TaG93L0hpZGU8L2E+XFxuICAgIDwvbGk+XFxuICAgIDxsaT5cXG4gICAgICA8YSBocmVmPScjJyBjbGFzcz1cXFwiY29sbGFwc2VSZXNvdXJjZVxcXCIgZGF0YS1pZD1cXFwiXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuc2FuaXRpemUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuc2FuaXRpemUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLmlkIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIlxcXCIgZGF0YS1zdy10cmFuc2xhdGU+XFxuICAgICAgICBMaXN0IE9wZXJhdGlvbnNcXG4gICAgICA8L2E+XFxuICAgIDwvbGk+XFxuICAgIDxsaT5cXG4gICAgICA8YSBocmVmPScjJyBjbGFzcz1cXFwiZXhwYW5kUmVzb3VyY2VcXFwiIGRhdGEtaWQ9XFxcIlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pZCA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiIGRhdGEtc3ctdHJhbnNsYXRlPlxcbiAgICAgICAgRXhwYW5kIE9wZXJhdGlvbnNcXG4gICAgICA8L2E+XFxuICAgIDwvbGk+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC51cmwgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDMsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiAgPC91bD5cXG48L2Rpdj5cXG48dWwgY2xhc3M9J2VuZHBvaW50cycgaWQ9J1wiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pZCA6IGRlcHRoMCkse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJfZW5kcG9pbnRfbGlzdCcgc3R5bGU9J2Rpc3BsYXk6bm9uZSc+XFxuXFxuPC91bD5cXG5cIjtcbn0sXCJ1c2VEYXRhXCI6dHJ1ZX0pO1xudGVtcGxhdGVzWydyZXNwb25zZV9jb250ZW50X3R5cGUnXSA9IHRlbXBsYXRlKHtcIjFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazE7XG5cbiAgcmV0dXJuICgoc3RhY2sxID0gaGVscGVycy5lYWNoLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAucHJvZHVjZXMgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVhY2hcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMiwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIik7XG59LFwiMlwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiICA8b3B0aW9uIHZhbHVlPVxcXCJcIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSxkZXB0aDAse1wibmFtZVwiOlwic2FuaXRpemVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLnNhbml0aXplIHx8IChkZXB0aDAgJiYgZGVwdGgwLnNhbml0aXplKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLGRlcHRoMCx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvb3B0aW9uPlxcblwiO1xufSxcIjRcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHJldHVybiBcIiAgPG9wdGlvbiB2YWx1ZT1cXFwiYXBwbGljYXRpb24vanNvblxcXCI+YXBwbGljYXRpb24vanNvbjwvb3B0aW9uPlxcblwiO1xufSxcImNvbXBpbGVyXCI6WzcsXCI+PSA0LjAuMFwiXSxcIm1haW5cIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGhlbHBlciwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3NpbmcsIGFsaWFzMz1cImZ1bmN0aW9uXCIsIGFsaWFzND1jb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbjtcblxuICByZXR1cm4gXCI8bGFiZWwgZGF0YS1zdy10cmFuc2xhdGUgZm9yPVxcXCJcIlxuICAgICsgYWxpYXM0KCgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMucmVzcG9uc2VDb250ZW50VHlwZUlkIHx8IChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5yZXNwb25zZUNvbnRlbnRUeXBlSWQgOiBkZXB0aDApKSAhPSBudWxsID8gaGVscGVyIDogYWxpYXMyKSwodHlwZW9mIGhlbHBlciA9PT0gYWxpYXMzID8gaGVscGVyLmNhbGwoYWxpYXMxLHtcIm5hbWVcIjpcInJlc3BvbnNlQ29udGVudFR5cGVJZFwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSA6IGhlbHBlcikpKVxuICAgICsgXCJcXFwiPlJlc3BvbnNlIENvbnRlbnQgVHlwZTwvbGFiZWw+XFxuPHNlbGVjdCBuYW1lPVxcXCJyZXNwb25zZUNvbnRlbnRUeXBlXFxcIiBpZD1cXFwiXCJcbiAgICArIGFsaWFzNCgoKGhlbHBlciA9IChoZWxwZXIgPSBoZWxwZXJzLnJlc3BvbnNlQ29udGVudFR5cGVJZCB8fCAoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAucmVzcG9uc2VDb250ZW50VHlwZUlkIDogZGVwdGgwKSkgIT0gbnVsbCA/IGhlbHBlciA6IGFsaWFzMiksKHR5cGVvZiBoZWxwZXIgPT09IGFsaWFzMyA/IGhlbHBlci5jYWxsKGFsaWFzMSx7XCJuYW1lXCI6XCJyZXNwb25zZUNvbnRlbnRUeXBlSWRcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkgOiBoZWxwZXIpKSlcbiAgICArIFwiXFxcIj5cXG5cIlxuICAgICsgKChzdGFjazEgPSBoZWxwZXJzW1wiaWZcIl0uY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnByb2R1Y2VzIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIucHJvZ3JhbSg0LCBkYXRhLCAwKSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3NlbGVjdD5cXG5cIjtcbn0sXCJ1c2VEYXRhXCI6dHJ1ZX0pO1xudGVtcGxhdGVzWydzaWduYXR1cmUnXSA9IHRlbXBsYXRlKHtcIjFcIjpmdW5jdGlvbihjb250YWluZXIsZGVwdGgwLGhlbHBlcnMscGFydGlhbHMsZGF0YSkge1xuICAgIHZhciBzdGFjazEsIGFsaWFzMT1kZXB0aDAgIT0gbnVsbCA/IGRlcHRoMCA6IHt9O1xuXG4gIHJldHVybiBcIlxcbjxkaXY+XFxuPHVsIGNsYXNzPVxcXCJzaWduYXR1cmUtbmF2XFxcIj5cXG4gIDxsaT48YSBjbGFzcz1cXFwiZGVzY3JpcHRpb24tbGlua1xcXCIgaHJlZj1cXFwiI1xcXCIgZGF0YS1zdy10cmFuc2xhdGU+TW9kZWw8L2E+PC9saT5cXG4gIDxsaT48YSBjbGFzcz1cXFwic25pcHBldC1saW5rXFxcIiBocmVmPVxcXCIjXFxcIiBkYXRhLXN3LXRyYW5zbGF0ZT5FeGFtcGxlIFZhbHVlPC9hPjwvbGk+XFxuPC91bD5cXG48ZGl2PlxcblxcbjxkaXYgY2xhc3M9XFxcInNpZ25hdHVyZS1jb250YWluZXJcXFwiPlxcbiAgPGRpdiBjbGFzcz1cXFwiZGVzY3JpcHRpb25cXFwiPlxcbiAgICAgIFwiXG4gICAgKyBjb250YWluZXIuZXNjYXBlRXhwcmVzc2lvbigoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc2lnbmF0dXJlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJzYW5pdGl6ZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSlcbiAgICArIFwiXFxuICA8L2Rpdj5cXG5cXG4gIDxkaXYgY2xhc3M9XFxcInNuaXBwZXRcXFwiPlxcblwiXG4gICAgKyAoKHN0YWNrMSA9IGhlbHBlcnNbXCJpZlwiXS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc2FtcGxlSlNPTiA6IGRlcHRoMCkse1wibmFtZVwiOlwiaWZcIixcImhhc2hcIjp7fSxcImZuXCI6Y29udGFpbmVyLnByb2dyYW0oMiwgZGF0YSwgMCksXCJpbnZlcnNlXCI6Y29udGFpbmVyLm5vb3AsXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zYW1wbGVYTUwgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDUsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiAgPC9kaXY+XFxuPC9kaXY+XFxuXCI7XG59LFwiMlwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge307XG5cbiAgcmV0dXJuIFwiICAgICAgPGRpdiBjbGFzcz1cXFwic25pcHBldF9qc29uXFxcIj5cXG4gICAgICAgIDxwcmU+PGNvZGU+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc2FtcGxlSlNPTiA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC9jb2RlPjwvcHJlPlxcbiAgICAgICAgXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pc1BhcmFtIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgzLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG4gICAgICA8L2Rpdj5cXG5cIjtcbn0sXCIzXCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICByZXR1cm4gXCI8c21hbGwgY2xhc3M9XFxcIm5vdGljZVxcXCIgZGF0YS1zdy10cmFuc2xhdGU+PC9zbWFsbD5cIjtcbn0sXCI1XCI6ZnVuY3Rpb24oY29udGFpbmVyLGRlcHRoMCxoZWxwZXJzLHBhcnRpYWxzLGRhdGEpIHtcbiAgICB2YXIgc3RhY2sxLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fTtcblxuICByZXR1cm4gXCIgICAgPGRpdiBjbGFzcz1cXFwic25pcHBldF94bWxcXFwiPlxcbiAgICAgIDxwcmU+PGNvZGU+XCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc2FtcGxlWE1MIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L2NvZGU+PC9wcmU+XFxuICAgICAgXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVyc1tcImlmXCJdLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5pc1BhcmFtIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJpZlwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgzLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIubm9vcCxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCJcXG4gICAgPC9kaXY+XFxuXCI7XG59LFwiN1wiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gXCIgICAgXCJcbiAgICArICgoc3RhY2sxID0gKGhlbHBlcnMuZXNjYXBlIHx8IChkZXB0aDAgJiYgZGVwdGgwLmVzY2FwZSkgfHwgaGVscGVycy5oZWxwZXJNaXNzaW5nKS5jYWxsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLnNpZ25hdHVyZSA6IGRlcHRoMCkse1wibmFtZVwiOlwiZXNjYXBlXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiXFxuXCI7XG59LFwiY29tcGlsZXJcIjpbNyxcIj49IDQuMC4wXCJdLFwibWFpblwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMTtcblxuICByZXR1cm4gKChzdGFjazEgPSAoaGVscGVycy5pZkNvbmQgfHwgKGRlcHRoMCAmJiBkZXB0aDAuaWZDb25kKSB8fCBoZWxwZXJzLmhlbHBlck1pc3NpbmcpLmNhbGwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuc2FtcGxlSlNPTiA6IGRlcHRoMCksXCJ8fFwiLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5zYW1wbGVYTUwgOiBkZXB0aDApLHtcIm5hbWVcIjpcImlmQ29uZFwiLFwiaGFzaFwiOnt9LFwiZm5cIjpjb250YWluZXIucHJvZ3JhbSgxLCBkYXRhLCAwKSxcImludmVyc2VcIjpjb250YWluZXIucHJvZ3JhbSg3LCBkYXRhLCAwKSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKTtcbn0sXCJ1c2VEYXRhXCI6dHJ1ZX0pO1xudGVtcGxhdGVzWydzdGF0dXNfY29kZSddID0gdGVtcGxhdGUoe1wiMVwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgaGVscGVyLCBhbGlhczE9ZGVwdGgwICE9IG51bGwgPyBkZXB0aDAgOiB7fSwgYWxpYXMyPWhlbHBlcnMuaGVscGVyTWlzc2luZztcblxuICByZXR1cm4gXCIgICAgICA8dHI+XFxuICAgICAgICA8dGQ+XCJcbiAgICArIGNvbnRhaW5lci5lc2NhcGVFeHByZXNzaW9uKCgoaGVscGVyID0gKGhlbHBlciA9IGhlbHBlcnMua2V5IHx8IChkYXRhICYmIGRhdGEua2V5KSkgIT0gbnVsbCA/IGhlbHBlciA6IGFsaWFzMiksKHR5cGVvZiBoZWxwZXIgPT09IFwiZnVuY3Rpb25cIiA/IGhlbHBlci5jYWxsKGFsaWFzMSx7XCJuYW1lXCI6XCJrZXlcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkgOiBoZWxwZXIpKSlcbiAgICArIFwiPC90ZD5cXG4gICAgICAgIDx0ZD5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5zYW5pdGl6ZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5zYW5pdGl6ZSkgfHwgYWxpYXMyKS5jYWxsKGFsaWFzMSwoZGVwdGgwICE9IG51bGwgPyBkZXB0aDAuZGVzY3JpcHRpb24gOiBkZXB0aDApLHtcIm5hbWVcIjpcInNhbml0aXplXCIsXCJoYXNoXCI6e30sXCJkYXRhXCI6ZGF0YX0pKSAhPSBudWxsID8gc3RhY2sxIDogXCJcIilcbiAgICArIFwiPC90ZD5cXG4gICAgICAgIDx0ZD5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC50eXBlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3RkPlxcbiAgICAgIDwvdHI+XFxuXCI7XG59LFwiY29tcGlsZXJcIjpbNyxcIj49IDQuMC4wXCJdLFwibWFpblwiOmZ1bmN0aW9uKGNvbnRhaW5lcixkZXB0aDAsaGVscGVycyxwYXJ0aWFscyxkYXRhKSB7XG4gICAgdmFyIHN0YWNrMSwgYWxpYXMxPWRlcHRoMCAhPSBudWxsID8gZGVwdGgwIDoge30sIGFsaWFzMj1oZWxwZXJzLmhlbHBlck1pc3Npbmc7XG5cbiAgcmV0dXJuIFwiPHRkIHdpZHRoPScxNSUnIGNsYXNzPSdjb2RlJz5cIlxuICAgICsgKChzdGFjazEgPSAoaGVscGVycy5lc2NhcGUgfHwgKGRlcHRoMCAmJiBkZXB0aDAuZXNjYXBlKSB8fCBhbGlhczIpLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5jb2RlIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlc2NhcGVcIixcImhhc2hcIjp7fSxcImRhdGFcIjpkYXRhfSkpICE9IG51bGwgPyBzdGFjazEgOiBcIlwiKVxuICAgICsgXCI8L3RkPlxcbjx0ZCBjbGFzcz1cXFwibWFya2Rvd25cXFwiPlwiXG4gICAgKyAoKHN0YWNrMSA9IChoZWxwZXJzLmVzY2FwZSB8fCAoZGVwdGgwICYmIGRlcHRoMC5lc2NhcGUpIHx8IGFsaWFzMikuY2FsbChhbGlhczEsKGRlcHRoMCAhPSBudWxsID8gZGVwdGgwLm1lc3NhZ2UgOiBkZXB0aDApLHtcIm5hbWVcIjpcImVzY2FwZVwiLFwiaGFzaFwiOnt9LFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIjwvdGQ+XFxuPHRkIHdpZHRoPSc1MCUnPjxzcGFuIGNsYXNzPVxcXCJtb2RlbC1zaWduYXR1cmVcXFwiIC8+PC90ZD5cXG48dGQgY2xhc3M9XFxcImhlYWRlcnNcXFwiPlxcbiAgPHRhYmxlPlxcbiAgICA8dGJvZHk+XFxuXCJcbiAgICArICgoc3RhY2sxID0gaGVscGVycy5lYWNoLmNhbGwoYWxpYXMxLChkZXB0aDAgIT0gbnVsbCA/IGRlcHRoMC5oZWFkZXJzIDogZGVwdGgwKSx7XCJuYW1lXCI6XCJlYWNoXCIsXCJoYXNoXCI6e30sXCJmblwiOmNvbnRhaW5lci5wcm9ncmFtKDEsIGRhdGEsIDApLFwiaW52ZXJzZVwiOmNvbnRhaW5lci5ub29wLFwiZGF0YVwiOmRhdGF9KSkgIT0gbnVsbCA/IHN0YWNrMSA6IFwiXCIpXG4gICAgKyBcIiAgICA8L3Rib2R5PlxcbiAgPC90YWJsZT5cXG48L3RkPlwiO1xufSxcInVzZURhdGFcIjp0cnVlfSk7XG59KSgpO30gXG4gLyoganNoaW50IGlnbm9yZTplbmQgKi8iLCIndXNlIHN0cmljdCc7XG5cblxuJChmdW5jdGlvbigpIHtcblxuXHQvLyBIZWxwZXIgZnVuY3Rpb24gZm9yIHZlcnRpY2FsbHkgYWxpZ25pbmcgRE9NIGVsZW1lbnRzXG5cdC8vIGh0dHA6Ly93d3cuc2VvZGVudmVyLmNvbS9zaW1wbGUtdmVydGljYWwtYWxpZ24tcGx1Z2luLWZvci1qcXVlcnkvXG5cdCQuZm4udkFsaWduID0gZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpe1xuXHRcdFx0dmFyIGFoID0gJCh0aGlzKS5oZWlnaHQoKTtcblx0XHRcdHZhciBwaCA9ICQodGhpcykucGFyZW50KCkuaGVpZ2h0KCk7XG5cdFx0XHR2YXIgbWggPSAocGggLSBhaCkgLyAyO1xuXHRcdFx0JCh0aGlzKS5jc3MoJ21hcmdpbi10b3AnLCBtaCk7XG5cdFx0fSk7XG5cdH07XG5cblx0JC5mbi5zdHJldGNoRm9ybXRhc3RpY0lucHV0V2lkdGhUb1BhcmVudCA9IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKXtcblx0XHRcdHZhciBwX3dpZHRoID0gJCh0aGlzKS5jbG9zZXN0KFwiZm9ybVwiKS5pbm5lcldpZHRoKCk7XG5cdFx0XHR2YXIgcF9wYWRkaW5nID0gcGFyc2VJbnQoJCh0aGlzKS5jbG9zZXN0KFwiZm9ybVwiKS5jc3MoJ3BhZGRpbmctbGVmdCcpICwxMCkgKyBwYXJzZUludCgkKHRoaXMpLmNsb3Nlc3QoJ2Zvcm0nKS5jc3MoJ3BhZGRpbmctcmlnaHQnKSwgMTApO1xuXHRcdFx0dmFyIHRoaXNfcGFkZGluZyA9IHBhcnNlSW50KCQodGhpcykuY3NzKCdwYWRkaW5nLWxlZnQnKSwgMTApICsgcGFyc2VJbnQoJCh0aGlzKS5jc3MoJ3BhZGRpbmctcmlnaHQnKSwgMTApO1xuXHRcdFx0JCh0aGlzKS5jc3MoJ3dpZHRoJywgcF93aWR0aCAtIHBfcGFkZGluZyAtIHRoaXNfcGFkZGluZyk7XG5cdFx0fSk7XG5cdH07XG5cblx0JCgnZm9ybS5mb3JtdGFzdGljIGxpLnN0cmluZyBpbnB1dCwgZm9ybS5mb3JtdGFzdGljIHRleHRhcmVhJykuc3RyZXRjaEZvcm10YXN0aWNJbnB1dFdpZHRoVG9QYXJlbnQoKTtcblxuXHQvLyBWZXJ0aWNhbGx5IGNlbnRlciB0aGVzZSBwYXJhZ3JhcGhzXG5cdC8vIFBhcmVudCBtYXkgbmVlZCBhIG1pbi1oZWlnaHQgZm9yIHRoaXMgdG8gd29yay4uXG5cdCQoJ3VsLmRvd25wbGF5ZWQgbGkgZGl2LmNvbnRlbnQgcCcpLnZBbGlnbigpO1xuXG5cdC8vIFdoZW4gYSBzYW5kYm94IGZvcm0gaXMgc3VibWl0dGVkLi5cblx0JChcImZvcm0uc2FuZGJveFwiKS5zdWJtaXQoZnVuY3Rpb24oKXtcblxuXHRcdHZhciBlcnJvcl9mcmVlID0gdHJ1ZTtcblxuXHRcdC8vIEN5Y2xlIHRocm91Z2ggdGhlIGZvcm1zIHJlcXVpcmVkIGlucHV0c1xuIFx0XHQkKHRoaXMpLmZpbmQoXCJpbnB1dC5yZXF1aXJlZFwiKS5lYWNoKGZ1bmN0aW9uKCkge1xuXG5cdFx0XHQvLyBSZW1vdmUgYW55IGV4aXN0aW5nIGVycm9yIHN0eWxlcyBmcm9tIHRoZSBpbnB1dFxuXHRcdFx0JCh0aGlzKS5yZW1vdmVDbGFzcygnZXJyb3InKTtcblxuXHRcdFx0Ly8gVGFjayB0aGUgZXJyb3Igc3R5bGUgb24gaWYgdGhlIGlucHV0IGlzIGVtcHR5Li5cblx0XHRcdGlmICgkKHRoaXMpLnZhbCgpID09PSAnJykge1xuXHRcdFx0XHQkKHRoaXMpLmFkZENsYXNzKCdlcnJvcicpO1xuXHRcdFx0XHQkKHRoaXMpLndpZ2dsZSgpO1xuXHRcdFx0XHRlcnJvcl9mcmVlID0gZmFsc2U7XG5cdFx0XHR9XG5cblx0XHR9KTtcblxuXHRcdHJldHVybiBlcnJvcl9mcmVlO1xuXHR9KTtcblxufSk7XG5cbmZ1bmN0aW9uIGNsaXBweUNvcGllZENhbGxiYWNrKCkge1xuICAkKCcjYXBpX2tleV9jb3BpZWQnKS5mYWRlSW4oKS5kZWxheSgxMDAwKS5mYWRlT3V0KCk7XG5cbiAgLy8gdmFyIGIgPSAkKFwiI2NsaXBweV90b29sdGlwX1wiICsgYSk7XG4gIC8vIGIubGVuZ3RoICE9IDAgJiYgKGIuYXR0cihcInRpdGxlXCIsIFwiY29waWVkIVwiKS50cmlnZ2VyKFwidGlwc3kucmVsb2FkXCIpLCBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAvLyAgIGIuYXR0cihcInRpdGxlXCIsIFwiY29weSB0byBjbGlwYm9hcmRcIilcbiAgLy8gfSxcbiAgLy8gNTAwKSlcbn1cblxuLy8gTG9nZ2luZyBmdW5jdGlvbiB0aGF0IGFjY291bnRzIGZvciBicm93c2VycyB0aGF0IGRvbid0IGhhdmUgd2luZG93LmNvbnNvbGVcbmZ1bmN0aW9uIGxvZygpe1xuICBsb2cuaGlzdG9yeSA9IGxvZy5oaXN0b3J5IHx8IFtdO1xuICBsb2cuaGlzdG9yeS5wdXNoKGFyZ3VtZW50cyk7XG4gIGlmKHRoaXMuY29uc29sZSl7XG4gICAgY29uc29sZS5sb2coIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cylbMF0gKTtcbiAgfVxufVxuXG4vLyBIYW5kbGUgYnJvd3NlcnMgdGhhdCBkbyBjb25zb2xlIGluY29ycmVjdGx5IChJRTkgYW5kIGJlbG93LCBzZWUgaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvNTUzOTM3OC83OTEzKVxuaWYgKEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kICYmIGNvbnNvbGUgJiYgdHlwZW9mIGNvbnNvbGUubG9nID09PSBcIm9iamVjdFwiKSB7XG4gICAgW1xuICAgICAgXCJsb2dcIixcImluZm9cIixcIndhcm5cIixcImVycm9yXCIsXCJhc3NlcnRcIixcImRpclwiLFwiY2xlYXJcIixcInByb2ZpbGVcIixcInByb2ZpbGVFbmRcIlxuICAgIF0uZm9yRWFjaChmdW5jdGlvbiAobWV0aG9kKSB7XG4gICAgICAgIGNvbnNvbGVbbWV0aG9kXSA9IHRoaXMuYmluZChjb25zb2xlW21ldGhvZF0sIGNvbnNvbGUpO1xuICAgIH0sIEZ1bmN0aW9uLnByb3RvdHlwZS5jYWxsKTtcbn1cblxud2luZG93LkRvY3MgPSB7XG5cblx0c2hlYmFuZzogZnVuY3Rpb24oKSB7XG5cblx0XHQvLyBJZiBzaGViYW5nIGhhcyBhbiBvcGVyYXRpb24gbmlja25hbWUgaW4gaXQuLlxuXHRcdC8vIGUuZy4gL2RvY3MvIyEvd29yZHMvZ2V0X3NlYXJjaFxuXHRcdHZhciBmcmFnbWVudHMgPSAkLnBhcmFtLmZyYWdtZW50KCkuc3BsaXQoJy8nKTtcblx0XHRmcmFnbWVudHMuc2hpZnQoKTsgLy8gZ2V0IHJpZCBvZiB0aGUgYmFuZ1xuXG5cdFx0c3dpdGNoIChmcmFnbWVudHMubGVuZ3RoKSB7XG5cdFx0XHRjYXNlIDE6XG4gICAgICAgIGlmIChmcmFnbWVudHNbMF0ubGVuZ3RoID4gMCkgeyAvLyBwcmV2ZW50IG1hdGNoaW5nIFwiIy9cIlxuICAgICAgICAgIC8vIEV4cGFuZCBhbGwgb3BlcmF0aW9ucyBmb3IgdGhlIHJlc291cmNlIGFuZCBzY3JvbGwgdG8gaXRcbiAgICAgICAgICB2YXIgZG9tX2lkID0gJ3Jlc291cmNlXycgKyBmcmFnbWVudHNbMF07XG5cbiAgICAgICAgICBEb2NzLmV4cGFuZEVuZHBvaW50TGlzdEZvclJlc291cmNlKGZyYWdtZW50c1swXSk7XG4gICAgICAgICAgJChcIiNcIitkb21faWQpLnNsaWRldG8oe2hpZ2hsaWdodDogZmFsc2V9KTtcbiAgICAgICAgfVxuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgMjpcblx0XHRcdFx0Ly8gUmVmZXIgdG8gdGhlIGVuZHBvaW50IERPTSBlbGVtZW50LCBlLmcuICN3b3Jkc19nZXRfc2VhcmNoXG5cbiAgICAgICAgLy8gRXhwYW5kIFJlc291cmNlXG4gICAgICAgIERvY3MuZXhwYW5kRW5kcG9pbnRMaXN0Rm9yUmVzb3VyY2UoZnJhZ21lbnRzWzBdKTtcbiAgICAgICAgJChcIiNcIitkb21faWQpLnNsaWRldG8oe2hpZ2hsaWdodDogZmFsc2V9KTtcblxuICAgICAgICAgICAgLy8gRXhwYW5kIG9wZXJhdGlvblxuICAgICAgICAgICAgdmFyIGxpX2RvbV9pZCA9IGZyYWdtZW50cy5qb2luKCdfJyk7XG4gICAgICAgICAgICB2YXIgbGlfY29udGVudF9kb21faWQgPSBsaV9kb21faWQgKyBcIl9jb250ZW50XCI7XG5cblxuICAgICAgICAgICAgRG9jcy5leHBhbmRPcGVyYXRpb24oJCgnIycrbGlfY29udGVudF9kb21faWQpKTtcbiAgICAgICAgICAgICQoJyMnK2xpX2RvbV9pZCkuc2xpZGV0byh7aGlnaGxpZ2h0OiBmYWxzZX0pO1xuICAgICAgICAgICAgYnJlYWs7XG5cdFx0fVxuXHR9LFxuXG5cdHRvZ2dsZUVuZHBvaW50TGlzdEZvclJlc291cmNlOiBmdW5jdGlvbihyZXNvdXJjZSkge1xuXHRcdHZhciBlbGVtID0gJCgnbGkjcmVzb3VyY2VfJyArIERvY3MuZXNjYXBlUmVzb3VyY2VOYW1lKHJlc291cmNlKSArICcgdWwuZW5kcG9pbnRzJyk7XG5cdFx0aWYgKGVsZW0uaXMoJzp2aXNpYmxlJykpIHtcblx0XHRcdCQuYmJxLnB1c2hTdGF0ZSgnIy8nLCAyKTtcblx0XHRcdERvY3MuY29sbGFwc2VFbmRwb2ludExpc3RGb3JSZXNvdXJjZShyZXNvdXJjZSk7XG5cdFx0fSBlbHNlIHtcbiAgICAgICAgICAgICQuYmJxLnB1c2hTdGF0ZSgnIy8nICsgcmVzb3VyY2UsIDIpO1xuXHRcdFx0RG9jcy5leHBhbmRFbmRwb2ludExpc3RGb3JSZXNvdXJjZShyZXNvdXJjZSk7XG5cdFx0fVxuXHR9LFxuXG5cdC8vIEV4cGFuZCByZXNvdXJjZVxuXHRleHBhbmRFbmRwb2ludExpc3RGb3JSZXNvdXJjZTogZnVuY3Rpb24ocmVzb3VyY2UpIHtcblx0XHR2YXIgcmVzb3VyY2UgPSBEb2NzLmVzY2FwZVJlc291cmNlTmFtZShyZXNvdXJjZSk7XG5cdFx0aWYgKHJlc291cmNlID09ICcnKSB7XG5cdFx0XHQkKCcucmVzb3VyY2UgdWwuZW5kcG9pbnRzJykuc2xpZGVEb3duKCk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0JCgnbGkjcmVzb3VyY2VfJyArIHJlc291cmNlKS5hZGRDbGFzcygnYWN0aXZlJyk7XG5cblx0XHR2YXIgZWxlbSA9ICQoJ2xpI3Jlc291cmNlXycgKyByZXNvdXJjZSArICcgdWwuZW5kcG9pbnRzJyk7XG5cdFx0ZWxlbS5zbGlkZURvd24oKTtcblx0fSxcblxuXHQvLyBDb2xsYXBzZSByZXNvdXJjZSBhbmQgbWFyayBhcyBleHBsaWNpdGx5IGNsb3NlZFxuXHRjb2xsYXBzZUVuZHBvaW50TGlzdEZvclJlc291cmNlOiBmdW5jdGlvbihyZXNvdXJjZSkge1xuXHRcdHZhciByZXNvdXJjZSA9IERvY3MuZXNjYXBlUmVzb3VyY2VOYW1lKHJlc291cmNlKTtcblx0XHRpZiAocmVzb3VyY2UgPT0gJycpIHtcblx0XHRcdCQoJy5yZXNvdXJjZSB1bC5lbmRwb2ludHMnKS5zbGlkZVVwKCk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0JCgnbGkjcmVzb3VyY2VfJyArIHJlc291cmNlKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG5cblx0XHR2YXIgZWxlbSA9ICQoJ2xpI3Jlc291cmNlXycgKyByZXNvdXJjZSArICcgdWwuZW5kcG9pbnRzJyk7XG5cdFx0ZWxlbS5zbGlkZVVwKCk7XG5cdH0sXG5cblx0ZXhwYW5kT3BlcmF0aW9uc0ZvclJlc291cmNlOiBmdW5jdGlvbihyZXNvdXJjZSkge1xuXHRcdC8vIE1ha2Ugc3VyZSB0aGUgcmVzb3VyY2UgY29udGFpbmVyIGlzIG9wZW4uLlxuXHRcdERvY3MuZXhwYW5kRW5kcG9pbnRMaXN0Rm9yUmVzb3VyY2UocmVzb3VyY2UpO1xuXG5cdFx0aWYgKHJlc291cmNlID09ICcnKSB7XG5cdFx0XHQkKCcucmVzb3VyY2UgdWwuZW5kcG9pbnRzIGxpLm9wZXJhdGlvbiBkaXYuY29udGVudCcpLnNsaWRlRG93bigpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdCQoJ2xpI3Jlc291cmNlXycgKyBEb2NzLmVzY2FwZVJlc291cmNlTmFtZShyZXNvdXJjZSkgKyAnIGxpLm9wZXJhdGlvbiBkaXYuY29udGVudCcpLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHREb2NzLmV4cGFuZE9wZXJhdGlvbigkKHRoaXMpKTtcblx0XHR9KTtcblx0fSxcblxuXHRjb2xsYXBzZU9wZXJhdGlvbnNGb3JSZXNvdXJjZTogZnVuY3Rpb24ocmVzb3VyY2UpIHtcblx0XHQvLyBNYWtlIHN1cmUgdGhlIHJlc291cmNlIGNvbnRhaW5lciBpcyBvcGVuLi5cblx0XHREb2NzLmV4cGFuZEVuZHBvaW50TGlzdEZvclJlc291cmNlKHJlc291cmNlKTtcblxuXHRcdGlmIChyZXNvdXJjZSA9PSAnJykge1xuXHRcdFx0JCgnLnJlc291cmNlIHVsLmVuZHBvaW50cyBsaS5vcGVyYXRpb24gZGl2LmNvbnRlbnQnKS5zbGlkZVVwKCk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0JCgnbGkjcmVzb3VyY2VfJyArIERvY3MuZXNjYXBlUmVzb3VyY2VOYW1lKHJlc291cmNlKSArICcgbGkub3BlcmF0aW9uIGRpdi5jb250ZW50JykuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdERvY3MuY29sbGFwc2VPcGVyYXRpb24oJCh0aGlzKSk7XG5cdFx0fSk7XG5cdH0sXG5cblx0ZXNjYXBlUmVzb3VyY2VOYW1lOiBmdW5jdGlvbihyZXNvdXJjZSkge1xuXHRcdHJldHVybiByZXNvdXJjZS5yZXBsYWNlKC9bIVwiIyQlJicoKSorLC5cXC86Ozw9Pj9AXFxbXFxcXFxcXVxcXmB7fH1+XS9nLCBcIlxcXFwkJlwiKTtcblx0fSxcblxuXHRleHBhbmRPcGVyYXRpb246IGZ1bmN0aW9uKGVsZW0pIHtcblx0XHRlbGVtLnNsaWRlRG93bigpO1xuXHR9LFxuXG5cdGNvbGxhcHNlT3BlcmF0aW9uOiBmdW5jdGlvbihlbGVtKSB7XG5cdFx0ZWxlbS5zbGlkZVVwKCk7XG5cdH1cbn07XG4iLCIvKiFcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9lcy1zaGltcy9lczUtc2hpbVxuICogQGxpY2Vuc2UgZXM1LXNoaW0gQ29weXJpZ2h0IDIwMDktMjAxNSBieSBjb250cmlidXRvcnMsIE1JVCBMaWNlbnNlXG4gKiBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2VzLXNoaW1zL2VzNS1zaGltL2Jsb2IvbWFzdGVyL0xJQ0VOU0VcbiAqL1xuXG4vLyB2aW06IHRzPTQgc3RzPTQgc3c9NCBleHBhbmR0YWJcblxuLy8gQWRkIHNlbWljb2xvbiB0byBwcmV2ZW50IElJRkUgZnJvbSBiZWluZyBwYXNzZWQgYXMgYXJndW1lbnQgdG8gY29uY2F0ZW5hdGVkIGNvZGUuXG47XG5cbi8vIFVNRCAoVW5pdmVyc2FsIE1vZHVsZSBEZWZpbml0aW9uKVxuLy8gc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS91bWRqcy91bWQvYmxvYi9tYXN0ZXIvdGVtcGxhdGVzL3JldHVybkV4cG9ydHMuanNcbihmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSkge1xuICAgICd1c2Ugc3RyaWN0JztcblxuICAgIC8qIGdsb2JhbCBkZWZpbmUsIGV4cG9ydHMsIG1vZHVsZSAqL1xuICAgIGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpIHtcbiAgICAgICAgLy8gQU1ELiBSZWdpc3RlciBhcyBhbiBhbm9ueW1vdXMgbW9kdWxlLlxuICAgICAgICBkZWZpbmUoZmFjdG9yeSk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgLy8gTm9kZS4gRG9lcyBub3Qgd29yayB3aXRoIHN0cmljdCBDb21tb25KUywgYnV0XG4gICAgICAgIC8vIG9ubHkgQ29tbW9uSlMtbGlrZSBlbnZpcm9tZW50cyB0aGF0IHN1cHBvcnQgbW9kdWxlLmV4cG9ydHMsXG4gICAgICAgIC8vIGxpa2UgTm9kZS5cbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQnJvd3NlciBnbG9iYWxzIChyb290IGlzIHdpbmRvdylcbiAgICAgICAgcm9vdC5yZXR1cm5FeHBvcnRzID0gZmFjdG9yeSgpO1xuICAgIH1cbn0odGhpcywgZnVuY3Rpb24gKCkge1xuICAgIC8qKlxuICAgICAqIEJyaW5ncyBhbiBlbnZpcm9ubWVudCBhcyBjbG9zZSB0byBFQ01BU2NyaXB0IDUgY29tcGxpYW5jZVxuICAgICAqIGFzIGlzIHBvc3NpYmxlIHdpdGggdGhlIGZhY2lsaXRpZXMgb2YgZXJzdHdoaWxlIGVuZ2luZXMuXG4gICAgICpcbiAgICAgKiBBbm5vdGF0ZWQgRVM1OiBodHRwOi8vZXM1LmdpdGh1Yi5jb20vIChzcGVjaWZpYyBsaW5rcyBiZWxvdylcbiAgICAgKiBFUzUgU3BlYzogaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL3B1YmxpY2F0aW9ucy9maWxlcy9FQ01BLVNUL0VjbWEtMjYyLnBkZlxuICAgICAqIFJlcXVpcmVkIHJlYWRpbmc6IGh0dHA6Ly9qYXZhc2NyaXB0d2VibG9nLndvcmRwcmVzcy5jb20vMjAxMS8xMi8wNS9leHRlbmRpbmctamF2YXNjcmlwdC1uYXRpdmVzL1xuICAgICAqL1xuXG4gICAgLy8gU2hvcnRjdXQgdG8gYW4gb2Z0ZW4gYWNjZXNzZWQgcHJvcGVydGllcywgaW4gb3JkZXIgdG8gYXZvaWQgbXVsdGlwbGVcbiAgICAvLyBkZXJlZmVyZW5jZSB0aGF0IGNvc3RzIHVuaXZlcnNhbGx5LiBUaGlzIGFsc28gaG9sZHMgYSByZWZlcmVuY2UgdG8ga25vd24tZ29vZFxuICAgIC8vIGZ1bmN0aW9ucy5cbiAgICB2YXIgJEFycmF5ID0gQXJyYXk7XG4gICAgdmFyIEFycmF5UHJvdG90eXBlID0gJEFycmF5LnByb3RvdHlwZTtcbiAgICB2YXIgJE9iamVjdCA9IE9iamVjdDtcbiAgICB2YXIgT2JqZWN0UHJvdG90eXBlID0gJE9iamVjdC5wcm90b3R5cGU7XG4gICAgdmFyICRGdW5jdGlvbiA9IEZ1bmN0aW9uO1xuICAgIHZhciBGdW5jdGlvblByb3RvdHlwZSA9ICRGdW5jdGlvbi5wcm90b3R5cGU7XG4gICAgdmFyICRTdHJpbmcgPSBTdHJpbmc7XG4gICAgdmFyIFN0cmluZ1Byb3RvdHlwZSA9ICRTdHJpbmcucHJvdG90eXBlO1xuICAgIHZhciAkTnVtYmVyID0gTnVtYmVyO1xuICAgIHZhciBOdW1iZXJQcm90b3R5cGUgPSAkTnVtYmVyLnByb3RvdHlwZTtcbiAgICB2YXIgYXJyYXlfc2xpY2UgPSBBcnJheVByb3RvdHlwZS5zbGljZTtcbiAgICB2YXIgYXJyYXlfc3BsaWNlID0gQXJyYXlQcm90b3R5cGUuc3BsaWNlO1xuICAgIHZhciBhcnJheV9wdXNoID0gQXJyYXlQcm90b3R5cGUucHVzaDtcbiAgICB2YXIgYXJyYXlfdW5zaGlmdCA9IEFycmF5UHJvdG90eXBlLnVuc2hpZnQ7XG4gICAgdmFyIGFycmF5X2NvbmNhdCA9IEFycmF5UHJvdG90eXBlLmNvbmNhdDtcbiAgICB2YXIgYXJyYXlfam9pbiA9IEFycmF5UHJvdG90eXBlLmpvaW47XG4gICAgdmFyIGNhbGwgPSBGdW5jdGlvblByb3RvdHlwZS5jYWxsO1xuICAgIHZhciBhcHBseSA9IEZ1bmN0aW9uUHJvdG90eXBlLmFwcGx5O1xuICAgIHZhciBtYXggPSBNYXRoLm1heDtcbiAgICB2YXIgbWluID0gTWF0aC5taW47XG5cbiAgICAvLyBIYXZpbmcgYSB0b1N0cmluZyBsb2NhbCB2YXJpYWJsZSBuYW1lIGJyZWFrcyBpbiBPcGVyYSBzbyB1c2UgdG9fc3RyaW5nLlxuICAgIHZhciB0b19zdHJpbmcgPSBPYmplY3RQcm90b3R5cGUudG9TdHJpbmc7XG5cbiAgICAvKiBnbG9iYWwgU3ltYm9sICovXG4gICAgLyogZXNsaW50LWRpc2FibGUgb25lLXZhci1kZWNsYXJhdGlvbi1wZXItbGluZSwgbm8tcmVkZWNsYXJlLCBtYXgtc3RhdGVtZW50cy1wZXItbGluZSAqL1xuICAgIHZhciBoYXNUb1N0cmluZ1RhZyA9IHR5cGVvZiBTeW1ib2wgPT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIFN5bWJvbC50b1N0cmluZ1RhZyA9PT0gJ3N5bWJvbCc7XG4gICAgdmFyIGlzQ2FsbGFibGU7IC8qIGlubGluZWQgZnJvbSBodHRwczovL25wbWpzLmNvbS9pcy1jYWxsYWJsZSAqLyB2YXIgZm5Ub1N0ciA9IEZ1bmN0aW9uLnByb3RvdHlwZS50b1N0cmluZywgY29uc3RydWN0b3JSZWdleCA9IC9eXFxzKmNsYXNzIC8sIGlzRVM2Q2xhc3NGbiA9IGZ1bmN0aW9uIGlzRVM2Q2xhc3NGbih2YWx1ZSkgeyB0cnkgeyB2YXIgZm5TdHIgPSBmblRvU3RyLmNhbGwodmFsdWUpOyB2YXIgc2luZ2xlU3RyaXBwZWQgPSBmblN0ci5yZXBsYWNlKC9cXC9cXC8uKlxcbi9nLCAnJyk7IHZhciBtdWx0aVN0cmlwcGVkID0gc2luZ2xlU3RyaXBwZWQucmVwbGFjZSgvXFwvXFwqWy5cXHNcXFNdKlxcKlxcLy9nLCAnJyk7IHZhciBzcGFjZVN0cmlwcGVkID0gbXVsdGlTdHJpcHBlZC5yZXBsYWNlKC9cXG4vbWcsICcgJykucmVwbGFjZSgvIHsyfS9nLCAnICcpOyByZXR1cm4gY29uc3RydWN0b3JSZWdleC50ZXN0KHNwYWNlU3RyaXBwZWQpOyB9IGNhdGNoIChlKSB7IHJldHVybiBmYWxzZTsgLyogbm90IGEgZnVuY3Rpb24gKi8gfSB9LCB0cnlGdW5jdGlvbk9iamVjdCA9IGZ1bmN0aW9uIHRyeUZ1bmN0aW9uT2JqZWN0KHZhbHVlKSB7IHRyeSB7IGlmIChpc0VTNkNsYXNzRm4odmFsdWUpKSB7IHJldHVybiBmYWxzZTsgfSBmblRvU3RyLmNhbGwodmFsdWUpOyByZXR1cm4gdHJ1ZTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gZmFsc2U7IH0gfSwgZm5DbGFzcyA9ICdbb2JqZWN0IEZ1bmN0aW9uXScsIGdlbkNsYXNzID0gJ1tvYmplY3QgR2VuZXJhdG9yRnVuY3Rpb25dJywgaXNDYWxsYWJsZSA9IGZ1bmN0aW9uIGlzQ2FsbGFibGUodmFsdWUpIHsgaWYgKCF2YWx1ZSkgeyByZXR1cm4gZmFsc2U7IH0gaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnKSB7IHJldHVybiBmYWxzZTsgfSBpZiAoaGFzVG9TdHJpbmdUYWcpIHsgcmV0dXJuIHRyeUZ1bmN0aW9uT2JqZWN0KHZhbHVlKTsgfSBpZiAoaXNFUzZDbGFzc0ZuKHZhbHVlKSkgeyByZXR1cm4gZmFsc2U7IH0gdmFyIHN0ckNsYXNzID0gdG9fc3RyaW5nLmNhbGwodmFsdWUpOyByZXR1cm4gc3RyQ2xhc3MgPT09IGZuQ2xhc3MgfHwgc3RyQ2xhc3MgPT09IGdlbkNsYXNzOyB9O1xuXG4gICAgdmFyIGlzUmVnZXg7IC8qIGlubGluZWQgZnJvbSBodHRwczovL25wbWpzLmNvbS9pcy1yZWdleCAqLyB2YXIgcmVnZXhFeGVjID0gUmVnRXhwLnByb3RvdHlwZS5leGVjLCB0cnlSZWdleEV4ZWMgPSBmdW5jdGlvbiB0cnlSZWdleEV4ZWModmFsdWUpIHsgdHJ5IHsgcmVnZXhFeGVjLmNhbGwodmFsdWUpOyByZXR1cm4gdHJ1ZTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gZmFsc2U7IH0gfSwgcmVnZXhDbGFzcyA9ICdbb2JqZWN0IFJlZ0V4cF0nOyBpc1JlZ2V4ID0gZnVuY3Rpb24gaXNSZWdleCh2YWx1ZSkgeyBpZiAodHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0JykgeyByZXR1cm4gZmFsc2U7IH0gcmV0dXJuIGhhc1RvU3RyaW5nVGFnID8gdHJ5UmVnZXhFeGVjKHZhbHVlKSA6IHRvX3N0cmluZy5jYWxsKHZhbHVlKSA9PT0gcmVnZXhDbGFzczsgfTtcbiAgICB2YXIgaXNTdHJpbmc7IC8qIGlubGluZWQgZnJvbSBodHRwczovL25wbWpzLmNvbS9pcy1zdHJpbmcgKi8gdmFyIHN0clZhbHVlID0gU3RyaW5nLnByb3RvdHlwZS52YWx1ZU9mLCB0cnlTdHJpbmdPYmplY3QgPSBmdW5jdGlvbiB0cnlTdHJpbmdPYmplY3QodmFsdWUpIHsgdHJ5IHsgc3RyVmFsdWUuY2FsbCh2YWx1ZSk7IHJldHVybiB0cnVlOyB9IGNhdGNoIChlKSB7IHJldHVybiBmYWxzZTsgfSB9LCBzdHJpbmdDbGFzcyA9ICdbb2JqZWN0IFN0cmluZ10nOyBpc1N0cmluZyA9IGZ1bmN0aW9uIGlzU3RyaW5nKHZhbHVlKSB7IGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7IHJldHVybiB0cnVlOyB9IGlmICh0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnKSB7IHJldHVybiBmYWxzZTsgfSByZXR1cm4gaGFzVG9TdHJpbmdUYWcgPyB0cnlTdHJpbmdPYmplY3QodmFsdWUpIDogdG9fc3RyaW5nLmNhbGwodmFsdWUpID09PSBzdHJpbmdDbGFzczsgfTtcbiAgICAvKiBlc2xpbnQtZW5hYmxlIG9uZS12YXItZGVjbGFyYXRpb24tcGVyLWxpbmUsIG5vLXJlZGVjbGFyZSwgbWF4LXN0YXRlbWVudHMtcGVyLWxpbmUgKi9cblxuICAgIC8qIGlubGluZWQgZnJvbSBodHRwOi8vbnBtanMuY29tL2RlZmluZS1wcm9wZXJ0aWVzICovXG4gICAgdmFyIHN1cHBvcnRzRGVzY3JpcHRvcnMgPSAkT2JqZWN0LmRlZmluZVByb3BlcnR5ICYmIChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB2YXIgb2JqID0ge307XG4gICAgICAgICAgICAkT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iaiwgJ3gnLCB7IGVudW1lcmFibGU6IGZhbHNlLCB2YWx1ZTogb2JqIH0pO1xuICAgICAgICAgICAgZm9yICh2YXIgXyBpbiBvYmopIHsgLy8ganNjczppZ25vcmUgZGlzYWxsb3dVbnVzZWRWYXJpYWJsZXNcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gb2JqLnggPT09IG9iajtcbiAgICAgICAgfSBjYXRjaCAoZSkgeyAvKiB0aGlzIGlzIEVTMyAqL1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfSgpKTtcbiAgICB2YXIgZGVmaW5lUHJvcGVydGllcyA9IChmdW5jdGlvbiAoaGFzKSB7XG4gICAgICAgIC8vIERlZmluZSBjb25maWd1cmFibGUsIHdyaXRhYmxlLCBhbmQgbm9uLWVudW1lcmFibGUgcHJvcHNcbiAgICAgICAgLy8gaWYgdGhleSBkb24ndCBleGlzdC5cbiAgICAgICAgdmFyIGRlZmluZVByb3BlcnR5O1xuICAgICAgICBpZiAoc3VwcG9ydHNEZXNjcmlwdG9ycykge1xuICAgICAgICAgICAgZGVmaW5lUHJvcGVydHkgPSBmdW5jdGlvbiAob2JqZWN0LCBuYW1lLCBtZXRob2QsIGZvcmNlQXNzaWduKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFmb3JjZUFzc2lnbiAmJiAobmFtZSBpbiBvYmplY3QpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgJE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmplY3QsIG5hbWUsIHtcbiAgICAgICAgICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiBtZXRob2RcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBkZWZpbmVQcm9wZXJ0eSA9IGZ1bmN0aW9uIChvYmplY3QsIG5hbWUsIG1ldGhvZCwgZm9yY2VBc3NpZ24pIHtcbiAgICAgICAgICAgICAgICBpZiAoIWZvcmNlQXNzaWduICYmIChuYW1lIGluIG9iamVjdCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBvYmplY3RbbmFtZV0gPSBtZXRob2Q7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKG9iamVjdCwgbWFwLCBmb3JjZUFzc2lnbikge1xuICAgICAgICAgICAgZm9yICh2YXIgbmFtZSBpbiBtYXApIHtcbiAgICAgICAgICAgICAgICBpZiAoaGFzLmNhbGwobWFwLCBuYW1lKSkge1xuICAgICAgICAgICAgICAgICAgICBkZWZpbmVQcm9wZXJ0eShvYmplY3QsIG5hbWUsIG1hcFtuYW1lXSwgZm9yY2VBc3NpZ24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9KE9iamVjdFByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eSkpO1xuXG4gICAgLy9cbiAgICAvLyBVdGlsXG4gICAgLy8gPT09PT09XG4gICAgLy9cblxuICAgIC8qIHJlcGxhY2VhYmxlIHdpdGggaHR0cHM6Ly9ucG1qcy5jb20vcGFja2FnZS9lcy1hYnN0cmFjdCAvaGVscGVycy9pc1ByaW1pdGl2ZSAqL1xuICAgIHZhciBpc1ByaW1pdGl2ZSA9IGZ1bmN0aW9uIGlzUHJpbWl0aXZlKGlucHV0KSB7XG4gICAgICAgIHZhciB0eXBlID0gdHlwZW9mIGlucHV0O1xuICAgICAgICByZXR1cm4gaW5wdXQgPT09IG51bGwgfHwgKHR5cGUgIT09ICdvYmplY3QnICYmIHR5cGUgIT09ICdmdW5jdGlvbicpO1xuICAgIH07XG5cbiAgICB2YXIgaXNBY3R1YWxOYU4gPSAkTnVtYmVyLmlzTmFOIHx8IGZ1bmN0aW9uIGlzQWN0dWFsTmFOKHgpIHtcbiAgICAgICAgcmV0dXJuIHggIT09IHg7XG4gICAgfTtcblxuICAgIHZhciBFUyA9IHtcbiAgICAgICAgLy8gRVM1IDkuNFxuICAgICAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3g5LjRcbiAgICAgICAgLy8gaHR0cDovL2pzcGVyZi5jb20vdG8taW50ZWdlclxuICAgICAgICAvKiByZXBsYWNlYWJsZSB3aXRoIGh0dHBzOi8vbnBtanMuY29tL3BhY2thZ2UvZXMtYWJzdHJhY3QgRVM1LlRvSW50ZWdlciAqL1xuICAgICAgICBUb0ludGVnZXI6IGZ1bmN0aW9uIFRvSW50ZWdlcihudW0pIHtcbiAgICAgICAgICAgIHZhciBuID0gK251bTtcbiAgICAgICAgICAgIGlmIChpc0FjdHVhbE5hTihuKSkge1xuICAgICAgICAgICAgICAgIG4gPSAwO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChuICE9PSAwICYmIG4gIT09ICgxIC8gMCkgJiYgbiAhPT0gLSgxIC8gMCkpIHtcbiAgICAgICAgICAgICAgICBuID0gKG4gPiAwIHx8IC0xKSAqIE1hdGguZmxvb3IoTWF0aC5hYnMobikpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG47XG4gICAgICAgIH0sXG5cbiAgICAgICAgLyogcmVwbGFjZWFibGUgd2l0aCBodHRwczovL25wbWpzLmNvbS9wYWNrYWdlL2VzLWFic3RyYWN0IEVTNS5Ub1ByaW1pdGl2ZSAqL1xuICAgICAgICBUb1ByaW1pdGl2ZTogZnVuY3Rpb24gVG9QcmltaXRpdmUoaW5wdXQpIHtcbiAgICAgICAgICAgIHZhciB2YWwsIHZhbHVlT2YsIHRvU3RyO1xuICAgICAgICAgICAgaWYgKGlzUHJpbWl0aXZlKGlucHV0KSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhbHVlT2YgPSBpbnB1dC52YWx1ZU9mO1xuICAgICAgICAgICAgaWYgKGlzQ2FsbGFibGUodmFsdWVPZikpIHtcbiAgICAgICAgICAgICAgICB2YWwgPSB2YWx1ZU9mLmNhbGwoaW5wdXQpO1xuICAgICAgICAgICAgICAgIGlmIChpc1ByaW1pdGl2ZSh2YWwpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdG9TdHIgPSBpbnB1dC50b1N0cmluZztcbiAgICAgICAgICAgIGlmIChpc0NhbGxhYmxlKHRvU3RyKSkge1xuICAgICAgICAgICAgICAgIHZhbCA9IHRvU3RyLmNhbGwoaW5wdXQpO1xuICAgICAgICAgICAgICAgIGlmIChpc1ByaW1pdGl2ZSh2YWwpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICB9LFxuXG4gICAgICAgIC8vIEVTNSA5LjlcbiAgICAgICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4OS45XG4gICAgICAgIC8qIHJlcGxhY2VhYmxlIHdpdGggaHR0cHM6Ly9ucG1qcy5jb20vcGFja2FnZS9lcy1hYnN0cmFjdCBFUzUuVG9PYmplY3QgKi9cbiAgICAgICAgVG9PYmplY3Q6IGZ1bmN0aW9uIChvKSB7XG4gICAgICAgICAgICBpZiAobyA9PSBudWxsKSB7IC8vIHRoaXMgbWF0Y2hlcyBib3RoIG51bGwgYW5kIHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJjYW4ndCBjb252ZXJ0IFwiICsgbyArICcgdG8gb2JqZWN0Jyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gJE9iamVjdChvKTtcbiAgICAgICAgfSxcblxuICAgICAgICAvKiByZXBsYWNlYWJsZSB3aXRoIGh0dHBzOi8vbnBtanMuY29tL3BhY2thZ2UvZXMtYWJzdHJhY3QgRVM1LlRvVWludDMyICovXG4gICAgICAgIFRvVWludDMyOiBmdW5jdGlvbiBUb1VpbnQzMih4KSB7XG4gICAgICAgICAgICByZXR1cm4geCA+Pj4gMDtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICAvL1xuICAgIC8vIEZ1bmN0aW9uXG4gICAgLy8gPT09PT09PT1cbiAgICAvL1xuXG4gICAgLy8gRVMtNSAxNS4zLjQuNVxuICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDE1LjMuNC41XG5cbiAgICB2YXIgRW1wdHkgPSBmdW5jdGlvbiBFbXB0eSgpIHt9O1xuXG4gICAgZGVmaW5lUHJvcGVydGllcyhGdW5jdGlvblByb3RvdHlwZSwge1xuICAgICAgICBiaW5kOiBmdW5jdGlvbiBiaW5kKHRoYXQpIHsgLy8gLmxlbmd0aCBpcyAxXG4gICAgICAgICAgICAvLyAxLiBMZXQgVGFyZ2V0IGJlIHRoZSB0aGlzIHZhbHVlLlxuICAgICAgICAgICAgdmFyIHRhcmdldCA9IHRoaXM7XG4gICAgICAgICAgICAvLyAyLiBJZiBJc0NhbGxhYmxlKFRhcmdldCkgaXMgZmFsc2UsIHRocm93IGEgVHlwZUVycm9yIGV4Y2VwdGlvbi5cbiAgICAgICAgICAgIGlmICghaXNDYWxsYWJsZSh0YXJnZXQpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgY2FsbGVkIG9uIGluY29tcGF0aWJsZSAnICsgdGFyZ2V0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIDMuIExldCBBIGJlIGEgbmV3IChwb3NzaWJseSBlbXB0eSkgaW50ZXJuYWwgbGlzdCBvZiBhbGwgb2YgdGhlXG4gICAgICAgICAgICAvLyAgIGFyZ3VtZW50IHZhbHVlcyBwcm92aWRlZCBhZnRlciB0aGlzQXJnIChhcmcxLCBhcmcyIGV0YyksIGluIG9yZGVyLlxuICAgICAgICAgICAgLy8gWFhYIHNsaWNlZEFyZ3Mgd2lsbCBzdGFuZCBpbiBmb3IgXCJBXCIgaWYgdXNlZFxuICAgICAgICAgICAgdmFyIGFyZ3MgPSBhcnJheV9zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7IC8vIGZvciBub3JtYWwgY2FsbFxuICAgICAgICAgICAgLy8gNC4gTGV0IEYgYmUgYSBuZXcgbmF0aXZlIEVDTUFTY3JpcHQgb2JqZWN0LlxuICAgICAgICAgICAgLy8gMTEuIFNldCB0aGUgW1tQcm90b3R5cGVdXSBpbnRlcm5hbCBwcm9wZXJ0eSBvZiBGIHRvIHRoZSBzdGFuZGFyZFxuICAgICAgICAgICAgLy8gICBidWlsdC1pbiBGdW5jdGlvbiBwcm90b3R5cGUgb2JqZWN0IGFzIHNwZWNpZmllZCBpbiAxNS4zLjMuMS5cbiAgICAgICAgICAgIC8vIDEyLiBTZXQgdGhlIFtbQ2FsbF1dIGludGVybmFsIHByb3BlcnR5IG9mIEYgYXMgZGVzY3JpYmVkIGluXG4gICAgICAgICAgICAvLyAgIDE1LjMuNC41LjEuXG4gICAgICAgICAgICAvLyAxMy4gU2V0IHRoZSBbW0NvbnN0cnVjdF1dIGludGVybmFsIHByb3BlcnR5IG9mIEYgYXMgZGVzY3JpYmVkIGluXG4gICAgICAgICAgICAvLyAgIDE1LjMuNC41LjIuXG4gICAgICAgICAgICAvLyAxNC4gU2V0IHRoZSBbW0hhc0luc3RhbmNlXV0gaW50ZXJuYWwgcHJvcGVydHkgb2YgRiBhcyBkZXNjcmliZWQgaW5cbiAgICAgICAgICAgIC8vICAgMTUuMy40LjUuMy5cbiAgICAgICAgICAgIHZhciBib3VuZDtcbiAgICAgICAgICAgIHZhciBiaW5kZXIgPSBmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcyBpbnN0YW5jZW9mIGJvdW5kKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIDE1LjMuNC41LjIgW1tDb25zdHJ1Y3RdXVxuICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIHRoZSBbW0NvbnN0cnVjdF1dIGludGVybmFsIG1ldGhvZCBvZiBhIGZ1bmN0aW9uIG9iamVjdCxcbiAgICAgICAgICAgICAgICAgICAgLy8gRiB0aGF0IHdhcyBjcmVhdGVkIHVzaW5nIHRoZSBiaW5kIGZ1bmN0aW9uIGlzIGNhbGxlZCB3aXRoIGFcbiAgICAgICAgICAgICAgICAgICAgLy8gbGlzdCBvZiBhcmd1bWVudHMgRXh0cmFBcmdzLCB0aGUgZm9sbG93aW5nIHN0ZXBzIGFyZSB0YWtlbjpcbiAgICAgICAgICAgICAgICAgICAgLy8gMS4gTGV0IHRhcmdldCBiZSB0aGUgdmFsdWUgb2YgRidzIFtbVGFyZ2V0RnVuY3Rpb25dXVxuICAgICAgICAgICAgICAgICAgICAvLyAgIGludGVybmFsIHByb3BlcnR5LlxuICAgICAgICAgICAgICAgICAgICAvLyAyLiBJZiB0YXJnZXQgaGFzIG5vIFtbQ29uc3RydWN0XV0gaW50ZXJuYWwgbWV0aG9kLCBhXG4gICAgICAgICAgICAgICAgICAgIC8vICAgVHlwZUVycm9yIGV4Y2VwdGlvbiBpcyB0aHJvd24uXG4gICAgICAgICAgICAgICAgICAgIC8vIDMuIExldCBib3VuZEFyZ3MgYmUgdGhlIHZhbHVlIG9mIEYncyBbW0JvdW5kQXJnc11dIGludGVybmFsXG4gICAgICAgICAgICAgICAgICAgIC8vICAgcHJvcGVydHkuXG4gICAgICAgICAgICAgICAgICAgIC8vIDQuIExldCBhcmdzIGJlIGEgbmV3IGxpc3QgY29udGFpbmluZyB0aGUgc2FtZSB2YWx1ZXMgYXMgdGhlXG4gICAgICAgICAgICAgICAgICAgIC8vICAgbGlzdCBib3VuZEFyZ3MgaW4gdGhlIHNhbWUgb3JkZXIgZm9sbG93ZWQgYnkgdGhlIHNhbWVcbiAgICAgICAgICAgICAgICAgICAgLy8gICB2YWx1ZXMgYXMgdGhlIGxpc3QgRXh0cmFBcmdzIGluIHRoZSBzYW1lIG9yZGVyLlxuICAgICAgICAgICAgICAgICAgICAvLyA1LiBSZXR1cm4gdGhlIHJlc3VsdCBvZiBjYWxsaW5nIHRoZSBbW0NvbnN0cnVjdF1dIGludGVybmFsXG4gICAgICAgICAgICAgICAgICAgIC8vICAgbWV0aG9kIG9mIHRhcmdldCBwcm92aWRpbmcgYXJncyBhcyB0aGUgYXJndW1lbnRzLlxuXG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSBhcHBseS5jYWxsKFxuICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5X2NvbmNhdC5jYWxsKGFyZ3MsIGFycmF5X3NsaWNlLmNhbGwoYXJndW1lbnRzKSlcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCRPYmplY3QocmVzdWx0KSA9PT0gcmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gMTUuMy40LjUuMSBbW0NhbGxdXVxuICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIHRoZSBbW0NhbGxdXSBpbnRlcm5hbCBtZXRob2Qgb2YgYSBmdW5jdGlvbiBvYmplY3QsIEYsXG4gICAgICAgICAgICAgICAgICAgIC8vIHdoaWNoIHdhcyBjcmVhdGVkIHVzaW5nIHRoZSBiaW5kIGZ1bmN0aW9uIGlzIGNhbGxlZCB3aXRoIGFcbiAgICAgICAgICAgICAgICAgICAgLy8gdGhpcyB2YWx1ZSBhbmQgYSBsaXN0IG9mIGFyZ3VtZW50cyBFeHRyYUFyZ3MsIHRoZSBmb2xsb3dpbmdcbiAgICAgICAgICAgICAgICAgICAgLy8gc3RlcHMgYXJlIHRha2VuOlxuICAgICAgICAgICAgICAgICAgICAvLyAxLiBMZXQgYm91bmRBcmdzIGJlIHRoZSB2YWx1ZSBvZiBGJ3MgW1tCb3VuZEFyZ3NdXSBpbnRlcm5hbFxuICAgICAgICAgICAgICAgICAgICAvLyAgIHByb3BlcnR5LlxuICAgICAgICAgICAgICAgICAgICAvLyAyLiBMZXQgYm91bmRUaGlzIGJlIHRoZSB2YWx1ZSBvZiBGJ3MgW1tCb3VuZFRoaXNdXSBpbnRlcm5hbFxuICAgICAgICAgICAgICAgICAgICAvLyAgIHByb3BlcnR5LlxuICAgICAgICAgICAgICAgICAgICAvLyAzLiBMZXQgdGFyZ2V0IGJlIHRoZSB2YWx1ZSBvZiBGJ3MgW1tUYXJnZXRGdW5jdGlvbl1dIGludGVybmFsXG4gICAgICAgICAgICAgICAgICAgIC8vICAgcHJvcGVydHkuXG4gICAgICAgICAgICAgICAgICAgIC8vIDQuIExldCBhcmdzIGJlIGEgbmV3IGxpc3QgY29udGFpbmluZyB0aGUgc2FtZSB2YWx1ZXMgYXMgdGhlXG4gICAgICAgICAgICAgICAgICAgIC8vICAgbGlzdCBib3VuZEFyZ3MgaW4gdGhlIHNhbWUgb3JkZXIgZm9sbG93ZWQgYnkgdGhlIHNhbWVcbiAgICAgICAgICAgICAgICAgICAgLy8gICB2YWx1ZXMgYXMgdGhlIGxpc3QgRXh0cmFBcmdzIGluIHRoZSBzYW1lIG9yZGVyLlxuICAgICAgICAgICAgICAgICAgICAvLyA1LiBSZXR1cm4gdGhlIHJlc3VsdCBvZiBjYWxsaW5nIHRoZSBbW0NhbGxdXSBpbnRlcm5hbCBtZXRob2RcbiAgICAgICAgICAgICAgICAgICAgLy8gICBvZiB0YXJnZXQgcHJvdmlkaW5nIGJvdW5kVGhpcyBhcyB0aGUgdGhpcyB2YWx1ZSBhbmRcbiAgICAgICAgICAgICAgICAgICAgLy8gICBwcm92aWRpbmcgYXJncyBhcyB0aGUgYXJndW1lbnRzLlxuXG4gICAgICAgICAgICAgICAgICAgIC8vIGVxdWl2OiB0YXJnZXQuY2FsbCh0aGlzLCAuLi5ib3VuZEFyZ3MsIC4uLmFyZ3MpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBhcHBseS5jYWxsKFxuICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhhdCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5X2NvbmNhdC5jYWxsKGFyZ3MsIGFycmF5X3NsaWNlLmNhbGwoYXJndW1lbnRzKSlcbiAgICAgICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLy8gMTUuIElmIHRoZSBbW0NsYXNzXV0gaW50ZXJuYWwgcHJvcGVydHkgb2YgVGFyZ2V0IGlzIFwiRnVuY3Rpb25cIiwgdGhlblxuICAgICAgICAgICAgLy8gICAgIGEuIExldCBMIGJlIHRoZSBsZW5ndGggcHJvcGVydHkgb2YgVGFyZ2V0IG1pbnVzIHRoZSBsZW5ndGggb2YgQS5cbiAgICAgICAgICAgIC8vICAgICBiLiBTZXQgdGhlIGxlbmd0aCBvd24gcHJvcGVydHkgb2YgRiB0byBlaXRoZXIgMCBvciBMLCB3aGljaGV2ZXIgaXNcbiAgICAgICAgICAgIC8vICAgICAgIGxhcmdlci5cbiAgICAgICAgICAgIC8vIDE2LiBFbHNlIHNldCB0aGUgbGVuZ3RoIG93biBwcm9wZXJ0eSBvZiBGIHRvIDAuXG5cbiAgICAgICAgICAgIHZhciBib3VuZExlbmd0aCA9IG1heCgwLCB0YXJnZXQubGVuZ3RoIC0gYXJncy5sZW5ndGgpO1xuXG4gICAgICAgICAgICAvLyAxNy4gU2V0IHRoZSBhdHRyaWJ1dGVzIG9mIHRoZSBsZW5ndGggb3duIHByb3BlcnR5IG9mIEYgdG8gdGhlIHZhbHVlc1xuICAgICAgICAgICAgLy8gICBzcGVjaWZpZWQgaW4gMTUuMy41LjEuXG4gICAgICAgICAgICB2YXIgYm91bmRBcmdzID0gW107XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJvdW5kTGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBhcnJheV9wdXNoLmNhbGwoYm91bmRBcmdzLCAnJCcgKyBpKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gWFhYIEJ1aWxkIGEgZHluYW1pYyBmdW5jdGlvbiB3aXRoIGRlc2lyZWQgYW1vdW50IG9mIGFyZ3VtZW50cyBpcyB0aGUgb25seVxuICAgICAgICAgICAgLy8gd2F5IHRvIHNldCB0aGUgbGVuZ3RoIHByb3BlcnR5IG9mIGEgZnVuY3Rpb24uXG4gICAgICAgICAgICAvLyBJbiBlbnZpcm9ubWVudHMgd2hlcmUgQ29udGVudCBTZWN1cml0eSBQb2xpY2llcyBlbmFibGVkIChDaHJvbWUgZXh0ZW5zaW9ucyxcbiAgICAgICAgICAgIC8vIGZvciBleC4pIGFsbCB1c2Ugb2YgZXZhbCBvciBGdW5jdGlvbiBjb3N0cnVjdG9yIHRocm93cyBhbiBleGNlcHRpb24uXG4gICAgICAgICAgICAvLyBIb3dldmVyIGluIGFsbCBvZiB0aGVzZSBlbnZpcm9ubWVudHMgRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgZXhpc3RzXG4gICAgICAgICAgICAvLyBhbmQgc28gdGhpcyBjb2RlIHdpbGwgbmV2ZXIgYmUgZXhlY3V0ZWQuXG4gICAgICAgICAgICBib3VuZCA9ICRGdW5jdGlvbignYmluZGVyJywgJ3JldHVybiBmdW5jdGlvbiAoJyArIGFycmF5X2pvaW4uY2FsbChib3VuZEFyZ3MsICcsJykgKyAnKXsgcmV0dXJuIGJpbmRlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9JykoYmluZGVyKTtcblxuICAgICAgICAgICAgaWYgKHRhcmdldC5wcm90b3R5cGUpIHtcbiAgICAgICAgICAgICAgICBFbXB0eS5wcm90b3R5cGUgPSB0YXJnZXQucHJvdG90eXBlO1xuICAgICAgICAgICAgICAgIGJvdW5kLnByb3RvdHlwZSA9IG5ldyBFbXB0eSgpO1xuICAgICAgICAgICAgICAgIC8vIENsZWFuIHVwIGRhbmdsaW5nIHJlZmVyZW5jZXMuXG4gICAgICAgICAgICAgICAgRW1wdHkucHJvdG90eXBlID0gbnVsbDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gVE9ET1xuICAgICAgICAgICAgLy8gMTguIFNldCB0aGUgW1tFeHRlbnNpYmxlXV0gaW50ZXJuYWwgcHJvcGVydHkgb2YgRiB0byB0cnVlLlxuXG4gICAgICAgICAgICAvLyBUT0RPXG4gICAgICAgICAgICAvLyAxOS4gTGV0IHRocm93ZXIgYmUgdGhlIFtbVGhyb3dUeXBlRXJyb3JdXSBmdW5jdGlvbiBPYmplY3QgKDEzLjIuMykuXG4gICAgICAgICAgICAvLyAyMC4gQ2FsbCB0aGUgW1tEZWZpbmVPd25Qcm9wZXJ0eV1dIGludGVybmFsIG1ldGhvZCBvZiBGIHdpdGhcbiAgICAgICAgICAgIC8vICAgYXJndW1lbnRzIFwiY2FsbGVyXCIsIFByb3BlcnR5RGVzY3JpcHRvciB7W1tHZXRdXTogdGhyb3dlciwgW1tTZXRdXTpcbiAgICAgICAgICAgIC8vICAgdGhyb3dlciwgW1tFbnVtZXJhYmxlXV06IGZhbHNlLCBbW0NvbmZpZ3VyYWJsZV1dOiBmYWxzZX0sIGFuZFxuICAgICAgICAgICAgLy8gICBmYWxzZS5cbiAgICAgICAgICAgIC8vIDIxLiBDYWxsIHRoZSBbW0RlZmluZU93blByb3BlcnR5XV0gaW50ZXJuYWwgbWV0aG9kIG9mIEYgd2l0aFxuICAgICAgICAgICAgLy8gICBhcmd1bWVudHMgXCJhcmd1bWVudHNcIiwgUHJvcGVydHlEZXNjcmlwdG9yIHtbW0dldF1dOiB0aHJvd2VyLFxuICAgICAgICAgICAgLy8gICBbW1NldF1dOiB0aHJvd2VyLCBbW0VudW1lcmFibGVdXTogZmFsc2UsIFtbQ29uZmlndXJhYmxlXV06IGZhbHNlfSxcbiAgICAgICAgICAgIC8vICAgYW5kIGZhbHNlLlxuXG4gICAgICAgICAgICAvLyBUT0RPXG4gICAgICAgICAgICAvLyBOT1RFIEZ1bmN0aW9uIG9iamVjdHMgY3JlYXRlZCB1c2luZyBGdW5jdGlvbi5wcm90b3R5cGUuYmluZCBkbyBub3RcbiAgICAgICAgICAgIC8vIGhhdmUgYSBwcm90b3R5cGUgcHJvcGVydHkgb3IgdGhlIFtbQ29kZV1dLCBbW0Zvcm1hbFBhcmFtZXRlcnNdXSwgYW5kXG4gICAgICAgICAgICAvLyBbW1Njb3BlXV0gaW50ZXJuYWwgcHJvcGVydGllcy5cbiAgICAgICAgICAgIC8vIFhYWCBjYW4ndCBkZWxldGUgcHJvdG90eXBlIGluIHB1cmUtanMuXG5cbiAgICAgICAgICAgIC8vIDIyLiBSZXR1cm4gRi5cbiAgICAgICAgICAgIHJldHVybiBib3VuZDtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gX1BsZWFzZSBub3RlOiBTaG9ydGN1dHMgYXJlIGRlZmluZWQgYWZ0ZXIgYEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kYCBhcyB3ZVxuICAgIC8vIHVzZSBpdCBpbiBkZWZpbmluZyBzaG9ydGN1dHMuXG4gICAgdmFyIG93bnMgPSBjYWxsLmJpbmQoT2JqZWN0UHJvdG90eXBlLmhhc093blByb3BlcnR5KTtcbiAgICB2YXIgdG9TdHIgPSBjYWxsLmJpbmQoT2JqZWN0UHJvdG90eXBlLnRvU3RyaW5nKTtcbiAgICB2YXIgYXJyYXlTbGljZSA9IGNhbGwuYmluZChhcnJheV9zbGljZSk7XG4gICAgdmFyIGFycmF5U2xpY2VBcHBseSA9IGFwcGx5LmJpbmQoYXJyYXlfc2xpY2UpO1xuICAgIHZhciBzdHJTbGljZSA9IGNhbGwuYmluZChTdHJpbmdQcm90b3R5cGUuc2xpY2UpO1xuICAgIHZhciBzdHJTcGxpdCA9IGNhbGwuYmluZChTdHJpbmdQcm90b3R5cGUuc3BsaXQpO1xuICAgIHZhciBzdHJJbmRleE9mID0gY2FsbC5iaW5kKFN0cmluZ1Byb3RvdHlwZS5pbmRleE9mKTtcbiAgICB2YXIgcHVzaENhbGwgPSBjYWxsLmJpbmQoYXJyYXlfcHVzaCk7XG4gICAgdmFyIGlzRW51bSA9IGNhbGwuYmluZChPYmplY3RQcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUpO1xuICAgIHZhciBhcnJheVNvcnQgPSBjYWxsLmJpbmQoQXJyYXlQcm90b3R5cGUuc29ydCk7XG5cbiAgICAvL1xuICAgIC8vIEFycmF5XG4gICAgLy8gPT09PT1cbiAgICAvL1xuXG4gICAgdmFyIGlzQXJyYXkgPSAkQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiBpc0FycmF5KG9iaikge1xuICAgICAgICByZXR1cm4gdG9TdHIob2JqKSA9PT0gJ1tvYmplY3QgQXJyYXldJztcbiAgICB9O1xuXG4gICAgLy8gRVM1IDE1LjQuNC4xMlxuICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDE1LjQuNC4xM1xuICAgIC8vIFJldHVybiBsZW4rYXJnQ291bnQuXG4gICAgLy8gW2J1Z2ZpeCwgaWVsdDhdXG4gICAgLy8gSUUgPCA4IGJ1ZzogW10udW5zaGlmdCgwKSA9PT0gdW5kZWZpbmVkIGJ1dCBzaG91bGQgYmUgXCIxXCJcbiAgICB2YXIgaGFzVW5zaGlmdFJldHVyblZhbHVlQnVnID0gW10udW5zaGlmdCgwKSAhPT0gMTtcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgIHVuc2hpZnQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGFycmF5X3Vuc2hpZnQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmxlbmd0aDtcbiAgICAgICAgfVxuICAgIH0sIGhhc1Vuc2hpZnRSZXR1cm5WYWx1ZUJ1Zyk7XG5cbiAgICAvLyBFUzUgMTUuNC4zLjJcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS40LjMuMlxuICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0FycmF5L2lzQXJyYXlcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKCRBcnJheSwgeyBpc0FycmF5OiBpc0FycmF5IH0pO1xuXG4gICAgLy8gVGhlIElzQ2FsbGFibGUoKSBjaGVjayBpbiB0aGUgQXJyYXkgZnVuY3Rpb25zXG4gICAgLy8gaGFzIGJlZW4gcmVwbGFjZWQgd2l0aCBhIHN0cmljdCBjaGVjayBvbiB0aGVcbiAgICAvLyBpbnRlcm5hbCBjbGFzcyBvZiB0aGUgb2JqZWN0IHRvIHRyYXAgY2FzZXMgd2hlcmVcbiAgICAvLyB0aGUgcHJvdmlkZWQgZnVuY3Rpb24gd2FzIGFjdHVhbGx5IGEgcmVndWxhclxuICAgIC8vIGV4cHJlc3Npb24gbGl0ZXJhbCwgd2hpY2ggaW4gVjggYW5kXG4gICAgLy8gSmF2YVNjcmlwdENvcmUgaXMgYSB0eXBlb2YgXCJmdW5jdGlvblwiLiAgT25seSBpblxuICAgIC8vIFY4IGFyZSByZWd1bGFyIGV4cHJlc3Npb24gbGl0ZXJhbHMgcGVybWl0dGVkIGFzXG4gICAgLy8gcmVkdWNlIHBhcmFtZXRlcnMsIHNvIGl0IGlzIGRlc2lyYWJsZSBpbiB0aGVcbiAgICAvLyBnZW5lcmFsIGNhc2UgZm9yIHRoZSBzaGltIHRvIG1hdGNoIHRoZSBtb3JlXG4gICAgLy8gc3RyaWN0IGFuZCBjb21tb24gYmVoYXZpb3Igb2YgcmVqZWN0aW5nIHJlZ3VsYXJcbiAgICAvLyBleHByZXNzaW9ucy5cblxuICAgIC8vIEVTNSAxNS40LjQuMThcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS40LjQuMThcbiAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9hcnJheS9mb3JFYWNoXG5cbiAgICAvLyBDaGVjayBmYWlsdXJlIG9mIGJ5LWluZGV4IGFjY2VzcyBvZiBzdHJpbmcgY2hhcmFjdGVycyAoSUUgPCA5KVxuICAgIC8vIGFuZCBmYWlsdXJlIG9mIGAwIGluIGJveGVkU3RyaW5nYCAoUmhpbm8pXG4gICAgdmFyIGJveGVkU3RyaW5nID0gJE9iamVjdCgnYScpO1xuICAgIHZhciBzcGxpdFN0cmluZyA9IGJveGVkU3RyaW5nWzBdICE9PSAnYScgfHwgISgwIGluIGJveGVkU3RyaW5nKTtcblxuICAgIHZhciBwcm9wZXJseUJveGVzQ29udGV4dCA9IGZ1bmN0aW9uIHByb3Blcmx5Qm94ZWQobWV0aG9kKSB7XG4gICAgICAgIC8vIENoZWNrIG5vZGUgMC42LjIxIGJ1ZyB3aGVyZSB0aGlyZCBwYXJhbWV0ZXIgaXMgbm90IGJveGVkXG4gICAgICAgIHZhciBwcm9wZXJseUJveGVzTm9uU3RyaWN0ID0gdHJ1ZTtcbiAgICAgICAgdmFyIHByb3Blcmx5Qm94ZXNTdHJpY3QgPSB0cnVlO1xuICAgICAgICB2YXIgdGhyZXdFeGNlcHRpb24gPSBmYWxzZTtcbiAgICAgICAgaWYgKG1ldGhvZCkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBtZXRob2QuY2FsbCgnZm9vJywgZnVuY3Rpb24gKF8sIF9fLCBjb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgY29udGV4dCAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb3Blcmx5Qm94ZXNOb25TdHJpY3QgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgbWV0aG9kLmNhbGwoWzFdLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICd1c2Ugc3RyaWN0JztcblxuICAgICAgICAgICAgICAgICAgICBwcm9wZXJseUJveGVzU3RyaWN0ID0gdHlwZW9mIHRoaXMgPT09ICdzdHJpbmcnO1xuICAgICAgICAgICAgICAgIH0sICd4Jyk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgdGhyZXdFeGNlcHRpb24gPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiAhIW1ldGhvZCAmJiAhdGhyZXdFeGNlcHRpb24gJiYgcHJvcGVybHlCb3hlc05vblN0cmljdCAmJiBwcm9wZXJseUJveGVzU3RyaWN0O1xuICAgIH07XG5cbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgIGZvckVhY2g6IGZ1bmN0aW9uIGZvckVhY2goY2FsbGJhY2tmbi8qLCB0aGlzQXJnKi8pIHtcbiAgICAgICAgICAgIHZhciBvYmplY3QgPSBFUy5Ub09iamVjdCh0aGlzKTtcbiAgICAgICAgICAgIHZhciBzZWxmID0gc3BsaXRTdHJpbmcgJiYgaXNTdHJpbmcodGhpcykgPyBzdHJTcGxpdCh0aGlzLCAnJykgOiBvYmplY3Q7XG4gICAgICAgICAgICB2YXIgaSA9IC0xO1xuICAgICAgICAgICAgdmFyIGxlbmd0aCA9IEVTLlRvVWludDMyKHNlbGYubGVuZ3RoKTtcbiAgICAgICAgICAgIHZhciBUO1xuICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgVCA9IGFyZ3VtZW50c1sxXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gSWYgbm8gY2FsbGJhY2sgZnVuY3Rpb24gb3IgaWYgY2FsbGJhY2sgaXMgbm90IGEgY2FsbGFibGUgZnVuY3Rpb25cbiAgICAgICAgICAgIGlmICghaXNDYWxsYWJsZShjYWxsYmFja2ZuKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FycmF5LnByb3RvdHlwZS5mb3JFYWNoIGNhbGxiYWNrIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB3aGlsZSAoKytpIDwgbGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgaWYgKGkgaW4gc2VsZikge1xuICAgICAgICAgICAgICAgICAgICAvLyBJbnZva2UgdGhlIGNhbGxiYWNrIGZ1bmN0aW9uIHdpdGggY2FsbCwgcGFzc2luZyBhcmd1bWVudHM6XG4gICAgICAgICAgICAgICAgICAgIC8vIGNvbnRleHQsIHByb3BlcnR5IHZhbHVlLCBwcm9wZXJ0eSBrZXksIHRoaXNBcmcgb2JqZWN0XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgVCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrZm4oc2VsZltpXSwgaSwgb2JqZWN0KTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrZm4uY2FsbChULCBzZWxmW2ldLCBpLCBvYmplY3QpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSwgIXByb3Blcmx5Qm94ZXNDb250ZXh0KEFycmF5UHJvdG90eXBlLmZvckVhY2gpKTtcblxuICAgIC8vIEVTNSAxNS40LjQuMTlcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS40LjQuMTlcbiAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi9Db3JlX0phdmFTY3JpcHRfMS41X1JlZmVyZW5jZS9PYmplY3RzL0FycmF5L21hcFxuICAgIGRlZmluZVByb3BlcnRpZXMoQXJyYXlQcm90b3R5cGUsIHtcbiAgICAgICAgbWFwOiBmdW5jdGlvbiBtYXAoY2FsbGJhY2tmbi8qLCB0aGlzQXJnKi8pIHtcbiAgICAgICAgICAgIHZhciBvYmplY3QgPSBFUy5Ub09iamVjdCh0aGlzKTtcbiAgICAgICAgICAgIHZhciBzZWxmID0gc3BsaXRTdHJpbmcgJiYgaXNTdHJpbmcodGhpcykgPyBzdHJTcGxpdCh0aGlzLCAnJykgOiBvYmplY3Q7XG4gICAgICAgICAgICB2YXIgbGVuZ3RoID0gRVMuVG9VaW50MzIoc2VsZi5sZW5ndGgpO1xuICAgICAgICAgICAgdmFyIHJlc3VsdCA9ICRBcnJheShsZW5ndGgpO1xuICAgICAgICAgICAgdmFyIFQ7XG4gICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgICAgICBUID0gYXJndW1lbnRzWzFdO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBJZiBubyBjYWxsYmFjayBmdW5jdGlvbiBvciBpZiBjYWxsYmFjayBpcyBub3QgYSBjYWxsYWJsZSBmdW5jdGlvblxuICAgICAgICAgICAgaWYgKCFpc0NhbGxhYmxlKGNhbGxiYWNrZm4pKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJyYXkucHJvdG90eXBlLm1hcCBjYWxsYmFjayBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmIChpIGluIHNlbGYpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBUID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0W2ldID0gY2FsbGJhY2tmbihzZWxmW2ldLCBpLCBvYmplY3QpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0W2ldID0gY2FsbGJhY2tmbi5jYWxsKFQsIHNlbGZbaV0sIGksIG9iamVjdCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG4gICAgfSwgIXByb3Blcmx5Qm94ZXNDb250ZXh0KEFycmF5UHJvdG90eXBlLm1hcCkpO1xuXG4gICAgLy8gRVM1IDE1LjQuNC4yMFxuICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDE1LjQuNC4yMFxuICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL0NvcmVfSmF2YVNjcmlwdF8xLjVfUmVmZXJlbmNlL09iamVjdHMvQXJyYXkvZmlsdGVyXG4gICAgZGVmaW5lUHJvcGVydGllcyhBcnJheVByb3RvdHlwZSwge1xuICAgICAgICBmaWx0ZXI6IGZ1bmN0aW9uIGZpbHRlcihjYWxsYmFja2ZuLyosIHRoaXNBcmcqLykge1xuICAgICAgICAgICAgdmFyIG9iamVjdCA9IEVTLlRvT2JqZWN0KHRoaXMpO1xuICAgICAgICAgICAgdmFyIHNlbGYgPSBzcGxpdFN0cmluZyAmJiBpc1N0cmluZyh0aGlzKSA/IHN0clNwbGl0KHRoaXMsICcnKSA6IG9iamVjdDtcbiAgICAgICAgICAgIHZhciBsZW5ndGggPSBFUy5Ub1VpbnQzMihzZWxmLmxlbmd0aCk7XG4gICAgICAgICAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgICAgICAgICB2YXIgdmFsdWU7XG4gICAgICAgICAgICB2YXIgVDtcbiAgICAgICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgICAgIFQgPSBhcmd1bWVudHNbMV07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIElmIG5vIGNhbGxiYWNrIGZ1bmN0aW9uIG9yIGlmIGNhbGxiYWNrIGlzIG5vdCBhIGNhbGxhYmxlIGZ1bmN0aW9uXG4gICAgICAgICAgICBpZiAoIWlzQ2FsbGFibGUoY2FsbGJhY2tmbikpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcnJheS5wcm90b3R5cGUuZmlsdGVyIGNhbGxiYWNrIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGkgaW4gc2VsZikge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHNlbGZbaV07XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgVCA9PT0gJ3VuZGVmaW5lZCcgPyBjYWxsYmFja2ZuKHZhbHVlLCBpLCBvYmplY3QpIDogY2FsbGJhY2tmbi5jYWxsKFQsIHZhbHVlLCBpLCBvYmplY3QpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwdXNoQ2FsbChyZXN1bHQsIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH1cbiAgICB9LCAhcHJvcGVybHlCb3hlc0NvbnRleHQoQXJyYXlQcm90b3R5cGUuZmlsdGVyKSk7XG5cbiAgICAvLyBFUzUgMTUuNC40LjE2XG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4MTUuNC40LjE2XG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4vSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvQXJyYXkvZXZlcnlcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgIGV2ZXJ5OiBmdW5jdGlvbiBldmVyeShjYWxsYmFja2ZuLyosIHRoaXNBcmcqLykge1xuICAgICAgICAgICAgdmFyIG9iamVjdCA9IEVTLlRvT2JqZWN0KHRoaXMpO1xuICAgICAgICAgICAgdmFyIHNlbGYgPSBzcGxpdFN0cmluZyAmJiBpc1N0cmluZyh0aGlzKSA/IHN0clNwbGl0KHRoaXMsICcnKSA6IG9iamVjdDtcbiAgICAgICAgICAgIHZhciBsZW5ndGggPSBFUy5Ub1VpbnQzMihzZWxmLmxlbmd0aCk7XG4gICAgICAgICAgICB2YXIgVDtcbiAgICAgICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgICAgIFQgPSBhcmd1bWVudHNbMV07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIElmIG5vIGNhbGxiYWNrIGZ1bmN0aW9uIG9yIGlmIGNhbGxiYWNrIGlzIG5vdCBhIGNhbGxhYmxlIGZ1bmN0aW9uXG4gICAgICAgICAgICBpZiAoIWlzQ2FsbGFibGUoY2FsbGJhY2tmbikpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcnJheS5wcm90b3R5cGUuZXZlcnkgY2FsbGJhY2sgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoaSBpbiBzZWxmICYmICEodHlwZW9mIFQgPT09ICd1bmRlZmluZWQnID8gY2FsbGJhY2tmbihzZWxmW2ldLCBpLCBvYmplY3QpIDogY2FsbGJhY2tmbi5jYWxsKFQsIHNlbGZbaV0sIGksIG9iamVjdCkpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH0sICFwcm9wZXJseUJveGVzQ29udGV4dChBcnJheVByb3RvdHlwZS5ldmVyeSkpO1xuXG4gICAgLy8gRVM1IDE1LjQuNC4xN1xuICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDE1LjQuNC4xN1xuICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0FycmF5L3NvbWVcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgIHNvbWU6IGZ1bmN0aW9uIHNvbWUoY2FsbGJhY2tmbi8qLCB0aGlzQXJnICovKSB7XG4gICAgICAgICAgICB2YXIgb2JqZWN0ID0gRVMuVG9PYmplY3QodGhpcyk7XG4gICAgICAgICAgICB2YXIgc2VsZiA9IHNwbGl0U3RyaW5nICYmIGlzU3RyaW5nKHRoaXMpID8gc3RyU3BsaXQodGhpcywgJycpIDogb2JqZWN0O1xuICAgICAgICAgICAgdmFyIGxlbmd0aCA9IEVTLlRvVWludDMyKHNlbGYubGVuZ3RoKTtcbiAgICAgICAgICAgIHZhciBUO1xuICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgVCA9IGFyZ3VtZW50c1sxXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gSWYgbm8gY2FsbGJhY2sgZnVuY3Rpb24gb3IgaWYgY2FsbGJhY2sgaXMgbm90IGEgY2FsbGFibGUgZnVuY3Rpb25cbiAgICAgICAgICAgIGlmICghaXNDYWxsYWJsZShjYWxsYmFja2ZuKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FycmF5LnByb3RvdHlwZS5zb21lIGNhbGxiYWNrIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGkgaW4gc2VsZiAmJiAodHlwZW9mIFQgPT09ICd1bmRlZmluZWQnID8gY2FsbGJhY2tmbihzZWxmW2ldLCBpLCBvYmplY3QpIDogY2FsbGJhY2tmbi5jYWxsKFQsIHNlbGZbaV0sIGksIG9iamVjdCkpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH0sICFwcm9wZXJseUJveGVzQ29udGV4dChBcnJheVByb3RvdHlwZS5zb21lKSk7XG5cbiAgICAvLyBFUzUgMTUuNC40LjIxXG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4MTUuNC40LjIxXG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4vQ29yZV9KYXZhU2NyaXB0XzEuNV9SZWZlcmVuY2UvT2JqZWN0cy9BcnJheS9yZWR1Y2VcbiAgICB2YXIgcmVkdWNlQ29lcmNlc1RvT2JqZWN0ID0gZmFsc2U7XG4gICAgaWYgKEFycmF5UHJvdG90eXBlLnJlZHVjZSkge1xuICAgICAgICByZWR1Y2VDb2VyY2VzVG9PYmplY3QgPSB0eXBlb2YgQXJyYXlQcm90b3R5cGUucmVkdWNlLmNhbGwoJ2VzNScsIGZ1bmN0aW9uIChfLCBfXywgX19fLCBsaXN0KSB7XG4gICAgICAgICAgICByZXR1cm4gbGlzdDtcbiAgICAgICAgfSkgPT09ICdvYmplY3QnO1xuICAgIH1cbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgIHJlZHVjZTogZnVuY3Rpb24gcmVkdWNlKGNhbGxiYWNrZm4vKiwgaW5pdGlhbFZhbHVlKi8pIHtcbiAgICAgICAgICAgIHZhciBvYmplY3QgPSBFUy5Ub09iamVjdCh0aGlzKTtcbiAgICAgICAgICAgIHZhciBzZWxmID0gc3BsaXRTdHJpbmcgJiYgaXNTdHJpbmcodGhpcykgPyBzdHJTcGxpdCh0aGlzLCAnJykgOiBvYmplY3Q7XG4gICAgICAgICAgICB2YXIgbGVuZ3RoID0gRVMuVG9VaW50MzIoc2VsZi5sZW5ndGgpO1xuXG4gICAgICAgICAgICAvLyBJZiBubyBjYWxsYmFjayBmdW5jdGlvbiBvciBpZiBjYWxsYmFjayBpcyBub3QgYSBjYWxsYWJsZSBmdW5jdGlvblxuICAgICAgICAgICAgaWYgKCFpc0NhbGxhYmxlKGNhbGxiYWNrZm4pKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJyYXkucHJvdG90eXBlLnJlZHVjZSBjYWxsYmFjayBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gbm8gdmFsdWUgdG8gcmV0dXJuIGlmIG5vIGluaXRpYWwgdmFsdWUgYW5kIGFuIGVtcHR5IGFycmF5XG4gICAgICAgICAgICBpZiAobGVuZ3RoID09PSAwICYmIGFyZ3VtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdyZWR1Y2Ugb2YgZW1wdHkgYXJyYXkgd2l0aCBubyBpbml0aWFsIHZhbHVlJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBpID0gMDtcbiAgICAgICAgICAgIHZhciByZXN1bHQ7XG4gICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSAyKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gYXJndW1lbnRzWzFdO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBkbyB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpIGluIHNlbGYpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHNlbGZbaSsrXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gaWYgYXJyYXkgY29udGFpbnMgbm8gdmFsdWVzLCBubyBpbml0aWFsIHZhbHVlIHRvIHJldHVyblxuICAgICAgICAgICAgICAgICAgICBpZiAoKytpID49IGxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigncmVkdWNlIG9mIGVtcHR5IGFycmF5IHdpdGggbm8gaW5pdGlhbCB2YWx1ZScpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSB3aGlsZSAodHJ1ZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZvciAoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoaSBpbiBzZWxmKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGNhbGxiYWNrZm4ocmVzdWx0LCBzZWxmW2ldLCBpLCBvYmplY3QpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfVxuICAgIH0sICFyZWR1Y2VDb2VyY2VzVG9PYmplY3QpO1xuXG4gICAgLy8gRVM1IDE1LjQuNC4yMlxuICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDE1LjQuNC4yMlxuICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL0NvcmVfSmF2YVNjcmlwdF8xLjVfUmVmZXJlbmNlL09iamVjdHMvQXJyYXkvcmVkdWNlUmlnaHRcbiAgICB2YXIgcmVkdWNlUmlnaHRDb2VyY2VzVG9PYmplY3QgPSBmYWxzZTtcbiAgICBpZiAoQXJyYXlQcm90b3R5cGUucmVkdWNlUmlnaHQpIHtcbiAgICAgICAgcmVkdWNlUmlnaHRDb2VyY2VzVG9PYmplY3QgPSB0eXBlb2YgQXJyYXlQcm90b3R5cGUucmVkdWNlUmlnaHQuY2FsbCgnZXM1JywgZnVuY3Rpb24gKF8sIF9fLCBfX18sIGxpc3QpIHtcbiAgICAgICAgICAgIHJldHVybiBsaXN0O1xuICAgICAgICB9KSA9PT0gJ29iamVjdCc7XG4gICAgfVxuICAgIGRlZmluZVByb3BlcnRpZXMoQXJyYXlQcm90b3R5cGUsIHtcbiAgICAgICAgcmVkdWNlUmlnaHQ6IGZ1bmN0aW9uIHJlZHVjZVJpZ2h0KGNhbGxiYWNrZm4vKiwgaW5pdGlhbCovKSB7XG4gICAgICAgICAgICB2YXIgb2JqZWN0ID0gRVMuVG9PYmplY3QodGhpcyk7XG4gICAgICAgICAgICB2YXIgc2VsZiA9IHNwbGl0U3RyaW5nICYmIGlzU3RyaW5nKHRoaXMpID8gc3RyU3BsaXQodGhpcywgJycpIDogb2JqZWN0O1xuICAgICAgICAgICAgdmFyIGxlbmd0aCA9IEVTLlRvVWludDMyKHNlbGYubGVuZ3RoKTtcblxuICAgICAgICAgICAgLy8gSWYgbm8gY2FsbGJhY2sgZnVuY3Rpb24gb3IgaWYgY2FsbGJhY2sgaXMgbm90IGEgY2FsbGFibGUgZnVuY3Rpb25cbiAgICAgICAgICAgIGlmICghaXNDYWxsYWJsZShjYWxsYmFja2ZuKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FycmF5LnByb3RvdHlwZS5yZWR1Y2VSaWdodCBjYWxsYmFjayBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gbm8gdmFsdWUgdG8gcmV0dXJuIGlmIG5vIGluaXRpYWwgdmFsdWUsIGVtcHR5IGFycmF5XG4gICAgICAgICAgICBpZiAobGVuZ3RoID09PSAwICYmIGFyZ3VtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdyZWR1Y2VSaWdodCBvZiBlbXB0eSBhcnJheSB3aXRoIG5vIGluaXRpYWwgdmFsdWUnKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIHJlc3VsdDtcbiAgICAgICAgICAgIHZhciBpID0gbGVuZ3RoIC0gMTtcbiAgICAgICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDIpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBhcmd1bWVudHNbMV07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGkgaW4gc2VsZikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gc2VsZltpLS1dO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBpZiBhcnJheSBjb250YWlucyBubyB2YWx1ZXMsIG5vIGluaXRpYWwgdmFsdWUgdG8gcmV0dXJuXG4gICAgICAgICAgICAgICAgICAgIGlmICgtLWkgPCAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdyZWR1Y2VSaWdodCBvZiBlbXB0eSBhcnJheSB3aXRoIG5vIGluaXRpYWwgdmFsdWUnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gd2hpbGUgKHRydWUpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoaSA8IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBkbyB7XG4gICAgICAgICAgICAgICAgaWYgKGkgaW4gc2VsZikge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBjYWxsYmFja2ZuKHJlc3VsdCwgc2VsZltpXSwgaSwgb2JqZWN0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IHdoaWxlIChpLS0pO1xuXG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG4gICAgfSwgIXJlZHVjZVJpZ2h0Q29lcmNlc1RvT2JqZWN0KTtcblxuICAgIC8vIEVTNSAxNS40LjQuMTRcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS40LjQuMTRcbiAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9BcnJheS9pbmRleE9mXG4gICAgdmFyIGhhc0ZpcmVmb3gySW5kZXhPZkJ1ZyA9IEFycmF5UHJvdG90eXBlLmluZGV4T2YgJiYgWzAsIDFdLmluZGV4T2YoMSwgMikgIT09IC0xO1xuICAgIGRlZmluZVByb3BlcnRpZXMoQXJyYXlQcm90b3R5cGUsIHtcbiAgICAgICAgaW5kZXhPZjogZnVuY3Rpb24gaW5kZXhPZihzZWFyY2hFbGVtZW50LyosIGZyb21JbmRleCAqLykge1xuICAgICAgICAgICAgdmFyIHNlbGYgPSBzcGxpdFN0cmluZyAmJiBpc1N0cmluZyh0aGlzKSA/IHN0clNwbGl0KHRoaXMsICcnKSA6IEVTLlRvT2JqZWN0KHRoaXMpO1xuICAgICAgICAgICAgdmFyIGxlbmd0aCA9IEVTLlRvVWludDMyKHNlbGYubGVuZ3RoKTtcblxuICAgICAgICAgICAgaWYgKGxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIGkgPSAwO1xuICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgaSA9IEVTLlRvSW50ZWdlcihhcmd1bWVudHNbMV0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBoYW5kbGUgbmVnYXRpdmUgaW5kaWNlc1xuICAgICAgICAgICAgaSA9IGkgPj0gMCA/IGkgOiBtYXgoMCwgbGVuZ3RoICsgaSk7XG4gICAgICAgICAgICBmb3IgKDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGkgaW4gc2VsZiAmJiBzZWxmW2ldID09PSBzZWFyY2hFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgfVxuICAgIH0sIGhhc0ZpcmVmb3gySW5kZXhPZkJ1Zyk7XG5cbiAgICAvLyBFUzUgMTUuNC40LjE1XG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4MTUuNC40LjE1XG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4vSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvQXJyYXkvbGFzdEluZGV4T2ZcbiAgICB2YXIgaGFzRmlyZWZveDJMYXN0SW5kZXhPZkJ1ZyA9IEFycmF5UHJvdG90eXBlLmxhc3RJbmRleE9mICYmIFswLCAxXS5sYXN0SW5kZXhPZigwLCAtMykgIT09IC0xO1xuICAgIGRlZmluZVByb3BlcnRpZXMoQXJyYXlQcm90b3R5cGUsIHtcbiAgICAgICAgbGFzdEluZGV4T2Y6IGZ1bmN0aW9uIGxhc3RJbmRleE9mKHNlYXJjaEVsZW1lbnQvKiwgZnJvbUluZGV4ICovKSB7XG4gICAgICAgICAgICB2YXIgc2VsZiA9IHNwbGl0U3RyaW5nICYmIGlzU3RyaW5nKHRoaXMpID8gc3RyU3BsaXQodGhpcywgJycpIDogRVMuVG9PYmplY3QodGhpcyk7XG4gICAgICAgICAgICB2YXIgbGVuZ3RoID0gRVMuVG9VaW50MzIoc2VsZi5sZW5ndGgpO1xuXG4gICAgICAgICAgICBpZiAobGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGkgPSBsZW5ndGggLSAxO1xuICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgaSA9IG1pbihpLCBFUy5Ub0ludGVnZXIoYXJndW1lbnRzWzFdKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBoYW5kbGUgbmVnYXRpdmUgaW5kaWNlc1xuICAgICAgICAgICAgaSA9IGkgPj0gMCA/IGkgOiBsZW5ndGggLSBNYXRoLmFicyhpKTtcbiAgICAgICAgICAgIGZvciAoOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgICAgIGlmIChpIGluIHNlbGYgJiYgc2VhcmNoRWxlbWVudCA9PT0gc2VsZltpXSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIH1cbiAgICB9LCBoYXNGaXJlZm94Mkxhc3RJbmRleE9mQnVnKTtcblxuICAgIC8vIEVTNSAxNS40LjQuMTJcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS40LjQuMTJcbiAgICB2YXIgc3BsaWNlTm9vcFJldHVybnNFbXB0eUFycmF5ID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGEgPSBbMSwgMl07XG4gICAgICAgIHZhciByZXN1bHQgPSBhLnNwbGljZSgpO1xuICAgICAgICByZXR1cm4gYS5sZW5ndGggPT09IDIgJiYgaXNBcnJheShyZXN1bHQpICYmIHJlc3VsdC5sZW5ndGggPT09IDA7XG4gICAgfSgpKTtcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgIC8vIFNhZmFyaSA1LjAgYnVnIHdoZXJlIC5zcGxpY2UoKSByZXR1cm5zIHVuZGVmaW5lZFxuICAgICAgICBzcGxpY2U6IGZ1bmN0aW9uIHNwbGljZShzdGFydCwgZGVsZXRlQ291bnQpIHtcbiAgICAgICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXlfc3BsaWNlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LCAhc3BsaWNlTm9vcFJldHVybnNFbXB0eUFycmF5KTtcblxuICAgIHZhciBzcGxpY2VXb3Jrc1dpdGhFbXB0eU9iamVjdCA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBvYmogPSB7fTtcbiAgICAgICAgQXJyYXlQcm90b3R5cGUuc3BsaWNlLmNhbGwob2JqLCAwLCAwLCAxKTtcbiAgICAgICAgcmV0dXJuIG9iai5sZW5ndGggPT09IDE7XG4gICAgfSgpKTtcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgIHNwbGljZTogZnVuY3Rpb24gc3BsaWNlKHN0YXJ0LCBkZWxldGVDb3VudCkge1xuICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgYXJncyA9IGFyZ3VtZW50cztcbiAgICAgICAgICAgIHRoaXMubGVuZ3RoID0gbWF4KEVTLlRvSW50ZWdlcih0aGlzLmxlbmd0aCksIDApO1xuICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIHR5cGVvZiBkZWxldGVDb3VudCAhPT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgICBhcmdzID0gYXJyYXlTbGljZShhcmd1bWVudHMpO1xuICAgICAgICAgICAgICAgIGlmIChhcmdzLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgcHVzaENhbGwoYXJncywgdGhpcy5sZW5ndGggLSBzdGFydCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYXJnc1sxXSA9IEVTLlRvSW50ZWdlcihkZWxldGVDb3VudCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGFycmF5X3NwbGljZS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgfVxuICAgIH0sICFzcGxpY2VXb3Jrc1dpdGhFbXB0eU9iamVjdCk7XG4gICAgdmFyIHNwbGljZVdvcmtzV2l0aExhcmdlU3BhcnNlQXJyYXlzID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gUGVyIGh0dHBzOi8vZ2l0aHViLmNvbS9lcy1zaGltcy9lczUtc2hpbS9pc3N1ZXMvMjk1XG4gICAgICAgIC8vIFNhZmFyaSA3LzggYnJlYWtzIHdpdGggc3BhcnNlIGFycmF5cyBvZiBzaXplIDFlNSBvciBncmVhdGVyXG4gICAgICAgIHZhciBhcnIgPSBuZXcgJEFycmF5KDFlNSk7XG4gICAgICAgIC8vIG5vdGU6IHRoZSBpbmRleCBNVVNUIGJlIDggb3IgbGFyZ2VyIG9yIHRoZSB0ZXN0IHdpbGwgZmFsc2UgcGFzc1xuICAgICAgICBhcnJbOF0gPSAneCc7XG4gICAgICAgIGFyci5zcGxpY2UoMSwgMSk7XG4gICAgICAgIC8vIG5vdGU6IHRoaXMgdGVzdCBtdXN0IGJlIGRlZmluZWQgKmFmdGVyKiB0aGUgaW5kZXhPZiBzaGltXG4gICAgICAgIC8vIHBlciBodHRwczovL2dpdGh1Yi5jb20vZXMtc2hpbXMvZXM1LXNoaW0vaXNzdWVzLzMxM1xuICAgICAgICByZXR1cm4gYXJyLmluZGV4T2YoJ3gnKSA9PT0gNztcbiAgICB9KCkpO1xuICAgIHZhciBzcGxpY2VXb3Jrc1dpdGhTbWFsbFNwYXJzZUFycmF5cyA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIFBlciBodHRwczovL2dpdGh1Yi5jb20vZXMtc2hpbXMvZXM1LXNoaW0vaXNzdWVzLzI5NVxuICAgICAgICAvLyBPcGVyYSAxMi4xNSBicmVha3Mgb24gdGhpcywgbm8gaWRlYSB3aHkuXG4gICAgICAgIHZhciBuID0gMjU2O1xuICAgICAgICB2YXIgYXJyID0gW107XG4gICAgICAgIGFycltuXSA9ICdhJztcbiAgICAgICAgYXJyLnNwbGljZShuICsgMSwgMCwgJ2InKTtcbiAgICAgICAgcmV0dXJuIGFycltuXSA9PT0gJ2EnO1xuICAgIH0oKSk7XG4gICAgZGVmaW5lUHJvcGVydGllcyhBcnJheVByb3RvdHlwZSwge1xuICAgICAgICBzcGxpY2U6IGZ1bmN0aW9uIHNwbGljZShzdGFydCwgZGVsZXRlQ291bnQpIHtcbiAgICAgICAgICAgIHZhciBPID0gRVMuVG9PYmplY3QodGhpcyk7XG4gICAgICAgICAgICB2YXIgQSA9IFtdO1xuICAgICAgICAgICAgdmFyIGxlbiA9IEVTLlRvVWludDMyKE8ubGVuZ3RoKTtcbiAgICAgICAgICAgIHZhciByZWxhdGl2ZVN0YXJ0ID0gRVMuVG9JbnRlZ2VyKHN0YXJ0KTtcbiAgICAgICAgICAgIHZhciBhY3R1YWxTdGFydCA9IHJlbGF0aXZlU3RhcnQgPCAwID8gbWF4KChsZW4gKyByZWxhdGl2ZVN0YXJ0KSwgMCkgOiBtaW4ocmVsYXRpdmVTdGFydCwgbGVuKTtcbiAgICAgICAgICAgIHZhciBhY3R1YWxEZWxldGVDb3VudCA9IG1pbihtYXgoRVMuVG9JbnRlZ2VyKGRlbGV0ZUNvdW50KSwgMCksIGxlbiAtIGFjdHVhbFN0YXJ0KTtcblxuICAgICAgICAgICAgdmFyIGsgPSAwO1xuICAgICAgICAgICAgdmFyIGZyb207XG4gICAgICAgICAgICB3aGlsZSAoayA8IGFjdHVhbERlbGV0ZUNvdW50KSB7XG4gICAgICAgICAgICAgICAgZnJvbSA9ICRTdHJpbmcoYWN0dWFsU3RhcnQgKyBrKTtcbiAgICAgICAgICAgICAgICBpZiAob3ducyhPLCBmcm9tKSkge1xuICAgICAgICAgICAgICAgICAgICBBW2tdID0gT1tmcm9tXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgayArPSAxO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgaXRlbXMgPSBhcnJheVNsaWNlKGFyZ3VtZW50cywgMik7XG4gICAgICAgICAgICB2YXIgaXRlbUNvdW50ID0gaXRlbXMubGVuZ3RoO1xuICAgICAgICAgICAgdmFyIHRvO1xuICAgICAgICAgICAgaWYgKGl0ZW1Db3VudCA8IGFjdHVhbERlbGV0ZUNvdW50KSB7XG4gICAgICAgICAgICAgICAgayA9IGFjdHVhbFN0YXJ0O1xuICAgICAgICAgICAgICAgIHZhciBtYXhLID0gbGVuIC0gYWN0dWFsRGVsZXRlQ291bnQ7XG4gICAgICAgICAgICAgICAgd2hpbGUgKGsgPCBtYXhLKSB7XG4gICAgICAgICAgICAgICAgICAgIGZyb20gPSAkU3RyaW5nKGsgKyBhY3R1YWxEZWxldGVDb3VudCk7XG4gICAgICAgICAgICAgICAgICAgIHRvID0gJFN0cmluZyhrICsgaXRlbUNvdW50KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG93bnMoTywgZnJvbSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIE9bdG9dID0gT1tmcm9tXTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBPW3RvXTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBrICs9IDE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGsgPSBsZW47XG4gICAgICAgICAgICAgICAgdmFyIG1pbksgPSBsZW4gLSBhY3R1YWxEZWxldGVDb3VudCArIGl0ZW1Db3VudDtcbiAgICAgICAgICAgICAgICB3aGlsZSAoayA+IG1pbkspIHtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIE9bayAtIDFdO1xuICAgICAgICAgICAgICAgICAgICBrIC09IDE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChpdGVtQ291bnQgPiBhY3R1YWxEZWxldGVDb3VudCkge1xuICAgICAgICAgICAgICAgIGsgPSBsZW4gLSBhY3R1YWxEZWxldGVDb3VudDtcbiAgICAgICAgICAgICAgICB3aGlsZSAoayA+IGFjdHVhbFN0YXJ0KSB7XG4gICAgICAgICAgICAgICAgICAgIGZyb20gPSAkU3RyaW5nKGsgKyBhY3R1YWxEZWxldGVDb3VudCAtIDEpO1xuICAgICAgICAgICAgICAgICAgICB0byA9ICRTdHJpbmcoayArIGl0ZW1Db3VudCAtIDEpO1xuICAgICAgICAgICAgICAgICAgICBpZiAob3ducyhPLCBmcm9tKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgT1t0b10gPSBPW2Zyb21dO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIE9bdG9dO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGsgLT0gMTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBrID0gYWN0dWFsU3RhcnQ7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGl0ZW1zLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgT1trXSA9IGl0ZW1zW2ldO1xuICAgICAgICAgICAgICAgIGsgKz0gMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIE8ubGVuZ3RoID0gbGVuIC0gYWN0dWFsRGVsZXRlQ291bnQgKyBpdGVtQ291bnQ7XG5cbiAgICAgICAgICAgIHJldHVybiBBO1xuICAgICAgICB9XG4gICAgfSwgIXNwbGljZVdvcmtzV2l0aExhcmdlU3BhcnNlQXJyYXlzIHx8ICFzcGxpY2VXb3Jrc1dpdGhTbWFsbFNwYXJzZUFycmF5cyk7XG5cbiAgICB2YXIgb3JpZ2luYWxKb2luID0gQXJyYXlQcm90b3R5cGUuam9pbjtcbiAgICB2YXIgaGFzU3RyaW5nSm9pbkJ1ZztcbiAgICB0cnkge1xuICAgICAgICBoYXNTdHJpbmdKb2luQnVnID0gQXJyYXkucHJvdG90eXBlLmpvaW4uY2FsbCgnMTIzJywgJywnKSAhPT0gJzEsMiwzJztcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGhhc1N0cmluZ0pvaW5CdWcgPSB0cnVlO1xuICAgIH1cbiAgICBpZiAoaGFzU3RyaW5nSm9pbkJ1Zykge1xuICAgICAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgICAgICBqb2luOiBmdW5jdGlvbiBqb2luKHNlcGFyYXRvcikge1xuICAgICAgICAgICAgICAgIHZhciBzZXAgPSB0eXBlb2Ygc2VwYXJhdG9yID09PSAndW5kZWZpbmVkJyA/ICcsJyA6IHNlcGFyYXRvcjtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3JpZ2luYWxKb2luLmNhbGwoaXNTdHJpbmcodGhpcykgPyBzdHJTcGxpdCh0aGlzLCAnJykgOiB0aGlzLCBzZXApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCBoYXNTdHJpbmdKb2luQnVnKTtcbiAgICB9XG5cbiAgICB2YXIgaGFzSm9pblVuZGVmaW5lZEJ1ZyA9IFsxLCAyXS5qb2luKHVuZGVmaW5lZCkgIT09ICcxLDInO1xuICAgIGlmIChoYXNKb2luVW5kZWZpbmVkQnVnKSB7XG4gICAgICAgIGRlZmluZVByb3BlcnRpZXMoQXJyYXlQcm90b3R5cGUsIHtcbiAgICAgICAgICAgIGpvaW46IGZ1bmN0aW9uIGpvaW4oc2VwYXJhdG9yKSB7XG4gICAgICAgICAgICAgICAgdmFyIHNlcCA9IHR5cGVvZiBzZXBhcmF0b3IgPT09ICd1bmRlZmluZWQnID8gJywnIDogc2VwYXJhdG9yO1xuICAgICAgICAgICAgICAgIHJldHVybiBvcmlnaW5hbEpvaW4uY2FsbCh0aGlzLCBzZXApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCBoYXNKb2luVW5kZWZpbmVkQnVnKTtcbiAgICB9XG5cbiAgICB2YXIgcHVzaFNoaW0gPSBmdW5jdGlvbiBwdXNoKGl0ZW0pIHtcbiAgICAgICAgdmFyIE8gPSBFUy5Ub09iamVjdCh0aGlzKTtcbiAgICAgICAgdmFyIG4gPSBFUy5Ub1VpbnQzMihPLmxlbmd0aCk7XG4gICAgICAgIHZhciBpID0gMDtcbiAgICAgICAgd2hpbGUgKGkgPCBhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICAgICAgICBPW24gKyBpXSA9IGFyZ3VtZW50c1tpXTtcbiAgICAgICAgICAgIGkgKz0gMTtcbiAgICAgICAgfVxuICAgICAgICBPLmxlbmd0aCA9IG4gKyBpO1xuICAgICAgICByZXR1cm4gbiArIGk7XG4gICAgfTtcblxuICAgIHZhciBwdXNoSXNOb3RHZW5lcmljID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG9iaiA9IHt9O1xuICAgICAgICB2YXIgcmVzdWx0ID0gQXJyYXkucHJvdG90eXBlLnB1c2guY2FsbChvYmosIHVuZGVmaW5lZCk7XG4gICAgICAgIHJldHVybiByZXN1bHQgIT09IDEgfHwgb2JqLmxlbmd0aCAhPT0gMSB8fCB0eXBlb2Ygb2JqWzBdICE9PSAndW5kZWZpbmVkJyB8fCAhb3ducyhvYmosIDApO1xuICAgIH0oKSk7XG4gICAgZGVmaW5lUHJvcGVydGllcyhBcnJheVByb3RvdHlwZSwge1xuICAgICAgICBwdXNoOiBmdW5jdGlvbiBwdXNoKGl0ZW0pIHtcbiAgICAgICAgICAgIGlmIChpc0FycmF5KHRoaXMpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFycmF5X3B1c2guYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBwdXNoU2hpbS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB9XG4gICAgfSwgcHVzaElzTm90R2VuZXJpYyk7XG5cbiAgICAvLyBUaGlzIGZpeGVzIGEgdmVyeSB3ZWlyZCBidWcgaW4gT3BlcmEgMTAuNiB3aGVuIHB1c2hpbmcgYHVuZGVmaW5lZFxuICAgIHZhciBwdXNoVW5kZWZpbmVkSXNXZWlyZCA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBhcnIgPSBbXTtcbiAgICAgICAgdmFyIHJlc3VsdCA9IGFyci5wdXNoKHVuZGVmaW5lZCk7XG4gICAgICAgIHJldHVybiByZXN1bHQgIT09IDEgfHwgYXJyLmxlbmd0aCAhPT0gMSB8fCB0eXBlb2YgYXJyWzBdICE9PSAndW5kZWZpbmVkJyB8fCAhb3ducyhhcnIsIDApO1xuICAgIH0oKSk7XG4gICAgZGVmaW5lUHJvcGVydGllcyhBcnJheVByb3RvdHlwZSwgeyBwdXNoOiBwdXNoU2hpbSB9LCBwdXNoVW5kZWZpbmVkSXNXZWlyZCk7XG5cbiAgICAvLyBFUzUgMTUuMi4zLjE0XG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuaW8vI3gxNS40LjQuMTBcbiAgICAvLyBGaXggYm94ZWQgc3RyaW5nIGJ1Z1xuICAgIGRlZmluZVByb3BlcnRpZXMoQXJyYXlQcm90b3R5cGUsIHtcbiAgICAgICAgc2xpY2U6IGZ1bmN0aW9uIChzdGFydCwgZW5kKSB7XG4gICAgICAgICAgICB2YXIgYXJyID0gaXNTdHJpbmcodGhpcykgPyBzdHJTcGxpdCh0aGlzLCAnJykgOiB0aGlzO1xuICAgICAgICAgICAgcmV0dXJuIGFycmF5U2xpY2VBcHBseShhcnIsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cbiAgICB9LCBzcGxpdFN0cmluZyk7XG5cbiAgICB2YXIgc29ydElnbm9yZXNOb25GdW5jdGlvbnMgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgWzEsIDJdLnNvcnQobnVsbCk7XG4gICAgICAgICAgICBbMSwgMl0uc29ydCh7fSk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSBjYXRjaCAoZSkge31cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0oKSk7XG4gICAgdmFyIHNvcnRUaHJvd3NPblJlZ2V4ID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gdGhpcyBpcyBhIHByb2JsZW0gaW4gRmlyZWZveCA0LCBpbiB3aGljaCBgdHlwZW9mIC9hLyA9PT0gJ2Z1bmN0aW9uJ2BcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIFsxLCAyXS5zb3J0KC9hLyk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH0oKSk7XG4gICAgdmFyIHNvcnRJZ25vcmVzVW5kZWZpbmVkID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gYXBwbGllcyBpbiBJRSA4LCBmb3Igb25lLlxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgWzEsIDJdLnNvcnQodW5kZWZpbmVkKTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9IGNhdGNoIChlKSB7fVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSgpKTtcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKEFycmF5UHJvdG90eXBlLCB7XG4gICAgICAgIHNvcnQ6IGZ1bmN0aW9uIHNvcnQoY29tcGFyZUZuKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGNvbXBhcmVGbiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXJyYXlTb3J0KHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFpc0NhbGxhYmxlKGNvbXBhcmVGbikpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcnJheS5wcm90b3R5cGUuc29ydCBjYWxsYmFjayBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBhcnJheVNvcnQodGhpcywgY29tcGFyZUZuKTtcbiAgICAgICAgfVxuICAgIH0sIHNvcnRJZ25vcmVzTm9uRnVuY3Rpb25zIHx8ICFzb3J0SWdub3Jlc1VuZGVmaW5lZCB8fCAhc29ydFRocm93c09uUmVnZXgpO1xuXG4gICAgLy9cbiAgICAvLyBPYmplY3RcbiAgICAvLyA9PT09PT1cbiAgICAvL1xuXG4gICAgLy8gRVM1IDE1LjIuMy4xNFxuICAgIC8vIGh0dHA6Ly9lczUuZ2l0aHViLmNvbS8jeDE1LjIuMy4xNFxuXG4gICAgLy8gaHR0cDovL3doYXR0aGVoZWFkc2FpZC5jb20vMjAxMC8xMC9hLXNhZmVyLW9iamVjdC1rZXlzLWNvbXBhdGliaWxpdHktaW1wbGVtZW50YXRpb25cbiAgICB2YXIgaGFzRG9udEVudW1CdWcgPSAhaXNFbnVtKHsgJ3RvU3RyaW5nJzogbnVsbCB9LCAndG9TdHJpbmcnKTtcbiAgICB2YXIgaGFzUHJvdG9FbnVtQnVnID0gaXNFbnVtKGZ1bmN0aW9uICgpIHt9LCAncHJvdG90eXBlJyk7XG4gICAgdmFyIGhhc1N0cmluZ0VudW1CdWcgPSAhb3ducygneCcsICcwJyk7XG4gICAgdmFyIGVxdWFsc0NvbnN0cnVjdG9yUHJvdG90eXBlID0gZnVuY3Rpb24gKG8pIHtcbiAgICAgICAgdmFyIGN0b3IgPSBvLmNvbnN0cnVjdG9yO1xuICAgICAgICByZXR1cm4gY3RvciAmJiBjdG9yLnByb3RvdHlwZSA9PT0gbztcbiAgICB9O1xuICAgIHZhciBibGFja2xpc3RlZEtleXMgPSB7XG4gICAgICAgICR3aW5kb3c6IHRydWUsXG4gICAgICAgICRjb25zb2xlOiB0cnVlLFxuICAgICAgICAkcGFyZW50OiB0cnVlLFxuICAgICAgICAkc2VsZjogdHJ1ZSxcbiAgICAgICAgJGZyYW1lOiB0cnVlLFxuICAgICAgICAkZnJhbWVzOiB0cnVlLFxuICAgICAgICAkZnJhbWVFbGVtZW50OiB0cnVlLFxuICAgICAgICAkd2Via2l0SW5kZXhlZERCOiB0cnVlLFxuICAgICAgICAkd2Via2l0U3RvcmFnZUluZm86IHRydWUsXG4gICAgICAgICRleHRlcm5hbDogdHJ1ZVxuICAgIH07XG4gICAgdmFyIGhhc0F1dG9tYXRpb25FcXVhbGl0eUJ1ZyA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8qIGdsb2JhbHMgd2luZG93ICovXG4gICAgICAgIGlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGZvciAodmFyIGsgaW4gd2luZG93KSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICghYmxhY2tsaXN0ZWRLZXlzWyckJyArIGtdICYmIG93bnMod2luZG93LCBrKSAmJiB3aW5kb3dba10gIT09IG51bGwgJiYgdHlwZW9mIHdpbmRvd1trXSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUod2luZG93W2tdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0oKSk7XG4gICAgdmFyIGVxdWFsc0NvbnN0cnVjdG9yUHJvdG90eXBlSWZOb3RCdWdneSA9IGZ1bmN0aW9uIChvYmplY3QpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnIHx8ICFoYXNBdXRvbWF0aW9uRXF1YWxpdHlCdWcpIHtcbiAgICAgICAgICAgIHJldHVybiBlcXVhbHNDb25zdHJ1Y3RvclByb3RvdHlwZShvYmplY3QpO1xuICAgICAgICB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGUob2JqZWN0KTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfTtcbiAgICB2YXIgZG9udEVudW1zID0gW1xuICAgICAgICAndG9TdHJpbmcnLFxuICAgICAgICAndG9Mb2NhbGVTdHJpbmcnLFxuICAgICAgICAndmFsdWVPZicsXG4gICAgICAgICdoYXNPd25Qcm9wZXJ0eScsXG4gICAgICAgICdpc1Byb3RvdHlwZU9mJyxcbiAgICAgICAgJ3Byb3BlcnR5SXNFbnVtZXJhYmxlJyxcbiAgICAgICAgJ2NvbnN0cnVjdG9yJ1xuICAgIF07XG4gICAgdmFyIGRvbnRFbnVtc0xlbmd0aCA9IGRvbnRFbnVtcy5sZW5ndGg7XG5cbiAgICAvLyB0YWtlbiBkaXJlY3RseSBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9samhhcmIvaXMtYXJndW1lbnRzL2Jsb2IvbWFzdGVyL2luZGV4LmpzXG4gICAgLy8gY2FuIGJlIHJlcGxhY2VkIHdpdGggcmVxdWlyZSgnaXMtYXJndW1lbnRzJykgaWYgd2UgZXZlciB1c2UgYSBidWlsZCBwcm9jZXNzIGluc3RlYWRcbiAgICB2YXIgaXNTdGFuZGFyZEFyZ3VtZW50cyA9IGZ1bmN0aW9uIGlzQXJndW1lbnRzKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB0b1N0cih2YWx1ZSkgPT09ICdbb2JqZWN0IEFyZ3VtZW50c10nO1xuICAgIH07XG4gICAgdmFyIGlzTGVnYWN5QXJndW1lbnRzID0gZnVuY3Rpb24gaXNBcmd1bWVudHModmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlICE9PSBudWxsICYmXG4gICAgICAgICAgICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmXG4gICAgICAgICAgICB0eXBlb2YgdmFsdWUubGVuZ3RoID09PSAnbnVtYmVyJyAmJlxuICAgICAgICAgICAgdmFsdWUubGVuZ3RoID49IDAgJiZcbiAgICAgICAgICAgICFpc0FycmF5KHZhbHVlKSAmJlxuICAgICAgICAgICAgaXNDYWxsYWJsZSh2YWx1ZS5jYWxsZWUpO1xuICAgIH07XG4gICAgdmFyIGlzQXJndW1lbnRzID0gaXNTdGFuZGFyZEFyZ3VtZW50cyhhcmd1bWVudHMpID8gaXNTdGFuZGFyZEFyZ3VtZW50cyA6IGlzTGVnYWN5QXJndW1lbnRzO1xuXG4gICAgZGVmaW5lUHJvcGVydGllcygkT2JqZWN0LCB7XG4gICAgICAgIGtleXM6IGZ1bmN0aW9uIGtleXMob2JqZWN0KSB7XG4gICAgICAgICAgICB2YXIgaXNGbiA9IGlzQ2FsbGFibGUob2JqZWN0KTtcbiAgICAgICAgICAgIHZhciBpc0FyZ3MgPSBpc0FyZ3VtZW50cyhvYmplY3QpO1xuICAgICAgICAgICAgdmFyIGlzT2JqZWN0ID0gb2JqZWN0ICE9PSBudWxsICYmIHR5cGVvZiBvYmplY3QgPT09ICdvYmplY3QnO1xuICAgICAgICAgICAgdmFyIGlzU3RyID0gaXNPYmplY3QgJiYgaXNTdHJpbmcob2JqZWN0KTtcblxuICAgICAgICAgICAgaWYgKCFpc09iamVjdCAmJiAhaXNGbiAmJiAhaXNBcmdzKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignT2JqZWN0LmtleXMgY2FsbGVkIG9uIGEgbm9uLW9iamVjdCcpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgdGhlS2V5cyA9IFtdO1xuICAgICAgICAgICAgdmFyIHNraXBQcm90byA9IGhhc1Byb3RvRW51bUJ1ZyAmJiBpc0ZuO1xuICAgICAgICAgICAgaWYgKChpc1N0ciAmJiBoYXNTdHJpbmdFbnVtQnVnKSB8fCBpc0FyZ3MpIHtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgICAgICBwdXNoQ2FsbCh0aGVLZXlzLCAkU3RyaW5nKGkpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghaXNBcmdzKSB7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgbmFtZSBpbiBvYmplY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEoc2tpcFByb3RvICYmIG5hbWUgPT09ICdwcm90b3R5cGUnKSAmJiBvd25zKG9iamVjdCwgbmFtZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1c2hDYWxsKHRoZUtleXMsICRTdHJpbmcobmFtZSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoaGFzRG9udEVudW1CdWcpIHtcbiAgICAgICAgICAgICAgICB2YXIgc2tpcENvbnN0cnVjdG9yID0gZXF1YWxzQ29uc3RydWN0b3JQcm90b3R5cGVJZk5vdEJ1Z2d5KG9iamVjdCk7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBkb250RW51bXNMZW5ndGg7IGorKykge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZG9udEVudW0gPSBkb250RW51bXNbal07XG4gICAgICAgICAgICAgICAgICAgIGlmICghKHNraXBDb25zdHJ1Y3RvciAmJiBkb250RW51bSA9PT0gJ2NvbnN0cnVjdG9yJykgJiYgb3ducyhvYmplY3QsIGRvbnRFbnVtKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcHVzaENhbGwodGhlS2V5cywgZG9udEVudW0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoZUtleXM7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIHZhciBrZXlzV29ya3NXaXRoQXJndW1lbnRzID0gJE9iamVjdC5rZXlzICYmIChmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIFNhZmFyaSA1LjAgYnVnXG4gICAgICAgIHJldHVybiAkT2JqZWN0LmtleXMoYXJndW1lbnRzKS5sZW5ndGggPT09IDI7XG4gICAgfSgxLCAyKSk7XG4gICAgdmFyIGtleXNIYXNBcmd1bWVudHNMZW5ndGhCdWcgPSAkT2JqZWN0LmtleXMgJiYgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGFyZ0tleXMgPSAkT2JqZWN0LmtleXMoYXJndW1lbnRzKTtcbiAgICAgICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggIT09IDEgfHwgYXJnS2V5cy5sZW5ndGggIT09IDEgfHwgYXJnS2V5c1swXSAhPT0gMTtcbiAgICB9KDEpKTtcbiAgICB2YXIgb3JpZ2luYWxLZXlzID0gJE9iamVjdC5rZXlzO1xuICAgIGRlZmluZVByb3BlcnRpZXMoJE9iamVjdCwge1xuICAgICAgICBrZXlzOiBmdW5jdGlvbiBrZXlzKG9iamVjdCkge1xuICAgICAgICAgICAgaWYgKGlzQXJndW1lbnRzKG9iamVjdCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3JpZ2luYWxLZXlzKGFycmF5U2xpY2Uob2JqZWN0KSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBvcmlnaW5hbEtleXMob2JqZWN0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0sICFrZXlzV29ya3NXaXRoQXJndW1lbnRzIHx8IGtleXNIYXNBcmd1bWVudHNMZW5ndGhCdWcpO1xuXG4gICAgLy9cbiAgICAvLyBEYXRlXG4gICAgLy8gPT09PVxuICAgIC8vXG5cbiAgICB2YXIgaGFzTmVnYXRpdmVNb250aFllYXJCdWcgPSBuZXcgRGF0ZSgtMzUwOTgyNzMyOTYwMDI5MikuZ2V0VVRDTW9udGgoKSAhPT0gMDtcbiAgICB2YXIgYU5lZ2F0aXZlVGVzdERhdGUgPSBuZXcgRGF0ZSgtMTUwOTg0MjI4OTYwMDI5Mik7XG4gICAgdmFyIGFQb3NpdGl2ZVRlc3REYXRlID0gbmV3IERhdGUoMTQ0OTY2MjQwMDAwMCk7XG4gICAgdmFyIGhhc1RvVVRDU3RyaW5nRm9ybWF0QnVnID0gYU5lZ2F0aXZlVGVzdERhdGUudG9VVENTdHJpbmcoKSAhPT0gJ01vbiwgMDEgSmFuIC00NTg3NSAxMTo1OTo1OSBHTVQnO1xuICAgIHZhciBoYXNUb0RhdGVTdHJpbmdGb3JtYXRCdWc7XG4gICAgdmFyIGhhc1RvU3RyaW5nRm9ybWF0QnVnO1xuICAgIHZhciB0aW1lWm9uZU9mZnNldCA9IGFOZWdhdGl2ZVRlc3REYXRlLmdldFRpbWV6b25lT2Zmc2V0KCk7XG4gICAgaWYgKHRpbWVab25lT2Zmc2V0IDwgLTcyMCkge1xuICAgICAgICBoYXNUb0RhdGVTdHJpbmdGb3JtYXRCdWcgPSBhTmVnYXRpdmVUZXN0RGF0ZS50b0RhdGVTdHJpbmcoKSAhPT0gJ1R1ZSBKYW4gMDIgLTQ1ODc1JztcbiAgICAgICAgaGFzVG9TdHJpbmdGb3JtYXRCdWcgPSAhKC9eVGh1IERlYyAxMCAyMDE1IFxcZFxcZDpcXGRcXGQ6XFxkXFxkIEdNVFstXFwrXVxcZFxcZFxcZFxcZCg/OiB8JCkvKS50ZXN0KGFQb3NpdGl2ZVRlc3REYXRlLnRvU3RyaW5nKCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGhhc1RvRGF0ZVN0cmluZ0Zvcm1hdEJ1ZyA9IGFOZWdhdGl2ZVRlc3REYXRlLnRvRGF0ZVN0cmluZygpICE9PSAnTW9uIEphbiAwMSAtNDU4NzUnO1xuICAgICAgICBoYXNUb1N0cmluZ0Zvcm1hdEJ1ZyA9ICEoL15XZWQgRGVjIDA5IDIwMTUgXFxkXFxkOlxcZFxcZDpcXGRcXGQgR01UWy1cXCtdXFxkXFxkXFxkXFxkKD86IHwkKS8pLnRlc3QoYVBvc2l0aXZlVGVzdERhdGUudG9TdHJpbmcoKSk7XG4gICAgfVxuXG4gICAgdmFyIG9yaWdpbmFsR2V0RnVsbFllYXIgPSBjYWxsLmJpbmQoRGF0ZS5wcm90b3R5cGUuZ2V0RnVsbFllYXIpO1xuICAgIHZhciBvcmlnaW5hbEdldE1vbnRoID0gY2FsbC5iaW5kKERhdGUucHJvdG90eXBlLmdldE1vbnRoKTtcbiAgICB2YXIgb3JpZ2luYWxHZXREYXRlID0gY2FsbC5iaW5kKERhdGUucHJvdG90eXBlLmdldERhdGUpO1xuICAgIHZhciBvcmlnaW5hbEdldFVUQ0Z1bGxZZWFyID0gY2FsbC5iaW5kKERhdGUucHJvdG90eXBlLmdldFVUQ0Z1bGxZZWFyKTtcbiAgICB2YXIgb3JpZ2luYWxHZXRVVENNb250aCA9IGNhbGwuYmluZChEYXRlLnByb3RvdHlwZS5nZXRVVENNb250aCk7XG4gICAgdmFyIG9yaWdpbmFsR2V0VVRDRGF0ZSA9IGNhbGwuYmluZChEYXRlLnByb3RvdHlwZS5nZXRVVENEYXRlKTtcbiAgICB2YXIgb3JpZ2luYWxHZXRVVENEYXkgPSBjYWxsLmJpbmQoRGF0ZS5wcm90b3R5cGUuZ2V0VVRDRGF5KTtcbiAgICB2YXIgb3JpZ2luYWxHZXRVVENIb3VycyA9IGNhbGwuYmluZChEYXRlLnByb3RvdHlwZS5nZXRVVENIb3Vycyk7XG4gICAgdmFyIG9yaWdpbmFsR2V0VVRDTWludXRlcyA9IGNhbGwuYmluZChEYXRlLnByb3RvdHlwZS5nZXRVVENNaW51dGVzKTtcbiAgICB2YXIgb3JpZ2luYWxHZXRVVENTZWNvbmRzID0gY2FsbC5iaW5kKERhdGUucHJvdG90eXBlLmdldFVUQ1NlY29uZHMpO1xuICAgIHZhciBvcmlnaW5hbEdldFVUQ01pbGxpc2Vjb25kcyA9IGNhbGwuYmluZChEYXRlLnByb3RvdHlwZS5nZXRVVENNaWxsaXNlY29uZHMpO1xuICAgIHZhciBkYXlOYW1lID0gWydTdW4nLCAnTW9uJywgJ1R1ZScsICdXZWQnLCAnVGh1JywgJ0ZyaScsICdTYXQnXTtcbiAgICB2YXIgbW9udGhOYW1lID0gWydKYW4nLCAnRmViJywgJ01hcicsICdBcHInLCAnTWF5JywgJ0p1bicsICdKdWwnLCAnQXVnJywgJ1NlcCcsICdPY3QnLCAnTm92JywgJ0RlYyddO1xuICAgIHZhciBkYXlzSW5Nb250aCA9IGZ1bmN0aW9uIGRheXNJbk1vbnRoKG1vbnRoLCB5ZWFyKSB7XG4gICAgICAgIHJldHVybiBvcmlnaW5hbEdldERhdGUobmV3IERhdGUoeWVhciwgbW9udGgsIDApKTtcbiAgICB9O1xuXG4gICAgZGVmaW5lUHJvcGVydGllcyhEYXRlLnByb3RvdHlwZSwge1xuICAgICAgICBnZXRGdWxsWWVhcjogZnVuY3Rpb24gZ2V0RnVsbFllYXIoKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMgfHwgISh0aGlzIGluc3RhbmNlb2YgRGF0ZSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCd0aGlzIGlzIG5vdCBhIERhdGUgb2JqZWN0LicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHllYXIgPSBvcmlnaW5hbEdldEZ1bGxZZWFyKHRoaXMpO1xuICAgICAgICAgICAgaWYgKHllYXIgPCAwICYmIG9yaWdpbmFsR2V0TW9udGgodGhpcykgPiAxMSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB5ZWFyICsgMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB5ZWFyO1xuICAgICAgICB9LFxuICAgICAgICBnZXRNb250aDogZnVuY3Rpb24gZ2V0TW9udGgoKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMgfHwgISh0aGlzIGluc3RhbmNlb2YgRGF0ZSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCd0aGlzIGlzIG5vdCBhIERhdGUgb2JqZWN0LicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHllYXIgPSBvcmlnaW5hbEdldEZ1bGxZZWFyKHRoaXMpO1xuICAgICAgICAgICAgdmFyIG1vbnRoID0gb3JpZ2luYWxHZXRNb250aCh0aGlzKTtcbiAgICAgICAgICAgIGlmICh5ZWFyIDwgMCAmJiBtb250aCA+IDExKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbW9udGg7XG4gICAgICAgIH0sXG4gICAgICAgIGdldERhdGU6IGZ1bmN0aW9uIGdldERhdGUoKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMgfHwgISh0aGlzIGluc3RhbmNlb2YgRGF0ZSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCd0aGlzIGlzIG5vdCBhIERhdGUgb2JqZWN0LicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHllYXIgPSBvcmlnaW5hbEdldEZ1bGxZZWFyKHRoaXMpO1xuICAgICAgICAgICAgdmFyIG1vbnRoID0gb3JpZ2luYWxHZXRNb250aCh0aGlzKTtcbiAgICAgICAgICAgIHZhciBkYXRlID0gb3JpZ2luYWxHZXREYXRlKHRoaXMpO1xuICAgICAgICAgICAgaWYgKHllYXIgPCAwICYmIG1vbnRoID4gMTEpIHtcbiAgICAgICAgICAgICAgICBpZiAobW9udGggPT09IDEyKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBkYXRlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB2YXIgZGF5cyA9IGRheXNJbk1vbnRoKDAsIHllYXIgKyAxKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gKGRheXMgLSBkYXRlKSArIDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZGF0ZTtcbiAgICAgICAgfSxcbiAgICAgICAgZ2V0VVRDRnVsbFllYXI6IGZ1bmN0aW9uIGdldFVUQ0Z1bGxZZWFyKCkge1xuICAgICAgICAgICAgaWYgKCF0aGlzIHx8ICEodGhpcyBpbnN0YW5jZW9mIERhdGUpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndGhpcyBpcyBub3QgYSBEYXRlIG9iamVjdC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciB5ZWFyID0gb3JpZ2luYWxHZXRVVENGdWxsWWVhcih0aGlzKTtcbiAgICAgICAgICAgIGlmICh5ZWFyIDwgMCAmJiBvcmlnaW5hbEdldFVUQ01vbnRoKHRoaXMpID4gMTEpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4geWVhciArIDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4geWVhcjtcbiAgICAgICAgfSxcbiAgICAgICAgZ2V0VVRDTW9udGg6IGZ1bmN0aW9uIGdldFVUQ01vbnRoKCkge1xuICAgICAgICAgICAgaWYgKCF0aGlzIHx8ICEodGhpcyBpbnN0YW5jZW9mIERhdGUpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndGhpcyBpcyBub3QgYSBEYXRlIG9iamVjdC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciB5ZWFyID0gb3JpZ2luYWxHZXRVVENGdWxsWWVhcih0aGlzKTtcbiAgICAgICAgICAgIHZhciBtb250aCA9IG9yaWdpbmFsR2V0VVRDTW9udGgodGhpcyk7XG4gICAgICAgICAgICBpZiAoeWVhciA8IDAgJiYgbW9udGggPiAxMSkge1xuICAgICAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG1vbnRoO1xuICAgICAgICB9LFxuICAgICAgICBnZXRVVENEYXRlOiBmdW5jdGlvbiBnZXRVVENEYXRlKCkge1xuICAgICAgICAgICAgaWYgKCF0aGlzIHx8ICEodGhpcyBpbnN0YW5jZW9mIERhdGUpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndGhpcyBpcyBub3QgYSBEYXRlIG9iamVjdC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciB5ZWFyID0gb3JpZ2luYWxHZXRVVENGdWxsWWVhcih0aGlzKTtcbiAgICAgICAgICAgIHZhciBtb250aCA9IG9yaWdpbmFsR2V0VVRDTW9udGgodGhpcyk7XG4gICAgICAgICAgICB2YXIgZGF0ZSA9IG9yaWdpbmFsR2V0VVRDRGF0ZSh0aGlzKTtcbiAgICAgICAgICAgIGlmICh5ZWFyIDwgMCAmJiBtb250aCA+IDExKSB7XG4gICAgICAgICAgICAgICAgaWYgKG1vbnRoID09PSAxMikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGF0ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmFyIGRheXMgPSBkYXlzSW5Nb250aCgwLCB5ZWFyICsgMSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChkYXlzIC0gZGF0ZSkgKyAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGRhdGU7XG4gICAgICAgIH1cbiAgICB9LCBoYXNOZWdhdGl2ZU1vbnRoWWVhckJ1Zyk7XG5cbiAgICBkZWZpbmVQcm9wZXJ0aWVzKERhdGUucHJvdG90eXBlLCB7XG4gICAgICAgIHRvVVRDU3RyaW5nOiBmdW5jdGlvbiB0b1VUQ1N0cmluZygpIHtcbiAgICAgICAgICAgIGlmICghdGhpcyB8fCAhKHRoaXMgaW5zdGFuY2VvZiBEYXRlKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3RoaXMgaXMgbm90IGEgRGF0ZSBvYmplY3QuJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgZGF5ID0gb3JpZ2luYWxHZXRVVENEYXkodGhpcyk7XG4gICAgICAgICAgICB2YXIgZGF0ZSA9IG9yaWdpbmFsR2V0VVRDRGF0ZSh0aGlzKTtcbiAgICAgICAgICAgIHZhciBtb250aCA9IG9yaWdpbmFsR2V0VVRDTW9udGgodGhpcyk7XG4gICAgICAgICAgICB2YXIgeWVhciA9IG9yaWdpbmFsR2V0VVRDRnVsbFllYXIodGhpcyk7XG4gICAgICAgICAgICB2YXIgaG91ciA9IG9yaWdpbmFsR2V0VVRDSG91cnModGhpcyk7XG4gICAgICAgICAgICB2YXIgbWludXRlID0gb3JpZ2luYWxHZXRVVENNaW51dGVzKHRoaXMpO1xuICAgICAgICAgICAgdmFyIHNlY29uZCA9IG9yaWdpbmFsR2V0VVRDU2Vjb25kcyh0aGlzKTtcbiAgICAgICAgICAgIHJldHVybiBkYXlOYW1lW2RheV0gKyAnLCAnICtcbiAgICAgICAgICAgICAgICAoZGF0ZSA8IDEwID8gJzAnICsgZGF0ZSA6IGRhdGUpICsgJyAnICtcbiAgICAgICAgICAgICAgICBtb250aE5hbWVbbW9udGhdICsgJyAnICtcbiAgICAgICAgICAgICAgICB5ZWFyICsgJyAnICtcbiAgICAgICAgICAgICAgICAoaG91ciA8IDEwID8gJzAnICsgaG91ciA6IGhvdXIpICsgJzonICtcbiAgICAgICAgICAgICAgICAobWludXRlIDwgMTAgPyAnMCcgKyBtaW51dGUgOiBtaW51dGUpICsgJzonICtcbiAgICAgICAgICAgICAgICAoc2Vjb25kIDwgMTAgPyAnMCcgKyBzZWNvbmQgOiBzZWNvbmQpICsgJyBHTVQnO1xuICAgICAgICB9XG4gICAgfSwgaGFzTmVnYXRpdmVNb250aFllYXJCdWcgfHwgaGFzVG9VVENTdHJpbmdGb3JtYXRCdWcpO1xuXG4gICAgLy8gT3BlcmEgMTIgaGFzIGAsYFxuICAgIGRlZmluZVByb3BlcnRpZXMoRGF0ZS5wcm90b3R5cGUsIHtcbiAgICAgICAgdG9EYXRlU3RyaW5nOiBmdW5jdGlvbiB0b0RhdGVTdHJpbmcoKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMgfHwgISh0aGlzIGluc3RhbmNlb2YgRGF0ZSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCd0aGlzIGlzIG5vdCBhIERhdGUgb2JqZWN0LicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGRheSA9IHRoaXMuZ2V0RGF5KCk7XG4gICAgICAgICAgICB2YXIgZGF0ZSA9IHRoaXMuZ2V0RGF0ZSgpO1xuICAgICAgICAgICAgdmFyIG1vbnRoID0gdGhpcy5nZXRNb250aCgpO1xuICAgICAgICAgICAgdmFyIHllYXIgPSB0aGlzLmdldEZ1bGxZZWFyKCk7XG4gICAgICAgICAgICByZXR1cm4gZGF5TmFtZVtkYXldICsgJyAnICtcbiAgICAgICAgICAgICAgICBtb250aE5hbWVbbW9udGhdICsgJyAnICtcbiAgICAgICAgICAgICAgICAoZGF0ZSA8IDEwID8gJzAnICsgZGF0ZSA6IGRhdGUpICsgJyAnICtcbiAgICAgICAgICAgICAgICB5ZWFyO1xuICAgICAgICB9XG4gICAgfSwgaGFzTmVnYXRpdmVNb250aFllYXJCdWcgfHwgaGFzVG9EYXRlU3RyaW5nRm9ybWF0QnVnKTtcblxuICAgIC8vIGNhbid0IHVzZSBkZWZpbmVQcm9wZXJ0aWVzIGhlcmUgYmVjYXVzZSBvZiB0b1N0cmluZyBlbnVtZXJhdGlvbiBpc3N1ZSBpbiBJRSA8PSA4XG4gICAgaWYgKGhhc05lZ2F0aXZlTW9udGhZZWFyQnVnIHx8IGhhc1RvU3RyaW5nRm9ybWF0QnVnKSB7XG4gICAgICAgIERhdGUucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcoKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMgfHwgISh0aGlzIGluc3RhbmNlb2YgRGF0ZSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCd0aGlzIGlzIG5vdCBhIERhdGUgb2JqZWN0LicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGRheSA9IHRoaXMuZ2V0RGF5KCk7XG4gICAgICAgICAgICB2YXIgZGF0ZSA9IHRoaXMuZ2V0RGF0ZSgpO1xuICAgICAgICAgICAgdmFyIG1vbnRoID0gdGhpcy5nZXRNb250aCgpO1xuICAgICAgICAgICAgdmFyIHllYXIgPSB0aGlzLmdldEZ1bGxZZWFyKCk7XG4gICAgICAgICAgICB2YXIgaG91ciA9IHRoaXMuZ2V0SG91cnMoKTtcbiAgICAgICAgICAgIHZhciBtaW51dGUgPSB0aGlzLmdldE1pbnV0ZXMoKTtcbiAgICAgICAgICAgIHZhciBzZWNvbmQgPSB0aGlzLmdldFNlY29uZHMoKTtcbiAgICAgICAgICAgIHZhciB0aW1lem9uZU9mZnNldCA9IHRoaXMuZ2V0VGltZXpvbmVPZmZzZXQoKTtcbiAgICAgICAgICAgIHZhciBob3Vyc09mZnNldCA9IE1hdGguZmxvb3IoTWF0aC5hYnModGltZXpvbmVPZmZzZXQpIC8gNjApO1xuICAgICAgICAgICAgdmFyIG1pbnV0ZXNPZmZzZXQgPSBNYXRoLmZsb29yKE1hdGguYWJzKHRpbWV6b25lT2Zmc2V0KSAlIDYwKTtcbiAgICAgICAgICAgIHJldHVybiBkYXlOYW1lW2RheV0gKyAnICcgK1xuICAgICAgICAgICAgICAgIG1vbnRoTmFtZVttb250aF0gKyAnICcgK1xuICAgICAgICAgICAgICAgIChkYXRlIDwgMTAgPyAnMCcgKyBkYXRlIDogZGF0ZSkgKyAnICcgK1xuICAgICAgICAgICAgICAgIHllYXIgKyAnICcgK1xuICAgICAgICAgICAgICAgIChob3VyIDwgMTAgPyAnMCcgKyBob3VyIDogaG91cikgKyAnOicgK1xuICAgICAgICAgICAgICAgIChtaW51dGUgPCAxMCA/ICcwJyArIG1pbnV0ZSA6IG1pbnV0ZSkgKyAnOicgK1xuICAgICAgICAgICAgICAgIChzZWNvbmQgPCAxMCA/ICcwJyArIHNlY29uZCA6IHNlY29uZCkgKyAnIEdNVCcgK1xuICAgICAgICAgICAgICAgICh0aW1lem9uZU9mZnNldCA+IDAgPyAnLScgOiAnKycpICtcbiAgICAgICAgICAgICAgICAoaG91cnNPZmZzZXQgPCAxMCA/ICcwJyArIGhvdXJzT2Zmc2V0IDogaG91cnNPZmZzZXQpICtcbiAgICAgICAgICAgICAgICAobWludXRlc09mZnNldCA8IDEwID8gJzAnICsgbWludXRlc09mZnNldCA6IG1pbnV0ZXNPZmZzZXQpO1xuICAgICAgICB9O1xuICAgICAgICBpZiAoc3VwcG9ydHNEZXNjcmlwdG9ycykge1xuICAgICAgICAgICAgJE9iamVjdC5kZWZpbmVQcm9wZXJ0eShEYXRlLnByb3RvdHlwZSwgJ3RvU3RyaW5nJywge1xuICAgICAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB3cml0YWJsZTogdHJ1ZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBFUzUgMTUuOS41LjQzXG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4MTUuOS41LjQzXG4gICAgLy8gVGhpcyBmdW5jdGlvbiByZXR1cm5zIGEgU3RyaW5nIHZhbHVlIHJlcHJlc2VudCB0aGUgaW5zdGFuY2UgaW4gdGltZVxuICAgIC8vIHJlcHJlc2VudGVkIGJ5IHRoaXMgRGF0ZSBvYmplY3QuIFRoZSBmb3JtYXQgb2YgdGhlIFN0cmluZyBpcyB0aGUgRGF0ZSBUaW1lXG4gICAgLy8gc3RyaW5nIGZvcm1hdCBkZWZpbmVkIGluIDE1LjkuMS4xNS4gQWxsIGZpZWxkcyBhcmUgcHJlc2VudCBpbiB0aGUgU3RyaW5nLlxuICAgIC8vIFRoZSB0aW1lIHpvbmUgaXMgYWx3YXlzIFVUQywgZGVub3RlZCBieSB0aGUgc3VmZml4IFouIElmIHRoZSB0aW1lIHZhbHVlIG9mXG4gICAgLy8gdGhpcyBvYmplY3QgaXMgbm90IGEgZmluaXRlIE51bWJlciBhIFJhbmdlRXJyb3IgZXhjZXB0aW9uIGlzIHRocm93bi5cbiAgICB2YXIgbmVnYXRpdmVEYXRlID0gLTYyMTk4NzU1MjAwMDAwO1xuICAgIHZhciBuZWdhdGl2ZVllYXJTdHJpbmcgPSAnLTAwMDAwMSc7XG4gICAgdmFyIGhhc05lZ2F0aXZlRGF0ZUJ1ZyA9IERhdGUucHJvdG90eXBlLnRvSVNPU3RyaW5nICYmIG5ldyBEYXRlKG5lZ2F0aXZlRGF0ZSkudG9JU09TdHJpbmcoKS5pbmRleE9mKG5lZ2F0aXZlWWVhclN0cmluZykgPT09IC0xO1xuICAgIHZhciBoYXNTYWZhcmk1MURhdGVCdWcgPSBEYXRlLnByb3RvdHlwZS50b0lTT1N0cmluZyAmJiBuZXcgRGF0ZSgtMSkudG9JU09TdHJpbmcoKSAhPT0gJzE5NjktMTItMzFUMjM6NTk6NTkuOTk5Wic7XG5cbiAgICB2YXIgZ2V0VGltZSA9IGNhbGwuYmluZChEYXRlLnByb3RvdHlwZS5nZXRUaW1lKTtcblxuICAgIGRlZmluZVByb3BlcnRpZXMoRGF0ZS5wcm90b3R5cGUsIHtcbiAgICAgICAgdG9JU09TdHJpbmc6IGZ1bmN0aW9uIHRvSVNPU3RyaW5nKCkge1xuICAgICAgICAgICAgaWYgKCFpc0Zpbml0ZSh0aGlzKSB8fCAhaXNGaW5pdGUoZ2V0VGltZSh0aGlzKSkpIHtcbiAgICAgICAgICAgICAgICAvLyBBZG9wZSBQaG90b3Nob3AgcmVxdWlyZXMgdGhlIHNlY29uZCBjaGVjay5cbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignRGF0ZS5wcm90b3R5cGUudG9JU09TdHJpbmcgY2FsbGVkIG9uIG5vbi1maW5pdGUgdmFsdWUuJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciB5ZWFyID0gb3JpZ2luYWxHZXRVVENGdWxsWWVhcih0aGlzKTtcblxuICAgICAgICAgICAgdmFyIG1vbnRoID0gb3JpZ2luYWxHZXRVVENNb250aCh0aGlzKTtcbiAgICAgICAgICAgIC8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vZXMtc2hpbXMvZXM1LXNoaW0vaXNzdWVzLzExMVxuICAgICAgICAgICAgeWVhciArPSBNYXRoLmZsb29yKG1vbnRoIC8gMTIpO1xuICAgICAgICAgICAgbW9udGggPSAobW9udGggJSAxMiArIDEyKSAlIDEyO1xuXG4gICAgICAgICAgICAvLyB0aGUgZGF0ZSB0aW1lIHN0cmluZyBmb3JtYXQgaXMgc3BlY2lmaWVkIGluIDE1LjkuMS4xNS5cbiAgICAgICAgICAgIHZhciByZXN1bHQgPSBbbW9udGggKyAxLCBvcmlnaW5hbEdldFVUQ0RhdGUodGhpcyksIG9yaWdpbmFsR2V0VVRDSG91cnModGhpcyksIG9yaWdpbmFsR2V0VVRDTWludXRlcyh0aGlzKSwgb3JpZ2luYWxHZXRVVENTZWNvbmRzKHRoaXMpXTtcbiAgICAgICAgICAgIHllYXIgPSAoXG4gICAgICAgICAgICAgICAgKHllYXIgPCAwID8gJy0nIDogKHllYXIgPiA5OTk5ID8gJysnIDogJycpKSArXG4gICAgICAgICAgICAgICAgc3RyU2xpY2UoJzAwMDAwJyArIE1hdGguYWJzKHllYXIpLCAoMCA8PSB5ZWFyICYmIHllYXIgPD0gOTk5OSkgPyAtNCA6IC02KVxuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByZXN1bHQubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAvLyBwYWQgbW9udGhzLCBkYXlzLCBob3VycywgbWludXRlcywgYW5kIHNlY29uZHMgdG8gaGF2ZSB0d28gZGlnaXRzLlxuICAgICAgICAgICAgICAgIHJlc3VsdFtpXSA9IHN0clNsaWNlKCcwMCcgKyByZXN1bHRbaV0sIC0yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHBhZCBtaWxsaXNlY29uZHMgdG8gaGF2ZSB0aHJlZSBkaWdpdHMuXG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIHllYXIgKyAnLScgKyBhcnJheVNsaWNlKHJlc3VsdCwgMCwgMikuam9pbignLScpICtcbiAgICAgICAgICAgICAgICAnVCcgKyBhcnJheVNsaWNlKHJlc3VsdCwgMikuam9pbignOicpICsgJy4nICtcbiAgICAgICAgICAgICAgICBzdHJTbGljZSgnMDAwJyArIG9yaWdpbmFsR2V0VVRDTWlsbGlzZWNvbmRzKHRoaXMpLCAtMykgKyAnWidcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICB9LCBoYXNOZWdhdGl2ZURhdGVCdWcgfHwgaGFzU2FmYXJpNTFEYXRlQnVnKTtcblxuICAgIC8vIEVTNSAxNS45LjUuNDRcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS45LjUuNDRcbiAgICAvLyBUaGlzIGZ1bmN0aW9uIHByb3ZpZGVzIGEgU3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGEgRGF0ZSBvYmplY3QgZm9yIHVzZSBieVxuICAgIC8vIEpTT04uc3RyaW5naWZ5ICgxNS4xMi4zKS5cbiAgICB2YXIgZGF0ZVRvSlNPTklzU3VwcG9ydGVkID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiBEYXRlLnByb3RvdHlwZS50b0pTT04gJiZcbiAgICAgICAgICAgICAgICBuZXcgRGF0ZShOYU4pLnRvSlNPTigpID09PSBudWxsICYmXG4gICAgICAgICAgICAgICAgbmV3IERhdGUobmVnYXRpdmVEYXRlKS50b0pTT04oKS5pbmRleE9mKG5lZ2F0aXZlWWVhclN0cmluZykgIT09IC0xICYmXG4gICAgICAgICAgICAgICAgRGF0ZS5wcm90b3R5cGUudG9KU09OLmNhbGwoeyAvLyBnZW5lcmljXG4gICAgICAgICAgICAgICAgICAgIHRvSVNPU3RyaW5nOiBmdW5jdGlvbiAoKSB7IHJldHVybiB0cnVlOyB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH0oKSk7XG4gICAgaWYgKCFkYXRlVG9KU09OSXNTdXBwb3J0ZWQpIHtcbiAgICAgICAgRGF0ZS5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKGtleSkge1xuICAgICAgICAgICAgLy8gV2hlbiB0aGUgdG9KU09OIG1ldGhvZCBpcyBjYWxsZWQgd2l0aCBhcmd1bWVudCBrZXksIHRoZSBmb2xsb3dpbmdcbiAgICAgICAgICAgIC8vIHN0ZXBzIGFyZSB0YWtlbjpcblxuICAgICAgICAgICAgLy8gMS4gIExldCBPIGJlIHRoZSByZXN1bHQgb2YgY2FsbGluZyBUb09iamVjdCwgZ2l2aW5nIGl0IHRoZSB0aGlzXG4gICAgICAgICAgICAvLyB2YWx1ZSBhcyBpdHMgYXJndW1lbnQuXG4gICAgICAgICAgICAvLyAyLiBMZXQgdHYgYmUgRVMuVG9QcmltaXRpdmUoTywgaGludCBOdW1iZXIpLlxuICAgICAgICAgICAgdmFyIE8gPSAkT2JqZWN0KHRoaXMpO1xuICAgICAgICAgICAgdmFyIHR2ID0gRVMuVG9QcmltaXRpdmUoTyk7XG4gICAgICAgICAgICAvLyAzLiBJZiB0diBpcyBhIE51bWJlciBhbmQgaXMgbm90IGZpbml0ZSwgcmV0dXJuIG51bGwuXG4gICAgICAgICAgICBpZiAodHlwZW9mIHR2ID09PSAnbnVtYmVyJyAmJiAhaXNGaW5pdGUodHYpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyA0LiBMZXQgdG9JU08gYmUgdGhlIHJlc3VsdCBvZiBjYWxsaW5nIHRoZSBbW0dldF1dIGludGVybmFsIG1ldGhvZCBvZlxuICAgICAgICAgICAgLy8gTyB3aXRoIGFyZ3VtZW50IFwidG9JU09TdHJpbmdcIi5cbiAgICAgICAgICAgIHZhciB0b0lTTyA9IE8udG9JU09TdHJpbmc7XG4gICAgICAgICAgICAvLyA1LiBJZiBJc0NhbGxhYmxlKHRvSVNPKSBpcyBmYWxzZSwgdGhyb3cgYSBUeXBlRXJyb3IgZXhjZXB0aW9uLlxuICAgICAgICAgICAgaWYgKCFpc0NhbGxhYmxlKHRvSVNPKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3RvSVNPU3RyaW5nIHByb3BlcnR5IGlzIG5vdCBjYWxsYWJsZScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gNi4gUmV0dXJuIHRoZSByZXN1bHQgb2YgY2FsbGluZyB0aGUgW1tDYWxsXV0gaW50ZXJuYWwgbWV0aG9kIG9mXG4gICAgICAgICAgICAvLyAgdG9JU08gd2l0aCBPIGFzIHRoZSB0aGlzIHZhbHVlIGFuZCBhbiBlbXB0eSBhcmd1bWVudCBsaXN0LlxuICAgICAgICAgICAgcmV0dXJuIHRvSVNPLmNhbGwoTyk7XG5cbiAgICAgICAgICAgIC8vIE5PVEUgMSBUaGUgYXJndW1lbnQgaXMgaWdub3JlZC5cblxuICAgICAgICAgICAgLy8gTk9URSAyIFRoZSB0b0pTT04gZnVuY3Rpb24gaXMgaW50ZW50aW9uYWxseSBnZW5lcmljOyBpdCBkb2VzIG5vdFxuICAgICAgICAgICAgLy8gcmVxdWlyZSB0aGF0IGl0cyB0aGlzIHZhbHVlIGJlIGEgRGF0ZSBvYmplY3QuIFRoZXJlZm9yZSwgaXQgY2FuIGJlXG4gICAgICAgICAgICAvLyB0cmFuc2ZlcnJlZCB0byBvdGhlciBraW5kcyBvZiBvYmplY3RzIGZvciB1c2UgYXMgYSBtZXRob2QuIEhvd2V2ZXIsXG4gICAgICAgICAgICAvLyBpdCBkb2VzIHJlcXVpcmUgdGhhdCBhbnkgc3VjaCBvYmplY3QgaGF2ZSBhIHRvSVNPU3RyaW5nIG1ldGhvZC4gQW5cbiAgICAgICAgICAgIC8vIG9iamVjdCBpcyBmcmVlIHRvIHVzZSB0aGUgYXJndW1lbnQga2V5IHRvIGZpbHRlciBpdHNcbiAgICAgICAgICAgIC8vIHN0cmluZ2lmaWNhdGlvbi5cbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBFUzUgMTUuOS40LjJcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS45LjQuMlxuICAgIC8vIGJhc2VkIG9uIHdvcmsgc2hhcmVkIGJ5IERhbmllbCBGcmllc2VuIChkYW50bWFuKVxuICAgIC8vIGh0dHA6Ly9naXN0LmdpdGh1Yi5jb20vMzAzMjQ5XG4gICAgdmFyIHN1cHBvcnRzRXh0ZW5kZWRZZWFycyA9IERhdGUucGFyc2UoJyswMzM2NTgtMDktMjdUMDE6NDY6NDAuMDAwWicpID09PSAxZTE1O1xuICAgIHZhciBhY2NlcHRzSW52YWxpZERhdGVzID0gIWlzTmFOKERhdGUucGFyc2UoJzIwMTItMDQtMDRUMjQ6MDA6MDAuNTAwWicpKSB8fCAhaXNOYU4oRGF0ZS5wYXJzZSgnMjAxMi0xMS0zMVQyMzo1OTo1OS4wMDBaJykpIHx8ICFpc05hTihEYXRlLnBhcnNlKCcyMDEyLTEyLTMxVDIzOjU5OjYwLjAwMFonKSk7XG4gICAgdmFyIGRvZXNOb3RQYXJzZVkyS05ld1llYXIgPSBpc05hTihEYXRlLnBhcnNlKCcyMDAwLTAxLTAxVDAwOjAwOjAwLjAwMFonKSk7XG4gICAgaWYgKGRvZXNOb3RQYXJzZVkyS05ld1llYXIgfHwgYWNjZXB0c0ludmFsaWREYXRlcyB8fCAhc3VwcG9ydHNFeHRlbmRlZFllYXJzKSB7XG4gICAgICAgIC8vIFhYWCBnbG9iYWwgYXNzaWdubWVudCB3b24ndCB3b3JrIGluIGVtYmVkZGluZ3MgdGhhdCB1c2VcbiAgICAgICAgLy8gYW4gYWx0ZXJuYXRlIG9iamVjdCBmb3IgdGhlIGNvbnRleHQuXG4gICAgICAgIC8qIGdsb2JhbCBEYXRlOiB0cnVlICovXG4gICAgICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLXVuZGVmICovXG4gICAgICAgIHZhciBtYXhTYWZlVW5zaWduZWQzMkJpdCA9IE1hdGgucG93KDIsIDMxKSAtIDE7XG4gICAgICAgIHZhciBoYXNTYWZhcmlTaWduZWRJbnRCdWcgPSBpc0FjdHVhbE5hTihuZXcgRGF0ZSgxOTcwLCAwLCAxLCAwLCAwLCAwLCBtYXhTYWZlVW5zaWduZWQzMkJpdCArIDEpLmdldFRpbWUoKSk7XG4gICAgICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLWltcGxpY2l0LWdsb2JhbHMgKi9cbiAgICAgICAgRGF0ZSA9IChmdW5jdGlvbiAoTmF0aXZlRGF0ZSkge1xuICAgICAgICAvKiBlc2xpbnQtZW5hYmxlIG5vLWltcGxpY2l0LWdsb2JhbHMgKi9cbiAgICAgICAgLyogZXNsaW50LWVuYWJsZSBuby11bmRlZiAqL1xuICAgICAgICAgICAgLy8gRGF0ZS5sZW5ndGggPT09IDdcbiAgICAgICAgICAgIHZhciBEYXRlU2hpbSA9IGZ1bmN0aW9uIERhdGUoWSwgTSwgRCwgaCwgbSwgcywgbXMpIHtcbiAgICAgICAgICAgICAgICB2YXIgbGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICAgICAgICAgICAgICB2YXIgZGF0ZTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcyBpbnN0YW5jZW9mIE5hdGl2ZURhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNlY29uZHMgPSBzO1xuICAgICAgICAgICAgICAgICAgICB2YXIgbWlsbGlzID0gbXM7XG4gICAgICAgICAgICAgICAgICAgIGlmIChoYXNTYWZhcmlTaWduZWRJbnRCdWcgJiYgbGVuZ3RoID49IDcgJiYgbXMgPiBtYXhTYWZlVW5zaWduZWQzMkJpdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gd29yayBhcm91bmQgYSBTYWZhcmkgOC85IGJ1ZyB3aGVyZSBpdCB0cmVhdHMgdGhlIHNlY29uZHMgYXMgc2lnbmVkXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbXNUb1NoaWZ0ID0gTWF0aC5mbG9vcihtcyAvIG1heFNhZmVVbnNpZ25lZDMyQml0KSAqIG1heFNhZmVVbnNpZ25lZDMyQml0O1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNUb1NoaWZ0ID0gTWF0aC5mbG9vcihtc1RvU2hpZnQgLyAxZTMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2Vjb25kcyArPSBzVG9TaGlmdDtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1pbGxpcyAtPSBzVG9TaGlmdCAqIDFlMztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBkYXRlID0gbGVuZ3RoID09PSAxICYmICRTdHJpbmcoWSkgPT09IFkgPyAvLyBpc1N0cmluZyhZKVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2UgZXhwbGljaXRseSBwYXNzIGl0IHRocm91Z2ggcGFyc2U6XG4gICAgICAgICAgICAgICAgICAgICAgICBuZXcgTmF0aXZlRGF0ZShEYXRlU2hpbS5wYXJzZShZKSkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2UgaGF2ZSB0byBtYW51YWxseSBtYWtlIGNhbGxzIGRlcGVuZGluZyBvbiBhcmd1bWVudFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gbGVuZ3RoIGhlcmVcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCA+PSA3ID8gbmV3IE5hdGl2ZURhdGUoWSwgTSwgRCwgaCwgbSwgc2Vjb25kcywgbWlsbGlzKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGggPj0gNiA/IG5ldyBOYXRpdmVEYXRlKFksIE0sIEQsIGgsIG0sIHNlY29uZHMpIDpcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCA+PSA1ID8gbmV3IE5hdGl2ZURhdGUoWSwgTSwgRCwgaCwgbSkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoID49IDQgPyBuZXcgTmF0aXZlRGF0ZShZLCBNLCBELCBoKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGggPj0gMyA/IG5ldyBOYXRpdmVEYXRlKFksIE0sIEQpIDpcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCA+PSAyID8gbmV3IE5hdGl2ZURhdGUoWSwgTSkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoID49IDEgPyBuZXcgTmF0aXZlRGF0ZShZIGluc3RhbmNlb2YgTmF0aXZlRGF0ZSA/ICtZIDogWSkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgTmF0aXZlRGF0ZSgpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGRhdGUgPSBOYXRpdmVEYXRlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghaXNQcmltaXRpdmUoZGF0ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gUHJldmVudCBtaXh1cHMgd2l0aCB1bmZpeGVkIERhdGUgb2JqZWN0XG4gICAgICAgICAgICAgICAgICAgIGRlZmluZVByb3BlcnRpZXMoZGF0ZSwgeyBjb25zdHJ1Y3RvcjogRGF0ZVNoaW0gfSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBkYXRlO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLy8gMTUuOS4xLjE1IERhdGUgVGltZSBTdHJpbmcgRm9ybWF0LlxuICAgICAgICAgICAgdmFyIGlzb0RhdGVFeHByZXNzaW9uID0gbmV3IFJlZ0V4cCgnXicgK1xuICAgICAgICAgICAgICAgICcoXFxcXGR7NH18WystXVxcXFxkezZ9KScgKyAvLyBmb3VyLWRpZ2l0IHllYXIgY2FwdHVyZSBvciBzaWduICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIDYtZGlnaXQgZXh0ZW5kZWQgeWVhclxuICAgICAgICAgICAgICAgICcoPzotKFxcXFxkezJ9KScgKyAvLyBvcHRpb25hbCBtb250aCBjYXB0dXJlXG4gICAgICAgICAgICAgICAgJyg/Oi0oXFxcXGR7Mn0pJyArIC8vIG9wdGlvbmFsIGRheSBjYXB0dXJlXG4gICAgICAgICAgICAgICAgJyg/OicgKyAvLyBjYXB0dXJlIGhvdXJzOm1pbnV0ZXM6c2Vjb25kcy5taWxsaXNlY29uZHNcbiAgICAgICAgICAgICAgICAgICAgJ1QoXFxcXGR7Mn0pJyArIC8vIGhvdXJzIGNhcHR1cmVcbiAgICAgICAgICAgICAgICAgICAgJzooXFxcXGR7Mn0pJyArIC8vIG1pbnV0ZXMgY2FwdHVyZVxuICAgICAgICAgICAgICAgICAgICAnKD86JyArIC8vIG9wdGlvbmFsIDpzZWNvbmRzLm1pbGxpc2Vjb25kc1xuICAgICAgICAgICAgICAgICAgICAgICAgJzooXFxcXGR7Mn0pJyArIC8vIHNlY29uZHMgY2FwdHVyZVxuICAgICAgICAgICAgICAgICAgICAgICAgJyg/OihcXFxcLlxcXFxkezEsfSkpPycgKyAvLyBtaWxsaXNlY29uZHMgY2FwdHVyZVxuICAgICAgICAgICAgICAgICAgICAnKT8nICtcbiAgICAgICAgICAgICAgICAnKCcgKyAvLyBjYXB0dXJlIFVUQyBvZmZzZXQgY29tcG9uZW50XG4gICAgICAgICAgICAgICAgICAgICdafCcgKyAvLyBVVEMgY2FwdHVyZVxuICAgICAgICAgICAgICAgICAgICAnKD86JyArIC8vIG9mZnNldCBzcGVjaWZpZXIgKy8taG91cnM6bWludXRlc1xuICAgICAgICAgICAgICAgICAgICAgICAgJyhbLStdKScgKyAvLyBzaWduIGNhcHR1cmVcbiAgICAgICAgICAgICAgICAgICAgICAgICcoXFxcXGR7Mn0pJyArIC8vIGhvdXJzIG9mZnNldCBjYXB0dXJlXG4gICAgICAgICAgICAgICAgICAgICAgICAnOihcXFxcZHsyfSknICsgLy8gbWludXRlcyBvZmZzZXQgY2FwdHVyZVxuICAgICAgICAgICAgICAgICAgICAnKScgK1xuICAgICAgICAgICAgICAgICcpPyk/KT8pPycgK1xuICAgICAgICAgICAgJyQnKTtcblxuICAgICAgICAgICAgdmFyIG1vbnRocyA9IFswLCAzMSwgNTksIDkwLCAxMjAsIDE1MSwgMTgxLCAyMTIsIDI0MywgMjczLCAzMDQsIDMzNCwgMzY1XTtcblxuICAgICAgICAgICAgdmFyIGRheUZyb21Nb250aCA9IGZ1bmN0aW9uIGRheUZyb21Nb250aCh5ZWFyLCBtb250aCkge1xuICAgICAgICAgICAgICAgIHZhciB0ID0gbW9udGggPiAxID8gMSA6IDA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICAgICAgbW9udGhzW21vbnRoXSArXG4gICAgICAgICAgICAgICAgICAgIE1hdGguZmxvb3IoKHllYXIgLSAxOTY5ICsgdCkgLyA0KSAtXG4gICAgICAgICAgICAgICAgICAgIE1hdGguZmxvb3IoKHllYXIgLSAxOTAxICsgdCkgLyAxMDApICtcbiAgICAgICAgICAgICAgICAgICAgTWF0aC5mbG9vcigoeWVhciAtIDE2MDEgKyB0KSAvIDQwMCkgK1xuICAgICAgICAgICAgICAgICAgICAzNjUgKiAoeWVhciAtIDE5NzApXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHZhciB0b1VUQyA9IGZ1bmN0aW9uIHRvVVRDKHQpIHtcbiAgICAgICAgICAgICAgICB2YXIgcyA9IDA7XG4gICAgICAgICAgICAgICAgdmFyIG1zID0gdDtcbiAgICAgICAgICAgICAgICBpZiAoaGFzU2FmYXJpU2lnbmVkSW50QnVnICYmIG1zID4gbWF4U2FmZVVuc2lnbmVkMzJCaXQpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gd29yayBhcm91bmQgYSBTYWZhcmkgOC85IGJ1ZyB3aGVyZSBpdCB0cmVhdHMgdGhlIHNlY29uZHMgYXMgc2lnbmVkXG4gICAgICAgICAgICAgICAgICAgIHZhciBtc1RvU2hpZnQgPSBNYXRoLmZsb29yKG1zIC8gbWF4U2FmZVVuc2lnbmVkMzJCaXQpICogbWF4U2FmZVVuc2lnbmVkMzJCaXQ7XG4gICAgICAgICAgICAgICAgICAgIHZhciBzVG9TaGlmdCA9IE1hdGguZmxvb3IobXNUb1NoaWZ0IC8gMWUzKTtcbiAgICAgICAgICAgICAgICAgICAgcyArPSBzVG9TaGlmdDtcbiAgICAgICAgICAgICAgICAgICAgbXMgLT0gc1RvU2hpZnQgKiAxZTM7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiAkTnVtYmVyKG5ldyBOYXRpdmVEYXRlKDE5NzAsIDAsIDEsIDAsIDAsIHMsIG1zKSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvLyBDb3B5IGFueSBjdXN0b20gbWV0aG9kcyBhIDNyZCBwYXJ0eSBsaWJyYXJ5IG1heSBoYXZlIGFkZGVkXG4gICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gTmF0aXZlRGF0ZSkge1xuICAgICAgICAgICAgICAgIGlmIChvd25zKE5hdGl2ZURhdGUsIGtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgRGF0ZVNoaW1ba2V5XSA9IE5hdGl2ZURhdGVba2V5XTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENvcHkgXCJuYXRpdmVcIiBtZXRob2RzIGV4cGxpY2l0bHk7IHRoZXkgbWF5IGJlIG5vbi1lbnVtZXJhYmxlXG4gICAgICAgICAgICBkZWZpbmVQcm9wZXJ0aWVzKERhdGVTaGltLCB7XG4gICAgICAgICAgICAgICAgbm93OiBOYXRpdmVEYXRlLm5vdyxcbiAgICAgICAgICAgICAgICBVVEM6IE5hdGl2ZURhdGUuVVRDXG4gICAgICAgICAgICB9LCB0cnVlKTtcbiAgICAgICAgICAgIERhdGVTaGltLnByb3RvdHlwZSA9IE5hdGl2ZURhdGUucHJvdG90eXBlO1xuICAgICAgICAgICAgZGVmaW5lUHJvcGVydGllcyhEYXRlU2hpbS5wcm90b3R5cGUsIHtcbiAgICAgICAgICAgICAgICBjb25zdHJ1Y3RvcjogRGF0ZVNoaW1cbiAgICAgICAgICAgIH0sIHRydWUpO1xuXG4gICAgICAgICAgICAvLyBVcGdyYWRlIERhdGUucGFyc2UgdG8gaGFuZGxlIHNpbXBsaWZpZWQgSVNPIDg2MDEgc3RyaW5nc1xuICAgICAgICAgICAgdmFyIHBhcnNlU2hpbSA9IGZ1bmN0aW9uIHBhcnNlKHN0cmluZykge1xuICAgICAgICAgICAgICAgIHZhciBtYXRjaCA9IGlzb0RhdGVFeHByZXNzaW9uLmV4ZWMoc3RyaW5nKTtcbiAgICAgICAgICAgICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gcGFyc2UgbW9udGhzLCBkYXlzLCBob3VycywgbWludXRlcywgc2Vjb25kcywgYW5kIG1pbGxpc2Vjb25kc1xuICAgICAgICAgICAgICAgICAgICAvLyBwcm92aWRlIGRlZmF1bHQgdmFsdWVzIGlmIG5lY2Vzc2FyeVxuICAgICAgICAgICAgICAgICAgICAvLyBwYXJzZSB0aGUgVVRDIG9mZnNldCBjb21wb25lbnRcbiAgICAgICAgICAgICAgICAgICAgdmFyIHllYXIgPSAkTnVtYmVyKG1hdGNoWzFdKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1vbnRoID0gJE51bWJlcihtYXRjaFsyXSB8fCAxKSAtIDEsXG4gICAgICAgICAgICAgICAgICAgICAgICBkYXkgPSAkTnVtYmVyKG1hdGNoWzNdIHx8IDEpIC0gMSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGhvdXIgPSAkTnVtYmVyKG1hdGNoWzRdIHx8IDApLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWludXRlID0gJE51bWJlcihtYXRjaFs1XSB8fCAwKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlY29uZCA9ICROdW1iZXIobWF0Y2hbNl0gfHwgMCksXG4gICAgICAgICAgICAgICAgICAgICAgICBtaWxsaXNlY29uZCA9IE1hdGguZmxvb3IoJE51bWJlcihtYXRjaFs3XSB8fCAwKSAqIDEwMDApLFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gV2hlbiB0aW1lIHpvbmUgaXMgbWlzc2VkLCBsb2NhbCBvZmZzZXQgc2hvdWxkIGJlIHVzZWRcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIChFUyA1LjEgYnVnKVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2VlIGh0dHBzOi8vYnVncy5lY21hc2NyaXB0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTEyXG4gICAgICAgICAgICAgICAgICAgICAgICBpc0xvY2FsVGltZSA9IEJvb2xlYW4obWF0Y2hbNF0gJiYgIW1hdGNoWzhdKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpZ25PZmZzZXQgPSBtYXRjaFs5XSA9PT0gJy0nID8gMSA6IC0xLFxuICAgICAgICAgICAgICAgICAgICAgICAgaG91ck9mZnNldCA9ICROdW1iZXIobWF0Y2hbMTBdIHx8IDApLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWludXRlT2Zmc2V0ID0gJE51bWJlcihtYXRjaFsxMV0gfHwgMCksXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQ7XG4gICAgICAgICAgICAgICAgICAgIHZhciBoYXNNaW51dGVzT3JTZWNvbmRzT3JNaWxsaXNlY29uZHMgPSBtaW51dGUgPiAwIHx8IHNlY29uZCA+IDAgfHwgbWlsbGlzZWNvbmQgPiAwO1xuICAgICAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgICAgICBob3VyIDwgKGhhc01pbnV0ZXNPclNlY29uZHNPck1pbGxpc2Vjb25kcyA/IDI0IDogMjUpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBtaW51dGUgPCA2MCAmJiBzZWNvbmQgPCA2MCAmJiBtaWxsaXNlY29uZCA8IDEwMDAgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIG1vbnRoID4gLTEgJiYgbW9udGggPCAxMiAmJiBob3VyT2Zmc2V0IDwgMjQgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIG1pbnV0ZU9mZnNldCA8IDYwICYmIC8vIGRldGVjdCBpbnZhbGlkIG9mZnNldHNcbiAgICAgICAgICAgICAgICAgICAgICAgIGRheSA+IC0xICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBkYXkgPCAoZGF5RnJvbU1vbnRoKHllYXIsIG1vbnRoICsgMSkgLSBkYXlGcm9tTW9udGgoeWVhciwgbW9udGgpKVxuICAgICAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZGF5RnJvbU1vbnRoKHllYXIsIG1vbnRoKSArIGRheSkgKiAyNCArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaG91ciArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaG91ck9mZnNldCAqIHNpZ25PZmZzZXRcbiAgICAgICAgICAgICAgICAgICAgICAgICkgKiA2MDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVzdWx0ICsgbWludXRlICsgbWludXRlT2Zmc2V0ICogc2lnbk9mZnNldCkgKiA2MCArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vjb25kXG4gICAgICAgICAgICAgICAgICAgICAgICApICogMTAwMCArIG1pbGxpc2Vjb25kO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzTG9jYWxUaW1lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gdG9VVEMocmVzdWx0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgtOC42NGUxNSA8PSByZXN1bHQgJiYgcmVzdWx0IDw9IDguNjRlMTUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBOYU47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBOYXRpdmVEYXRlLnBhcnNlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgZGVmaW5lUHJvcGVydGllcyhEYXRlU2hpbSwgeyBwYXJzZTogcGFyc2VTaGltIH0pO1xuXG4gICAgICAgICAgICByZXR1cm4gRGF0ZVNoaW07XG4gICAgICAgIH0oRGF0ZSkpO1xuICAgICAgICAvKiBnbG9iYWwgRGF0ZTogZmFsc2UgKi9cbiAgICB9XG5cbiAgICAvLyBFUzUgMTUuOS40LjRcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS45LjQuNFxuICAgIGlmICghRGF0ZS5ub3cpIHtcbiAgICAgICAgRGF0ZS5ub3cgPSBmdW5jdGlvbiBub3coKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLy9cbiAgICAvLyBOdW1iZXJcbiAgICAvLyA9PT09PT1cbiAgICAvL1xuXG4gICAgLy8gRVM1LjEgMTUuNy40LjVcbiAgICAvLyBodHRwOi8vZXM1LmdpdGh1Yi5jb20vI3gxNS43LjQuNVxuICAgIHZhciBoYXNUb0ZpeGVkQnVncyA9IE51bWJlclByb3RvdHlwZS50b0ZpeGVkICYmIChcbiAgICAgICgwLjAwMDA4KS50b0ZpeGVkKDMpICE9PSAnMC4wMDAnIHx8XG4gICAgICAoMC45KS50b0ZpeGVkKDApICE9PSAnMScgfHxcbiAgICAgICgxLjI1NSkudG9GaXhlZCgyKSAhPT0gJzEuMjUnIHx8XG4gICAgICAoMTAwMDAwMDAwMDAwMDAwMDEyOCkudG9GaXhlZCgwKSAhPT0gJzEwMDAwMDAwMDAwMDAwMDAxMjgnXG4gICAgKTtcblxuICAgIHZhciB0b0ZpeGVkSGVscGVycyA9IHtcbiAgICAgICAgYmFzZTogMWU3LFxuICAgICAgICBzaXplOiA2LFxuICAgICAgICBkYXRhOiBbMCwgMCwgMCwgMCwgMCwgMF0sXG4gICAgICAgIG11bHRpcGx5OiBmdW5jdGlvbiBtdWx0aXBseShuLCBjKSB7XG4gICAgICAgICAgICB2YXIgaSA9IC0xO1xuICAgICAgICAgICAgdmFyIGMyID0gYztcbiAgICAgICAgICAgIHdoaWxlICgrK2kgPCB0b0ZpeGVkSGVscGVycy5zaXplKSB7XG4gICAgICAgICAgICAgICAgYzIgKz0gbiAqIHRvRml4ZWRIZWxwZXJzLmRhdGFbaV07XG4gICAgICAgICAgICAgICAgdG9GaXhlZEhlbHBlcnMuZGF0YVtpXSA9IGMyICUgdG9GaXhlZEhlbHBlcnMuYmFzZTtcbiAgICAgICAgICAgICAgICBjMiA9IE1hdGguZmxvb3IoYzIgLyB0b0ZpeGVkSGVscGVycy5iYXNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgZGl2aWRlOiBmdW5jdGlvbiBkaXZpZGUobikge1xuICAgICAgICAgICAgdmFyIGkgPSB0b0ZpeGVkSGVscGVycy5zaXplO1xuICAgICAgICAgICAgdmFyIGMgPSAwO1xuICAgICAgICAgICAgd2hpbGUgKC0taSA+PSAwKSB7XG4gICAgICAgICAgICAgICAgYyArPSB0b0ZpeGVkSGVscGVycy5kYXRhW2ldO1xuICAgICAgICAgICAgICAgIHRvRml4ZWRIZWxwZXJzLmRhdGFbaV0gPSBNYXRoLmZsb29yKGMgLyBuKTtcbiAgICAgICAgICAgICAgICBjID0gKGMgJSBuKSAqIHRvRml4ZWRIZWxwZXJzLmJhc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIG51bVRvU3RyaW5nOiBmdW5jdGlvbiBudW1Ub1N0cmluZygpIHtcbiAgICAgICAgICAgIHZhciBpID0gdG9GaXhlZEhlbHBlcnMuc2l6ZTtcbiAgICAgICAgICAgIHZhciBzID0gJyc7XG4gICAgICAgICAgICB3aGlsZSAoLS1pID49IDApIHtcbiAgICAgICAgICAgICAgICBpZiAocyAhPT0gJycgfHwgaSA9PT0gMCB8fCB0b0ZpeGVkSGVscGVycy5kYXRhW2ldICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciB0ID0gJFN0cmluZyh0b0ZpeGVkSGVscGVycy5kYXRhW2ldKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHMgPT09ICcnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzID0gdDtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHMgKz0gc3RyU2xpY2UoJzAwMDAwMDAnLCAwLCA3IC0gdC5sZW5ndGgpICsgdDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzO1xuICAgICAgICB9LFxuICAgICAgICBwb3c6IGZ1bmN0aW9uIHBvdyh4LCBuLCBhY2MpIHtcbiAgICAgICAgICAgIHJldHVybiAobiA9PT0gMCA/IGFjYyA6IChuICUgMiA9PT0gMSA/IHBvdyh4LCBuIC0gMSwgYWNjICogeCkgOiBwb3coeCAqIHgsIG4gLyAyLCBhY2MpKSk7XG4gICAgICAgIH0sXG4gICAgICAgIGxvZzogZnVuY3Rpb24gbG9nKHgpIHtcbiAgICAgICAgICAgIHZhciBuID0gMDtcbiAgICAgICAgICAgIHZhciB4MiA9IHg7XG4gICAgICAgICAgICB3aGlsZSAoeDIgPj0gNDA5Nikge1xuICAgICAgICAgICAgICAgIG4gKz0gMTI7XG4gICAgICAgICAgICAgICAgeDIgLz0gNDA5NjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHdoaWxlICh4MiA+PSAyKSB7XG4gICAgICAgICAgICAgICAgbiArPSAxO1xuICAgICAgICAgICAgICAgIHgyIC89IDI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbjtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB2YXIgdG9GaXhlZFNoaW0gPSBmdW5jdGlvbiB0b0ZpeGVkKGZyYWN0aW9uRGlnaXRzKSB7XG4gICAgICAgIHZhciBmLCB4LCBzLCBtLCBlLCB6LCBqLCBrO1xuXG4gICAgICAgIC8vIFRlc3QgZm9yIE5hTiBhbmQgcm91bmQgZnJhY3Rpb25EaWdpdHMgZG93blxuICAgICAgICBmID0gJE51bWJlcihmcmFjdGlvbkRpZ2l0cyk7XG4gICAgICAgIGYgPSBpc0FjdHVhbE5hTihmKSA/IDAgOiBNYXRoLmZsb29yKGYpO1xuXG4gICAgICAgIGlmIChmIDwgMCB8fCBmID4gMjApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdOdW1iZXIudG9GaXhlZCBjYWxsZWQgd2l0aCBpbnZhbGlkIG51bWJlciBvZiBkZWNpbWFscycpO1xuICAgICAgICB9XG5cbiAgICAgICAgeCA9ICROdW1iZXIodGhpcyk7XG5cbiAgICAgICAgaWYgKGlzQWN0dWFsTmFOKHgpKSB7XG4gICAgICAgICAgICByZXR1cm4gJ05hTic7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiBpdCBpcyB0b28gYmlnIG9yIHNtYWxsLCByZXR1cm4gdGhlIHN0cmluZyB2YWx1ZSBvZiB0aGUgbnVtYmVyXG4gICAgICAgIGlmICh4IDw9IC0xZTIxIHx8IHggPj0gMWUyMSkge1xuICAgICAgICAgICAgcmV0dXJuICRTdHJpbmcoeCk7XG4gICAgICAgIH1cblxuICAgICAgICBzID0gJyc7XG5cbiAgICAgICAgaWYgKHggPCAwKSB7XG4gICAgICAgICAgICBzID0gJy0nO1xuICAgICAgICAgICAgeCA9IC14O1xuICAgICAgICB9XG5cbiAgICAgICAgbSA9ICcwJztcblxuICAgICAgICBpZiAoeCA+IDFlLTIxKSB7XG4gICAgICAgICAgICAvLyAxZS0yMSA8IHggPCAxZTIxXG4gICAgICAgICAgICAvLyAtNzAgPCBsb2cyKHgpIDwgNzBcbiAgICAgICAgICAgIGUgPSB0b0ZpeGVkSGVscGVycy5sb2coeCAqIHRvRml4ZWRIZWxwZXJzLnBvdygyLCA2OSwgMSkpIC0gNjk7XG4gICAgICAgICAgICB6ID0gKGUgPCAwID8geCAqIHRvRml4ZWRIZWxwZXJzLnBvdygyLCAtZSwgMSkgOiB4IC8gdG9GaXhlZEhlbHBlcnMucG93KDIsIGUsIDEpKTtcbiAgICAgICAgICAgIHogKj0gMHgxMDAwMDAwMDAwMDAwMDsgLy8gTWF0aC5wb3coMiwgNTIpO1xuICAgICAgICAgICAgZSA9IDUyIC0gZTtcblxuICAgICAgICAgICAgLy8gLTE4IDwgZSA8IDEyMlxuICAgICAgICAgICAgLy8geCA9IHogLyAyIF4gZVxuICAgICAgICAgICAgaWYgKGUgPiAwKSB7XG4gICAgICAgICAgICAgICAgdG9GaXhlZEhlbHBlcnMubXVsdGlwbHkoMCwgeik7XG4gICAgICAgICAgICAgICAgaiA9IGY7XG5cbiAgICAgICAgICAgICAgICB3aGlsZSAoaiA+PSA3KSB7XG4gICAgICAgICAgICAgICAgICAgIHRvRml4ZWRIZWxwZXJzLm11bHRpcGx5KDFlNywgMCk7XG4gICAgICAgICAgICAgICAgICAgIGogLT0gNztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0b0ZpeGVkSGVscGVycy5tdWx0aXBseSh0b0ZpeGVkSGVscGVycy5wb3coMTAsIGosIDEpLCAwKTtcbiAgICAgICAgICAgICAgICBqID0gZSAtIDE7XG5cbiAgICAgICAgICAgICAgICB3aGlsZSAoaiA+PSAyMykge1xuICAgICAgICAgICAgICAgICAgICB0b0ZpeGVkSGVscGVycy5kaXZpZGUoMSA8PCAyMyk7XG4gICAgICAgICAgICAgICAgICAgIGogLT0gMjM7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdG9GaXhlZEhlbHBlcnMuZGl2aWRlKDEgPDwgaik7XG4gICAgICAgICAgICAgICAgdG9GaXhlZEhlbHBlcnMubXVsdGlwbHkoMSwgMSk7XG4gICAgICAgICAgICAgICAgdG9GaXhlZEhlbHBlcnMuZGl2aWRlKDIpO1xuICAgICAgICAgICAgICAgIG0gPSB0b0ZpeGVkSGVscGVycy5udW1Ub1N0cmluZygpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0b0ZpeGVkSGVscGVycy5tdWx0aXBseSgwLCB6KTtcbiAgICAgICAgICAgICAgICB0b0ZpeGVkSGVscGVycy5tdWx0aXBseSgxIDw8ICgtZSksIDApO1xuICAgICAgICAgICAgICAgIG0gPSB0b0ZpeGVkSGVscGVycy5udW1Ub1N0cmluZygpICsgc3RyU2xpY2UoJzAuMDAwMDAwMDAwMDAwMDAwMDAwMDAnLCAyLCAyICsgZik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZiA+IDApIHtcbiAgICAgICAgICAgIGsgPSBtLmxlbmd0aDtcblxuICAgICAgICAgICAgaWYgKGsgPD0gZikge1xuICAgICAgICAgICAgICAgIG0gPSBzICsgc3RyU2xpY2UoJzAuMDAwMDAwMDAwMDAwMDAwMDAwMCcsIDAsIGYgLSBrICsgMikgKyBtO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBtID0gcyArIHN0clNsaWNlKG0sIDAsIGsgLSBmKSArICcuJyArIHN0clNsaWNlKG0sIGsgLSBmKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG0gPSBzICsgbTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBtO1xuICAgIH07XG4gICAgZGVmaW5lUHJvcGVydGllcyhOdW1iZXJQcm90b3R5cGUsIHsgdG9GaXhlZDogdG9GaXhlZFNoaW0gfSwgaGFzVG9GaXhlZEJ1Z3MpO1xuXG4gICAgdmFyIGhhc1RvUHJlY2lzaW9uVW5kZWZpbmVkQnVnID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiAxLjAudG9QcmVjaXNpb24odW5kZWZpbmVkKSA9PT0gJzEnO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH0oKSk7XG4gICAgdmFyIG9yaWdpbmFsVG9QcmVjaXNpb24gPSBOdW1iZXJQcm90b3R5cGUudG9QcmVjaXNpb247XG4gICAgZGVmaW5lUHJvcGVydGllcyhOdW1iZXJQcm90b3R5cGUsIHtcbiAgICAgICAgdG9QcmVjaXNpb246IGZ1bmN0aW9uIHRvUHJlY2lzaW9uKHByZWNpc2lvbikge1xuICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiBwcmVjaXNpb24gPT09ICd1bmRlZmluZWQnID8gb3JpZ2luYWxUb1ByZWNpc2lvbi5jYWxsKHRoaXMpIDogb3JpZ2luYWxUb1ByZWNpc2lvbi5jYWxsKHRoaXMsIHByZWNpc2lvbik7XG4gICAgICAgIH1cbiAgICB9LCBoYXNUb1ByZWNpc2lvblVuZGVmaW5lZEJ1Zyk7XG5cbiAgICAvL1xuICAgIC8vIFN0cmluZ1xuICAgIC8vID09PT09PVxuICAgIC8vXG5cbiAgICAvLyBFUzUgMTUuNS40LjE0XG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuY29tLyN4MTUuNS40LjE0XG5cbiAgICAvLyBbYnVnZml4LCBJRSBsdCA5LCBmaXJlZm94IDQsIEtvbnF1ZXJvciwgT3BlcmEsIG9ic2N1cmUgYnJvd3NlcnNdXG4gICAgLy8gTWFueSBicm93c2VycyBkbyBub3Qgc3BsaXQgcHJvcGVybHkgd2l0aCByZWd1bGFyIGV4cHJlc3Npb25zIG9yIHRoZXlcbiAgICAvLyBkbyBub3QgcGVyZm9ybSB0aGUgc3BsaXQgY29ycmVjdGx5IHVuZGVyIG9ic2N1cmUgY29uZGl0aW9ucy5cbiAgICAvLyBTZWUgaHR0cDovL2Jsb2cuc3RldmVubGV2aXRoYW4uY29tL2FyY2hpdmVzL2Nyb3NzLWJyb3dzZXItc3BsaXRcbiAgICAvLyBJJ3ZlIHRlc3RlZCBpbiBtYW55IGJyb3dzZXJzIGFuZCB0aGlzIHNlZW1zIHRvIGNvdmVyIHRoZSBkZXZpYW50IG9uZXM6XG4gICAgLy8gICAgJ2FiJy5zcGxpdCgvKD86YWIpKi8pIHNob3VsZCBiZSBbXCJcIiwgXCJcIl0sIG5vdCBbXCJcIl1cbiAgICAvLyAgICAnLicuc3BsaXQoLyguPykoLj8pLykgc2hvdWxkIGJlIFtcIlwiLCBcIi5cIiwgXCJcIiwgXCJcIl0sIG5vdCBbXCJcIiwgXCJcIl1cbiAgICAvLyAgICAndGVzc3QnLnNwbGl0KC8ocykqLykgc2hvdWxkIGJlIFtcInRcIiwgdW5kZWZpbmVkLCBcImVcIiwgXCJzXCIsIFwidFwiXSwgbm90XG4gICAgLy8gICAgICAgW3VuZGVmaW5lZCwgXCJ0XCIsIHVuZGVmaW5lZCwgXCJlXCIsIC4uLl1cbiAgICAvLyAgICAnJy5zcGxpdCgvLj8vKSBzaG91bGQgYmUgW10sIG5vdCBbXCJcIl1cbiAgICAvLyAgICAnLicuc3BsaXQoLygpKCkvKSBzaG91bGQgYmUgW1wiLlwiXSwgbm90IFtcIlwiLCBcIlwiLCBcIi5cIl1cblxuICAgIGlmIChcbiAgICAgICAgJ2FiJy5zcGxpdCgvKD86YWIpKi8pLmxlbmd0aCAhPT0gMiB8fFxuICAgICAgICAnLicuc3BsaXQoLyguPykoLj8pLykubGVuZ3RoICE9PSA0IHx8XG4gICAgICAgICd0ZXNzdCcuc3BsaXQoLyhzKSovKVsxXSA9PT0gJ3QnIHx8XG4gICAgICAgICd0ZXN0Jy5zcGxpdCgvKD86KS8sIC0xKS5sZW5ndGggIT09IDQgfHxcbiAgICAgICAgJycuc3BsaXQoLy4/LykubGVuZ3RoIHx8XG4gICAgICAgICcuJy5zcGxpdCgvKCkoKS8pLmxlbmd0aCA+IDFcbiAgICApIHtcbiAgICAgICAgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBjb21wbGlhbnRFeGVjTnBjZyA9IHR5cGVvZiAoLygpPz8vKS5leGVjKCcnKVsxXSA9PT0gJ3VuZGVmaW5lZCc7IC8vIE5QQ0c6IG5vbnBhcnRpY2lwYXRpbmcgY2FwdHVyaW5nIGdyb3VwXG4gICAgICAgICAgICB2YXIgbWF4U2FmZTMyQml0SW50ID0gTWF0aC5wb3coMiwgMzIpIC0gMTtcblxuICAgICAgICAgICAgU3RyaW5nUHJvdG90eXBlLnNwbGl0ID0gZnVuY3Rpb24gKHNlcGFyYXRvciwgbGltaXQpIHtcbiAgICAgICAgICAgICAgICB2YXIgc3RyaW5nID0gU3RyaW5nKHRoaXMpO1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygc2VwYXJhdG9yID09PSAndW5kZWZpbmVkJyAmJiBsaW1pdCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gSWYgYHNlcGFyYXRvcmAgaXMgbm90IGEgcmVnZXgsIHVzZSBuYXRpdmUgc3BsaXRcbiAgICAgICAgICAgICAgICBpZiAoIWlzUmVnZXgoc2VwYXJhdG9yKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RyU3BsaXQodGhpcywgc2VwYXJhdG9yLCBsaW1pdCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdmFyIG91dHB1dCA9IFtdO1xuICAgICAgICAgICAgICAgIHZhciBmbGFncyA9IChzZXBhcmF0b3IuaWdub3JlQ2FzZSA/ICdpJyA6ICcnKSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKHNlcGFyYXRvci5tdWx0aWxpbmUgPyAnbScgOiAnJykgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzZXBhcmF0b3IudW5pY29kZSA/ICd1JyA6ICcnKSArIC8vIGluIEVTNlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzZXBhcmF0b3Iuc3RpY2t5ID8gJ3knIDogJycpLCAvLyBGaXJlZm94IDMrIGFuZCBFUzZcbiAgICAgICAgICAgICAgICAgICAgbGFzdExhc3RJbmRleCA9IDAsXG4gICAgICAgICAgICAgICAgICAgIC8vIE1ha2UgYGdsb2JhbGAgYW5kIGF2b2lkIGBsYXN0SW5kZXhgIGlzc3VlcyBieSB3b3JraW5nIHdpdGggYSBjb3B5XG4gICAgICAgICAgICAgICAgICAgIHNlcGFyYXRvcjIsIG1hdGNoLCBsYXN0SW5kZXgsIGxhc3RMZW5ndGg7XG4gICAgICAgICAgICAgICAgdmFyIHNlcGFyYXRvckNvcHkgPSBuZXcgUmVnRXhwKHNlcGFyYXRvci5zb3VyY2UsIGZsYWdzICsgJ2cnKTtcbiAgICAgICAgICAgICAgICBpZiAoIWNvbXBsaWFudEV4ZWNOcGNnKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIERvZXNuJ3QgbmVlZCBmbGFncyBneSwgYnV0IHRoZXkgZG9uJ3QgaHVydFxuICAgICAgICAgICAgICAgICAgICBzZXBhcmF0b3IyID0gbmV3IFJlZ0V4cCgnXicgKyBzZXBhcmF0b3JDb3B5LnNvdXJjZSArICckKD8hXFxcXHMpJywgZmxhZ3MpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvKiBWYWx1ZXMgZm9yIGBsaW1pdGAsIHBlciB0aGUgc3BlYzpcbiAgICAgICAgICAgICAgICAgKiBJZiB1bmRlZmluZWQ6IDQyOTQ5NjcyOTUgLy8gbWF4U2FmZTMyQml0SW50XG4gICAgICAgICAgICAgICAgICogSWYgMCwgSW5maW5pdHksIG9yIE5hTjogMFxuICAgICAgICAgICAgICAgICAqIElmIHBvc2l0aXZlIG51bWJlcjogbGltaXQgPSBNYXRoLmZsb29yKGxpbWl0KTsgaWYgKGxpbWl0ID4gNDI5NDk2NzI5NSkgbGltaXQgLT0gNDI5NDk2NzI5NjtcbiAgICAgICAgICAgICAgICAgKiBJZiBuZWdhdGl2ZSBudW1iZXI6IDQyOTQ5NjcyOTYgLSBNYXRoLmZsb29yKE1hdGguYWJzKGxpbWl0KSlcbiAgICAgICAgICAgICAgICAgKiBJZiBvdGhlcjogVHlwZS1jb252ZXJ0LCB0aGVuIHVzZSB0aGUgYWJvdmUgcnVsZXNcbiAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICB2YXIgc3BsaXRMaW1pdCA9IHR5cGVvZiBsaW1pdCA9PT0gJ3VuZGVmaW5lZCcgPyBtYXhTYWZlMzJCaXRJbnQgOiBFUy5Ub1VpbnQzMihsaW1pdCk7XG4gICAgICAgICAgICAgICAgbWF0Y2ggPSBzZXBhcmF0b3JDb3B5LmV4ZWMoc3RyaW5nKTtcbiAgICAgICAgICAgICAgICB3aGlsZSAobWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gYHNlcGFyYXRvckNvcHkubGFzdEluZGV4YCBpcyBub3QgcmVsaWFibGUgY3Jvc3MtYnJvd3NlclxuICAgICAgICAgICAgICAgICAgICBsYXN0SW5kZXggPSBtYXRjaC5pbmRleCArIG1hdGNoWzBdLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxhc3RJbmRleCA+IGxhc3RMYXN0SW5kZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1c2hDYWxsKG91dHB1dCwgc3RyU2xpY2Uoc3RyaW5nLCBsYXN0TGFzdEluZGV4LCBtYXRjaC5pbmRleCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gRml4IGJyb3dzZXJzIHdob3NlIGBleGVjYCBtZXRob2RzIGRvbid0IGNvbnNpc3RlbnRseSByZXR1cm4gYHVuZGVmaW5lZGAgZm9yXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBub25wYXJ0aWNpcGF0aW5nIGNhcHR1cmluZyBncm91cHNcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghY29tcGxpYW50RXhlY05wY2cgJiYgbWF0Y2gubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLWxvb3AtZnVuYyAqL1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoWzBdLnJlcGxhY2Uoc2VwYXJhdG9yMiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGggLSAyOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgYXJndW1lbnRzW2ldID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoW2ldID0gdm9pZCAwO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZXNsaW50LWVuYWJsZSBuby1sb29wLWZ1bmMgKi9cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtYXRjaC5sZW5ndGggPiAxICYmIG1hdGNoLmluZGV4IDwgc3RyaW5nLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycmF5X3B1c2guYXBwbHkob3V0cHV0LCBhcnJheVNsaWNlKG1hdGNoLCAxKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBsYXN0TGVuZ3RoID0gbWF0Y2hbMF0ubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICAgICAgbGFzdExhc3RJbmRleCA9IGxhc3RJbmRleDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvdXRwdXQubGVuZ3RoID49IHNwbGl0TGltaXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VwYXJhdG9yQ29weS5sYXN0SW5kZXggPT09IG1hdGNoLmluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXBhcmF0b3JDb3B5Lmxhc3RJbmRleCsrOyAvLyBBdm9pZCBhbiBpbmZpbml0ZSBsb29wXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgbWF0Y2ggPSBzZXBhcmF0b3JDb3B5LmV4ZWMoc3RyaW5nKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGxhc3RMYXN0SW5kZXggPT09IHN0cmluZy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxhc3RMZW5ndGggfHwgIXNlcGFyYXRvckNvcHkudGVzdCgnJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1c2hDYWxsKG91dHB1dCwgJycpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcHVzaENhbGwob3V0cHV0LCBzdHJTbGljZShzdHJpbmcsIGxhc3RMYXN0SW5kZXgpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIG91dHB1dC5sZW5ndGggPiBzcGxpdExpbWl0ID8gYXJyYXlTbGljZShvdXRwdXQsIDAsIHNwbGl0TGltaXQpIDogb3V0cHV0O1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSgpKTtcblxuICAgIC8vIFtidWdmaXgsIGNocm9tZV1cbiAgICAvLyBJZiBzZXBhcmF0b3IgaXMgdW5kZWZpbmVkLCB0aGVuIHRoZSByZXN1bHQgYXJyYXkgY29udGFpbnMganVzdCBvbmUgU3RyaW5nLFxuICAgIC8vIHdoaWNoIGlzIHRoZSB0aGlzIHZhbHVlIChjb252ZXJ0ZWQgdG8gYSBTdHJpbmcpLiBJZiBsaW1pdCBpcyBub3QgdW5kZWZpbmVkLFxuICAgIC8vIHRoZW4gdGhlIG91dHB1dCBhcnJheSBpcyB0cnVuY2F0ZWQgc28gdGhhdCBpdCBjb250YWlucyBubyBtb3JlIHRoYW4gbGltaXRcbiAgICAvLyBlbGVtZW50cy5cbiAgICAvLyBcIjBcIi5zcGxpdCh1bmRlZmluZWQsIDApIC0+IFtdXG4gICAgfSBlbHNlIGlmICgnMCcuc3BsaXQodm9pZCAwLCAwKS5sZW5ndGgpIHtcbiAgICAgICAgU3RyaW5nUHJvdG90eXBlLnNwbGl0ID0gZnVuY3Rpb24gc3BsaXQoc2VwYXJhdG9yLCBsaW1pdCkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBzZXBhcmF0b3IgPT09ICd1bmRlZmluZWQnICYmIGxpbWl0ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHN0clNwbGl0KHRoaXMsIHNlcGFyYXRvciwgbGltaXQpO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIHZhciBzdHJfcmVwbGFjZSA9IFN0cmluZ1Byb3RvdHlwZS5yZXBsYWNlO1xuICAgIHZhciByZXBsYWNlUmVwb3J0c0dyb3Vwc0NvcnJlY3RseSA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBncm91cHMgPSBbXTtcbiAgICAgICAgJ3gnLnJlcGxhY2UoL3goLik/L2csIGZ1bmN0aW9uIChtYXRjaCwgZ3JvdXApIHtcbiAgICAgICAgICAgIHB1c2hDYWxsKGdyb3VwcywgZ3JvdXApO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGdyb3Vwcy5sZW5ndGggPT09IDEgJiYgdHlwZW9mIGdyb3Vwc1swXSA9PT0gJ3VuZGVmaW5lZCc7XG4gICAgfSgpKTtcblxuICAgIGlmICghcmVwbGFjZVJlcG9ydHNHcm91cHNDb3JyZWN0bHkpIHtcbiAgICAgICAgU3RyaW5nUHJvdG90eXBlLnJlcGxhY2UgPSBmdW5jdGlvbiByZXBsYWNlKHNlYXJjaFZhbHVlLCByZXBsYWNlVmFsdWUpIHtcbiAgICAgICAgICAgIHZhciBpc0ZuID0gaXNDYWxsYWJsZShyZXBsYWNlVmFsdWUpO1xuICAgICAgICAgICAgdmFyIGhhc0NhcHR1cmluZ0dyb3VwcyA9IGlzUmVnZXgoc2VhcmNoVmFsdWUpICYmICgvXFwpWyo/XS8pLnRlc3Qoc2VhcmNoVmFsdWUuc291cmNlKTtcbiAgICAgICAgICAgIGlmICghaXNGbiB8fCAhaGFzQ2FwdHVyaW5nR3JvdXBzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHN0cl9yZXBsYWNlLmNhbGwodGhpcywgc2VhcmNoVmFsdWUsIHJlcGxhY2VWYWx1ZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhciB3cmFwcGVkUmVwbGFjZVZhbHVlID0gZnVuY3Rpb24gKG1hdGNoKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICB2YXIgb3JpZ2luYWxMYXN0SW5kZXggPSBzZWFyY2hWYWx1ZS5sYXN0SW5kZXg7XG4gICAgICAgICAgICAgICAgICAgIHNlYXJjaFZhbHVlLmxhc3RJbmRleCA9IDA7XG4gICAgICAgICAgICAgICAgICAgIHZhciBhcmdzID0gc2VhcmNoVmFsdWUuZXhlYyhtYXRjaCkgfHwgW107XG4gICAgICAgICAgICAgICAgICAgIHNlYXJjaFZhbHVlLmxhc3RJbmRleCA9IG9yaWdpbmFsTGFzdEluZGV4O1xuICAgICAgICAgICAgICAgICAgICBwdXNoQ2FsbChhcmdzLCBhcmd1bWVudHNbbGVuZ3RoIC0gMl0sIGFyZ3VtZW50c1tsZW5ndGggLSAxXSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXBsYWNlVmFsdWUuYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICByZXR1cm4gc3RyX3JlcGxhY2UuY2FsbCh0aGlzLCBzZWFyY2hWYWx1ZSwgd3JhcHBlZFJlcGxhY2VWYWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gRUNNQS0yNjIsIDNyZCBCLjIuM1xuICAgIC8vIE5vdCBhbiBFQ01BU2NyaXB0IHN0YW5kYXJkLCBhbHRob3VnaCBFQ01BU2NyaXB0IDNyZCBFZGl0aW9uIGhhcyBhXG4gICAgLy8gbm9uLW5vcm1hdGl2ZSBzZWN0aW9uIHN1Z2dlc3RpbmcgdW5pZm9ybSBzZW1hbnRpY3MgYW5kIGl0IHNob3VsZCBiZVxuICAgIC8vIG5vcm1hbGl6ZWQgYWNyb3NzIGFsbCBicm93c2Vyc1xuICAgIC8vIFtidWdmaXgsIElFIGx0IDldIElFIDwgOSBzdWJzdHIoKSB3aXRoIG5lZ2F0aXZlIHZhbHVlIG5vdCB3b3JraW5nIGluIElFXG4gICAgdmFyIHN0cmluZ19zdWJzdHIgPSBTdHJpbmdQcm90b3R5cGUuc3Vic3RyO1xuICAgIHZhciBoYXNOZWdhdGl2ZVN1YnN0ckJ1ZyA9ICcnLnN1YnN0ciAmJiAnMGInLnN1YnN0cigtMSkgIT09ICdiJztcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKFN0cmluZ1Byb3RvdHlwZSwge1xuICAgICAgICBzdWJzdHI6IGZ1bmN0aW9uIHN1YnN0cihzdGFydCwgbGVuZ3RoKSB7XG4gICAgICAgICAgICB2YXIgbm9ybWFsaXplZFN0YXJ0ID0gc3RhcnQ7XG4gICAgICAgICAgICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgICAgICAgICAgICAgbm9ybWFsaXplZFN0YXJ0ID0gbWF4KHRoaXMubGVuZ3RoICsgc3RhcnQsIDApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHN0cmluZ19zdWJzdHIuY2FsbCh0aGlzLCBub3JtYWxpemVkU3RhcnQsIGxlbmd0aCk7XG4gICAgICAgIH1cbiAgICB9LCBoYXNOZWdhdGl2ZVN1YnN0ckJ1Zyk7XG5cbiAgICAvLyBFUzUgMTUuNS40LjIwXG4gICAgLy8gd2hpdGVzcGFjZSBmcm9tOiBodHRwOi8vZXM1LmdpdGh1Yi5pby8jeDE1LjUuNC4yMFxuICAgIHZhciB3cyA9ICdcXHgwOVxceDBBXFx4MEJcXHgwQ1xceDBEXFx4MjBcXHhBMFxcdTE2ODBcXHUxODBFXFx1MjAwMFxcdTIwMDFcXHUyMDAyXFx1MjAwMycgK1xuICAgICAgICAnXFx1MjAwNFxcdTIwMDVcXHUyMDA2XFx1MjAwN1xcdTIwMDhcXHUyMDA5XFx1MjAwQVxcdTIwMkZcXHUyMDVGXFx1MzAwMFxcdTIwMjgnICtcbiAgICAgICAgJ1xcdTIwMjlcXHVGRUZGJztcbiAgICB2YXIgemVyb1dpZHRoID0gJ1xcdTIwMGInO1xuICAgIHZhciB3c1JlZ2V4Q2hhcnMgPSAnWycgKyB3cyArICddJztcbiAgICB2YXIgdHJpbUJlZ2luUmVnZXhwID0gbmV3IFJlZ0V4cCgnXicgKyB3c1JlZ2V4Q2hhcnMgKyB3c1JlZ2V4Q2hhcnMgKyAnKicpO1xuICAgIHZhciB0cmltRW5kUmVnZXhwID0gbmV3IFJlZ0V4cCh3c1JlZ2V4Q2hhcnMgKyB3c1JlZ2V4Q2hhcnMgKyAnKiQnKTtcbiAgICB2YXIgaGFzVHJpbVdoaXRlc3BhY2VCdWcgPSBTdHJpbmdQcm90b3R5cGUudHJpbSAmJiAod3MudHJpbSgpIHx8ICF6ZXJvV2lkdGgudHJpbSgpKTtcbiAgICBkZWZpbmVQcm9wZXJ0aWVzKFN0cmluZ1Byb3RvdHlwZSwge1xuICAgICAgICAvLyBodHRwOi8vYmxvZy5zdGV2ZW5sZXZpdGhhbi5jb20vYXJjaGl2ZXMvZmFzdGVyLXRyaW0tamF2YXNjcmlwdFxuICAgICAgICAvLyBodHRwOi8vcGVyZmVjdGlvbmtpbGxzLmNvbS93aGl0ZXNwYWNlLWRldmlhdGlvbnMvXG4gICAgICAgIHRyaW06IGZ1bmN0aW9uIHRyaW0oKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHRoaXMgPT09ICd1bmRlZmluZWQnIHx8IHRoaXMgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiY2FuJ3QgY29udmVydCBcIiArIHRoaXMgKyAnIHRvIG9iamVjdCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuICRTdHJpbmcodGhpcykucmVwbGFjZSh0cmltQmVnaW5SZWdleHAsICcnKS5yZXBsYWNlKHRyaW1FbmRSZWdleHAsICcnKTtcbiAgICAgICAgfVxuICAgIH0sIGhhc1RyaW1XaGl0ZXNwYWNlQnVnKTtcbiAgICB2YXIgdHJpbSA9IGNhbGwuYmluZChTdHJpbmcucHJvdG90eXBlLnRyaW0pO1xuXG4gICAgdmFyIGhhc0xhc3RJbmRleEJ1ZyA9IFN0cmluZ1Byb3RvdHlwZS5sYXN0SW5kZXhPZiAmJiAnYWJj44GC44GEJy5sYXN0SW5kZXhPZign44GC44GEJywgMikgIT09IC0xO1xuICAgIGRlZmluZVByb3BlcnRpZXMoU3RyaW5nUHJvdG90eXBlLCB7XG4gICAgICAgIGxhc3RJbmRleE9mOiBmdW5jdGlvbiBsYXN0SW5kZXhPZihzZWFyY2hTdHJpbmcpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdGhpcyA9PT0gJ3VuZGVmaW5lZCcgfHwgdGhpcyA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJjYW4ndCBjb252ZXJ0IFwiICsgdGhpcyArICcgdG8gb2JqZWN0Jyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgUyA9ICRTdHJpbmcodGhpcyk7XG4gICAgICAgICAgICB2YXIgc2VhcmNoU3RyID0gJFN0cmluZyhzZWFyY2hTdHJpbmcpO1xuICAgICAgICAgICAgdmFyIG51bVBvcyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxID8gJE51bWJlcihhcmd1bWVudHNbMV0pIDogTmFOO1xuICAgICAgICAgICAgdmFyIHBvcyA9IGlzQWN0dWFsTmFOKG51bVBvcykgPyBJbmZpbml0eSA6IEVTLlRvSW50ZWdlcihudW1Qb3MpO1xuICAgICAgICAgICAgdmFyIHN0YXJ0ID0gbWluKG1heChwb3MsIDApLCBTLmxlbmd0aCk7XG4gICAgICAgICAgICB2YXIgc2VhcmNoTGVuID0gc2VhcmNoU3RyLmxlbmd0aDtcbiAgICAgICAgICAgIHZhciBrID0gc3RhcnQgKyBzZWFyY2hMZW47XG4gICAgICAgICAgICB3aGlsZSAoayA+IDApIHtcbiAgICAgICAgICAgICAgICBrID0gbWF4KDAsIGsgLSBzZWFyY2hMZW4pO1xuICAgICAgICAgICAgICAgIHZhciBpbmRleCA9IHN0ckluZGV4T2Yoc3RyU2xpY2UoUywgaywgc3RhcnQgKyBzZWFyY2hMZW4pLCBzZWFyY2hTdHIpO1xuICAgICAgICAgICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGsgKyBpbmRleDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIH1cbiAgICB9LCBoYXNMYXN0SW5kZXhCdWcpO1xuXG4gICAgdmFyIG9yaWdpbmFsTGFzdEluZGV4T2YgPSBTdHJpbmdQcm90b3R5cGUubGFzdEluZGV4T2Y7XG4gICAgZGVmaW5lUHJvcGVydGllcyhTdHJpbmdQcm90b3R5cGUsIHtcbiAgICAgICAgbGFzdEluZGV4T2Y6IGZ1bmN0aW9uIGxhc3RJbmRleE9mKHNlYXJjaFN0cmluZykge1xuICAgICAgICAgICAgcmV0dXJuIG9yaWdpbmFsTGFzdEluZGV4T2YuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgfVxuICAgIH0sIFN0cmluZ1Byb3RvdHlwZS5sYXN0SW5kZXhPZi5sZW5ndGggIT09IDEpO1xuXG4gICAgLy8gRVMtNSAxNS4xLjIuMlxuICAgIC8qIGVzbGludC1kaXNhYmxlIHJhZGl4ICovXG4gICAgaWYgKHBhcnNlSW50KHdzICsgJzA4JykgIT09IDggfHwgcGFyc2VJbnQod3MgKyAnMHgxNicpICE9PSAyMikge1xuICAgIC8qIGVzbGludC1lbmFibGUgcmFkaXggKi9cbiAgICAgICAgLyogZ2xvYmFsIHBhcnNlSW50OiB0cnVlICovXG4gICAgICAgIHBhcnNlSW50ID0gKGZ1bmN0aW9uIChvcmlnUGFyc2VJbnQpIHtcbiAgICAgICAgICAgIHZhciBoZXhSZWdleCA9IC9eW1xcLStdPzBbeFhdLztcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiBwYXJzZUludChzdHIsIHJhZGl4KSB7XG4gICAgICAgICAgICAgICAgdmFyIHN0cmluZyA9IHRyaW0oU3RyaW5nKHN0cikpO1xuICAgICAgICAgICAgICAgIHZhciBkZWZhdWx0ZWRSYWRpeCA9ICROdW1iZXIocmFkaXgpIHx8IChoZXhSZWdleC50ZXN0KHN0cmluZykgPyAxNiA6IDEwKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3JpZ1BhcnNlSW50KHN0cmluZywgZGVmYXVsdGVkUmFkaXgpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfShwYXJzZUludCkpO1xuICAgIH1cblxuICAgIC8vIGh0dHBzOi8vZXM1LmdpdGh1Yi5pby8jeDE1LjEuMi4zXG4gICAgaWYgKDEgLyBwYXJzZUZsb2F0KCctMCcpICE9PSAtSW5maW5pdHkpIHtcbiAgICAgICAgLyogZ2xvYmFsIHBhcnNlRmxvYXQ6IHRydWUgKi9cbiAgICAgICAgcGFyc2VGbG9hdCA9IChmdW5jdGlvbiAob3JpZ1BhcnNlRmxvYXQpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiBwYXJzZUZsb2F0KHN0cmluZykge1xuICAgICAgICAgICAgICAgIHZhciBpbnB1dFN0cmluZyA9IHRyaW0oU3RyaW5nKHN0cmluZykpO1xuICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSBvcmlnUGFyc2VGbG9hdChpbnB1dFN0cmluZyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCA9PT0gMCAmJiBzdHJTbGljZShpbnB1dFN0cmluZywgMCwgMSkgPT09ICctJyA/IC0wIDogcmVzdWx0O1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfShwYXJzZUZsb2F0KSk7XG4gICAgfVxuXG4gICAgaWYgKFN0cmluZyhuZXcgUmFuZ2VFcnJvcigndGVzdCcpKSAhPT0gJ1JhbmdlRXJyb3I6IHRlc3QnKSB7XG4gICAgICAgIHZhciBlcnJvclRvU3RyaW5nU2hpbSA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB0aGlzID09PSAndW5kZWZpbmVkJyB8fCB0aGlzID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImNhbid0IGNvbnZlcnQgXCIgKyB0aGlzICsgJyB0byBvYmplY3QnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBuYW1lID0gdGhpcy5uYW1lO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBuYW1lID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgIG5hbWUgPSAnRXJyb3InO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgbmFtZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICBuYW1lID0gJFN0cmluZyhuYW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBtc2cgPSB0aGlzLm1lc3NhZ2U7XG4gICAgICAgICAgICBpZiAodHlwZW9mIG1zZyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICBtc2cgPSAnJztcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIG1zZyAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICBtc2cgPSAkU3RyaW5nKG1zZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbXNnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFtc2cpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmFtZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBuYW1lICsgJzogJyArIG1zZztcbiAgICAgICAgfTtcbiAgICAgICAgLy8gY2FuJ3QgdXNlIGRlZmluZVByb3BlcnRpZXMgaGVyZSBiZWNhdXNlIG9mIHRvU3RyaW5nIGVudW1lcmF0aW9uIGlzc3VlIGluIElFIDw9IDhcbiAgICAgICAgRXJyb3IucHJvdG90eXBlLnRvU3RyaW5nID0gZXJyb3JUb1N0cmluZ1NoaW07XG4gICAgfVxuXG4gICAgaWYgKHN1cHBvcnRzRGVzY3JpcHRvcnMpIHtcbiAgICAgICAgdmFyIGVuc3VyZU5vbkVudW1lcmFibGUgPSBmdW5jdGlvbiAob2JqLCBwcm9wKSB7XG4gICAgICAgICAgICBpZiAoaXNFbnVtKG9iaiwgcHJvcCkpIHtcbiAgICAgICAgICAgICAgICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqLCBwcm9wKTtcbiAgICAgICAgICAgICAgICBpZiAoZGVzYy5jb25maWd1cmFibGUpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVzYy5lbnVtZXJhYmxlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosIHByb3AsIGRlc2MpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgZW5zdXJlTm9uRW51bWVyYWJsZShFcnJvci5wcm90b3R5cGUsICdtZXNzYWdlJyk7XG4gICAgICAgIGlmIChFcnJvci5wcm90b3R5cGUubWVzc2FnZSAhPT0gJycpIHtcbiAgICAgICAgICAgIEVycm9yLnByb3RvdHlwZS5tZXNzYWdlID0gJyc7XG4gICAgICAgIH1cbiAgICAgICAgZW5zdXJlTm9uRW51bWVyYWJsZShFcnJvci5wcm90b3R5cGUsICduYW1lJyk7XG4gICAgfVxuXG4gICAgaWYgKFN0cmluZygvYS9taWcpICE9PSAnL2EvZ2ltJykge1xuICAgICAgICB2YXIgcmVnZXhUb1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgICAgICAgICAgdmFyIHN0ciA9ICcvJyArIHRoaXMuc291cmNlICsgJy8nO1xuICAgICAgICAgICAgaWYgKHRoaXMuZ2xvYmFsKSB7XG4gICAgICAgICAgICAgICAgc3RyICs9ICdnJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLmlnbm9yZUNhc2UpIHtcbiAgICAgICAgICAgICAgICBzdHIgKz0gJ2knO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMubXVsdGlsaW5lKSB7XG4gICAgICAgICAgICAgICAgc3RyICs9ICdtJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzdHI7XG4gICAgICAgIH07XG4gICAgICAgIC8vIGNhbid0IHVzZSBkZWZpbmVQcm9wZXJ0aWVzIGhlcmUgYmVjYXVzZSBvZiB0b1N0cmluZyBlbnVtZXJhdGlvbiBpc3N1ZSBpbiBJRSA8PSA4XG4gICAgICAgIFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcgPSByZWdleFRvU3RyaW5nO1xuICAgIH1cbn0pKTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8qanNsaW50IGVxZXE6IHRydWUqL1xuXG5IYW5kbGViYXJzLnJlZ2lzdGVySGVscGVyKCdzYW5pdGl6ZScsIGZ1bmN0aW9uICh0ZXh0KSB7XG4gICAgdmFyIHJlc3VsdDtcblxuICAgIGlmICh0ZXh0ID09PSB1bmRlZmluZWQpIHsgcmV0dXJuICcnOyB9XG5cbiAgICByZXN1bHQgPSBzYW5pdGl6ZUh0bWwodGV4dCwge1xuICAgICAgICBhbGxvd2VkVGFnczogWyAnZGl2JywgJ3NwYW4nLCAnYicsICdpJywgJ2VtJywgJ3N0cm9uZycsICdhJywgJ2JyJywgJ3RhYmxlJywgJ3Rib2R5JywgJ3RyJywgJ3RoJywgJ3RkJyBdLFxuICAgICAgICBhbGxvd2VkQXR0cmlidXRlczoge1xuICAgICAgICAgICAgJ2Rpdic6IFsgJ2NsYXNzJyBdLFxuICAgICAgICAgICAgJ3NwYW4nOiBbICdjbGFzcycgXSxcbiAgICAgICAgICAgICd0YWJsZSc6IFsgJ2NsYXNzJyBdLFxuICAgICAgICAgICAgJ3RkJzogWyAnY2xhc3MnIF0sXG4gICAgICAgICAgICAndGgnOiBbICdjb2xzcGFuJyBdLFxuICAgICAgICAgICAgJ2EnOiBbICdocmVmJyBdXG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiBuZXcgSGFuZGxlYmFycy5TYWZlU3RyaW5nKHJlc3VsdCk7XG59KTtcblxuSGFuZGxlYmFycy5yZWdpc3RlckhlbHBlcigncmVuZGVyVGV4dFBhcmFtJywgZnVuY3Rpb24ocGFyYW0pIHtcbiAgICB2YXIgcmVzdWx0LCB0eXBlID0gJ3RleHQnLCBpZEF0dCA9ICcnO1xuICAgIHZhciBwYXJhbVR5cGUgPSBwYXJhbS50eXBlIHx8IHBhcmFtLnNjaGVtYSAmJiBwYXJhbS5zY2hlbWEudHlwZSB8fCAnJztcbiAgICB2YXIgaXNBcnJheSA9IHBhcmFtVHlwZS50b0xvd2VyQ2FzZSgpID09PSAnYXJyYXknIHx8IHBhcmFtLmFsbG93TXVsdGlwbGU7XG4gICAgdmFyIGRlZmF1bHRWYWx1ZSA9IGlzQXJyYXkgJiYgQXJyYXkuaXNBcnJheShwYXJhbS5kZWZhdWx0KSA/IHBhcmFtLmRlZmF1bHQuam9pbignXFxuJykgOiBwYXJhbS5kZWZhdWx0O1xuICAgIHZhciBuYW1lID0gSGFuZGxlYmFycy5VdGlscy5lc2NhcGVFeHByZXNzaW9uKHBhcmFtLm5hbWUpO1xuICAgIHZhciB2YWx1ZUlkID0gSGFuZGxlYmFycy5VdGlscy5lc2NhcGVFeHByZXNzaW9uKHBhcmFtLnZhbHVlSWQpO1xuICAgIHBhcmFtVHlwZSA9IEhhbmRsZWJhcnMuVXRpbHMuZXNjYXBlRXhwcmVzc2lvbihwYXJhbVR5cGUpO1xuXG4gICAgdmFyIGRhdGFWZW5kb3JFeHRlbnNpb25zID0gT2JqZWN0LmtleXMocGFyYW0pLmZpbHRlcihmdW5jdGlvbihwcm9wZXJ0eSkge1xuICAgICAgICAvLyBmaWx0ZXIgWC1kYXRhLSBwcm9wZXJ0aWVzXG4gICAgICAgIHJldHVybiBwcm9wZXJ0eS5tYXRjaCgvXlgtZGF0YS0vaSkgIT09IG51bGw7XG4gICAgfSkucmVkdWNlKGZ1bmN0aW9uKHJlc3VsdCwgcHJvcGVydHkpIHtcbiAgICAgICAgLy8gcmVtb3ZlIFgtIGZyb20gcHJvcGVydHkgbmFtZSwgc28gaXQgcmVzdWx0cyBpbiBodG1sIGF0dHJpYnV0ZXMgbGlrZSBkYXRhLWZvbz0nYmFyJ1xuICAgICAgICByZXR1cm4gcmVzdWx0ICs9ICcgJyArIHByb3BlcnR5LnN1YnN0cmluZygyLCBwcm9wZXJ0eS5sZW5ndGgpICsgJz1cXCcnICsgcGFyYW1bcHJvcGVydHldICsgJ1xcJyc7XG4gICAgfSwgJycpO1xuXG4gICAgaWYocGFyYW0uZm9ybWF0ICYmIHBhcmFtLmZvcm1hdCA9PT0gJ3Bhc3N3b3JkJykge1xuICAgICAgICB0eXBlID0gJ3Bhc3N3b3JkJztcbiAgICB9XG5cbiAgICBpZih2YWx1ZUlkKSB7XG4gICAgICAgIGlkQXR0ID0gJyBpZD1cXCcnICsgdmFsdWVJZCArICdcXCcnO1xuICAgIH1cblxuICAgIGlmIChkZWZhdWx0VmFsdWUpIHtcbiAgICAgIGRlZmF1bHRWYWx1ZSA9IHNhbml0aXplSHRtbChkZWZhdWx0VmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWZhdWx0VmFsdWUgPSAnJztcbiAgICB9XG5cbiAgICBpZihpc0FycmF5KSB7XG4gICAgICAgIHJlc3VsdCA9ICc8dGV4dGFyZWEgY2xhc3M9XFwnYm9keS10ZXh0YXJlYScgKyAocGFyYW0ucmVxdWlyZWQgPyAnIHJlcXVpcmVkJyA6ICcnKSArICdcXCcgbmFtZT1cXCcnICsgbmFtZSArICdcXCcnICsgaWRBdHQgKyBkYXRhVmVuZG9yRXh0ZW5zaW9ucztcbiAgICAgICAgcmVzdWx0ICs9ICcgcGxhY2Vob2xkZXI9XFwnUHJvdmlkZSBtdWx0aXBsZSB2YWx1ZXMgaW4gbmV3IGxpbmVzJyArIChwYXJhbS5yZXF1aXJlZCA/ICcgKGF0IGxlYXN0IG9uZSByZXF1aXJlZCkuJyA6ICcuJykgKyAnXFwnPic7XG4gICAgICAgIHJlc3VsdCArPSBkZWZhdWx0VmFsdWUgKyAnPC90ZXh0YXJlYT4nO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBwYXJhbWV0ZXJDbGFzcyA9ICdwYXJhbWV0ZXInO1xuICAgICAgICBpZihwYXJhbS5yZXF1aXJlZCkge1xuICAgICAgICAgIHBhcmFtZXRlckNsYXNzICs9ICcgcmVxdWlyZWQnO1xuICAgICAgICB9XG4gICAgICAgIHJlc3VsdCA9ICc8aW5wdXQgY2xhc3M9XFwnJyArIHBhcmFtZXRlckNsYXNzICsgJ1xcJyBtaW5sZW5ndGg9XFwnJyArIChwYXJhbS5yZXF1aXJlZCA/IDEgOiAwKSArICdcXCcnO1xuICAgICAgICByZXN1bHQgKz0gJyBuYW1lPVxcJycgKyBuYW1lICsnXFwnIHBsYWNlaG9sZGVyPVxcJycgKyAocGFyYW0ucmVxdWlyZWQgPyAnKHJlcXVpcmVkKScgOiAnJykgKyAnXFwnJyArIGlkQXR0ICsgZGF0YVZlbmRvckV4dGVuc2lvbnM7XG4gICAgICAgIHJlc3VsdCArPSAnIHR5cGU9XFwnJyArIHR5cGUgKyAnXFwnIHZhbHVlPVxcJycgKyBkZWZhdWx0VmFsdWUgKyAnXFwnLz4nO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IEhhbmRsZWJhcnMuU2FmZVN0cmluZyhyZXN1bHQpO1xufSk7XG5cbkhhbmRsZWJhcnMucmVnaXN0ZXJIZWxwZXIoJ2lmQ29uZCcsIGZ1bmN0aW9uICh2MSwgb3BlcmF0b3IsIHYyLCBvcHRpb25zKSB7XG5cbiAgICBzd2l0Y2ggKG9wZXJhdG9yKSB7XG4gICAgICAgIGNhc2UgJz09JzpcbiAgICAgICAgICAgIHJldHVybiAodjEgPT0gdjIpID8gb3B0aW9ucy5mbih0aGlzKSA6IG9wdGlvbnMuaW52ZXJzZSh0aGlzKTtcbiAgICAgICAgY2FzZSAnPT09JzpcbiAgICAgICAgICAgIHJldHVybiAodjEgPT09IHYyKSA/IG9wdGlvbnMuZm4odGhpcykgOiBvcHRpb25zLmludmVyc2UodGhpcyk7XG4gICAgICAgIGNhc2UgJzwnOlxuICAgICAgICAgICAgcmV0dXJuICh2MSA8IHYyKSA/IG9wdGlvbnMuZm4odGhpcykgOiBvcHRpb25zLmludmVyc2UodGhpcyk7XG4gICAgICAgIGNhc2UgJzw9JzpcbiAgICAgICAgICAgIHJldHVybiAodjEgPD0gdjIpID8gb3B0aW9ucy5mbih0aGlzKSA6IG9wdGlvbnMuaW52ZXJzZSh0aGlzKTtcbiAgICAgICAgY2FzZSAnPic6XG4gICAgICAgICAgICByZXR1cm4gKHYxID4gdjIpID8gb3B0aW9ucy5mbih0aGlzKSA6IG9wdGlvbnMuaW52ZXJzZSh0aGlzKTtcbiAgICAgICAgY2FzZSAnPj0nOlxuICAgICAgICAgICAgcmV0dXJuICh2MSA+PSB2MikgPyBvcHRpb25zLmZuKHRoaXMpIDogb3B0aW9ucy5pbnZlcnNlKHRoaXMpO1xuICAgICAgICBjYXNlICcmJic6XG4gICAgICAgICAgICByZXR1cm4gKHYxICYmIHYyKSA/IG9wdGlvbnMuZm4odGhpcykgOiBvcHRpb25zLmludmVyc2UodGhpcyk7XG4gICAgICAgIGNhc2UgJ3x8JzpcbiAgICAgICAgICAgIHJldHVybiAodjEgfHwgdjIpID8gb3B0aW9ucy5mbih0aGlzKSA6IG9wdGlvbnMuaW52ZXJzZSh0aGlzKTtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJldHVybiBvcHRpb25zLmludmVyc2UodGhpcyk7XG4gICAgfVxufSk7XG5cbkhhbmRsZWJhcnMucmVnaXN0ZXJIZWxwZXIoJ2VzY2FwZScsIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHZhciB0ZXh0ID0gSGFuZGxlYmFycy5VdGlscy5lc2NhcGVFeHByZXNzaW9uKHZhbHVlKTtcblxuICAgIHJldHVybiBuZXcgSGFuZGxlYmFycy5TYWZlU3RyaW5nKHRleHQpO1xufSk7XG4iLCIoZnVuY3Rpb24oZil7aWYodHlwZW9mIGV4cG9ydHM9PT1cIm9iamVjdFwiJiZ0eXBlb2YgbW9kdWxlIT09XCJ1bmRlZmluZWRcIil7bW9kdWxlLmV4cG9ydHM9ZigpfWVsc2UgaWYodHlwZW9mIGRlZmluZT09PVwiZnVuY3Rpb25cIiYmZGVmaW5lLmFtZCl7ZGVmaW5lKFtdLGYpfWVsc2V7dmFyIGc7aWYodHlwZW9mIHdpbmRvdyE9PVwidW5kZWZpbmVkXCIpe2c9d2luZG93fWVsc2UgaWYodHlwZW9mIGdsb2JhbCE9PVwidW5kZWZpbmVkXCIpe2c9Z2xvYmFsfWVsc2UgaWYodHlwZW9mIHNlbGYhPT1cInVuZGVmaW5lZFwiKXtnPXNlbGZ9ZWxzZXtnPXRoaXN9Zy5zYW5pdGl6ZUh0bWw9ZigpfX0pKGZ1bmN0aW9uKCl7dmFyIGRlZmluZSxtb2R1bGUsZXhwb3J0cztyZXR1cm4gZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KHsxOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgaHRtbHBhcnNlcj1yZXF1aXJlKFwiaHRtbHBhcnNlcjJcIik7dmFyIGV4dGVuZD1yZXF1aXJlKFwieHRlbmRcIik7dmFyIHF1b3RlUmVnZXhwPXJlcXVpcmUoXCJyZWdleHAtcXVvdGVcIik7ZnVuY3Rpb24gZWFjaChvYmosY2Ipe2lmKG9iailPYmplY3Qua2V5cyhvYmopLmZvckVhY2goZnVuY3Rpb24oa2V5KXtjYihvYmpba2V5XSxrZXkpfSl9ZnVuY3Rpb24gaGFzKG9iaixrZXkpe3JldHVybnt9Lmhhc093blByb3BlcnR5LmNhbGwob2JqLGtleSl9bW9kdWxlLmV4cG9ydHM9c2FuaXRpemVIdG1sO2Z1bmN0aW9uIHNhbml0aXplSHRtbChodG1sLG9wdGlvbnMsX3JlY3Vyc2luZyl7dmFyIHJlc3VsdD1cIlwiO2Z1bmN0aW9uIEZyYW1lKHRhZyxhdHRyaWJzKXt2YXIgdGhhdD10aGlzO3RoaXMudGFnPXRhZzt0aGlzLmF0dHJpYnM9YXR0cmlic3x8e307dGhpcy50YWdQb3NpdGlvbj1yZXN1bHQubGVuZ3RoO3RoaXMudGV4dD1cIlwiO3RoaXMudXBkYXRlUGFyZW50Tm9kZVRleHQ9ZnVuY3Rpb24oKXtpZihzdGFjay5sZW5ndGgpe3ZhciBwYXJlbnRGcmFtZT1zdGFja1tzdGFjay5sZW5ndGgtMV07cGFyZW50RnJhbWUudGV4dCs9dGhhdC50ZXh0fX19aWYoIW9wdGlvbnMpe29wdGlvbnM9c2FuaXRpemVIdG1sLmRlZmF1bHRzO29wdGlvbnMucGFyc2VyPWh0bWxQYXJzZXJEZWZhdWx0c31lbHNle29wdGlvbnM9ZXh0ZW5kKHNhbml0aXplSHRtbC5kZWZhdWx0cyxvcHRpb25zKTtpZihvcHRpb25zLnBhcnNlcil7b3B0aW9ucy5wYXJzZXI9ZXh0ZW5kKGh0bWxQYXJzZXJEZWZhdWx0cyxvcHRpb25zLnBhcnNlcil9ZWxzZXtvcHRpb25zLnBhcnNlcj1odG1sUGFyc2VyRGVmYXVsdHN9fXZhciBub25UZXh0VGFnc0FycmF5PW9wdGlvbnMubm9uVGV4dFRhZ3N8fFtcInNjcmlwdFwiLFwic3R5bGVcIixcInRleHRhcmVhXCJdO3ZhciBhbGxvd2VkQXR0cmlidXRlc01hcDt2YXIgYWxsb3dlZEF0dHJpYnV0ZXNHbG9iTWFwO2lmKG9wdGlvbnMuYWxsb3dlZEF0dHJpYnV0ZXMpe2FsbG93ZWRBdHRyaWJ1dGVzTWFwPXt9O2FsbG93ZWRBdHRyaWJ1dGVzR2xvYk1hcD17fTtlYWNoKG9wdGlvbnMuYWxsb3dlZEF0dHJpYnV0ZXMsZnVuY3Rpb24oYXR0cmlidXRlcyx0YWcpe2FsbG93ZWRBdHRyaWJ1dGVzTWFwW3RhZ109W107dmFyIGdsb2JSZWdleD1bXTthdHRyaWJ1dGVzLmZvckVhY2goZnVuY3Rpb24obmFtZSl7aWYobmFtZS5pbmRleE9mKFwiKlwiKT49MCl7Z2xvYlJlZ2V4LnB1c2gocXVvdGVSZWdleHAobmFtZSkucmVwbGFjZSgvXFxcXFxcKi9nLFwiLipcIikpfWVsc2V7YWxsb3dlZEF0dHJpYnV0ZXNNYXBbdGFnXS5wdXNoKG5hbWUpfX0pO2FsbG93ZWRBdHRyaWJ1dGVzR2xvYk1hcFt0YWddPW5ldyBSZWdFeHAoXCJeKFwiK2dsb2JSZWdleC5qb2luKFwifFwiKStcIikkXCIpfSl9dmFyIGFsbG93ZWRDbGFzc2VzTWFwPXt9O2VhY2gob3B0aW9ucy5hbGxvd2VkQ2xhc3NlcyxmdW5jdGlvbihjbGFzc2VzLHRhZyl7aWYoYWxsb3dlZEF0dHJpYnV0ZXNNYXApe2lmKCFoYXMoYWxsb3dlZEF0dHJpYnV0ZXNNYXAsdGFnKSl7YWxsb3dlZEF0dHJpYnV0ZXNNYXBbdGFnXT1bXX1hbGxvd2VkQXR0cmlidXRlc01hcFt0YWddLnB1c2goXCJjbGFzc1wiKX1hbGxvd2VkQ2xhc3Nlc01hcFt0YWddPWNsYXNzZXN9KTt2YXIgdHJhbnNmb3JtVGFnc01hcD17fTt2YXIgdHJhbnNmb3JtVGFnc0FsbDtlYWNoKG9wdGlvbnMudHJhbnNmb3JtVGFncyxmdW5jdGlvbih0cmFuc2Zvcm0sdGFnKXt2YXIgdHJhbnNGdW47aWYodHlwZW9mIHRyYW5zZm9ybT09PVwiZnVuY3Rpb25cIil7dHJhbnNGdW49dHJhbnNmb3JtfWVsc2UgaWYodHlwZW9mIHRyYW5zZm9ybT09PVwic3RyaW5nXCIpe3RyYW5zRnVuPXNhbml0aXplSHRtbC5zaW1wbGVUcmFuc2Zvcm0odHJhbnNmb3JtKX1pZih0YWc9PT1cIipcIil7dHJhbnNmb3JtVGFnc0FsbD10cmFuc0Z1bn1lbHNle3RyYW5zZm9ybVRhZ3NNYXBbdGFnXT10cmFuc0Z1bn19KTt2YXIgZGVwdGg9MDt2YXIgc3RhY2s9W107dmFyIHNraXBNYXA9e307dmFyIHRyYW5zZm9ybU1hcD17fTt2YXIgc2tpcFRleHQ9ZmFsc2U7dmFyIHNraXBUZXh0RGVwdGg9MDt2YXIgcGFyc2VyPW5ldyBodG1scGFyc2VyLlBhcnNlcih7b25vcGVudGFnOmZ1bmN0aW9uKG5hbWUsYXR0cmlicyl7aWYoc2tpcFRleHQpe3NraXBUZXh0RGVwdGgrKztyZXR1cm59dmFyIGZyYW1lPW5ldyBGcmFtZShuYW1lLGF0dHJpYnMpO3N0YWNrLnB1c2goZnJhbWUpO3ZhciBza2lwPWZhbHNlO3ZhciBoYXNUZXh0PWZyYW1lLnRleHQ/dHJ1ZTpmYWxzZTt2YXIgdHJhbnNmb3JtZWRUYWc7aWYoaGFzKHRyYW5zZm9ybVRhZ3NNYXAsbmFtZSkpe3RyYW5zZm9ybWVkVGFnPXRyYW5zZm9ybVRhZ3NNYXBbbmFtZV0obmFtZSxhdHRyaWJzKTtmcmFtZS5hdHRyaWJzPWF0dHJpYnM9dHJhbnNmb3JtZWRUYWcuYXR0cmlicztpZih0cmFuc2Zvcm1lZFRhZy50ZXh0IT09dW5kZWZpbmVkKXtmcmFtZS5pbm5lclRleHQ9dHJhbnNmb3JtZWRUYWcudGV4dH1pZihuYW1lIT09dHJhbnNmb3JtZWRUYWcudGFnTmFtZSl7ZnJhbWUubmFtZT1uYW1lPXRyYW5zZm9ybWVkVGFnLnRhZ05hbWU7dHJhbnNmb3JtTWFwW2RlcHRoXT10cmFuc2Zvcm1lZFRhZy50YWdOYW1lfX1pZih0cmFuc2Zvcm1UYWdzQWxsKXt0cmFuc2Zvcm1lZFRhZz10cmFuc2Zvcm1UYWdzQWxsKG5hbWUsYXR0cmlicyk7ZnJhbWUuYXR0cmlicz1hdHRyaWJzPXRyYW5zZm9ybWVkVGFnLmF0dHJpYnM7aWYobmFtZSE9PXRyYW5zZm9ybWVkVGFnLnRhZ05hbWUpe2ZyYW1lLm5hbWU9bmFtZT10cmFuc2Zvcm1lZFRhZy50YWdOYW1lO3RyYW5zZm9ybU1hcFtkZXB0aF09dHJhbnNmb3JtZWRUYWcudGFnTmFtZX19aWYob3B0aW9ucy5hbGxvd2VkVGFncyYmb3B0aW9ucy5hbGxvd2VkVGFncy5pbmRleE9mKG5hbWUpPT09LTEpe3NraXA9dHJ1ZTtpZihub25UZXh0VGFnc0FycmF5LmluZGV4T2YobmFtZSkhPT0tMSl7c2tpcFRleHQ9dHJ1ZTtza2lwVGV4dERlcHRoPTF9c2tpcE1hcFtkZXB0aF09dHJ1ZX1kZXB0aCsrO2lmKHNraXApe3JldHVybn1yZXN1bHQrPVwiPFwiK25hbWU7aWYoIWFsbG93ZWRBdHRyaWJ1dGVzTWFwfHxoYXMoYWxsb3dlZEF0dHJpYnV0ZXNNYXAsbmFtZSl8fGFsbG93ZWRBdHRyaWJ1dGVzTWFwW1wiKlwiXSl7ZWFjaChhdHRyaWJzLGZ1bmN0aW9uKHZhbHVlLGEpe2lmKCFhbGxvd2VkQXR0cmlidXRlc01hcHx8aGFzKGFsbG93ZWRBdHRyaWJ1dGVzTWFwLG5hbWUpJiZhbGxvd2VkQXR0cmlidXRlc01hcFtuYW1lXS5pbmRleE9mKGEpIT09LTF8fGFsbG93ZWRBdHRyaWJ1dGVzTWFwW1wiKlwiXSYmYWxsb3dlZEF0dHJpYnV0ZXNNYXBbXCIqXCJdLmluZGV4T2YoYSkhPT0tMXx8aGFzKGFsbG93ZWRBdHRyaWJ1dGVzR2xvYk1hcCxuYW1lKSYmYWxsb3dlZEF0dHJpYnV0ZXNHbG9iTWFwW25hbWVdLnRlc3QoYSl8fGFsbG93ZWRBdHRyaWJ1dGVzR2xvYk1hcFtcIipcIl0mJmFsbG93ZWRBdHRyaWJ1dGVzR2xvYk1hcFtcIipcIl0udGVzdChhKSl7aWYoYT09PVwiaHJlZlwifHxhPT09XCJzcmNcIil7aWYobmF1Z2h0eUhyZWYobmFtZSx2YWx1ZSkpe2RlbGV0ZSBmcmFtZS5hdHRyaWJzW2FdO3JldHVybn19aWYoYT09PVwiY2xhc3NcIil7dmFsdWU9ZmlsdGVyQ2xhc3Nlcyh2YWx1ZSxhbGxvd2VkQ2xhc3Nlc01hcFtuYW1lXSk7aWYoIXZhbHVlLmxlbmd0aCl7ZGVsZXRlIGZyYW1lLmF0dHJpYnNbYV07cmV0dXJufX1yZXN1bHQrPVwiIFwiK2E7aWYodmFsdWUubGVuZ3RoKXtyZXN1bHQrPSc9XCInK2VzY2FwZUh0bWwodmFsdWUpKydcIid9fWVsc2V7ZGVsZXRlIGZyYW1lLmF0dHJpYnNbYV19fSl9aWYob3B0aW9ucy5zZWxmQ2xvc2luZy5pbmRleE9mKG5hbWUpIT09LTEpe3Jlc3VsdCs9XCIgLz5cIn1lbHNle3Jlc3VsdCs9XCI+XCI7aWYoZnJhbWUuaW5uZXJUZXh0JiYhaGFzVGV4dCYmIW9wdGlvbnMudGV4dEZpbHRlcil7cmVzdWx0Kz1mcmFtZS5pbm5lclRleHR9fX0sb250ZXh0OmZ1bmN0aW9uKHRleHQpe2lmKHNraXBUZXh0KXtyZXR1cm59dmFyIGxhc3RGcmFtZT1zdGFja1tzdGFjay5sZW5ndGgtMV07dmFyIHRhZztpZihsYXN0RnJhbWUpe3RhZz1sYXN0RnJhbWUudGFnO3RleHQ9bGFzdEZyYW1lLmlubmVyVGV4dCE9PXVuZGVmaW5lZD9sYXN0RnJhbWUuaW5uZXJUZXh0OnRleHR9aWYodGFnPT09XCJzY3JpcHRcInx8dGFnPT09XCJzdHlsZVwiKXtyZXN1bHQrPXRleHR9ZWxzZXt2YXIgZXNjYXBlZD1lc2NhcGVIdG1sKHRleHQpO2lmKG9wdGlvbnMudGV4dEZpbHRlcil7cmVzdWx0Kz1vcHRpb25zLnRleHRGaWx0ZXIoZXNjYXBlZCl9ZWxzZXtyZXN1bHQrPWVzY2FwZWR9fWlmKHN0YWNrLmxlbmd0aCl7dmFyIGZyYW1lPXN0YWNrW3N0YWNrLmxlbmd0aC0xXTtmcmFtZS50ZXh0Kz10ZXh0fX0sb25jbG9zZXRhZzpmdW5jdGlvbihuYW1lKXtpZihza2lwVGV4dCl7c2tpcFRleHREZXB0aC0tO2lmKCFza2lwVGV4dERlcHRoKXtza2lwVGV4dD1mYWxzZX1lbHNle3JldHVybn19dmFyIGZyYW1lPXN0YWNrLnBvcCgpO2lmKCFmcmFtZSl7cmV0dXJufXNraXBUZXh0PWZhbHNlO2RlcHRoLS07aWYoc2tpcE1hcFtkZXB0aF0pe2RlbGV0ZSBza2lwTWFwW2RlcHRoXTtmcmFtZS51cGRhdGVQYXJlbnROb2RlVGV4dCgpO3JldHVybn1pZih0cmFuc2Zvcm1NYXBbZGVwdGhdKXtuYW1lPXRyYW5zZm9ybU1hcFtkZXB0aF07ZGVsZXRlIHRyYW5zZm9ybU1hcFtkZXB0aF19aWYob3B0aW9ucy5leGNsdXNpdmVGaWx0ZXImJm9wdGlvbnMuZXhjbHVzaXZlRmlsdGVyKGZyYW1lKSl7cmVzdWx0PXJlc3VsdC5zdWJzdHIoMCxmcmFtZS50YWdQb3NpdGlvbik7cmV0dXJufWZyYW1lLnVwZGF0ZVBhcmVudE5vZGVUZXh0KCk7aWYob3B0aW9ucy5zZWxmQ2xvc2luZy5pbmRleE9mKG5hbWUpIT09LTEpe3JldHVybn1yZXN1bHQrPVwiPC9cIituYW1lK1wiPlwifX0sb3B0aW9ucy5wYXJzZXIpO3BhcnNlci53cml0ZShodG1sKTtwYXJzZXIuZW5kKCk7cmV0dXJuIHJlc3VsdDtmdW5jdGlvbiBlc2NhcGVIdG1sKHMpe2lmKHR5cGVvZiBzIT09XCJzdHJpbmdcIil7cz1zK1wiXCJ9cmV0dXJuIHMucmVwbGFjZSgvXFwmL2csXCImYW1wO1wiKS5yZXBsYWNlKC88L2csXCImbHQ7XCIpLnJlcGxhY2UoL1xcPi9nLFwiJmd0O1wiKS5yZXBsYWNlKC9cXFwiL2csXCImcXVvdDtcIil9ZnVuY3Rpb24gbmF1Z2h0eUhyZWYobmFtZSxocmVmKXtocmVmPWhyZWYucmVwbGFjZSgvW1xceDAwLVxceDIwXSsvZyxcIlwiKTtocmVmPWhyZWYucmVwbGFjZSgvPFxcIVxcLVxcLS4qP1xcLVxcLVxcPi9nLFwiXCIpO3ZhciBtYXRjaGVzPWhyZWYubWF0Y2goL14oW2EtekEtWl0rKVxcOi8pO2lmKCFtYXRjaGVzKXtyZXR1cm4gZmFsc2V9dmFyIHNjaGVtZT1tYXRjaGVzWzFdLnRvTG93ZXJDYXNlKCk7aWYoaGFzKG9wdGlvbnMuYWxsb3dlZFNjaGVtZXNCeVRhZyxuYW1lKSl7cmV0dXJuIG9wdGlvbnMuYWxsb3dlZFNjaGVtZXNCeVRhZ1tuYW1lXS5pbmRleE9mKHNjaGVtZSk9PT0tMX1yZXR1cm4hb3B0aW9ucy5hbGxvd2VkU2NoZW1lc3x8b3B0aW9ucy5hbGxvd2VkU2NoZW1lcy5pbmRleE9mKHNjaGVtZSk9PT0tMX1mdW5jdGlvbiBmaWx0ZXJDbGFzc2VzKGNsYXNzZXMsYWxsb3dlZCl7aWYoIWFsbG93ZWQpe3JldHVybiBjbGFzc2VzfWNsYXNzZXM9Y2xhc3Nlcy5zcGxpdCgvXFxzKy8pO3JldHVybiBjbGFzc2VzLmZpbHRlcihmdW5jdGlvbihjbHNzKXtyZXR1cm4gYWxsb3dlZC5pbmRleE9mKGNsc3MpIT09LTF9KS5qb2luKFwiIFwiKX19dmFyIGh0bWxQYXJzZXJEZWZhdWx0cz17ZGVjb2RlRW50aXRpZXM6dHJ1ZX07c2FuaXRpemVIdG1sLmRlZmF1bHRzPXthbGxvd2VkVGFnczpbXCJoM1wiLFwiaDRcIixcImg1XCIsXCJoNlwiLFwiYmxvY2txdW90ZVwiLFwicFwiLFwiYVwiLFwidWxcIixcIm9sXCIsXCJubFwiLFwibGlcIixcImJcIixcImlcIixcInN0cm9uZ1wiLFwiZW1cIixcInN0cmlrZVwiLFwiY29kZVwiLFwiaHJcIixcImJyXCIsXCJkaXZcIixcInRhYmxlXCIsXCJ0aGVhZFwiLFwiY2FwdGlvblwiLFwidGJvZHlcIixcInRyXCIsXCJ0aFwiLFwidGRcIixcInByZVwiXSxhbGxvd2VkQXR0cmlidXRlczp7YTpbXCJocmVmXCIsXCJuYW1lXCIsXCJ0YXJnZXRcIl0saW1nOltcInNyY1wiXX0sc2VsZkNsb3Npbmc6W1wiaW1nXCIsXCJiclwiLFwiaHJcIixcImFyZWFcIixcImJhc2VcIixcImJhc2Vmb250XCIsXCJpbnB1dFwiLFwibGlua1wiLFwibWV0YVwiXSxhbGxvd2VkU2NoZW1lczpbXCJodHRwXCIsXCJodHRwc1wiLFwiZnRwXCIsXCJtYWlsdG9cIl0sYWxsb3dlZFNjaGVtZXNCeVRhZzp7fX07c2FuaXRpemVIdG1sLnNpbXBsZVRyYW5zZm9ybT1mdW5jdGlvbihuZXdUYWdOYW1lLG5ld0F0dHJpYnMsbWVyZ2Upe21lcmdlPW1lcmdlPT09dW5kZWZpbmVkP3RydWU6bWVyZ2U7bmV3QXR0cmlicz1uZXdBdHRyaWJzfHx7fTtyZXR1cm4gZnVuY3Rpb24odGFnTmFtZSxhdHRyaWJzKXt2YXIgYXR0cmliO2lmKG1lcmdlKXtmb3IoYXR0cmliIGluIG5ld0F0dHJpYnMpe2F0dHJpYnNbYXR0cmliXT1uZXdBdHRyaWJzW2F0dHJpYl19fWVsc2V7YXR0cmlicz1uZXdBdHRyaWJzfXJldHVybnt0YWdOYW1lOm5ld1RhZ05hbWUsYXR0cmliczphdHRyaWJzfX19fSx7aHRtbHBhcnNlcjI6MzYsXCJyZWdleHAtcXVvdGVcIjo1NCx4dGVuZDo1OH1dLDI6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1widXNlIHN0cmljdFwiO2V4cG9ydHMudG9CeXRlQXJyYXk9dG9CeXRlQXJyYXk7ZXhwb3J0cy5mcm9tQnl0ZUFycmF5PWZyb21CeXRlQXJyYXk7dmFyIGxvb2t1cD1bXTt2YXIgcmV2TG9va3VwPVtdO3ZhciBBcnI9dHlwZW9mIFVpbnQ4QXJyYXkhPT1cInVuZGVmaW5lZFwiP1VpbnQ4QXJyYXk6QXJyYXk7ZnVuY3Rpb24gaW5pdCgpe3ZhciBjb2RlPVwiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrL1wiO2Zvcih2YXIgaT0wLGxlbj1jb2RlLmxlbmd0aDtpPGxlbjsrK2kpe2xvb2t1cFtpXT1jb2RlW2ldO3Jldkxvb2t1cFtjb2RlLmNoYXJDb2RlQXQoaSldPWl9cmV2TG9va3VwW1wiLVwiLmNoYXJDb2RlQXQoMCldPTYyO3Jldkxvb2t1cFtcIl9cIi5jaGFyQ29kZUF0KDApXT02M31pbml0KCk7ZnVuY3Rpb24gdG9CeXRlQXJyYXkoYjY0KXt2YXIgaSxqLGwsdG1wLHBsYWNlSG9sZGVycyxhcnI7dmFyIGxlbj1iNjQubGVuZ3RoO2lmKGxlbiU0PjApe3Rocm93IG5ldyBFcnJvcihcIkludmFsaWQgc3RyaW5nLiBMZW5ndGggbXVzdCBiZSBhIG11bHRpcGxlIG9mIDRcIil9cGxhY2VIb2xkZXJzPWI2NFtsZW4tMl09PT1cIj1cIj8yOmI2NFtsZW4tMV09PT1cIj1cIj8xOjA7YXJyPW5ldyBBcnIobGVuKjMvNC1wbGFjZUhvbGRlcnMpO2w9cGxhY2VIb2xkZXJzPjA/bGVuLTQ6bGVuO3ZhciBMPTA7Zm9yKGk9MCxqPTA7aTxsO2krPTQsais9Myl7dG1wPXJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKV08PDE4fHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKzEpXTw8MTJ8cmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkrMildPDw2fHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKzMpXTthcnJbTCsrXT10bXA+PjE2JjI1NTthcnJbTCsrXT10bXA+PjgmMjU1O2FycltMKytdPXRtcCYyNTV9aWYocGxhY2VIb2xkZXJzPT09Mil7dG1wPXJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKV08PDJ8cmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkrMSldPj40O2FycltMKytdPXRtcCYyNTV9ZWxzZSBpZihwbGFjZUhvbGRlcnM9PT0xKXt0bXA9cmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXTw8MTB8cmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkrMSldPDw0fHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpKzIpXT4+MjthcnJbTCsrXT10bXA+PjgmMjU1O2FycltMKytdPXRtcCYyNTV9cmV0dXJuIGFycn1mdW5jdGlvbiB0cmlwbGV0VG9CYXNlNjQobnVtKXtyZXR1cm4gbG9va3VwW251bT4+MTgmNjNdK2xvb2t1cFtudW0+PjEyJjYzXStsb29rdXBbbnVtPj42JjYzXStsb29rdXBbbnVtJjYzXX1mdW5jdGlvbiBlbmNvZGVDaHVuayh1aW50OCxzdGFydCxlbmQpe3ZhciB0bXA7dmFyIG91dHB1dD1bXTtmb3IodmFyIGk9c3RhcnQ7aTxlbmQ7aSs9Myl7dG1wPSh1aW50OFtpXTw8MTYpKyh1aW50OFtpKzFdPDw4KSt1aW50OFtpKzJdO291dHB1dC5wdXNoKHRyaXBsZXRUb0Jhc2U2NCh0bXApKX1yZXR1cm4gb3V0cHV0LmpvaW4oXCJcIil9ZnVuY3Rpb24gZnJvbUJ5dGVBcnJheSh1aW50OCl7dmFyIHRtcDt2YXIgbGVuPXVpbnQ4Lmxlbmd0aDt2YXIgZXh0cmFCeXRlcz1sZW4lMzt2YXIgb3V0cHV0PVwiXCI7dmFyIHBhcnRzPVtdO3ZhciBtYXhDaHVua0xlbmd0aD0xNjM4Mztmb3IodmFyIGk9MCxsZW4yPWxlbi1leHRyYUJ5dGVzO2k8bGVuMjtpKz1tYXhDaHVua0xlbmd0aCl7cGFydHMucHVzaChlbmNvZGVDaHVuayh1aW50OCxpLGkrbWF4Q2h1bmtMZW5ndGg+bGVuMj9sZW4yOmkrbWF4Q2h1bmtMZW5ndGgpKX1pZihleHRyYUJ5dGVzPT09MSl7dG1wPXVpbnQ4W2xlbi0xXTtvdXRwdXQrPWxvb2t1cFt0bXA+PjJdO291dHB1dCs9bG9va3VwW3RtcDw8NCY2M107b3V0cHV0Kz1cIj09XCJ9ZWxzZSBpZihleHRyYUJ5dGVzPT09Mil7dG1wPSh1aW50OFtsZW4tMl08PDgpK3VpbnQ4W2xlbi0xXTtvdXRwdXQrPWxvb2t1cFt0bXA+PjEwXTtvdXRwdXQrPWxvb2t1cFt0bXA+PjQmNjNdO291dHB1dCs9bG9va3VwW3RtcDw8MiY2M107b3V0cHV0Kz1cIj1cIn1wYXJ0cy5wdXNoKG91dHB1dCk7cmV0dXJuIHBhcnRzLmpvaW4oXCJcIil9fSx7fV0sMzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7fSx7fV0sNDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7KGZ1bmN0aW9uKGdsb2JhbCl7XCJ1c2Ugc3RyaWN0XCI7dmFyIGJ1ZmZlcj1yZXF1aXJlKFwiYnVmZmVyXCIpO3ZhciBCdWZmZXI9YnVmZmVyLkJ1ZmZlcjt2YXIgU2xvd0J1ZmZlcj1idWZmZXIuU2xvd0J1ZmZlcjt2YXIgTUFYX0xFTj1idWZmZXIua01heExlbmd0aHx8MjE0NzQ4MzY0NztleHBvcnRzLmFsbG9jPWZ1bmN0aW9uIGFsbG9jKHNpemUsZmlsbCxlbmNvZGluZyl7aWYodHlwZW9mIEJ1ZmZlci5hbGxvYz09PVwiZnVuY3Rpb25cIil7cmV0dXJuIEJ1ZmZlci5hbGxvYyhzaXplLGZpbGwsZW5jb2RpbmcpfWlmKHR5cGVvZiBlbmNvZGluZz09PVwibnVtYmVyXCIpe3Rocm93IG5ldyBUeXBlRXJyb3IoXCJlbmNvZGluZyBtdXN0IG5vdCBiZSBudW1iZXJcIil9aWYodHlwZW9mIHNpemUhPT1cIm51bWJlclwiKXt0aHJvdyBuZXcgVHlwZUVycm9yKFwic2l6ZSBtdXN0IGJlIGEgbnVtYmVyXCIpfWlmKHNpemU+TUFYX0xFTil7dGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJzaXplIGlzIHRvbyBsYXJnZVwiKX12YXIgZW5jPWVuY29kaW5nO3ZhciBfZmlsbD1maWxsO2lmKF9maWxsPT09dW5kZWZpbmVkKXtlbmM9dW5kZWZpbmVkO19maWxsPTB9dmFyIGJ1Zj1uZXcgQnVmZmVyKHNpemUpO2lmKHR5cGVvZiBfZmlsbD09PVwic3RyaW5nXCIpe3ZhciBmaWxsQnVmPW5ldyBCdWZmZXIoX2ZpbGwsZW5jKTt2YXIgZmxlbj1maWxsQnVmLmxlbmd0aDt2YXIgaT0tMTt3aGlsZSgrK2k8c2l6ZSl7YnVmW2ldPWZpbGxCdWZbaSVmbGVuXX19ZWxzZXtidWYuZmlsbChfZmlsbCl9cmV0dXJuIGJ1Zn07ZXhwb3J0cy5hbGxvY1Vuc2FmZT1mdW5jdGlvbiBhbGxvY1Vuc2FmZShzaXplKXtpZih0eXBlb2YgQnVmZmVyLmFsbG9jVW5zYWZlPT09XCJmdW5jdGlvblwiKXtyZXR1cm4gQnVmZmVyLmFsbG9jVW5zYWZlKHNpemUpfWlmKHR5cGVvZiBzaXplIT09XCJudW1iZXJcIil7dGhyb3cgbmV3IFR5cGVFcnJvcihcInNpemUgbXVzdCBiZSBhIG51bWJlclwiKX1pZihzaXplPk1BWF9MRU4pe3Rocm93IG5ldyBSYW5nZUVycm9yKFwic2l6ZSBpcyB0b28gbGFyZ2VcIil9cmV0dXJuIG5ldyBCdWZmZXIoc2l6ZSl9O2V4cG9ydHMuZnJvbT1mdW5jdGlvbiBmcm9tKHZhbHVlLGVuY29kaW5nT3JPZmZzZXQsbGVuZ3RoKXtpZih0eXBlb2YgQnVmZmVyLmZyb209PT1cImZ1bmN0aW9uXCImJighZ2xvYmFsLlVpbnQ4QXJyYXl8fFVpbnQ4QXJyYXkuZnJvbSE9PUJ1ZmZlci5mcm9tKSl7cmV0dXJuIEJ1ZmZlci5mcm9tKHZhbHVlLGVuY29kaW5nT3JPZmZzZXQsbGVuZ3RoKX1pZih0eXBlb2YgdmFsdWU9PT1cIm51bWJlclwiKXt0aHJvdyBuZXcgVHlwZUVycm9yKCdcInZhbHVlXCIgYXJndW1lbnQgbXVzdCBub3QgYmUgYSBudW1iZXInKX1pZih0eXBlb2YgdmFsdWU9PT1cInN0cmluZ1wiKXtyZXR1cm4gbmV3IEJ1ZmZlcih2YWx1ZSxlbmNvZGluZ09yT2Zmc2V0KX1pZih0eXBlb2YgQXJyYXlCdWZmZXIhPT1cInVuZGVmaW5lZFwiJiZ2YWx1ZSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKXt2YXIgb2Zmc2V0PWVuY29kaW5nT3JPZmZzZXQ7aWYoYXJndW1lbnRzLmxlbmd0aD09PTEpe3JldHVybiBuZXcgQnVmZmVyKHZhbHVlKX1pZih0eXBlb2Ygb2Zmc2V0PT09XCJ1bmRlZmluZWRcIil7b2Zmc2V0PTB9dmFyIGxlbj1sZW5ndGg7aWYodHlwZW9mIGxlbj09PVwidW5kZWZpbmVkXCIpe2xlbj12YWx1ZS5ieXRlTGVuZ3RoLW9mZnNldH1pZihvZmZzZXQ+PXZhbHVlLmJ5dGVMZW5ndGgpe3Rocm93IG5ldyBSYW5nZUVycm9yKFwiJ29mZnNldCcgaXMgb3V0IG9mIGJvdW5kc1wiKX1pZihsZW4+dmFsdWUuYnl0ZUxlbmd0aC1vZmZzZXQpe3Rocm93IG5ldyBSYW5nZUVycm9yKFwiJ2xlbmd0aCcgaXMgb3V0IG9mIGJvdW5kc1wiKX1yZXR1cm4gbmV3IEJ1ZmZlcih2YWx1ZS5zbGljZShvZmZzZXQsb2Zmc2V0K2xlbikpfWlmKEJ1ZmZlci5pc0J1ZmZlcih2YWx1ZSkpe3ZhciBvdXQ9bmV3IEJ1ZmZlcih2YWx1ZS5sZW5ndGgpO3ZhbHVlLmNvcHkob3V0LDAsMCx2YWx1ZS5sZW5ndGgpO3JldHVybiBvdXR9aWYodmFsdWUpe2lmKEFycmF5LmlzQXJyYXkodmFsdWUpfHx0eXBlb2YgQXJyYXlCdWZmZXIhPT1cInVuZGVmaW5lZFwiJiZ2YWx1ZS5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcnx8XCJsZW5ndGhcImluIHZhbHVlKXtyZXR1cm4gbmV3IEJ1ZmZlcih2YWx1ZSl9aWYodmFsdWUudHlwZT09PVwiQnVmZmVyXCImJkFycmF5LmlzQXJyYXkodmFsdWUuZGF0YSkpe3JldHVybiBuZXcgQnVmZmVyKHZhbHVlLmRhdGEpfX10aHJvdyBuZXcgVHlwZUVycm9yKFwiRmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhIHN0cmluZywgQnVmZmVyLCBcIitcIkFycmF5QnVmZmVyLCBBcnJheSwgb3IgYXJyYXktbGlrZSBvYmplY3QuXCIpfTtleHBvcnRzLmFsbG9jVW5zYWZlU2xvdz1mdW5jdGlvbiBhbGxvY1Vuc2FmZVNsb3coc2l6ZSl7aWYodHlwZW9mIEJ1ZmZlci5hbGxvY1Vuc2FmZVNsb3c9PT1cImZ1bmN0aW9uXCIpe3JldHVybiBCdWZmZXIuYWxsb2NVbnNhZmVTbG93KHNpemUpfWlmKHR5cGVvZiBzaXplIT09XCJudW1iZXJcIil7dGhyb3cgbmV3IFR5cGVFcnJvcihcInNpemUgbXVzdCBiZSBhIG51bWJlclwiKX1pZihzaXplPj1NQVhfTEVOKXt0aHJvdyBuZXcgUmFuZ2VFcnJvcihcInNpemUgaXMgdG9vIGxhcmdlXCIpfXJldHVybiBuZXcgU2xvd0J1ZmZlcihzaXplKX19KS5jYWxsKHRoaXMsdHlwZW9mIGdsb2JhbCE9PVwidW5kZWZpbmVkXCI/Z2xvYmFsOnR5cGVvZiBzZWxmIT09XCJ1bmRlZmluZWRcIj9zZWxmOnR5cGVvZiB3aW5kb3chPT1cInVuZGVmaW5lZFwiP3dpbmRvdzp7fSl9LHtidWZmZXI6NX1dLDU6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpeyhmdW5jdGlvbihnbG9iYWwpe1widXNlIHN0cmljdFwiO3ZhciBiYXNlNjQ9cmVxdWlyZShcImJhc2U2NC1qc1wiKTt2YXIgaWVlZTc1ND1yZXF1aXJlKFwiaWVlZTc1NFwiKTt2YXIgaXNBcnJheT1yZXF1aXJlKFwiaXNhcnJheVwiKTtleHBvcnRzLkJ1ZmZlcj1CdWZmZXI7ZXhwb3J0cy5TbG93QnVmZmVyPVNsb3dCdWZmZXI7ZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFUz01MDtCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVD1nbG9iYWwuVFlQRURfQVJSQVlfU1VQUE9SVCE9PXVuZGVmaW5lZD9nbG9iYWwuVFlQRURfQVJSQVlfU1VQUE9SVDp0eXBlZEFycmF5U3VwcG9ydCgpO2V4cG9ydHMua01heExlbmd0aD1rTWF4TGVuZ3RoKCk7ZnVuY3Rpb24gdHlwZWRBcnJheVN1cHBvcnQoKXt0cnl7dmFyIGFycj1uZXcgVWludDhBcnJheSgxKTthcnIuX19wcm90b19fPXtfX3Byb3RvX186VWludDhBcnJheS5wcm90b3R5cGUsZm9vOmZ1bmN0aW9uKCl7cmV0dXJuIDQyfX07cmV0dXJuIGFyci5mb28oKT09PTQyJiZ0eXBlb2YgYXJyLnN1YmFycmF5PT09XCJmdW5jdGlvblwiJiZhcnIuc3ViYXJyYXkoMSwxKS5ieXRlTGVuZ3RoPT09MH1jYXRjaChlKXtyZXR1cm4gZmFsc2V9fWZ1bmN0aW9uIGtNYXhMZW5ndGgoKXtyZXR1cm4gQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQ/MjE0NzQ4MzY0NzoxMDczNzQxODIzfWZ1bmN0aW9uIGNyZWF0ZUJ1ZmZlcih0aGF0LGxlbmd0aCl7aWYoa01heExlbmd0aCgpPGxlbmd0aCl7dGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnZhbGlkIHR5cGVkIGFycmF5IGxlbmd0aFwiKX1pZihCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCl7dGhhdD1uZXcgVWludDhBcnJheShsZW5ndGgpO3RoYXQuX19wcm90b19fPUJ1ZmZlci5wcm90b3R5cGV9ZWxzZXtpZih0aGF0PT09bnVsbCl7dGhhdD1uZXcgQnVmZmVyKGxlbmd0aCl9dGhhdC5sZW5ndGg9bGVuZ3RofXJldHVybiB0aGF0fWZ1bmN0aW9uIEJ1ZmZlcihhcmcsZW5jb2RpbmdPck9mZnNldCxsZW5ndGgpe2lmKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCYmISh0aGlzIGluc3RhbmNlb2YgQnVmZmVyKSl7cmV0dXJuIG5ldyBCdWZmZXIoYXJnLGVuY29kaW5nT3JPZmZzZXQsbGVuZ3RoKX1pZih0eXBlb2YgYXJnPT09XCJudW1iZXJcIil7aWYodHlwZW9mIGVuY29kaW5nT3JPZmZzZXQ9PT1cInN0cmluZ1wiKXt0aHJvdyBuZXcgRXJyb3IoXCJJZiBlbmNvZGluZyBpcyBzcGVjaWZpZWQgdGhlbiB0aGUgZmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhIHN0cmluZ1wiKX1yZXR1cm4gYWxsb2NVbnNhZmUodGhpcyxhcmcpfXJldHVybiBmcm9tKHRoaXMsYXJnLGVuY29kaW5nT3JPZmZzZXQsbGVuZ3RoKX1CdWZmZXIucG9vbFNpemU9ODE5MjtCdWZmZXIuX2F1Z21lbnQ9ZnVuY3Rpb24oYXJyKXthcnIuX19wcm90b19fPUJ1ZmZlci5wcm90b3R5cGU7cmV0dXJuIGFycn07ZnVuY3Rpb24gZnJvbSh0aGF0LHZhbHVlLGVuY29kaW5nT3JPZmZzZXQsbGVuZ3RoKXtpZih0eXBlb2YgdmFsdWU9PT1cIm51bWJlclwiKXt0aHJvdyBuZXcgVHlwZUVycm9yKCdcInZhbHVlXCIgYXJndW1lbnQgbXVzdCBub3QgYmUgYSBudW1iZXInKX1pZih0eXBlb2YgQXJyYXlCdWZmZXIhPT1cInVuZGVmaW5lZFwiJiZ2YWx1ZSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKXtyZXR1cm4gZnJvbUFycmF5QnVmZmVyKHRoYXQsdmFsdWUsZW5jb2RpbmdPck9mZnNldCxsZW5ndGgpfWlmKHR5cGVvZiB2YWx1ZT09PVwic3RyaW5nXCIpe3JldHVybiBmcm9tU3RyaW5nKHRoYXQsdmFsdWUsZW5jb2RpbmdPck9mZnNldCl9cmV0dXJuIGZyb21PYmplY3QodGhhdCx2YWx1ZSl9QnVmZmVyLmZyb209ZnVuY3Rpb24odmFsdWUsZW5jb2RpbmdPck9mZnNldCxsZW5ndGgpe3JldHVybiBmcm9tKG51bGwsdmFsdWUsZW5jb2RpbmdPck9mZnNldCxsZW5ndGgpfTtpZihCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCl7QnVmZmVyLnByb3RvdHlwZS5fX3Byb3RvX189VWludDhBcnJheS5wcm90b3R5cGU7QnVmZmVyLl9fcHJvdG9fXz1VaW50OEFycmF5O2lmKHR5cGVvZiBTeW1ib2whPT1cInVuZGVmaW5lZFwiJiZTeW1ib2wuc3BlY2llcyYmQnVmZmVyW1N5bWJvbC5zcGVjaWVzXT09PUJ1ZmZlcil7T2JqZWN0LmRlZmluZVByb3BlcnR5KEJ1ZmZlcixTeW1ib2wuc3BlY2llcyx7dmFsdWU6bnVsbCxjb25maWd1cmFibGU6dHJ1ZX0pfX1mdW5jdGlvbiBhc3NlcnRTaXplKHNpemUpe2lmKHR5cGVvZiBzaXplIT09XCJudW1iZXJcIil7dGhyb3cgbmV3IFR5cGVFcnJvcignXCJzaXplXCIgYXJndW1lbnQgbXVzdCBiZSBhIG51bWJlcicpfWVsc2UgaWYoc2l6ZTwwKXt0aHJvdyBuZXcgUmFuZ2VFcnJvcignXCJzaXplXCIgYXJndW1lbnQgbXVzdCBub3QgYmUgbmVnYXRpdmUnKX19ZnVuY3Rpb24gYWxsb2ModGhhdCxzaXplLGZpbGwsZW5jb2Rpbmcpe2Fzc2VydFNpemUoc2l6ZSk7aWYoc2l6ZTw9MCl7cmV0dXJuIGNyZWF0ZUJ1ZmZlcih0aGF0LHNpemUpfWlmKGZpbGwhPT11bmRlZmluZWQpe3JldHVybiB0eXBlb2YgZW5jb2Rpbmc9PT1cInN0cmluZ1wiP2NyZWF0ZUJ1ZmZlcih0aGF0LHNpemUpLmZpbGwoZmlsbCxlbmNvZGluZyk6Y3JlYXRlQnVmZmVyKHRoYXQsc2l6ZSkuZmlsbChmaWxsKX1yZXR1cm4gY3JlYXRlQnVmZmVyKHRoYXQsc2l6ZSl9QnVmZmVyLmFsbG9jPWZ1bmN0aW9uKHNpemUsZmlsbCxlbmNvZGluZyl7cmV0dXJuIGFsbG9jKG51bGwsc2l6ZSxmaWxsLGVuY29kaW5nKX07ZnVuY3Rpb24gYWxsb2NVbnNhZmUodGhhdCxzaXplKXthc3NlcnRTaXplKHNpemUpO3RoYXQ9Y3JlYXRlQnVmZmVyKHRoYXQsc2l6ZTwwPzA6Y2hlY2tlZChzaXplKXwwKTtpZighQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpe2Zvcih2YXIgaT0wO2k8c2l6ZTsrK2kpe3RoYXRbaV09MH19cmV0dXJuIHRoYXR9QnVmZmVyLmFsbG9jVW5zYWZlPWZ1bmN0aW9uKHNpemUpe3JldHVybiBhbGxvY1Vuc2FmZShudWxsLHNpemUpfTtCdWZmZXIuYWxsb2NVbnNhZmVTbG93PWZ1bmN0aW9uKHNpemUpe3JldHVybiBhbGxvY1Vuc2FmZShudWxsLHNpemUpfTtmdW5jdGlvbiBmcm9tU3RyaW5nKHRoYXQsc3RyaW5nLGVuY29kaW5nKXtpZih0eXBlb2YgZW5jb2RpbmchPT1cInN0cmluZ1wifHxlbmNvZGluZz09PVwiXCIpe2VuY29kaW5nPVwidXRmOFwifWlmKCFCdWZmZXIuaXNFbmNvZGluZyhlbmNvZGluZykpe3Rocm93IG5ldyBUeXBlRXJyb3IoJ1wiZW5jb2RpbmdcIiBtdXN0IGJlIGEgdmFsaWQgc3RyaW5nIGVuY29kaW5nJyl9dmFyIGxlbmd0aD1ieXRlTGVuZ3RoKHN0cmluZyxlbmNvZGluZyl8MDt0aGF0PWNyZWF0ZUJ1ZmZlcih0aGF0LGxlbmd0aCk7dmFyIGFjdHVhbD10aGF0LndyaXRlKHN0cmluZyxlbmNvZGluZyk7aWYoYWN0dWFsIT09bGVuZ3RoKXt0aGF0PXRoYXQuc2xpY2UoMCxhY3R1YWwpfXJldHVybiB0aGF0fWZ1bmN0aW9uIGZyb21BcnJheUxpa2UodGhhdCxhcnJheSl7dmFyIGxlbmd0aD1hcnJheS5sZW5ndGg8MD8wOmNoZWNrZWQoYXJyYXkubGVuZ3RoKXwwO3RoYXQ9Y3JlYXRlQnVmZmVyKHRoYXQsbGVuZ3RoKTtmb3IodmFyIGk9MDtpPGxlbmd0aDtpKz0xKXt0aGF0W2ldPWFycmF5W2ldJjI1NX1yZXR1cm4gdGhhdH1mdW5jdGlvbiBmcm9tQXJyYXlCdWZmZXIodGhhdCxhcnJheSxieXRlT2Zmc2V0LGxlbmd0aCl7YXJyYXkuYnl0ZUxlbmd0aDtpZihieXRlT2Zmc2V0PDB8fGFycmF5LmJ5dGVMZW5ndGg8Ynl0ZU9mZnNldCl7dGhyb3cgbmV3IFJhbmdlRXJyb3IoXCInb2Zmc2V0JyBpcyBvdXQgb2YgYm91bmRzXCIpfWlmKGFycmF5LmJ5dGVMZW5ndGg8Ynl0ZU9mZnNldCsobGVuZ3RofHwwKSl7dGhyb3cgbmV3IFJhbmdlRXJyb3IoXCInbGVuZ3RoJyBpcyBvdXQgb2YgYm91bmRzXCIpfWlmKGJ5dGVPZmZzZXQ9PT11bmRlZmluZWQmJmxlbmd0aD09PXVuZGVmaW5lZCl7YXJyYXk9bmV3IFVpbnQ4QXJyYXkoYXJyYXkpfWVsc2UgaWYobGVuZ3RoPT09dW5kZWZpbmVkKXthcnJheT1uZXcgVWludDhBcnJheShhcnJheSxieXRlT2Zmc2V0KX1lbHNle2FycmF5PW5ldyBVaW50OEFycmF5KGFycmF5LGJ5dGVPZmZzZXQsbGVuZ3RoKX1pZihCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCl7dGhhdD1hcnJheTt0aGF0Ll9fcHJvdG9fXz1CdWZmZXIucHJvdG90eXBlfWVsc2V7dGhhdD1mcm9tQXJyYXlMaWtlKHRoYXQsYXJyYXkpfXJldHVybiB0aGF0fWZ1bmN0aW9uIGZyb21PYmplY3QodGhhdCxvYmope2lmKEJ1ZmZlci5pc0J1ZmZlcihvYmopKXt2YXIgbGVuPWNoZWNrZWQob2JqLmxlbmd0aCl8MDt0aGF0PWNyZWF0ZUJ1ZmZlcih0aGF0LGxlbik7aWYodGhhdC5sZW5ndGg9PT0wKXtyZXR1cm4gdGhhdH1vYmouY29weSh0aGF0LDAsMCxsZW4pO3JldHVybiB0aGF0fWlmKG9iail7aWYodHlwZW9mIEFycmF5QnVmZmVyIT09XCJ1bmRlZmluZWRcIiYmb2JqLmJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyfHxcImxlbmd0aFwiaW4gb2JqKXtpZih0eXBlb2Ygb2JqLmxlbmd0aCE9PVwibnVtYmVyXCJ8fGlzbmFuKG9iai5sZW5ndGgpKXtyZXR1cm4gY3JlYXRlQnVmZmVyKHRoYXQsMCl9cmV0dXJuIGZyb21BcnJheUxpa2UodGhhdCxvYmopfWlmKG9iai50eXBlPT09XCJCdWZmZXJcIiYmaXNBcnJheShvYmouZGF0YSkpe3JldHVybiBmcm9tQXJyYXlMaWtlKHRoYXQsb2JqLmRhdGEpfX10aHJvdyBuZXcgVHlwZUVycm9yKFwiRmlyc3QgYXJndW1lbnQgbXVzdCBiZSBhIHN0cmluZywgQnVmZmVyLCBBcnJheUJ1ZmZlciwgQXJyYXksIG9yIGFycmF5LWxpa2Ugb2JqZWN0LlwiKX1mdW5jdGlvbiBjaGVja2VkKGxlbmd0aCl7aWYobGVuZ3RoPj1rTWF4TGVuZ3RoKCkpe3Rocm93IG5ldyBSYW5nZUVycm9yKFwiQXR0ZW1wdCB0byBhbGxvY2F0ZSBCdWZmZXIgbGFyZ2VyIHRoYW4gbWF4aW11bSBcIitcInNpemU6IDB4XCIra01heExlbmd0aCgpLnRvU3RyaW5nKDE2KStcIiBieXRlc1wiKX1yZXR1cm4gbGVuZ3RofDB9ZnVuY3Rpb24gU2xvd0J1ZmZlcihsZW5ndGgpe2lmKCtsZW5ndGghPWxlbmd0aCl7bGVuZ3RoPTB9cmV0dXJuIEJ1ZmZlci5hbGxvYygrbGVuZ3RoKX1CdWZmZXIuaXNCdWZmZXI9ZnVuY3Rpb24gaXNCdWZmZXIoYil7cmV0dXJuISEoYiE9bnVsbCYmYi5faXNCdWZmZXIpfTtCdWZmZXIuY29tcGFyZT1mdW5jdGlvbiBjb21wYXJlKGEsYil7aWYoIUJ1ZmZlci5pc0J1ZmZlcihhKXx8IUJ1ZmZlci5pc0J1ZmZlcihiKSl7dGhyb3cgbmV3IFR5cGVFcnJvcihcIkFyZ3VtZW50cyBtdXN0IGJlIEJ1ZmZlcnNcIil9aWYoYT09PWIpcmV0dXJuIDA7dmFyIHg9YS5sZW5ndGg7dmFyIHk9Yi5sZW5ndGg7Zm9yKHZhciBpPTAsbGVuPU1hdGgubWluKHgseSk7aTxsZW47KytpKXtpZihhW2ldIT09YltpXSl7eD1hW2ldO3k9YltpXTticmVha319aWYoeDx5KXJldHVybi0xO2lmKHk8eClyZXR1cm4gMTtyZXR1cm4gMH07QnVmZmVyLmlzRW5jb2Rpbmc9ZnVuY3Rpb24gaXNFbmNvZGluZyhlbmNvZGluZyl7c3dpdGNoKFN0cmluZyhlbmNvZGluZykudG9Mb3dlckNhc2UoKSl7Y2FzZVwiaGV4XCI6Y2FzZVwidXRmOFwiOmNhc2VcInV0Zi04XCI6Y2FzZVwiYXNjaWlcIjpjYXNlXCJsYXRpbjFcIjpjYXNlXCJiaW5hcnlcIjpjYXNlXCJiYXNlNjRcIjpjYXNlXCJ1Y3MyXCI6Y2FzZVwidWNzLTJcIjpjYXNlXCJ1dGYxNmxlXCI6Y2FzZVwidXRmLTE2bGVcIjpyZXR1cm4gdHJ1ZTtkZWZhdWx0OnJldHVybiBmYWxzZX19O0J1ZmZlci5jb25jYXQ9ZnVuY3Rpb24gY29uY2F0KGxpc3QsbGVuZ3RoKXtpZighaXNBcnJheShsaXN0KSl7dGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0XCIgYXJndW1lbnQgbXVzdCBiZSBhbiBBcnJheSBvZiBCdWZmZXJzJyl9aWYobGlzdC5sZW5ndGg9PT0wKXtyZXR1cm4gQnVmZmVyLmFsbG9jKDApfXZhciBpO2lmKGxlbmd0aD09PXVuZGVmaW5lZCl7bGVuZ3RoPTA7Zm9yKGk9MDtpPGxpc3QubGVuZ3RoOysraSl7bGVuZ3RoKz1saXN0W2ldLmxlbmd0aH19dmFyIGJ1ZmZlcj1CdWZmZXIuYWxsb2NVbnNhZmUobGVuZ3RoKTt2YXIgcG9zPTA7Zm9yKGk9MDtpPGxpc3QubGVuZ3RoOysraSl7dmFyIGJ1Zj1saXN0W2ldO2lmKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSl7dGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0XCIgYXJndW1lbnQgbXVzdCBiZSBhbiBBcnJheSBvZiBCdWZmZXJzJyl9YnVmLmNvcHkoYnVmZmVyLHBvcyk7cG9zKz1idWYubGVuZ3RofXJldHVybiBidWZmZXJ9O2Z1bmN0aW9uIGJ5dGVMZW5ndGgoc3RyaW5nLGVuY29kaW5nKXtpZihCdWZmZXIuaXNCdWZmZXIoc3RyaW5nKSl7cmV0dXJuIHN0cmluZy5sZW5ndGh9aWYodHlwZW9mIEFycmF5QnVmZmVyIT09XCJ1bmRlZmluZWRcIiYmdHlwZW9mIEFycmF5QnVmZmVyLmlzVmlldz09PVwiZnVuY3Rpb25cIiYmKEFycmF5QnVmZmVyLmlzVmlldyhzdHJpbmcpfHxzdHJpbmcgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikpe3JldHVybiBzdHJpbmcuYnl0ZUxlbmd0aH1pZih0eXBlb2Ygc3RyaW5nIT09XCJzdHJpbmdcIil7c3RyaW5nPVwiXCIrc3RyaW5nfXZhciBsZW49c3RyaW5nLmxlbmd0aDtpZihsZW49PT0wKXJldHVybiAwO3ZhciBsb3dlcmVkQ2FzZT1mYWxzZTtmb3IoOzspe3N3aXRjaChlbmNvZGluZyl7Y2FzZVwiYXNjaWlcIjpjYXNlXCJsYXRpbjFcIjpjYXNlXCJiaW5hcnlcIjpyZXR1cm4gbGVuO2Nhc2VcInV0ZjhcIjpjYXNlXCJ1dGYtOFwiOmNhc2UgdW5kZWZpbmVkOnJldHVybiB1dGY4VG9CeXRlcyhzdHJpbmcpLmxlbmd0aDtjYXNlXCJ1Y3MyXCI6Y2FzZVwidWNzLTJcIjpjYXNlXCJ1dGYxNmxlXCI6Y2FzZVwidXRmLTE2bGVcIjpyZXR1cm4gbGVuKjI7Y2FzZVwiaGV4XCI6cmV0dXJuIGxlbj4+PjE7Y2FzZVwiYmFzZTY0XCI6cmV0dXJuIGJhc2U2NFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGg7ZGVmYXVsdDppZihsb3dlcmVkQ2FzZSlyZXR1cm4gdXRmOFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGg7ZW5jb2Rpbmc9KFwiXCIrZW5jb2RpbmcpLnRvTG93ZXJDYXNlKCk7bG93ZXJlZENhc2U9dHJ1ZX19fUJ1ZmZlci5ieXRlTGVuZ3RoPWJ5dGVMZW5ndGg7ZnVuY3Rpb24gc2xvd1RvU3RyaW5nKGVuY29kaW5nLHN0YXJ0LGVuZCl7dmFyIGxvd2VyZWRDYXNlPWZhbHNlO2lmKHN0YXJ0PT09dW5kZWZpbmVkfHxzdGFydDwwKXtzdGFydD0wfWlmKHN0YXJ0PnRoaXMubGVuZ3RoKXtyZXR1cm5cIlwifWlmKGVuZD09PXVuZGVmaW5lZHx8ZW5kPnRoaXMubGVuZ3RoKXtlbmQ9dGhpcy5sZW5ndGh9aWYoZW5kPD0wKXtyZXR1cm5cIlwifWVuZD4+Pj0wO3N0YXJ0Pj4+PTA7aWYoZW5kPD1zdGFydCl7cmV0dXJuXCJcIn1pZighZW5jb2RpbmcpZW5jb2Rpbmc9XCJ1dGY4XCI7d2hpbGUodHJ1ZSl7c3dpdGNoKGVuY29kaW5nKXtjYXNlXCJoZXhcIjpyZXR1cm4gaGV4U2xpY2UodGhpcyxzdGFydCxlbmQpO2Nhc2VcInV0ZjhcIjpjYXNlXCJ1dGYtOFwiOnJldHVybiB1dGY4U2xpY2UodGhpcyxzdGFydCxlbmQpO2Nhc2VcImFzY2lpXCI6cmV0dXJuIGFzY2lpU2xpY2UodGhpcyxzdGFydCxlbmQpO2Nhc2VcImxhdGluMVwiOmNhc2VcImJpbmFyeVwiOnJldHVybiBsYXRpbjFTbGljZSh0aGlzLHN0YXJ0LGVuZCk7Y2FzZVwiYmFzZTY0XCI6cmV0dXJuIGJhc2U2NFNsaWNlKHRoaXMsc3RhcnQsZW5kKTtjYXNlXCJ1Y3MyXCI6Y2FzZVwidWNzLTJcIjpjYXNlXCJ1dGYxNmxlXCI6Y2FzZVwidXRmLTE2bGVcIjpyZXR1cm4gdXRmMTZsZVNsaWNlKHRoaXMsc3RhcnQsZW5kKTtkZWZhdWx0OmlmKGxvd2VyZWRDYXNlKXRocm93IG5ldyBUeXBlRXJyb3IoXCJVbmtub3duIGVuY29kaW5nOiBcIitlbmNvZGluZyk7ZW5jb2Rpbmc9KGVuY29kaW5nK1wiXCIpLnRvTG93ZXJDYXNlKCk7bG93ZXJlZENhc2U9dHJ1ZX19fUJ1ZmZlci5wcm90b3R5cGUuX2lzQnVmZmVyPXRydWU7ZnVuY3Rpb24gc3dhcChiLG4sbSl7dmFyIGk9YltuXTtiW25dPWJbbV07YlttXT1pfUJ1ZmZlci5wcm90b3R5cGUuc3dhcDE2PWZ1bmN0aW9uIHN3YXAxNigpe3ZhciBsZW49dGhpcy5sZW5ndGg7aWYobGVuJTIhPT0wKXt0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkJ1ZmZlciBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiAxNi1iaXRzXCIpfWZvcih2YXIgaT0wO2k8bGVuO2krPTIpe3N3YXAodGhpcyxpLGkrMSl9cmV0dXJuIHRoaXN9O0J1ZmZlci5wcm90b3R5cGUuc3dhcDMyPWZ1bmN0aW9uIHN3YXAzMigpe3ZhciBsZW49dGhpcy5sZW5ndGg7aWYobGVuJTQhPT0wKXt0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkJ1ZmZlciBzaXplIG11c3QgYmUgYSBtdWx0aXBsZSBvZiAzMi1iaXRzXCIpfWZvcih2YXIgaT0wO2k8bGVuO2krPTQpe3N3YXAodGhpcyxpLGkrMyk7c3dhcCh0aGlzLGkrMSxpKzIpfXJldHVybiB0aGlzfTtCdWZmZXIucHJvdG90eXBlLnN3YXA2ND1mdW5jdGlvbiBzd2FwNjQoKXt2YXIgbGVuPXRoaXMubGVuZ3RoO2lmKGxlbiU4IT09MCl7dGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJCdWZmZXIgc2l6ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNjQtYml0c1wiKX1mb3IodmFyIGk9MDtpPGxlbjtpKz04KXtzd2FwKHRoaXMsaSxpKzcpO3N3YXAodGhpcyxpKzEsaSs2KTtzd2FwKHRoaXMsaSsyLGkrNSk7c3dhcCh0aGlzLGkrMyxpKzQpfXJldHVybiB0aGlzfTtCdWZmZXIucHJvdG90eXBlLnRvU3RyaW5nPWZ1bmN0aW9uIHRvU3RyaW5nKCl7dmFyIGxlbmd0aD10aGlzLmxlbmd0aHwwO2lmKGxlbmd0aD09PTApcmV0dXJuXCJcIjtpZihhcmd1bWVudHMubGVuZ3RoPT09MClyZXR1cm4gdXRmOFNsaWNlKHRoaXMsMCxsZW5ndGgpO3JldHVybiBzbG93VG9TdHJpbmcuYXBwbHkodGhpcyxhcmd1bWVudHMpfTtCdWZmZXIucHJvdG90eXBlLmVxdWFscz1mdW5jdGlvbiBlcXVhbHMoYil7aWYoIUJ1ZmZlci5pc0J1ZmZlcihiKSl0aHJvdyBuZXcgVHlwZUVycm9yKFwiQXJndW1lbnQgbXVzdCBiZSBhIEJ1ZmZlclwiKTtpZih0aGlzPT09YilyZXR1cm4gdHJ1ZTtyZXR1cm4gQnVmZmVyLmNvbXBhcmUodGhpcyxiKT09PTB9O0J1ZmZlci5wcm90b3R5cGUuaW5zcGVjdD1mdW5jdGlvbiBpbnNwZWN0KCl7dmFyIHN0cj1cIlwiO3ZhciBtYXg9ZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFUztpZih0aGlzLmxlbmd0aD4wKXtzdHI9dGhpcy50b1N0cmluZyhcImhleFwiLDAsbWF4KS5tYXRjaCgvLnsyfS9nKS5qb2luKFwiIFwiKTtpZih0aGlzLmxlbmd0aD5tYXgpc3RyKz1cIiAuLi4gXCJ9cmV0dXJuXCI8QnVmZmVyIFwiK3N0citcIj5cIn07QnVmZmVyLnByb3RvdHlwZS5jb21wYXJlPWZ1bmN0aW9uIGNvbXBhcmUodGFyZ2V0LHN0YXJ0LGVuZCx0aGlzU3RhcnQsdGhpc0VuZCl7aWYoIUJ1ZmZlci5pc0J1ZmZlcih0YXJnZXQpKXt0aHJvdyBuZXcgVHlwZUVycm9yKFwiQXJndW1lbnQgbXVzdCBiZSBhIEJ1ZmZlclwiKX1pZihzdGFydD09PXVuZGVmaW5lZCl7c3RhcnQ9MH1pZihlbmQ9PT11bmRlZmluZWQpe2VuZD10YXJnZXQ/dGFyZ2V0Lmxlbmd0aDowfWlmKHRoaXNTdGFydD09PXVuZGVmaW5lZCl7dGhpc1N0YXJ0PTB9aWYodGhpc0VuZD09PXVuZGVmaW5lZCl7dGhpc0VuZD10aGlzLmxlbmd0aH1pZihzdGFydDwwfHxlbmQ+dGFyZ2V0Lmxlbmd0aHx8dGhpc1N0YXJ0PDB8fHRoaXNFbmQ+dGhpcy5sZW5ndGgpe3Rocm93IG5ldyBSYW5nZUVycm9yKFwib3V0IG9mIHJhbmdlIGluZGV4XCIpfWlmKHRoaXNTdGFydD49dGhpc0VuZCYmc3RhcnQ+PWVuZCl7cmV0dXJuIDB9aWYodGhpc1N0YXJ0Pj10aGlzRW5kKXtyZXR1cm4tMX1pZihzdGFydD49ZW5kKXtyZXR1cm4gMX1zdGFydD4+Pj0wO2VuZD4+Pj0wO3RoaXNTdGFydD4+Pj0wO3RoaXNFbmQ+Pj49MDtpZih0aGlzPT09dGFyZ2V0KXJldHVybiAwO3ZhciB4PXRoaXNFbmQtdGhpc1N0YXJ0O3ZhciB5PWVuZC1zdGFydDt2YXIgbGVuPU1hdGgubWluKHgseSk7dmFyIHRoaXNDb3B5PXRoaXMuc2xpY2UodGhpc1N0YXJ0LHRoaXNFbmQpO3ZhciB0YXJnZXRDb3B5PXRhcmdldC5zbGljZShzdGFydCxlbmQpO2Zvcih2YXIgaT0wO2k8bGVuOysraSl7aWYodGhpc0NvcHlbaV0hPT10YXJnZXRDb3B5W2ldKXt4PXRoaXNDb3B5W2ldO3k9dGFyZ2V0Q29weVtpXTticmVha319aWYoeDx5KXJldHVybi0xO2lmKHk8eClyZXR1cm4gMTtyZXR1cm4gMH07ZnVuY3Rpb24gYmlkaXJlY3Rpb25hbEluZGV4T2YoYnVmZmVyLHZhbCxieXRlT2Zmc2V0LGVuY29kaW5nLGRpcil7aWYoYnVmZmVyLmxlbmd0aD09PTApcmV0dXJuLTE7aWYodHlwZW9mIGJ5dGVPZmZzZXQ9PT1cInN0cmluZ1wiKXtlbmNvZGluZz1ieXRlT2Zmc2V0O2J5dGVPZmZzZXQ9MH1lbHNlIGlmKGJ5dGVPZmZzZXQ+MjE0NzQ4MzY0Nyl7Ynl0ZU9mZnNldD0yMTQ3NDgzNjQ3fWVsc2UgaWYoYnl0ZU9mZnNldDwtMjE0NzQ4MzY0OCl7Ynl0ZU9mZnNldD0tMjE0NzQ4MzY0OH1ieXRlT2Zmc2V0PStieXRlT2Zmc2V0O2lmKGlzTmFOKGJ5dGVPZmZzZXQpKXtieXRlT2Zmc2V0PWRpcj8wOmJ1ZmZlci5sZW5ndGgtMX1pZihieXRlT2Zmc2V0PDApYnl0ZU9mZnNldD1idWZmZXIubGVuZ3RoK2J5dGVPZmZzZXQ7aWYoYnl0ZU9mZnNldD49YnVmZmVyLmxlbmd0aCl7aWYoZGlyKXJldHVybi0xO2Vsc2UgYnl0ZU9mZnNldD1idWZmZXIubGVuZ3RoLTF9ZWxzZSBpZihieXRlT2Zmc2V0PDApe2lmKGRpcilieXRlT2Zmc2V0PTA7ZWxzZSByZXR1cm4tMX1pZih0eXBlb2YgdmFsPT09XCJzdHJpbmdcIil7dmFsPUJ1ZmZlci5mcm9tKHZhbCxlbmNvZGluZyl9aWYoQnVmZmVyLmlzQnVmZmVyKHZhbCkpe2lmKHZhbC5sZW5ndGg9PT0wKXtyZXR1cm4tMX1yZXR1cm4gYXJyYXlJbmRleE9mKGJ1ZmZlcix2YWwsYnl0ZU9mZnNldCxlbmNvZGluZyxkaXIpfWVsc2UgaWYodHlwZW9mIHZhbD09PVwibnVtYmVyXCIpe3ZhbD12YWwmMjU1O2lmKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUJiZ0eXBlb2YgVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZj09PVwiZnVuY3Rpb25cIil7aWYoZGlyKXtyZXR1cm4gVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKGJ1ZmZlcix2YWwsYnl0ZU9mZnNldCl9ZWxzZXtyZXR1cm4gVWludDhBcnJheS5wcm90b3R5cGUubGFzdEluZGV4T2YuY2FsbChidWZmZXIsdmFsLGJ5dGVPZmZzZXQpfX1yZXR1cm4gYXJyYXlJbmRleE9mKGJ1ZmZlcixbdmFsXSxieXRlT2Zmc2V0LGVuY29kaW5nLGRpcil9dGhyb3cgbmV3IFR5cGVFcnJvcihcInZhbCBtdXN0IGJlIHN0cmluZywgbnVtYmVyIG9yIEJ1ZmZlclwiKX1mdW5jdGlvbiBhcnJheUluZGV4T2YoYXJyLHZhbCxieXRlT2Zmc2V0LGVuY29kaW5nLGRpcil7dmFyIGluZGV4U2l6ZT0xO3ZhciBhcnJMZW5ndGg9YXJyLmxlbmd0aDt2YXIgdmFsTGVuZ3RoPXZhbC5sZW5ndGg7aWYoZW5jb2RpbmchPT11bmRlZmluZWQpe2VuY29kaW5nPVN0cmluZyhlbmNvZGluZykudG9Mb3dlckNhc2UoKTtpZihlbmNvZGluZz09PVwidWNzMlwifHxlbmNvZGluZz09PVwidWNzLTJcInx8ZW5jb2Rpbmc9PT1cInV0ZjE2bGVcInx8ZW5jb2Rpbmc9PT1cInV0Zi0xNmxlXCIpe2lmKGFyci5sZW5ndGg8Mnx8dmFsLmxlbmd0aDwyKXtyZXR1cm4tMX1pbmRleFNpemU9MjthcnJMZW5ndGgvPTI7dmFsTGVuZ3RoLz0yO2J5dGVPZmZzZXQvPTJ9fWZ1bmN0aW9uIHJlYWQoYnVmLGkpe2lmKGluZGV4U2l6ZT09PTEpe3JldHVybiBidWZbaV19ZWxzZXtyZXR1cm4gYnVmLnJlYWRVSW50MTZCRShpKmluZGV4U2l6ZSl9fXZhciBpO2lmKGRpcil7dmFyIGZvdW5kSW5kZXg9LTE7Zm9yKGk9Ynl0ZU9mZnNldDtpPGFyckxlbmd0aDtpKyspe2lmKHJlYWQoYXJyLGkpPT09cmVhZCh2YWwsZm91bmRJbmRleD09PS0xPzA6aS1mb3VuZEluZGV4KSl7aWYoZm91bmRJbmRleD09PS0xKWZvdW5kSW5kZXg9aTtpZihpLWZvdW5kSW5kZXgrMT09PXZhbExlbmd0aClyZXR1cm4gZm91bmRJbmRleCppbmRleFNpemV9ZWxzZXtpZihmb3VuZEluZGV4IT09LTEpaS09aS1mb3VuZEluZGV4O2ZvdW5kSW5kZXg9LTF9fX1lbHNle2lmKGJ5dGVPZmZzZXQrdmFsTGVuZ3RoPmFyckxlbmd0aClieXRlT2Zmc2V0PWFyckxlbmd0aC12YWxMZW5ndGg7Zm9yKGk9Ynl0ZU9mZnNldDtpPj0wO2ktLSl7dmFyIGZvdW5kPXRydWU7Zm9yKHZhciBqPTA7ajx2YWxMZW5ndGg7aisrKXtpZihyZWFkKGFycixpK2opIT09cmVhZCh2YWwsaikpe2ZvdW5kPWZhbHNlO2JyZWFrfX1pZihmb3VuZClyZXR1cm4gaX19cmV0dXJuLTF9QnVmZmVyLnByb3RvdHlwZS5pbmNsdWRlcz1mdW5jdGlvbiBpbmNsdWRlcyh2YWwsYnl0ZU9mZnNldCxlbmNvZGluZyl7cmV0dXJuIHRoaXMuaW5kZXhPZih2YWwsYnl0ZU9mZnNldCxlbmNvZGluZykhPT0tMX07QnVmZmVyLnByb3RvdHlwZS5pbmRleE9mPWZ1bmN0aW9uIGluZGV4T2YodmFsLGJ5dGVPZmZzZXQsZW5jb2Rpbmcpe3JldHVybiBiaWRpcmVjdGlvbmFsSW5kZXhPZih0aGlzLHZhbCxieXRlT2Zmc2V0LGVuY29kaW5nLHRydWUpfTtCdWZmZXIucHJvdG90eXBlLmxhc3RJbmRleE9mPWZ1bmN0aW9uIGxhc3RJbmRleE9mKHZhbCxieXRlT2Zmc2V0LGVuY29kaW5nKXtyZXR1cm4gYmlkaXJlY3Rpb25hbEluZGV4T2YodGhpcyx2YWwsYnl0ZU9mZnNldCxlbmNvZGluZyxmYWxzZSl9O2Z1bmN0aW9uIGhleFdyaXRlKGJ1ZixzdHJpbmcsb2Zmc2V0LGxlbmd0aCl7b2Zmc2V0PU51bWJlcihvZmZzZXQpfHwwO3ZhciByZW1haW5pbmc9YnVmLmxlbmd0aC1vZmZzZXQ7aWYoIWxlbmd0aCl7bGVuZ3RoPXJlbWFpbmluZ31lbHNle2xlbmd0aD1OdW1iZXIobGVuZ3RoKTtpZihsZW5ndGg+cmVtYWluaW5nKXtsZW5ndGg9cmVtYWluaW5nfX12YXIgc3RyTGVuPXN0cmluZy5sZW5ndGg7aWYoc3RyTGVuJTIhPT0wKXRocm93IG5ldyBUeXBlRXJyb3IoXCJJbnZhbGlkIGhleCBzdHJpbmdcIik7aWYobGVuZ3RoPnN0ckxlbi8yKXtsZW5ndGg9c3RyTGVuLzJ9Zm9yKHZhciBpPTA7aTxsZW5ndGg7KytpKXt2YXIgcGFyc2VkPXBhcnNlSW50KHN0cmluZy5zdWJzdHIoaSoyLDIpLDE2KTtpZihpc05hTihwYXJzZWQpKXJldHVybiBpO2J1ZltvZmZzZXQraV09cGFyc2VkfXJldHVybiBpfWZ1bmN0aW9uIHV0ZjhXcml0ZShidWYsc3RyaW5nLG9mZnNldCxsZW5ndGgpe3JldHVybiBibGl0QnVmZmVyKHV0ZjhUb0J5dGVzKHN0cmluZyxidWYubGVuZ3RoLW9mZnNldCksYnVmLG9mZnNldCxsZW5ndGgpfWZ1bmN0aW9uIGFzY2lpV3JpdGUoYnVmLHN0cmluZyxvZmZzZXQsbGVuZ3RoKXtyZXR1cm4gYmxpdEJ1ZmZlcihhc2NpaVRvQnl0ZXMoc3RyaW5nKSxidWYsb2Zmc2V0LGxlbmd0aCl9ZnVuY3Rpb24gbGF0aW4xV3JpdGUoYnVmLHN0cmluZyxvZmZzZXQsbGVuZ3RoKXtyZXR1cm4gYXNjaWlXcml0ZShidWYsc3RyaW5nLG9mZnNldCxsZW5ndGgpfWZ1bmN0aW9uIGJhc2U2NFdyaXRlKGJ1ZixzdHJpbmcsb2Zmc2V0LGxlbmd0aCl7cmV0dXJuIGJsaXRCdWZmZXIoYmFzZTY0VG9CeXRlcyhzdHJpbmcpLGJ1ZixvZmZzZXQsbGVuZ3RoKX1mdW5jdGlvbiB1Y3MyV3JpdGUoYnVmLHN0cmluZyxvZmZzZXQsbGVuZ3RoKXtyZXR1cm4gYmxpdEJ1ZmZlcih1dGYxNmxlVG9CeXRlcyhzdHJpbmcsYnVmLmxlbmd0aC1vZmZzZXQpLGJ1ZixvZmZzZXQsbGVuZ3RoKX1CdWZmZXIucHJvdG90eXBlLndyaXRlPWZ1bmN0aW9uIHdyaXRlKHN0cmluZyxvZmZzZXQsbGVuZ3RoLGVuY29kaW5nKXtpZihvZmZzZXQ9PT11bmRlZmluZWQpe2VuY29kaW5nPVwidXRmOFwiO2xlbmd0aD10aGlzLmxlbmd0aDtvZmZzZXQ9MH1lbHNlIGlmKGxlbmd0aD09PXVuZGVmaW5lZCYmdHlwZW9mIG9mZnNldD09PVwic3RyaW5nXCIpe2VuY29kaW5nPW9mZnNldDtsZW5ndGg9dGhpcy5sZW5ndGg7b2Zmc2V0PTB9ZWxzZSBpZihpc0Zpbml0ZShvZmZzZXQpKXtvZmZzZXQ9b2Zmc2V0fDA7aWYoaXNGaW5pdGUobGVuZ3RoKSl7bGVuZ3RoPWxlbmd0aHwwO2lmKGVuY29kaW5nPT09dW5kZWZpbmVkKWVuY29kaW5nPVwidXRmOFwifWVsc2V7ZW5jb2Rpbmc9bGVuZ3RoO2xlbmd0aD11bmRlZmluZWR9fWVsc2V7dGhyb3cgbmV3IEVycm9yKFwiQnVmZmVyLndyaXRlKHN0cmluZywgZW5jb2RpbmcsIG9mZnNldFssIGxlbmd0aF0pIGlzIG5vIGxvbmdlciBzdXBwb3J0ZWRcIil9dmFyIHJlbWFpbmluZz10aGlzLmxlbmd0aC1vZmZzZXQ7aWYobGVuZ3RoPT09dW5kZWZpbmVkfHxsZW5ndGg+cmVtYWluaW5nKWxlbmd0aD1yZW1haW5pbmc7aWYoc3RyaW5nLmxlbmd0aD4wJiYobGVuZ3RoPDB8fG9mZnNldDwwKXx8b2Zmc2V0PnRoaXMubGVuZ3RoKXt0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkF0dGVtcHQgdG8gd3JpdGUgb3V0c2lkZSBidWZmZXIgYm91bmRzXCIpfWlmKCFlbmNvZGluZyllbmNvZGluZz1cInV0ZjhcIjt2YXIgbG93ZXJlZENhc2U9ZmFsc2U7Zm9yKDs7KXtzd2l0Y2goZW5jb2Rpbmcpe2Nhc2VcImhleFwiOnJldHVybiBoZXhXcml0ZSh0aGlzLHN0cmluZyxvZmZzZXQsbGVuZ3RoKTtjYXNlXCJ1dGY4XCI6Y2FzZVwidXRmLThcIjpyZXR1cm4gdXRmOFdyaXRlKHRoaXMsc3RyaW5nLG9mZnNldCxsZW5ndGgpO2Nhc2VcImFzY2lpXCI6cmV0dXJuIGFzY2lpV3JpdGUodGhpcyxzdHJpbmcsb2Zmc2V0LGxlbmd0aCk7Y2FzZVwibGF0aW4xXCI6Y2FzZVwiYmluYXJ5XCI6cmV0dXJuIGxhdGluMVdyaXRlKHRoaXMsc3RyaW5nLG9mZnNldCxsZW5ndGgpO2Nhc2VcImJhc2U2NFwiOnJldHVybiBiYXNlNjRXcml0ZSh0aGlzLHN0cmluZyxvZmZzZXQsbGVuZ3RoKTtjYXNlXCJ1Y3MyXCI6Y2FzZVwidWNzLTJcIjpjYXNlXCJ1dGYxNmxlXCI6Y2FzZVwidXRmLTE2bGVcIjpyZXR1cm4gdWNzMldyaXRlKHRoaXMsc3RyaW5nLG9mZnNldCxsZW5ndGgpO2RlZmF1bHQ6aWYobG93ZXJlZENhc2UpdGhyb3cgbmV3IFR5cGVFcnJvcihcIlVua25vd24gZW5jb2Rpbmc6IFwiK2VuY29kaW5nKTtlbmNvZGluZz0oXCJcIitlbmNvZGluZykudG9Mb3dlckNhc2UoKTtsb3dlcmVkQ2FzZT10cnVlfX19O0J1ZmZlci5wcm90b3R5cGUudG9KU09OPWZ1bmN0aW9uIHRvSlNPTigpe3JldHVybnt0eXBlOlwiQnVmZmVyXCIsZGF0YTpBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCh0aGlzLl9hcnJ8fHRoaXMsMCl9fTtmdW5jdGlvbiBiYXNlNjRTbGljZShidWYsc3RhcnQsZW5kKXtpZihzdGFydD09PTAmJmVuZD09PWJ1Zi5sZW5ndGgpe3JldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYpfWVsc2V7cmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1Zi5zbGljZShzdGFydCxlbmQpKX19ZnVuY3Rpb24gdXRmOFNsaWNlKGJ1ZixzdGFydCxlbmQpe2VuZD1NYXRoLm1pbihidWYubGVuZ3RoLGVuZCk7dmFyIHJlcz1bXTt2YXIgaT1zdGFydDt3aGlsZShpPGVuZCl7dmFyIGZpcnN0Qnl0ZT1idWZbaV07dmFyIGNvZGVQb2ludD1udWxsO3ZhciBieXRlc1BlclNlcXVlbmNlPWZpcnN0Qnl0ZT4yMzk/NDpmaXJzdEJ5dGU+MjIzPzM6Zmlyc3RCeXRlPjE5MT8yOjE7aWYoaStieXRlc1BlclNlcXVlbmNlPD1lbmQpe3ZhciBzZWNvbmRCeXRlLHRoaXJkQnl0ZSxmb3VydGhCeXRlLHRlbXBDb2RlUG9pbnQ7c3dpdGNoKGJ5dGVzUGVyU2VxdWVuY2Upe2Nhc2UgMTppZihmaXJzdEJ5dGU8MTI4KXtjb2RlUG9pbnQ9Zmlyc3RCeXRlfWJyZWFrO2Nhc2UgMjpzZWNvbmRCeXRlPWJ1ZltpKzFdO2lmKChzZWNvbmRCeXRlJjE5Mik9PT0xMjgpe3RlbXBDb2RlUG9pbnQ9KGZpcnN0Qnl0ZSYzMSk8PDZ8c2Vjb25kQnl0ZSY2MztpZih0ZW1wQ29kZVBvaW50PjEyNyl7Y29kZVBvaW50PXRlbXBDb2RlUG9pbnR9fWJyZWFrO2Nhc2UgMzpzZWNvbmRCeXRlPWJ1ZltpKzFdO3RoaXJkQnl0ZT1idWZbaSsyXTtpZigoc2Vjb25kQnl0ZSYxOTIpPT09MTI4JiYodGhpcmRCeXRlJjE5Mik9PT0xMjgpe3RlbXBDb2RlUG9pbnQ9KGZpcnN0Qnl0ZSYxNSk8PDEyfChzZWNvbmRCeXRlJjYzKTw8Nnx0aGlyZEJ5dGUmNjM7aWYodGVtcENvZGVQb2ludD4yMDQ3JiYodGVtcENvZGVQb2ludDw1NTI5Nnx8dGVtcENvZGVQb2ludD41NzM0Mykpe2NvZGVQb2ludD10ZW1wQ29kZVBvaW50fX1icmVhaztjYXNlIDQ6c2Vjb25kQnl0ZT1idWZbaSsxXTt0aGlyZEJ5dGU9YnVmW2krMl07Zm91cnRoQnl0ZT1idWZbaSszXTtpZigoc2Vjb25kQnl0ZSYxOTIpPT09MTI4JiYodGhpcmRCeXRlJjE5Mik9PT0xMjgmJihmb3VydGhCeXRlJjE5Mik9PT0xMjgpe3RlbXBDb2RlUG9pbnQ9KGZpcnN0Qnl0ZSYxNSk8PDE4fChzZWNvbmRCeXRlJjYzKTw8MTJ8KHRoaXJkQnl0ZSY2Myk8PDZ8Zm91cnRoQnl0ZSY2MztpZih0ZW1wQ29kZVBvaW50PjY1NTM1JiZ0ZW1wQ29kZVBvaW50PDExMTQxMTIpe2NvZGVQb2ludD10ZW1wQ29kZVBvaW50fX19fWlmKGNvZGVQb2ludD09PW51bGwpe2NvZGVQb2ludD02NTUzMztieXRlc1BlclNlcXVlbmNlPTF9ZWxzZSBpZihjb2RlUG9pbnQ+NjU1MzUpe2NvZGVQb2ludC09NjU1MzY7cmVzLnB1c2goY29kZVBvaW50Pj4+MTAmMTAyM3w1NTI5Nik7Y29kZVBvaW50PTU2MzIwfGNvZGVQb2ludCYxMDIzfXJlcy5wdXNoKGNvZGVQb2ludCk7aSs9Ynl0ZXNQZXJTZXF1ZW5jZX1yZXR1cm4gZGVjb2RlQ29kZVBvaW50c0FycmF5KHJlcyl9dmFyIE1BWF9BUkdVTUVOVFNfTEVOR1RIPTQwOTY7ZnVuY3Rpb24gZGVjb2RlQ29kZVBvaW50c0FycmF5KGNvZGVQb2ludHMpe3ZhciBsZW49Y29kZVBvaW50cy5sZW5ndGg7aWYobGVuPD1NQVhfQVJHVU1FTlRTX0xFTkdUSCl7cmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLGNvZGVQb2ludHMpfXZhciByZXM9XCJcIjt2YXIgaT0wO3doaWxlKGk8bGVuKXtyZXMrPVN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLGNvZGVQb2ludHMuc2xpY2UoaSxpKz1NQVhfQVJHVU1FTlRTX0xFTkdUSCkpfXJldHVybiByZXN9ZnVuY3Rpb24gYXNjaWlTbGljZShidWYsc3RhcnQsZW5kKXt2YXIgcmV0PVwiXCI7ZW5kPU1hdGgubWluKGJ1Zi5sZW5ndGgsZW5kKTtmb3IodmFyIGk9c3RhcnQ7aTxlbmQ7KytpKXtyZXQrPVN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldJjEyNyl9cmV0dXJuIHJldH1mdW5jdGlvbiBsYXRpbjFTbGljZShidWYsc3RhcnQsZW5kKXt2YXIgcmV0PVwiXCI7ZW5kPU1hdGgubWluKGJ1Zi5sZW5ndGgsZW5kKTtmb3IodmFyIGk9c3RhcnQ7aTxlbmQ7KytpKXtyZXQrPVN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldKX1yZXR1cm4gcmV0fWZ1bmN0aW9uIGhleFNsaWNlKGJ1ZixzdGFydCxlbmQpe3ZhciBsZW49YnVmLmxlbmd0aDtpZighc3RhcnR8fHN0YXJ0PDApc3RhcnQ9MDtpZighZW5kfHxlbmQ8MHx8ZW5kPmxlbillbmQ9bGVuO3ZhciBvdXQ9XCJcIjtmb3IodmFyIGk9c3RhcnQ7aTxlbmQ7KytpKXtvdXQrPXRvSGV4KGJ1ZltpXSl9cmV0dXJuIG91dH1mdW5jdGlvbiB1dGYxNmxlU2xpY2UoYnVmLHN0YXJ0LGVuZCl7dmFyIGJ5dGVzPWJ1Zi5zbGljZShzdGFydCxlbmQpO3ZhciByZXM9XCJcIjtmb3IodmFyIGk9MDtpPGJ5dGVzLmxlbmd0aDtpKz0yKXtyZXMrPVN0cmluZy5mcm9tQ2hhckNvZGUoYnl0ZXNbaV0rYnl0ZXNbaSsxXSoyNTYpfXJldHVybiByZXN9QnVmZmVyLnByb3RvdHlwZS5zbGljZT1mdW5jdGlvbiBzbGljZShzdGFydCxlbmQpe3ZhciBsZW49dGhpcy5sZW5ndGg7c3RhcnQ9fn5zdGFydDtlbmQ9ZW5kPT09dW5kZWZpbmVkP2xlbjp+fmVuZDtpZihzdGFydDwwKXtzdGFydCs9bGVuO2lmKHN0YXJ0PDApc3RhcnQ9MH1lbHNlIGlmKHN0YXJ0Pmxlbil7c3RhcnQ9bGVufWlmKGVuZDwwKXtlbmQrPWxlbjtpZihlbmQ8MCllbmQ9MH1lbHNlIGlmKGVuZD5sZW4pe2VuZD1sZW59aWYoZW5kPHN0YXJ0KWVuZD1zdGFydDt2YXIgbmV3QnVmO2lmKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKXtuZXdCdWY9dGhpcy5zdWJhcnJheShzdGFydCxlbmQpO25ld0J1Zi5fX3Byb3RvX189QnVmZmVyLnByb3RvdHlwZX1lbHNle3ZhciBzbGljZUxlbj1lbmQtc3RhcnQ7bmV3QnVmPW5ldyBCdWZmZXIoc2xpY2VMZW4sdW5kZWZpbmVkKTtmb3IodmFyIGk9MDtpPHNsaWNlTGVuOysraSl7bmV3QnVmW2ldPXRoaXNbaStzdGFydF19fXJldHVybiBuZXdCdWZ9O2Z1bmN0aW9uIGNoZWNrT2Zmc2V0KG9mZnNldCxleHQsbGVuZ3RoKXtpZihvZmZzZXQlMSE9PTB8fG9mZnNldDwwKXRocm93IG5ldyBSYW5nZUVycm9yKFwib2Zmc2V0IGlzIG5vdCB1aW50XCIpO2lmKG9mZnNldCtleHQ+bGVuZ3RoKXRocm93IG5ldyBSYW5nZUVycm9yKFwiVHJ5aW5nIHRvIGFjY2VzcyBiZXlvbmQgYnVmZmVyIGxlbmd0aFwiKX1CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50TEU9ZnVuY3Rpb24gcmVhZFVJbnRMRShvZmZzZXQsYnl0ZUxlbmd0aCxub0Fzc2VydCl7b2Zmc2V0PW9mZnNldHwwO2J5dGVMZW5ndGg9Ynl0ZUxlbmd0aHwwO2lmKCFub0Fzc2VydCljaGVja09mZnNldChvZmZzZXQsYnl0ZUxlbmd0aCx0aGlzLmxlbmd0aCk7dmFyIHZhbD10aGlzW29mZnNldF07dmFyIG11bD0xO3ZhciBpPTA7d2hpbGUoKytpPGJ5dGVMZW5ndGgmJihtdWwqPTI1Nikpe3ZhbCs9dGhpc1tvZmZzZXQraV0qbXVsfXJldHVybiB2YWx9O0J1ZmZlci5wcm90b3R5cGUucmVhZFVJbnRCRT1mdW5jdGlvbiByZWFkVUludEJFKG9mZnNldCxieXRlTGVuZ3RoLG5vQXNzZXJ0KXtvZmZzZXQ9b2Zmc2V0fDA7Ynl0ZUxlbmd0aD1ieXRlTGVuZ3RofDA7aWYoIW5vQXNzZXJ0KXtjaGVja09mZnNldChvZmZzZXQsYnl0ZUxlbmd0aCx0aGlzLmxlbmd0aCl9dmFyIHZhbD10aGlzW29mZnNldCstLWJ5dGVMZW5ndGhdO3ZhciBtdWw9MTt3aGlsZShieXRlTGVuZ3RoPjAmJihtdWwqPTI1Nikpe3ZhbCs9dGhpc1tvZmZzZXQrLS1ieXRlTGVuZ3RoXSptdWx9cmV0dXJuIHZhbH07QnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDg9ZnVuY3Rpb24gcmVhZFVJbnQ4KG9mZnNldCxub0Fzc2VydCl7aWYoIW5vQXNzZXJ0KWNoZWNrT2Zmc2V0KG9mZnNldCwxLHRoaXMubGVuZ3RoKTtyZXR1cm4gdGhpc1tvZmZzZXRdfTtCdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZMRT1mdW5jdGlvbiByZWFkVUludDE2TEUob2Zmc2V0LG5vQXNzZXJ0KXtpZighbm9Bc3NlcnQpY2hlY2tPZmZzZXQob2Zmc2V0LDIsdGhpcy5sZW5ndGgpO3JldHVybiB0aGlzW29mZnNldF18dGhpc1tvZmZzZXQrMV08PDh9O0J1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkJFPWZ1bmN0aW9uIHJlYWRVSW50MTZCRShvZmZzZXQsbm9Bc3NlcnQpe2lmKCFub0Fzc2VydCljaGVja09mZnNldChvZmZzZXQsMix0aGlzLmxlbmd0aCk7cmV0dXJuIHRoaXNbb2Zmc2V0XTw8OHx0aGlzW29mZnNldCsxXX07QnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyTEU9ZnVuY3Rpb24gcmVhZFVJbnQzMkxFKG9mZnNldCxub0Fzc2VydCl7aWYoIW5vQXNzZXJ0KWNoZWNrT2Zmc2V0KG9mZnNldCw0LHRoaXMubGVuZ3RoKTtyZXR1cm4odGhpc1tvZmZzZXRdfHRoaXNbb2Zmc2V0KzFdPDw4fHRoaXNbb2Zmc2V0KzJdPDwxNikrdGhpc1tvZmZzZXQrM10qMTY3NzcyMTZ9O0J1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkJFPWZ1bmN0aW9uIHJlYWRVSW50MzJCRShvZmZzZXQsbm9Bc3NlcnQpe2lmKCFub0Fzc2VydCljaGVja09mZnNldChvZmZzZXQsNCx0aGlzLmxlbmd0aCk7cmV0dXJuIHRoaXNbb2Zmc2V0XSoxNjc3NzIxNisodGhpc1tvZmZzZXQrMV08PDE2fHRoaXNbb2Zmc2V0KzJdPDw4fHRoaXNbb2Zmc2V0KzNdKX07QnVmZmVyLnByb3RvdHlwZS5yZWFkSW50TEU9ZnVuY3Rpb24gcmVhZEludExFKG9mZnNldCxieXRlTGVuZ3RoLG5vQXNzZXJ0KXtvZmZzZXQ9b2Zmc2V0fDA7Ynl0ZUxlbmd0aD1ieXRlTGVuZ3RofDA7aWYoIW5vQXNzZXJ0KWNoZWNrT2Zmc2V0KG9mZnNldCxieXRlTGVuZ3RoLHRoaXMubGVuZ3RoKTt2YXIgdmFsPXRoaXNbb2Zmc2V0XTt2YXIgbXVsPTE7dmFyIGk9MDt3aGlsZSgrK2k8Ynl0ZUxlbmd0aCYmKG11bCo9MjU2KSl7dmFsKz10aGlzW29mZnNldCtpXSptdWx9bXVsKj0xMjg7aWYodmFsPj1tdWwpdmFsLT1NYXRoLnBvdygyLDgqYnl0ZUxlbmd0aCk7cmV0dXJuIHZhbH07QnVmZmVyLnByb3RvdHlwZS5yZWFkSW50QkU9ZnVuY3Rpb24gcmVhZEludEJFKG9mZnNldCxieXRlTGVuZ3RoLG5vQXNzZXJ0KXtvZmZzZXQ9b2Zmc2V0fDA7Ynl0ZUxlbmd0aD1ieXRlTGVuZ3RofDA7aWYoIW5vQXNzZXJ0KWNoZWNrT2Zmc2V0KG9mZnNldCxieXRlTGVuZ3RoLHRoaXMubGVuZ3RoKTtcbnZhciBpPWJ5dGVMZW5ndGg7dmFyIG11bD0xO3ZhciB2YWw9dGhpc1tvZmZzZXQrLS1pXTt3aGlsZShpPjAmJihtdWwqPTI1Nikpe3ZhbCs9dGhpc1tvZmZzZXQrLS1pXSptdWx9bXVsKj0xMjg7aWYodmFsPj1tdWwpdmFsLT1NYXRoLnBvdygyLDgqYnl0ZUxlbmd0aCk7cmV0dXJuIHZhbH07QnVmZmVyLnByb3RvdHlwZS5yZWFkSW50OD1mdW5jdGlvbiByZWFkSW50OChvZmZzZXQsbm9Bc3NlcnQpe2lmKCFub0Fzc2VydCljaGVja09mZnNldChvZmZzZXQsMSx0aGlzLmxlbmd0aCk7aWYoISh0aGlzW29mZnNldF0mMTI4KSlyZXR1cm4gdGhpc1tvZmZzZXRdO3JldHVybigyNTUtdGhpc1tvZmZzZXRdKzEpKi0xfTtCdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkxFPWZ1bmN0aW9uIHJlYWRJbnQxNkxFKG9mZnNldCxub0Fzc2VydCl7aWYoIW5vQXNzZXJ0KWNoZWNrT2Zmc2V0KG9mZnNldCwyLHRoaXMubGVuZ3RoKTt2YXIgdmFsPXRoaXNbb2Zmc2V0XXx0aGlzW29mZnNldCsxXTw8ODtyZXR1cm4gdmFsJjMyNzY4P3ZhbHw0Mjk0OTAxNzYwOnZhbH07QnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZCRT1mdW5jdGlvbiByZWFkSW50MTZCRShvZmZzZXQsbm9Bc3NlcnQpe2lmKCFub0Fzc2VydCljaGVja09mZnNldChvZmZzZXQsMix0aGlzLmxlbmd0aCk7dmFyIHZhbD10aGlzW29mZnNldCsxXXx0aGlzW29mZnNldF08PDg7cmV0dXJuIHZhbCYzMjc2OD92YWx8NDI5NDkwMTc2MDp2YWx9O0J1ZmZlci5wcm90b3R5cGUucmVhZEludDMyTEU9ZnVuY3Rpb24gcmVhZEludDMyTEUob2Zmc2V0LG5vQXNzZXJ0KXtpZighbm9Bc3NlcnQpY2hlY2tPZmZzZXQob2Zmc2V0LDQsdGhpcy5sZW5ndGgpO3JldHVybiB0aGlzW29mZnNldF18dGhpc1tvZmZzZXQrMV08PDh8dGhpc1tvZmZzZXQrMl08PDE2fHRoaXNbb2Zmc2V0KzNdPDwyNH07QnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJCRT1mdW5jdGlvbiByZWFkSW50MzJCRShvZmZzZXQsbm9Bc3NlcnQpe2lmKCFub0Fzc2VydCljaGVja09mZnNldChvZmZzZXQsNCx0aGlzLmxlbmd0aCk7cmV0dXJuIHRoaXNbb2Zmc2V0XTw8MjR8dGhpc1tvZmZzZXQrMV08PDE2fHRoaXNbb2Zmc2V0KzJdPDw4fHRoaXNbb2Zmc2V0KzNdfTtCdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdExFPWZ1bmN0aW9uIHJlYWRGbG9hdExFKG9mZnNldCxub0Fzc2VydCl7aWYoIW5vQXNzZXJ0KWNoZWNrT2Zmc2V0KG9mZnNldCw0LHRoaXMubGVuZ3RoKTtyZXR1cm4gaWVlZTc1NC5yZWFkKHRoaXMsb2Zmc2V0LHRydWUsMjMsNCl9O0J1ZmZlci5wcm90b3R5cGUucmVhZEZsb2F0QkU9ZnVuY3Rpb24gcmVhZEZsb2F0QkUob2Zmc2V0LG5vQXNzZXJ0KXtpZighbm9Bc3NlcnQpY2hlY2tPZmZzZXQob2Zmc2V0LDQsdGhpcy5sZW5ndGgpO3JldHVybiBpZWVlNzU0LnJlYWQodGhpcyxvZmZzZXQsZmFsc2UsMjMsNCl9O0J1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUxFPWZ1bmN0aW9uIHJlYWREb3VibGVMRShvZmZzZXQsbm9Bc3NlcnQpe2lmKCFub0Fzc2VydCljaGVja09mZnNldChvZmZzZXQsOCx0aGlzLmxlbmd0aCk7cmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLG9mZnNldCx0cnVlLDUyLDgpfTtCdWZmZXIucHJvdG90eXBlLnJlYWREb3VibGVCRT1mdW5jdGlvbiByZWFkRG91YmxlQkUob2Zmc2V0LG5vQXNzZXJ0KXtpZighbm9Bc3NlcnQpY2hlY2tPZmZzZXQob2Zmc2V0LDgsdGhpcy5sZW5ndGgpO3JldHVybiBpZWVlNzU0LnJlYWQodGhpcyxvZmZzZXQsZmFsc2UsNTIsOCl9O2Z1bmN0aW9uIGNoZWNrSW50KGJ1Zix2YWx1ZSxvZmZzZXQsZXh0LG1heCxtaW4pe2lmKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSl0aHJvdyBuZXcgVHlwZUVycm9yKCdcImJ1ZmZlclwiIGFyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXIgaW5zdGFuY2UnKTtpZih2YWx1ZT5tYXh8fHZhbHVlPG1pbil0aHJvdyBuZXcgUmFuZ2VFcnJvcignXCJ2YWx1ZVwiIGFyZ3VtZW50IGlzIG91dCBvZiBib3VuZHMnKTtpZihvZmZzZXQrZXh0PmJ1Zi5sZW5ndGgpdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbmRleCBvdXQgb2YgcmFuZ2VcIil9QnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnRMRT1mdW5jdGlvbiB3cml0ZVVJbnRMRSh2YWx1ZSxvZmZzZXQsYnl0ZUxlbmd0aCxub0Fzc2VydCl7dmFsdWU9K3ZhbHVlO29mZnNldD1vZmZzZXR8MDtieXRlTGVuZ3RoPWJ5dGVMZW5ndGh8MDtpZighbm9Bc3NlcnQpe3ZhciBtYXhCeXRlcz1NYXRoLnBvdygyLDgqYnl0ZUxlbmd0aCktMTtjaGVja0ludCh0aGlzLHZhbHVlLG9mZnNldCxieXRlTGVuZ3RoLG1heEJ5dGVzLDApfXZhciBtdWw9MTt2YXIgaT0wO3RoaXNbb2Zmc2V0XT12YWx1ZSYyNTU7d2hpbGUoKytpPGJ5dGVMZW5ndGgmJihtdWwqPTI1Nikpe3RoaXNbb2Zmc2V0K2ldPXZhbHVlL211bCYyNTV9cmV0dXJuIG9mZnNldCtieXRlTGVuZ3RofTtCdWZmZXIucHJvdG90eXBlLndyaXRlVUludEJFPWZ1bmN0aW9uIHdyaXRlVUludEJFKHZhbHVlLG9mZnNldCxieXRlTGVuZ3RoLG5vQXNzZXJ0KXt2YWx1ZT0rdmFsdWU7b2Zmc2V0PW9mZnNldHwwO2J5dGVMZW5ndGg9Ynl0ZUxlbmd0aHwwO2lmKCFub0Fzc2VydCl7dmFyIG1heEJ5dGVzPU1hdGgucG93KDIsOCpieXRlTGVuZ3RoKS0xO2NoZWNrSW50KHRoaXMsdmFsdWUsb2Zmc2V0LGJ5dGVMZW5ndGgsbWF4Qnl0ZXMsMCl9dmFyIGk9Ynl0ZUxlbmd0aC0xO3ZhciBtdWw9MTt0aGlzW29mZnNldCtpXT12YWx1ZSYyNTU7d2hpbGUoLS1pPj0wJiYobXVsKj0yNTYpKXt0aGlzW29mZnNldCtpXT12YWx1ZS9tdWwmMjU1fXJldHVybiBvZmZzZXQrYnl0ZUxlbmd0aH07QnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQ4PWZ1bmN0aW9uIHdyaXRlVUludDgodmFsdWUsb2Zmc2V0LG5vQXNzZXJ0KXt2YWx1ZT0rdmFsdWU7b2Zmc2V0PW9mZnNldHwwO2lmKCFub0Fzc2VydCljaGVja0ludCh0aGlzLHZhbHVlLG9mZnNldCwxLDI1NSwwKTtpZighQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpdmFsdWU9TWF0aC5mbG9vcih2YWx1ZSk7dGhpc1tvZmZzZXRdPXZhbHVlJjI1NTtyZXR1cm4gb2Zmc2V0KzF9O2Z1bmN0aW9uIG9iamVjdFdyaXRlVUludDE2KGJ1Zix2YWx1ZSxvZmZzZXQsbGl0dGxlRW5kaWFuKXtpZih2YWx1ZTwwKXZhbHVlPTY1NTM1K3ZhbHVlKzE7Zm9yKHZhciBpPTAsaj1NYXRoLm1pbihidWYubGVuZ3RoLW9mZnNldCwyKTtpPGo7KytpKXtidWZbb2Zmc2V0K2ldPSh2YWx1ZSYyNTU8PDgqKGxpdHRsZUVuZGlhbj9pOjEtaSkpPj4+KGxpdHRsZUVuZGlhbj9pOjEtaSkqOH19QnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkxFPWZ1bmN0aW9uIHdyaXRlVUludDE2TEUodmFsdWUsb2Zmc2V0LG5vQXNzZXJ0KXt2YWx1ZT0rdmFsdWU7b2Zmc2V0PW9mZnNldHwwO2lmKCFub0Fzc2VydCljaGVja0ludCh0aGlzLHZhbHVlLG9mZnNldCwyLDY1NTM1LDApO2lmKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKXt0aGlzW29mZnNldF09dmFsdWUmMjU1O3RoaXNbb2Zmc2V0KzFdPXZhbHVlPj4+OH1lbHNle29iamVjdFdyaXRlVUludDE2KHRoaXMsdmFsdWUsb2Zmc2V0LHRydWUpfXJldHVybiBvZmZzZXQrMn07QnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkJFPWZ1bmN0aW9uIHdyaXRlVUludDE2QkUodmFsdWUsb2Zmc2V0LG5vQXNzZXJ0KXt2YWx1ZT0rdmFsdWU7b2Zmc2V0PW9mZnNldHwwO2lmKCFub0Fzc2VydCljaGVja0ludCh0aGlzLHZhbHVlLG9mZnNldCwyLDY1NTM1LDApO2lmKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKXt0aGlzW29mZnNldF09dmFsdWU+Pj44O3RoaXNbb2Zmc2V0KzFdPXZhbHVlJjI1NX1lbHNle29iamVjdFdyaXRlVUludDE2KHRoaXMsdmFsdWUsb2Zmc2V0LGZhbHNlKX1yZXR1cm4gb2Zmc2V0KzJ9O2Z1bmN0aW9uIG9iamVjdFdyaXRlVUludDMyKGJ1Zix2YWx1ZSxvZmZzZXQsbGl0dGxlRW5kaWFuKXtpZih2YWx1ZTwwKXZhbHVlPTQyOTQ5NjcyOTUrdmFsdWUrMTtmb3IodmFyIGk9MCxqPU1hdGgubWluKGJ1Zi5sZW5ndGgtb2Zmc2V0LDQpO2k8ajsrK2kpe2J1ZltvZmZzZXQraV09dmFsdWU+Pj4obGl0dGxlRW5kaWFuP2k6My1pKSo4JjI1NX19QnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkxFPWZ1bmN0aW9uIHdyaXRlVUludDMyTEUodmFsdWUsb2Zmc2V0LG5vQXNzZXJ0KXt2YWx1ZT0rdmFsdWU7b2Zmc2V0PW9mZnNldHwwO2lmKCFub0Fzc2VydCljaGVja0ludCh0aGlzLHZhbHVlLG9mZnNldCw0LDQyOTQ5NjcyOTUsMCk7aWYoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpe3RoaXNbb2Zmc2V0KzNdPXZhbHVlPj4+MjQ7dGhpc1tvZmZzZXQrMl09dmFsdWU+Pj4xNjt0aGlzW29mZnNldCsxXT12YWx1ZT4+Pjg7dGhpc1tvZmZzZXRdPXZhbHVlJjI1NX1lbHNle29iamVjdFdyaXRlVUludDMyKHRoaXMsdmFsdWUsb2Zmc2V0LHRydWUpfXJldHVybiBvZmZzZXQrNH07QnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkJFPWZ1bmN0aW9uIHdyaXRlVUludDMyQkUodmFsdWUsb2Zmc2V0LG5vQXNzZXJ0KXt2YWx1ZT0rdmFsdWU7b2Zmc2V0PW9mZnNldHwwO2lmKCFub0Fzc2VydCljaGVja0ludCh0aGlzLHZhbHVlLG9mZnNldCw0LDQyOTQ5NjcyOTUsMCk7aWYoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpe3RoaXNbb2Zmc2V0XT12YWx1ZT4+PjI0O3RoaXNbb2Zmc2V0KzFdPXZhbHVlPj4+MTY7dGhpc1tvZmZzZXQrMl09dmFsdWU+Pj44O3RoaXNbb2Zmc2V0KzNdPXZhbHVlJjI1NX1lbHNle29iamVjdFdyaXRlVUludDMyKHRoaXMsdmFsdWUsb2Zmc2V0LGZhbHNlKX1yZXR1cm4gb2Zmc2V0KzR9O0J1ZmZlci5wcm90b3R5cGUud3JpdGVJbnRMRT1mdW5jdGlvbiB3cml0ZUludExFKHZhbHVlLG9mZnNldCxieXRlTGVuZ3RoLG5vQXNzZXJ0KXt2YWx1ZT0rdmFsdWU7b2Zmc2V0PW9mZnNldHwwO2lmKCFub0Fzc2VydCl7dmFyIGxpbWl0PU1hdGgucG93KDIsOCpieXRlTGVuZ3RoLTEpO2NoZWNrSW50KHRoaXMsdmFsdWUsb2Zmc2V0LGJ5dGVMZW5ndGgsbGltaXQtMSwtbGltaXQpfXZhciBpPTA7dmFyIG11bD0xO3ZhciBzdWI9MDt0aGlzW29mZnNldF09dmFsdWUmMjU1O3doaWxlKCsraTxieXRlTGVuZ3RoJiYobXVsKj0yNTYpKXtpZih2YWx1ZTwwJiZzdWI9PT0wJiZ0aGlzW29mZnNldCtpLTFdIT09MCl7c3ViPTF9dGhpc1tvZmZzZXQraV09KHZhbHVlL211bD4+MCktc3ViJjI1NX1yZXR1cm4gb2Zmc2V0K2J5dGVMZW5ndGh9O0J1ZmZlci5wcm90b3R5cGUud3JpdGVJbnRCRT1mdW5jdGlvbiB3cml0ZUludEJFKHZhbHVlLG9mZnNldCxieXRlTGVuZ3RoLG5vQXNzZXJ0KXt2YWx1ZT0rdmFsdWU7b2Zmc2V0PW9mZnNldHwwO2lmKCFub0Fzc2VydCl7dmFyIGxpbWl0PU1hdGgucG93KDIsOCpieXRlTGVuZ3RoLTEpO2NoZWNrSW50KHRoaXMsdmFsdWUsb2Zmc2V0LGJ5dGVMZW5ndGgsbGltaXQtMSwtbGltaXQpfXZhciBpPWJ5dGVMZW5ndGgtMTt2YXIgbXVsPTE7dmFyIHN1Yj0wO3RoaXNbb2Zmc2V0K2ldPXZhbHVlJjI1NTt3aGlsZSgtLWk+PTAmJihtdWwqPTI1Nikpe2lmKHZhbHVlPDAmJnN1Yj09PTAmJnRoaXNbb2Zmc2V0K2krMV0hPT0wKXtzdWI9MX10aGlzW29mZnNldCtpXT0odmFsdWUvbXVsPj4wKS1zdWImMjU1fXJldHVybiBvZmZzZXQrYnl0ZUxlbmd0aH07QnVmZmVyLnByb3RvdHlwZS53cml0ZUludDg9ZnVuY3Rpb24gd3JpdGVJbnQ4KHZhbHVlLG9mZnNldCxub0Fzc2VydCl7dmFsdWU9K3ZhbHVlO29mZnNldD1vZmZzZXR8MDtpZighbm9Bc3NlcnQpY2hlY2tJbnQodGhpcyx2YWx1ZSxvZmZzZXQsMSwxMjcsLTEyOCk7aWYoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKXZhbHVlPU1hdGguZmxvb3IodmFsdWUpO2lmKHZhbHVlPDApdmFsdWU9MjU1K3ZhbHVlKzE7dGhpc1tvZmZzZXRdPXZhbHVlJjI1NTtyZXR1cm4gb2Zmc2V0KzF9O0J1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkxFPWZ1bmN0aW9uIHdyaXRlSW50MTZMRSh2YWx1ZSxvZmZzZXQsbm9Bc3NlcnQpe3ZhbHVlPSt2YWx1ZTtvZmZzZXQ9b2Zmc2V0fDA7aWYoIW5vQXNzZXJ0KWNoZWNrSW50KHRoaXMsdmFsdWUsb2Zmc2V0LDIsMzI3NjcsLTMyNzY4KTtpZihCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCl7dGhpc1tvZmZzZXRdPXZhbHVlJjI1NTt0aGlzW29mZnNldCsxXT12YWx1ZT4+Pjh9ZWxzZXtvYmplY3RXcml0ZVVJbnQxNih0aGlzLHZhbHVlLG9mZnNldCx0cnVlKX1yZXR1cm4gb2Zmc2V0KzJ9O0J1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkJFPWZ1bmN0aW9uIHdyaXRlSW50MTZCRSh2YWx1ZSxvZmZzZXQsbm9Bc3NlcnQpe3ZhbHVlPSt2YWx1ZTtvZmZzZXQ9b2Zmc2V0fDA7aWYoIW5vQXNzZXJ0KWNoZWNrSW50KHRoaXMsdmFsdWUsb2Zmc2V0LDIsMzI3NjcsLTMyNzY4KTtpZihCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCl7dGhpc1tvZmZzZXRdPXZhbHVlPj4+ODt0aGlzW29mZnNldCsxXT12YWx1ZSYyNTV9ZWxzZXtvYmplY3RXcml0ZVVJbnQxNih0aGlzLHZhbHVlLG9mZnNldCxmYWxzZSl9cmV0dXJuIG9mZnNldCsyfTtCdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJMRT1mdW5jdGlvbiB3cml0ZUludDMyTEUodmFsdWUsb2Zmc2V0LG5vQXNzZXJ0KXt2YWx1ZT0rdmFsdWU7b2Zmc2V0PW9mZnNldHwwO2lmKCFub0Fzc2VydCljaGVja0ludCh0aGlzLHZhbHVlLG9mZnNldCw0LDIxNDc0ODM2NDcsLTIxNDc0ODM2NDgpO2lmKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKXt0aGlzW29mZnNldF09dmFsdWUmMjU1O3RoaXNbb2Zmc2V0KzFdPXZhbHVlPj4+ODt0aGlzW29mZnNldCsyXT12YWx1ZT4+PjE2O3RoaXNbb2Zmc2V0KzNdPXZhbHVlPj4+MjR9ZWxzZXtvYmplY3RXcml0ZVVJbnQzMih0aGlzLHZhbHVlLG9mZnNldCx0cnVlKX1yZXR1cm4gb2Zmc2V0KzR9O0J1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkJFPWZ1bmN0aW9uIHdyaXRlSW50MzJCRSh2YWx1ZSxvZmZzZXQsbm9Bc3NlcnQpe3ZhbHVlPSt2YWx1ZTtvZmZzZXQ9b2Zmc2V0fDA7aWYoIW5vQXNzZXJ0KWNoZWNrSW50KHRoaXMsdmFsdWUsb2Zmc2V0LDQsMjE0NzQ4MzY0NywtMjE0NzQ4MzY0OCk7aWYodmFsdWU8MCl2YWx1ZT00Mjk0OTY3Mjk1K3ZhbHVlKzE7aWYoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpe3RoaXNbb2Zmc2V0XT12YWx1ZT4+PjI0O3RoaXNbb2Zmc2V0KzFdPXZhbHVlPj4+MTY7dGhpc1tvZmZzZXQrMl09dmFsdWU+Pj44O3RoaXNbb2Zmc2V0KzNdPXZhbHVlJjI1NX1lbHNle29iamVjdFdyaXRlVUludDMyKHRoaXMsdmFsdWUsb2Zmc2V0LGZhbHNlKX1yZXR1cm4gb2Zmc2V0KzR9O2Z1bmN0aW9uIGNoZWNrSUVFRTc1NChidWYsdmFsdWUsb2Zmc2V0LGV4dCxtYXgsbWluKXtpZihvZmZzZXQrZXh0PmJ1Zi5sZW5ndGgpdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbmRleCBvdXQgb2YgcmFuZ2VcIik7aWYob2Zmc2V0PDApdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbmRleCBvdXQgb2YgcmFuZ2VcIil9ZnVuY3Rpb24gd3JpdGVGbG9hdChidWYsdmFsdWUsb2Zmc2V0LGxpdHRsZUVuZGlhbixub0Fzc2VydCl7aWYoIW5vQXNzZXJ0KXtjaGVja0lFRUU3NTQoYnVmLHZhbHVlLG9mZnNldCw0LDMuNDAyODIzNDY2Mzg1Mjg4NmUzOCwtMy40MDI4MjM0NjYzODUyODg2ZTM4KX1pZWVlNzU0LndyaXRlKGJ1Zix2YWx1ZSxvZmZzZXQsbGl0dGxlRW5kaWFuLDIzLDQpO3JldHVybiBvZmZzZXQrNH1CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRMRT1mdW5jdGlvbiB3cml0ZUZsb2F0TEUodmFsdWUsb2Zmc2V0LG5vQXNzZXJ0KXtyZXR1cm4gd3JpdGVGbG9hdCh0aGlzLHZhbHVlLG9mZnNldCx0cnVlLG5vQXNzZXJ0KX07QnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0QkU9ZnVuY3Rpb24gd3JpdGVGbG9hdEJFKHZhbHVlLG9mZnNldCxub0Fzc2VydCl7cmV0dXJuIHdyaXRlRmxvYXQodGhpcyx2YWx1ZSxvZmZzZXQsZmFsc2Usbm9Bc3NlcnQpfTtmdW5jdGlvbiB3cml0ZURvdWJsZShidWYsdmFsdWUsb2Zmc2V0LGxpdHRsZUVuZGlhbixub0Fzc2VydCl7aWYoIW5vQXNzZXJ0KXtjaGVja0lFRUU3NTQoYnVmLHZhbHVlLG9mZnNldCw4LDEuNzk3NjkzMTM0ODYyMzE1N2UzMDgsLTEuNzk3NjkzMTM0ODYyMzE1N2UzMDgpfWllZWU3NTQud3JpdGUoYnVmLHZhbHVlLG9mZnNldCxsaXR0bGVFbmRpYW4sNTIsOCk7cmV0dXJuIG9mZnNldCs4fUJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVMRT1mdW5jdGlvbiB3cml0ZURvdWJsZUxFKHZhbHVlLG9mZnNldCxub0Fzc2VydCl7cmV0dXJuIHdyaXRlRG91YmxlKHRoaXMsdmFsdWUsb2Zmc2V0LHRydWUsbm9Bc3NlcnQpfTtCdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlQkU9ZnVuY3Rpb24gd3JpdGVEb3VibGVCRSh2YWx1ZSxvZmZzZXQsbm9Bc3NlcnQpe3JldHVybiB3cml0ZURvdWJsZSh0aGlzLHZhbHVlLG9mZnNldCxmYWxzZSxub0Fzc2VydCl9O0J1ZmZlci5wcm90b3R5cGUuY29weT1mdW5jdGlvbiBjb3B5KHRhcmdldCx0YXJnZXRTdGFydCxzdGFydCxlbmQpe2lmKCFzdGFydClzdGFydD0wO2lmKCFlbmQmJmVuZCE9PTApZW5kPXRoaXMubGVuZ3RoO2lmKHRhcmdldFN0YXJ0Pj10YXJnZXQubGVuZ3RoKXRhcmdldFN0YXJ0PXRhcmdldC5sZW5ndGg7aWYoIXRhcmdldFN0YXJ0KXRhcmdldFN0YXJ0PTA7aWYoZW5kPjAmJmVuZDxzdGFydCllbmQ9c3RhcnQ7aWYoZW5kPT09c3RhcnQpcmV0dXJuIDA7aWYodGFyZ2V0Lmxlbmd0aD09PTB8fHRoaXMubGVuZ3RoPT09MClyZXR1cm4gMDtpZih0YXJnZXRTdGFydDwwKXt0aHJvdyBuZXcgUmFuZ2VFcnJvcihcInRhcmdldFN0YXJ0IG91dCBvZiBib3VuZHNcIil9aWYoc3RhcnQ8MHx8c3RhcnQ+PXRoaXMubGVuZ3RoKXRocm93IG5ldyBSYW5nZUVycm9yKFwic291cmNlU3RhcnQgb3V0IG9mIGJvdW5kc1wiKTtpZihlbmQ8MCl0aHJvdyBuZXcgUmFuZ2VFcnJvcihcInNvdXJjZUVuZCBvdXQgb2YgYm91bmRzXCIpO2lmKGVuZD50aGlzLmxlbmd0aCllbmQ9dGhpcy5sZW5ndGg7aWYodGFyZ2V0Lmxlbmd0aC10YXJnZXRTdGFydDxlbmQtc3RhcnQpe2VuZD10YXJnZXQubGVuZ3RoLXRhcmdldFN0YXJ0K3N0YXJ0fXZhciBsZW49ZW5kLXN0YXJ0O3ZhciBpO2lmKHRoaXM9PT10YXJnZXQmJnN0YXJ0PHRhcmdldFN0YXJ0JiZ0YXJnZXRTdGFydDxlbmQpe2ZvcihpPWxlbi0xO2k+PTA7LS1pKXt0YXJnZXRbaSt0YXJnZXRTdGFydF09dGhpc1tpK3N0YXJ0XX19ZWxzZSBpZihsZW48MWUzfHwhQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpe2ZvcihpPTA7aTxsZW47KytpKXt0YXJnZXRbaSt0YXJnZXRTdGFydF09dGhpc1tpK3N0YXJ0XX19ZWxzZXtVaW50OEFycmF5LnByb3RvdHlwZS5zZXQuY2FsbCh0YXJnZXQsdGhpcy5zdWJhcnJheShzdGFydCxzdGFydCtsZW4pLHRhcmdldFN0YXJ0KX1yZXR1cm4gbGVufTtCdWZmZXIucHJvdG90eXBlLmZpbGw9ZnVuY3Rpb24gZmlsbCh2YWwsc3RhcnQsZW5kLGVuY29kaW5nKXtpZih0eXBlb2YgdmFsPT09XCJzdHJpbmdcIil7aWYodHlwZW9mIHN0YXJ0PT09XCJzdHJpbmdcIil7ZW5jb2Rpbmc9c3RhcnQ7c3RhcnQ9MDtlbmQ9dGhpcy5sZW5ndGh9ZWxzZSBpZih0eXBlb2YgZW5kPT09XCJzdHJpbmdcIil7ZW5jb2Rpbmc9ZW5kO2VuZD10aGlzLmxlbmd0aH1pZih2YWwubGVuZ3RoPT09MSl7dmFyIGNvZGU9dmFsLmNoYXJDb2RlQXQoMCk7aWYoY29kZTwyNTYpe3ZhbD1jb2RlfX1pZihlbmNvZGluZyE9PXVuZGVmaW5lZCYmdHlwZW9mIGVuY29kaW5nIT09XCJzdHJpbmdcIil7dGhyb3cgbmV3IFR5cGVFcnJvcihcImVuY29kaW5nIG11c3QgYmUgYSBzdHJpbmdcIil9aWYodHlwZW9mIGVuY29kaW5nPT09XCJzdHJpbmdcIiYmIUJ1ZmZlci5pc0VuY29kaW5nKGVuY29kaW5nKSl7dGhyb3cgbmV3IFR5cGVFcnJvcihcIlVua25vd24gZW5jb2Rpbmc6IFwiK2VuY29kaW5nKX19ZWxzZSBpZih0eXBlb2YgdmFsPT09XCJudW1iZXJcIil7dmFsPXZhbCYyNTV9aWYoc3RhcnQ8MHx8dGhpcy5sZW5ndGg8c3RhcnR8fHRoaXMubGVuZ3RoPGVuZCl7dGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJPdXQgb2YgcmFuZ2UgaW5kZXhcIil9aWYoZW5kPD1zdGFydCl7cmV0dXJuIHRoaXN9c3RhcnQ9c3RhcnQ+Pj4wO2VuZD1lbmQ9PT11bmRlZmluZWQ/dGhpcy5sZW5ndGg6ZW5kPj4+MDtpZighdmFsKXZhbD0wO3ZhciBpO2lmKHR5cGVvZiB2YWw9PT1cIm51bWJlclwiKXtmb3IoaT1zdGFydDtpPGVuZDsrK2kpe3RoaXNbaV09dmFsfX1lbHNle3ZhciBieXRlcz1CdWZmZXIuaXNCdWZmZXIodmFsKT92YWw6dXRmOFRvQnl0ZXMobmV3IEJ1ZmZlcih2YWwsZW5jb2RpbmcpLnRvU3RyaW5nKCkpO3ZhciBsZW49Ynl0ZXMubGVuZ3RoO2ZvcihpPTA7aTxlbmQtc3RhcnQ7KytpKXt0aGlzW2krc3RhcnRdPWJ5dGVzW2klbGVuXX19cmV0dXJuIHRoaXN9O3ZhciBJTlZBTElEX0JBU0U2NF9SRT0vW14rXFwvMC05QS1aYS16LV9dL2c7ZnVuY3Rpb24gYmFzZTY0Y2xlYW4oc3RyKXtzdHI9c3RyaW5ndHJpbShzdHIpLnJlcGxhY2UoSU5WQUxJRF9CQVNFNjRfUkUsXCJcIik7aWYoc3RyLmxlbmd0aDwyKXJldHVyblwiXCI7d2hpbGUoc3RyLmxlbmd0aCU0IT09MCl7c3RyPXN0citcIj1cIn1yZXR1cm4gc3RyfWZ1bmN0aW9uIHN0cmluZ3RyaW0oc3RyKXtpZihzdHIudHJpbSlyZXR1cm4gc3RyLnRyaW0oKTtyZXR1cm4gc3RyLnJlcGxhY2UoL15cXHMrfFxccyskL2csXCJcIil9ZnVuY3Rpb24gdG9IZXgobil7aWYobjwxNilyZXR1cm5cIjBcIituLnRvU3RyaW5nKDE2KTtyZXR1cm4gbi50b1N0cmluZygxNil9ZnVuY3Rpb24gdXRmOFRvQnl0ZXMoc3RyaW5nLHVuaXRzKXt1bml0cz11bml0c3x8SW5maW5pdHk7dmFyIGNvZGVQb2ludDt2YXIgbGVuZ3RoPXN0cmluZy5sZW5ndGg7dmFyIGxlYWRTdXJyb2dhdGU9bnVsbDt2YXIgYnl0ZXM9W107Zm9yKHZhciBpPTA7aTxsZW5ndGg7KytpKXtjb2RlUG9pbnQ9c3RyaW5nLmNoYXJDb2RlQXQoaSk7aWYoY29kZVBvaW50PjU1Mjk1JiZjb2RlUG9pbnQ8NTczNDQpe2lmKCFsZWFkU3Vycm9nYXRlKXtpZihjb2RlUG9pbnQ+NTYzMTkpe2lmKCh1bml0cy09Myk+LTEpYnl0ZXMucHVzaCgyMzksMTkxLDE4OSk7Y29udGludWV9ZWxzZSBpZihpKzE9PT1sZW5ndGgpe2lmKCh1bml0cy09Myk+LTEpYnl0ZXMucHVzaCgyMzksMTkxLDE4OSk7Y29udGludWV9bGVhZFN1cnJvZ2F0ZT1jb2RlUG9pbnQ7Y29udGludWV9aWYoY29kZVBvaW50PDU2MzIwKXtpZigodW5pdHMtPTMpPi0xKWJ5dGVzLnB1c2goMjM5LDE5MSwxODkpO2xlYWRTdXJyb2dhdGU9Y29kZVBvaW50O2NvbnRpbnVlfWNvZGVQb2ludD0obGVhZFN1cnJvZ2F0ZS01NTI5Njw8MTB8Y29kZVBvaW50LTU2MzIwKSs2NTUzNn1lbHNlIGlmKGxlYWRTdXJyb2dhdGUpe2lmKCh1bml0cy09Myk+LTEpYnl0ZXMucHVzaCgyMzksMTkxLDE4OSl9bGVhZFN1cnJvZ2F0ZT1udWxsO2lmKGNvZGVQb2ludDwxMjgpe2lmKCh1bml0cy09MSk8MClicmVhaztieXRlcy5wdXNoKGNvZGVQb2ludCl9ZWxzZSBpZihjb2RlUG9pbnQ8MjA0OCl7aWYoKHVuaXRzLT0yKTwwKWJyZWFrO2J5dGVzLnB1c2goY29kZVBvaW50Pj42fDE5Mixjb2RlUG9pbnQmNjN8MTI4KX1lbHNlIGlmKGNvZGVQb2ludDw2NTUzNil7aWYoKHVuaXRzLT0zKTwwKWJyZWFrO2J5dGVzLnB1c2goY29kZVBvaW50Pj4xMnwyMjQsY29kZVBvaW50Pj42JjYzfDEyOCxjb2RlUG9pbnQmNjN8MTI4KX1lbHNlIGlmKGNvZGVQb2ludDwxMTE0MTEyKXtpZigodW5pdHMtPTQpPDApYnJlYWs7Ynl0ZXMucHVzaChjb2RlUG9pbnQ+PjE4fDI0MCxjb2RlUG9pbnQ+PjEyJjYzfDEyOCxjb2RlUG9pbnQ+PjYmNjN8MTI4LGNvZGVQb2ludCY2M3wxMjgpfWVsc2V7dGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBjb2RlIHBvaW50XCIpfX1yZXR1cm4gYnl0ZXN9ZnVuY3Rpb24gYXNjaWlUb0J5dGVzKHN0cil7dmFyIGJ5dGVBcnJheT1bXTtmb3IodmFyIGk9MDtpPHN0ci5sZW5ndGg7KytpKXtieXRlQXJyYXkucHVzaChzdHIuY2hhckNvZGVBdChpKSYyNTUpfXJldHVybiBieXRlQXJyYXl9ZnVuY3Rpb24gdXRmMTZsZVRvQnl0ZXMoc3RyLHVuaXRzKXt2YXIgYyxoaSxsbzt2YXIgYnl0ZUFycmF5PVtdO2Zvcih2YXIgaT0wO2k8c3RyLmxlbmd0aDsrK2kpe2lmKCh1bml0cy09Mik8MClicmVhaztjPXN0ci5jaGFyQ29kZUF0KGkpO2hpPWM+Pjg7bG89YyUyNTY7Ynl0ZUFycmF5LnB1c2gobG8pO2J5dGVBcnJheS5wdXNoKGhpKX1yZXR1cm4gYnl0ZUFycmF5fWZ1bmN0aW9uIGJhc2U2NFRvQnl0ZXMoc3RyKXtyZXR1cm4gYmFzZTY0LnRvQnl0ZUFycmF5KGJhc2U2NGNsZWFuKHN0cikpfWZ1bmN0aW9uIGJsaXRCdWZmZXIoc3JjLGRzdCxvZmZzZXQsbGVuZ3RoKXtmb3IodmFyIGk9MDtpPGxlbmd0aDsrK2kpe2lmKGkrb2Zmc2V0Pj1kc3QubGVuZ3RofHxpPj1zcmMubGVuZ3RoKWJyZWFrO2RzdFtpK29mZnNldF09c3JjW2ldfXJldHVybiBpfWZ1bmN0aW9uIGlzbmFuKHZhbCl7cmV0dXJuIHZhbCE9PXZhbH19KS5jYWxsKHRoaXMsdHlwZW9mIGdsb2JhbCE9PVwidW5kZWZpbmVkXCI/Z2xvYmFsOnR5cGVvZiBzZWxmIT09XCJ1bmRlZmluZWRcIj9zZWxmOnR5cGVvZiB3aW5kb3chPT1cInVuZGVmaW5lZFwiP3dpbmRvdzp7fSl9LHtcImJhc2U2NC1qc1wiOjIsaWVlZTc1NDozNyxpc2FycmF5OjQwfV0sNjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7KGZ1bmN0aW9uKEJ1ZmZlcil7ZnVuY3Rpb24gaXNBcnJheShhcmcpe2lmKEFycmF5LmlzQXJyYXkpe3JldHVybiBBcnJheS5pc0FycmF5KGFyZyl9cmV0dXJuIG9iamVjdFRvU3RyaW5nKGFyZyk9PT1cIltvYmplY3QgQXJyYXldXCJ9ZXhwb3J0cy5pc0FycmF5PWlzQXJyYXk7ZnVuY3Rpb24gaXNCb29sZWFuKGFyZyl7cmV0dXJuIHR5cGVvZiBhcmc9PT1cImJvb2xlYW5cIn1leHBvcnRzLmlzQm9vbGVhbj1pc0Jvb2xlYW47ZnVuY3Rpb24gaXNOdWxsKGFyZyl7cmV0dXJuIGFyZz09PW51bGx9ZXhwb3J0cy5pc051bGw9aXNOdWxsO2Z1bmN0aW9uIGlzTnVsbE9yVW5kZWZpbmVkKGFyZyl7cmV0dXJuIGFyZz09bnVsbH1leHBvcnRzLmlzTnVsbE9yVW5kZWZpbmVkPWlzTnVsbE9yVW5kZWZpbmVkO2Z1bmN0aW9uIGlzTnVtYmVyKGFyZyl7cmV0dXJuIHR5cGVvZiBhcmc9PT1cIm51bWJlclwifWV4cG9ydHMuaXNOdW1iZXI9aXNOdW1iZXI7ZnVuY3Rpb24gaXNTdHJpbmcoYXJnKXtyZXR1cm4gdHlwZW9mIGFyZz09PVwic3RyaW5nXCJ9ZXhwb3J0cy5pc1N0cmluZz1pc1N0cmluZztmdW5jdGlvbiBpc1N5bWJvbChhcmcpe3JldHVybiB0eXBlb2YgYXJnPT09XCJzeW1ib2xcIn1leHBvcnRzLmlzU3ltYm9sPWlzU3ltYm9sO2Z1bmN0aW9uIGlzVW5kZWZpbmVkKGFyZyl7cmV0dXJuIGFyZz09PXZvaWQgMH1leHBvcnRzLmlzVW5kZWZpbmVkPWlzVW5kZWZpbmVkO2Z1bmN0aW9uIGlzUmVnRXhwKHJlKXtyZXR1cm4gb2JqZWN0VG9TdHJpbmcocmUpPT09XCJbb2JqZWN0IFJlZ0V4cF1cIn1leHBvcnRzLmlzUmVnRXhwPWlzUmVnRXhwO2Z1bmN0aW9uIGlzT2JqZWN0KGFyZyl7cmV0dXJuIHR5cGVvZiBhcmc9PT1cIm9iamVjdFwiJiZhcmchPT1udWxsfWV4cG9ydHMuaXNPYmplY3Q9aXNPYmplY3Q7ZnVuY3Rpb24gaXNEYXRlKGQpe3JldHVybiBvYmplY3RUb1N0cmluZyhkKT09PVwiW29iamVjdCBEYXRlXVwifWV4cG9ydHMuaXNEYXRlPWlzRGF0ZTtmdW5jdGlvbiBpc0Vycm9yKGUpe3JldHVybiBvYmplY3RUb1N0cmluZyhlKT09PVwiW29iamVjdCBFcnJvcl1cInx8ZSBpbnN0YW5jZW9mIEVycm9yfWV4cG9ydHMuaXNFcnJvcj1pc0Vycm9yO2Z1bmN0aW9uIGlzRnVuY3Rpb24oYXJnKXtyZXR1cm4gdHlwZW9mIGFyZz09PVwiZnVuY3Rpb25cIn1leHBvcnRzLmlzRnVuY3Rpb249aXNGdW5jdGlvbjtmdW5jdGlvbiBpc1ByaW1pdGl2ZShhcmcpe3JldHVybiBhcmc9PT1udWxsfHx0eXBlb2YgYXJnPT09XCJib29sZWFuXCJ8fHR5cGVvZiBhcmc9PT1cIm51bWJlclwifHx0eXBlb2YgYXJnPT09XCJzdHJpbmdcInx8dHlwZW9mIGFyZz09PVwic3ltYm9sXCJ8fHR5cGVvZiBhcmc9PT1cInVuZGVmaW5lZFwifWV4cG9ydHMuaXNQcmltaXRpdmU9aXNQcmltaXRpdmU7ZXhwb3J0cy5pc0J1ZmZlcj1CdWZmZXIuaXNCdWZmZXI7ZnVuY3Rpb24gb2JqZWN0VG9TdHJpbmcobyl7cmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKX19KS5jYWxsKHRoaXMse2lzQnVmZmVyOnJlcXVpcmUoXCIuLi8uLi9pcy1idWZmZXIvaW5kZXguanNcIil9KX0se1wiLi4vLi4vaXMtYnVmZmVyL2luZGV4LmpzXCI6Mzl9XSw3OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgRWxlbWVudFR5cGU9cmVxdWlyZShcImRvbWVsZW1lbnR0eXBlXCIpO3ZhciBlbnRpdGllcz1yZXF1aXJlKFwiZW50aXRpZXNcIik7dmFyIGJvb2xlYW5BdHRyaWJ1dGVzPXtfX3Byb3RvX186bnVsbCxhbGxvd2Z1bGxzY3JlZW46dHJ1ZSxhc3luYzp0cnVlLGF1dG9mb2N1czp0cnVlLGF1dG9wbGF5OnRydWUsY2hlY2tlZDp0cnVlLGNvbnRyb2xzOnRydWUsZGVmYXVsdDp0cnVlLGRlZmVyOnRydWUsZGlzYWJsZWQ6dHJ1ZSxoaWRkZW46dHJ1ZSxpc21hcDp0cnVlLGxvb3A6dHJ1ZSxtdWx0aXBsZTp0cnVlLG11dGVkOnRydWUsb3Blbjp0cnVlLHJlYWRvbmx5OnRydWUscmVxdWlyZWQ6dHJ1ZSxyZXZlcnNlZDp0cnVlLHNjb3BlZDp0cnVlLHNlYW1sZXNzOnRydWUsc2VsZWN0ZWQ6dHJ1ZSx0eXBlbXVzdG1hdGNoOnRydWV9O3ZhciB1bmVuY29kZWRFbGVtZW50cz17X19wcm90b19fOm51bGwsc3R5bGU6dHJ1ZSxzY3JpcHQ6dHJ1ZSx4bXA6dHJ1ZSxpZnJhbWU6dHJ1ZSxub2VtYmVkOnRydWUsbm9mcmFtZXM6dHJ1ZSxwbGFpbnRleHQ6dHJ1ZSxub3NjcmlwdDp0cnVlfTtmdW5jdGlvbiBmb3JtYXRBdHRycyhhdHRyaWJ1dGVzLG9wdHMpe2lmKCFhdHRyaWJ1dGVzKXJldHVybjt2YXIgb3V0cHV0PVwiXCIsdmFsdWU7Zm9yKHZhciBrZXkgaW4gYXR0cmlidXRlcyl7dmFsdWU9YXR0cmlidXRlc1trZXldO2lmKG91dHB1dCl7b3V0cHV0Kz1cIiBcIn1pZighdmFsdWUmJmJvb2xlYW5BdHRyaWJ1dGVzW2tleV0pe291dHB1dCs9a2V5fWVsc2V7b3V0cHV0Kz1rZXkrJz1cIicrKG9wdHMuZGVjb2RlRW50aXRpZXM/ZW50aXRpZXMuZW5jb2RlWE1MKHZhbHVlKTp2YWx1ZSkrJ1wiJ319cmV0dXJuIG91dHB1dH12YXIgc2luZ2xlVGFnPXtfX3Byb3RvX186bnVsbCxhcmVhOnRydWUsYmFzZTp0cnVlLGJhc2Vmb250OnRydWUsYnI6dHJ1ZSxjb2w6dHJ1ZSxjb21tYW5kOnRydWUsZW1iZWQ6dHJ1ZSxmcmFtZTp0cnVlLGhyOnRydWUsaW1nOnRydWUsaW5wdXQ6dHJ1ZSxpc2luZGV4OnRydWUsa2V5Z2VuOnRydWUsbGluazp0cnVlLG1ldGE6dHJ1ZSxwYXJhbTp0cnVlLHNvdXJjZTp0cnVlLHRyYWNrOnRydWUsd2JyOnRydWV9O3ZhciByZW5kZXI9bW9kdWxlLmV4cG9ydHM9ZnVuY3Rpb24oZG9tLG9wdHMpe2lmKCFBcnJheS5pc0FycmF5KGRvbSkmJiFkb20uY2hlZXJpbylkb209W2RvbV07b3B0cz1vcHRzfHx7fTt2YXIgb3V0cHV0PVwiXCI7Zm9yKHZhciBpPTA7aTxkb20ubGVuZ3RoO2krKyl7dmFyIGVsZW09ZG9tW2ldO2lmKGVsZW0udHlwZT09PVwicm9vdFwiKW91dHB1dCs9cmVuZGVyKGVsZW0uY2hpbGRyZW4sb3B0cyk7ZWxzZSBpZihFbGVtZW50VHlwZS5pc1RhZyhlbGVtKSlvdXRwdXQrPXJlbmRlclRhZyhlbGVtLG9wdHMpO2Vsc2UgaWYoZWxlbS50eXBlPT09RWxlbWVudFR5cGUuRGlyZWN0aXZlKW91dHB1dCs9cmVuZGVyRGlyZWN0aXZlKGVsZW0pO2Vsc2UgaWYoZWxlbS50eXBlPT09RWxlbWVudFR5cGUuQ29tbWVudClvdXRwdXQrPXJlbmRlckNvbW1lbnQoZWxlbSk7ZWxzZSBpZihlbGVtLnR5cGU9PT1FbGVtZW50VHlwZS5DREFUQSlvdXRwdXQrPXJlbmRlckNkYXRhKGVsZW0pO2Vsc2Ugb3V0cHV0Kz1yZW5kZXJUZXh0KGVsZW0sb3B0cyl9cmV0dXJuIG91dHB1dH07ZnVuY3Rpb24gcmVuZGVyVGFnKGVsZW0sb3B0cyl7aWYoZWxlbS5uYW1lPT09XCJzdmdcIilvcHRzPXtkZWNvZGVFbnRpdGllczpvcHRzLmRlY29kZUVudGl0aWVzLHhtbE1vZGU6dHJ1ZX07dmFyIHRhZz1cIjxcIitlbGVtLm5hbWUsYXR0cmlicz1mb3JtYXRBdHRycyhlbGVtLmF0dHJpYnMsb3B0cyk7aWYoYXR0cmlicyl7dGFnKz1cIiBcIithdHRyaWJzfWlmKG9wdHMueG1sTW9kZSYmKCFlbGVtLmNoaWxkcmVufHxlbGVtLmNoaWxkcmVuLmxlbmd0aD09PTApKXt0YWcrPVwiLz5cIn1lbHNle3RhZys9XCI+XCI7aWYoZWxlbS5jaGlsZHJlbil7dGFnKz1yZW5kZXIoZWxlbS5jaGlsZHJlbixvcHRzKX1pZighc2luZ2xlVGFnW2VsZW0ubmFtZV18fG9wdHMueG1sTW9kZSl7dGFnKz1cIjwvXCIrZWxlbS5uYW1lK1wiPlwifX1yZXR1cm4gdGFnfWZ1bmN0aW9uIHJlbmRlckRpcmVjdGl2ZShlbGVtKXtyZXR1cm5cIjxcIitlbGVtLmRhdGErXCI+XCJ9ZnVuY3Rpb24gcmVuZGVyVGV4dChlbGVtLG9wdHMpe3ZhciBkYXRhPWVsZW0uZGF0YXx8XCJcIjtpZihvcHRzLmRlY29kZUVudGl0aWVzJiYhKGVsZW0ucGFyZW50JiZlbGVtLnBhcmVudC5uYW1lIGluIHVuZW5jb2RlZEVsZW1lbnRzKSl7ZGF0YT1lbnRpdGllcy5lbmNvZGVYTUwoZGF0YSl9cmV0dXJuIGRhdGF9ZnVuY3Rpb24gcmVuZGVyQ2RhdGEoZWxlbSl7cmV0dXJuXCI8IVtDREFUQVtcIitlbGVtLmNoaWxkcmVuWzBdLmRhdGErXCJdXT5cIn1mdW5jdGlvbiByZW5kZXJDb21tZW50KGVsZW0pe3JldHVyblwiPCEtLVwiK2VsZW0uZGF0YStcIi0tPlwifX0se2RvbWVsZW1lbnR0eXBlOjgsZW50aXRpZXM6MjB9XSw4OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXttb2R1bGUuZXhwb3J0cz17VGV4dDpcInRleHRcIixEaXJlY3RpdmU6XCJkaXJlY3RpdmVcIixDb21tZW50OlwiY29tbWVudFwiLFNjcmlwdDpcInNjcmlwdFwiLFN0eWxlOlwic3R5bGVcIixUYWc6XCJ0YWdcIixDREFUQTpcImNkYXRhXCIsaXNUYWc6ZnVuY3Rpb24oZWxlbSl7cmV0dXJuIGVsZW0udHlwZT09PVwidGFnXCJ8fGVsZW0udHlwZT09PVwic2NyaXB0XCJ8fGVsZW0udHlwZT09PVwic3R5bGVcIn19fSx7fV0sOTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9e1RleHQ6XCJ0ZXh0XCIsRGlyZWN0aXZlOlwiZGlyZWN0aXZlXCIsQ29tbWVudDpcImNvbW1lbnRcIixTY3JpcHQ6XCJzY3JpcHRcIixTdHlsZTpcInN0eWxlXCIsVGFnOlwidGFnXCIsQ0RBVEE6XCJjZGF0YVwiLERvY3R5cGU6XCJkb2N0eXBlXCIsaXNUYWc6ZnVuY3Rpb24oZWxlbSl7cmV0dXJuIGVsZW0udHlwZT09PVwidGFnXCJ8fGVsZW0udHlwZT09PVwic2NyaXB0XCJ8fGVsZW0udHlwZT09PVwic3R5bGVcIn19fSx7fV0sMTA6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe3ZhciBFbGVtZW50VHlwZT1yZXF1aXJlKFwiZG9tZWxlbWVudHR5cGVcIik7dmFyIHJlX3doaXRlc3BhY2U9L1xccysvZzt2YXIgTm9kZVByb3RvdHlwZT1yZXF1aXJlKFwiLi9saWIvbm9kZVwiKTt2YXIgRWxlbWVudFByb3RvdHlwZT1yZXF1aXJlKFwiLi9saWIvZWxlbWVudFwiKTtmdW5jdGlvbiBEb21IYW5kbGVyKGNhbGxiYWNrLG9wdGlvbnMsZWxlbWVudENCKXtpZih0eXBlb2YgY2FsbGJhY2s9PT1cIm9iamVjdFwiKXtlbGVtZW50Q0I9b3B0aW9ucztvcHRpb25zPWNhbGxiYWNrO2NhbGxiYWNrPW51bGx9ZWxzZSBpZih0eXBlb2Ygb3B0aW9ucz09PVwiZnVuY3Rpb25cIil7ZWxlbWVudENCPW9wdGlvbnM7b3B0aW9ucz1kZWZhdWx0T3B0c310aGlzLl9jYWxsYmFjaz1jYWxsYmFjazt0aGlzLl9vcHRpb25zPW9wdGlvbnN8fGRlZmF1bHRPcHRzO3RoaXMuX2VsZW1lbnRDQj1lbGVtZW50Q0I7dGhpcy5kb209W107dGhpcy5fZG9uZT1mYWxzZTt0aGlzLl90YWdTdGFjaz1bXTt0aGlzLl9wYXJzZXI9dGhpcy5fcGFyc2VyfHxudWxsfXZhciBkZWZhdWx0T3B0cz17bm9ybWFsaXplV2hpdGVzcGFjZTpmYWxzZSx3aXRoU3RhcnRJbmRpY2VzOmZhbHNlfTtEb21IYW5kbGVyLnByb3RvdHlwZS5vbnBhcnNlcmluaXQ9ZnVuY3Rpb24ocGFyc2VyKXt0aGlzLl9wYXJzZXI9cGFyc2VyfTtEb21IYW5kbGVyLnByb3RvdHlwZS5vbnJlc2V0PWZ1bmN0aW9uKCl7RG9tSGFuZGxlci5jYWxsKHRoaXMsdGhpcy5fY2FsbGJhY2ssdGhpcy5fb3B0aW9ucyx0aGlzLl9lbGVtZW50Q0IpfTtEb21IYW5kbGVyLnByb3RvdHlwZS5vbmVuZD1mdW5jdGlvbigpe2lmKHRoaXMuX2RvbmUpcmV0dXJuO3RoaXMuX2RvbmU9dHJ1ZTt0aGlzLl9wYXJzZXI9bnVsbDt0aGlzLl9oYW5kbGVDYWxsYmFjayhudWxsKX07RG9tSGFuZGxlci5wcm90b3R5cGUuX2hhbmRsZUNhbGxiYWNrPURvbUhhbmRsZXIucHJvdG90eXBlLm9uZXJyb3I9ZnVuY3Rpb24oZXJyb3Ipe2lmKHR5cGVvZiB0aGlzLl9jYWxsYmFjaz09PVwiZnVuY3Rpb25cIil7dGhpcy5fY2FsbGJhY2soZXJyb3IsdGhpcy5kb20pfWVsc2V7aWYoZXJyb3IpdGhyb3cgZXJyb3J9fTtEb21IYW5kbGVyLnByb3RvdHlwZS5vbmNsb3NldGFnPWZ1bmN0aW9uKCl7dmFyIGVsZW09dGhpcy5fdGFnU3RhY2sucG9wKCk7aWYodGhpcy5fZWxlbWVudENCKXRoaXMuX2VsZW1lbnRDQihlbGVtKX07RG9tSGFuZGxlci5wcm90b3R5cGUuX2FkZERvbUVsZW1lbnQ9ZnVuY3Rpb24oZWxlbWVudCl7dmFyIHBhcmVudD10aGlzLl90YWdTdGFja1t0aGlzLl90YWdTdGFjay5sZW5ndGgtMV07dmFyIHNpYmxpbmdzPXBhcmVudD9wYXJlbnQuY2hpbGRyZW46dGhpcy5kb207dmFyIHByZXZpb3VzU2libGluZz1zaWJsaW5nc1tzaWJsaW5ncy5sZW5ndGgtMV07ZWxlbWVudC5uZXh0PW51bGw7aWYodGhpcy5fb3B0aW9ucy53aXRoU3RhcnRJbmRpY2VzKXtlbGVtZW50LnN0YXJ0SW5kZXg9dGhpcy5fcGFyc2VyLnN0YXJ0SW5kZXh9aWYodGhpcy5fb3B0aW9ucy53aXRoRG9tTHZsMSl7ZWxlbWVudC5fX3Byb3RvX189ZWxlbWVudC50eXBlPT09XCJ0YWdcIj9FbGVtZW50UHJvdG90eXBlOk5vZGVQcm90b3R5cGV9aWYocHJldmlvdXNTaWJsaW5nKXtlbGVtZW50LnByZXY9cHJldmlvdXNTaWJsaW5nO3ByZXZpb3VzU2libGluZy5uZXh0PWVsZW1lbnR9ZWxzZXtlbGVtZW50LnByZXY9bnVsbH1zaWJsaW5ncy5wdXNoKGVsZW1lbnQpO2VsZW1lbnQucGFyZW50PXBhcmVudHx8bnVsbH07RG9tSGFuZGxlci5wcm90b3R5cGUub25vcGVudGFnPWZ1bmN0aW9uKG5hbWUsYXR0cmlicyl7dmFyIGVsZW1lbnQ9e3R5cGU6bmFtZT09PVwic2NyaXB0XCI/RWxlbWVudFR5cGUuU2NyaXB0Om5hbWU9PT1cInN0eWxlXCI/RWxlbWVudFR5cGUuU3R5bGU6RWxlbWVudFR5cGUuVGFnLG5hbWU6bmFtZSxhdHRyaWJzOmF0dHJpYnMsY2hpbGRyZW46W119O3RoaXMuX2FkZERvbUVsZW1lbnQoZWxlbWVudCk7dGhpcy5fdGFnU3RhY2sucHVzaChlbGVtZW50KX07RG9tSGFuZGxlci5wcm90b3R5cGUub250ZXh0PWZ1bmN0aW9uKGRhdGEpe3ZhciBub3JtYWxpemU9dGhpcy5fb3B0aW9ucy5ub3JtYWxpemVXaGl0ZXNwYWNlfHx0aGlzLl9vcHRpb25zLmlnbm9yZVdoaXRlc3BhY2U7dmFyIGxhc3RUYWc7aWYoIXRoaXMuX3RhZ1N0YWNrLmxlbmd0aCYmdGhpcy5kb20ubGVuZ3RoJiYobGFzdFRhZz10aGlzLmRvbVt0aGlzLmRvbS5sZW5ndGgtMV0pLnR5cGU9PT1FbGVtZW50VHlwZS5UZXh0KXtpZihub3JtYWxpemUpe2xhc3RUYWcuZGF0YT0obGFzdFRhZy5kYXRhK2RhdGEpLnJlcGxhY2UocmVfd2hpdGVzcGFjZSxcIiBcIil9ZWxzZXtsYXN0VGFnLmRhdGErPWRhdGF9fWVsc2V7aWYodGhpcy5fdGFnU3RhY2subGVuZ3RoJiYobGFzdFRhZz10aGlzLl90YWdTdGFja1t0aGlzLl90YWdTdGFjay5sZW5ndGgtMV0pJiYobGFzdFRhZz1sYXN0VGFnLmNoaWxkcmVuW2xhc3RUYWcuY2hpbGRyZW4ubGVuZ3RoLTFdKSYmbGFzdFRhZy50eXBlPT09RWxlbWVudFR5cGUuVGV4dCl7aWYobm9ybWFsaXplKXtsYXN0VGFnLmRhdGE9KGxhc3RUYWcuZGF0YStkYXRhKS5yZXBsYWNlKHJlX3doaXRlc3BhY2UsXCIgXCIpfWVsc2V7bGFzdFRhZy5kYXRhKz1kYXRhfX1lbHNle2lmKG5vcm1hbGl6ZSl7ZGF0YT1kYXRhLnJlcGxhY2UocmVfd2hpdGVzcGFjZSxcIiBcIil9dGhpcy5fYWRkRG9tRWxlbWVudCh7ZGF0YTpkYXRhLHR5cGU6RWxlbWVudFR5cGUuVGV4dH0pfX19O0RvbUhhbmRsZXIucHJvdG90eXBlLm9uY29tbWVudD1mdW5jdGlvbihkYXRhKXt2YXIgbGFzdFRhZz10aGlzLl90YWdTdGFja1t0aGlzLl90YWdTdGFjay5sZW5ndGgtMV07aWYobGFzdFRhZyYmbGFzdFRhZy50eXBlPT09RWxlbWVudFR5cGUuQ29tbWVudCl7bGFzdFRhZy5kYXRhKz1kYXRhO3JldHVybn12YXIgZWxlbWVudD17ZGF0YTpkYXRhLHR5cGU6RWxlbWVudFR5cGUuQ29tbWVudH07dGhpcy5fYWRkRG9tRWxlbWVudChlbGVtZW50KTt0aGlzLl90YWdTdGFjay5wdXNoKGVsZW1lbnQpfTtEb21IYW5kbGVyLnByb3RvdHlwZS5vbmNkYXRhc3RhcnQ9ZnVuY3Rpb24oKXt2YXIgZWxlbWVudD17Y2hpbGRyZW46W3tkYXRhOlwiXCIsdHlwZTpFbGVtZW50VHlwZS5UZXh0fV0sdHlwZTpFbGVtZW50VHlwZS5DREFUQX07dGhpcy5fYWRkRG9tRWxlbWVudChlbGVtZW50KTt0aGlzLl90YWdTdGFjay5wdXNoKGVsZW1lbnQpfTtEb21IYW5kbGVyLnByb3RvdHlwZS5vbmNvbW1lbnRlbmQ9RG9tSGFuZGxlci5wcm90b3R5cGUub25jZGF0YWVuZD1mdW5jdGlvbigpe3RoaXMuX3RhZ1N0YWNrLnBvcCgpfTtEb21IYW5kbGVyLnByb3RvdHlwZS5vbnByb2Nlc3NpbmdpbnN0cnVjdGlvbj1mdW5jdGlvbihuYW1lLGRhdGEpe3RoaXMuX2FkZERvbUVsZW1lbnQoe25hbWU6bmFtZSxkYXRhOmRhdGEsdHlwZTpFbGVtZW50VHlwZS5EaXJlY3RpdmV9KX07bW9kdWxlLmV4cG9ydHM9RG9tSGFuZGxlcn0se1wiLi9saWIvZWxlbWVudFwiOjExLFwiLi9saWIvbm9kZVwiOjEyLGRvbWVsZW1lbnR0eXBlOjl9XSwxMTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7dmFyIE5vZGVQcm90b3R5cGU9cmVxdWlyZShcIi4vbm9kZVwiKTt2YXIgRWxlbWVudFByb3RvdHlwZT1tb2R1bGUuZXhwb3J0cz1PYmplY3QuY3JlYXRlKE5vZGVQcm90b3R5cGUpO3ZhciBkb21MdmwxPXt0YWdOYW1lOlwibmFtZVwifTtPYmplY3Qua2V5cyhkb21MdmwxKS5mb3JFYWNoKGZ1bmN0aW9uKGtleSl7dmFyIHNob3J0aGFuZD1kb21MdmwxW2tleV07T2JqZWN0LmRlZmluZVByb3BlcnR5KEVsZW1lbnRQcm90b3R5cGUsa2V5LHtnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpc1tzaG9ydGhhbmRdfHxudWxsfSxzZXQ6ZnVuY3Rpb24odmFsKXt0aGlzW3Nob3J0aGFuZF09dmFsO3JldHVybiB2YWx9fSl9KX0se1wiLi9ub2RlXCI6MTJ9XSwxMjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7dmFyIE5vZGVQcm90b3R5cGU9bW9kdWxlLmV4cG9ydHM9e2dldCBmaXJzdENoaWxkKCl7dmFyIGNoaWxkcmVuPXRoaXMuY2hpbGRyZW47cmV0dXJuIGNoaWxkcmVuJiZjaGlsZHJlblswXXx8bnVsbH0sZ2V0IGxhc3RDaGlsZCgpe3ZhciBjaGlsZHJlbj10aGlzLmNoaWxkcmVuO3JldHVybiBjaGlsZHJlbiYmY2hpbGRyZW5bY2hpbGRyZW4ubGVuZ3RoLTFdfHxudWxsfSxnZXQgbm9kZVR5cGUoKXtyZXR1cm4gbm9kZVR5cGVzW3RoaXMudHlwZV18fG5vZGVUeXBlcy5lbGVtZW50fX07dmFyIGRvbUx2bDE9e3RhZ05hbWU6XCJuYW1lXCIsY2hpbGROb2RlczpcImNoaWxkcmVuXCIscGFyZW50Tm9kZTpcInBhcmVudFwiLHByZXZpb3VzU2libGluZzpcInByZXZcIixuZXh0U2libGluZzpcIm5leHRcIixub2RlVmFsdWU6XCJkYXRhXCJ9O3ZhciBub2RlVHlwZXM9e2VsZW1lbnQ6MSx0ZXh0OjMsY2RhdGE6NCxjb21tZW50Ojh9O09iamVjdC5rZXlzKGRvbUx2bDEpLmZvckVhY2goZnVuY3Rpb24oa2V5KXt2YXIgc2hvcnRoYW5kPWRvbUx2bDFba2V5XTtPYmplY3QuZGVmaW5lUHJvcGVydHkoTm9kZVByb3RvdHlwZSxrZXkse2dldDpmdW5jdGlvbigpe3JldHVybiB0aGlzW3Nob3J0aGFuZF18fG51bGx9LHNldDpmdW5jdGlvbih2YWwpe3RoaXNbc2hvcnRoYW5kXT12YWw7cmV0dXJuIHZhbH19KX0pfSx7fV0sMTM6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe3ZhciBEb21VdGlscz1tb2R1bGUuZXhwb3J0cztbcmVxdWlyZShcIi4vbGliL3N0cmluZ2lmeVwiKSxyZXF1aXJlKFwiLi9saWIvdHJhdmVyc2FsXCIpLHJlcXVpcmUoXCIuL2xpYi9tYW5pcHVsYXRpb25cIikscmVxdWlyZShcIi4vbGliL3F1ZXJ5aW5nXCIpLHJlcXVpcmUoXCIuL2xpYi9sZWdhY3lcIikscmVxdWlyZShcIi4vbGliL2hlbHBlcnNcIildLmZvckVhY2goZnVuY3Rpb24oZXh0KXtPYmplY3Qua2V5cyhleHQpLmZvckVhY2goZnVuY3Rpb24oa2V5KXtEb21VdGlsc1trZXldPWV4dFtrZXldLmJpbmQoRG9tVXRpbHMpfSl9KX0se1wiLi9saWIvaGVscGVyc1wiOjE0LFwiLi9saWIvbGVnYWN5XCI6MTUsXCIuL2xpYi9tYW5pcHVsYXRpb25cIjoxNixcIi4vbGliL3F1ZXJ5aW5nXCI6MTcsXCIuL2xpYi9zdHJpbmdpZnlcIjoxOCxcIi4vbGliL3RyYXZlcnNhbFwiOjE5fV0sMTQ6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe2V4cG9ydHMucmVtb3ZlU3Vic2V0cz1mdW5jdGlvbihub2Rlcyl7dmFyIGlkeD1ub2Rlcy5sZW5ndGgsbm9kZSxhbmNlc3RvcixyZXBsYWNlO3doaWxlKC0taWR4Pi0xKXtub2RlPWFuY2VzdG9yPW5vZGVzW2lkeF07bm9kZXNbaWR4XT1udWxsO3JlcGxhY2U9dHJ1ZTt3aGlsZShhbmNlc3Rvcil7aWYobm9kZXMuaW5kZXhPZihhbmNlc3Rvcik+LTEpe3JlcGxhY2U9ZmFsc2U7bm9kZXMuc3BsaWNlKGlkeCwxKTticmVha31hbmNlc3Rvcj1hbmNlc3Rvci5wYXJlbnR9aWYocmVwbGFjZSl7bm9kZXNbaWR4XT1ub2RlfX1yZXR1cm4gbm9kZXN9O3ZhciBQT1NJVElPTj17RElTQ09OTkVDVEVEOjEsUFJFQ0VESU5HOjIsRk9MTE9XSU5HOjQsQ09OVEFJTlM6OCxDT05UQUlORURfQlk6MTZ9O3ZhciBjb21wYXJlUG9zPWV4cG9ydHMuY29tcGFyZURvY3VtZW50UG9zaXRpb249ZnVuY3Rpb24obm9kZUEsbm9kZUIpe3ZhciBhUGFyZW50cz1bXTt2YXIgYlBhcmVudHM9W107dmFyIGN1cnJlbnQsc2hhcmVkUGFyZW50LHNpYmxpbmdzLGFTaWJsaW5nLGJTaWJsaW5nLGlkeDtpZihub2RlQT09PW5vZGVCKXtyZXR1cm4gMH1jdXJyZW50PW5vZGVBO3doaWxlKGN1cnJlbnQpe2FQYXJlbnRzLnVuc2hpZnQoY3VycmVudCk7Y3VycmVudD1jdXJyZW50LnBhcmVudH1jdXJyZW50PW5vZGVCO3doaWxlKGN1cnJlbnQpe2JQYXJlbnRzLnVuc2hpZnQoY3VycmVudCk7Y3VycmVudD1jdXJyZW50LnBhcmVudH1pZHg9MDt3aGlsZShhUGFyZW50c1tpZHhdPT09YlBhcmVudHNbaWR4XSl7aWR4Kyt9aWYoaWR4PT09MCl7cmV0dXJuIFBPU0lUSU9OLkRJU0NPTk5FQ1RFRH1zaGFyZWRQYXJlbnQ9YVBhcmVudHNbaWR4LTFdO3NpYmxpbmdzPXNoYXJlZFBhcmVudC5jaGlsZHJlbjthU2libGluZz1hUGFyZW50c1tpZHhdO2JTaWJsaW5nPWJQYXJlbnRzW2lkeF07aWYoc2libGluZ3MuaW5kZXhPZihhU2libGluZyk+c2libGluZ3MuaW5kZXhPZihiU2libGluZykpe2lmKHNoYXJlZFBhcmVudD09PW5vZGVCKXtyZXR1cm4gUE9TSVRJT04uRk9MTE9XSU5HfFBPU0lUSU9OLkNPTlRBSU5FRF9CWX1yZXR1cm4gUE9TSVRJT04uRk9MTE9XSU5HfWVsc2V7aWYoc2hhcmVkUGFyZW50PT09bm9kZUEpe3JldHVybiBQT1NJVElPTi5QUkVDRURJTkd8UE9TSVRJT04uQ09OVEFJTlN9cmV0dXJuIFBPU0lUSU9OLlBSRUNFRElOR319O2V4cG9ydHMudW5pcXVlU29ydD1mdW5jdGlvbihub2Rlcyl7dmFyIGlkeD1ub2Rlcy5sZW5ndGgsbm9kZSxwb3NpdGlvbjtub2Rlcz1ub2Rlcy5zbGljZSgpO3doaWxlKC0taWR4Pi0xKXtub2RlPW5vZGVzW2lkeF07cG9zaXRpb249bm9kZXMuaW5kZXhPZihub2RlKTtpZihwb3NpdGlvbj4tMSYmcG9zaXRpb248aWR4KXtub2Rlcy5zcGxpY2UoaWR4LDEpfX1ub2Rlcy5zb3J0KGZ1bmN0aW9uKGEsYil7dmFyIHJlbGF0aXZlPWNvbXBhcmVQb3MoYSxiKTtpZihyZWxhdGl2ZSZQT1NJVElPTi5QUkVDRURJTkcpe3JldHVybi0xfWVsc2UgaWYocmVsYXRpdmUmUE9TSVRJT04uRk9MTE9XSU5HKXtyZXR1cm4gMX1yZXR1cm4gMH0pO3JldHVybiBub2Rlc319LHt9XSwxNTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7dmFyIEVsZW1lbnRUeXBlPXJlcXVpcmUoXCJkb21lbGVtZW50dHlwZVwiKTt2YXIgaXNUYWc9ZXhwb3J0cy5pc1RhZz1FbGVtZW50VHlwZS5pc1RhZztleHBvcnRzLnRlc3RFbGVtZW50PWZ1bmN0aW9uKG9wdGlvbnMsZWxlbWVudCl7Zm9yKHZhciBrZXkgaW4gb3B0aW9ucyl7aWYoIW9wdGlvbnMuaGFzT3duUHJvcGVydHkoa2V5KSk7ZWxzZSBpZihrZXk9PT1cInRhZ19uYW1lXCIpe2lmKCFpc1RhZyhlbGVtZW50KXx8IW9wdGlvbnMudGFnX25hbWUoZWxlbWVudC5uYW1lKSl7cmV0dXJuIGZhbHNlfX1lbHNlIGlmKGtleT09PVwidGFnX3R5cGVcIil7aWYoIW9wdGlvbnMudGFnX3R5cGUoZWxlbWVudC50eXBlKSlyZXR1cm4gZmFsc2V9ZWxzZSBpZihrZXk9PT1cInRhZ19jb250YWluc1wiKXtpZihpc1RhZyhlbGVtZW50KXx8IW9wdGlvbnMudGFnX2NvbnRhaW5zKGVsZW1lbnQuZGF0YSkpe3JldHVybiBmYWxzZX19ZWxzZSBpZighZWxlbWVudC5hdHRyaWJzfHwhb3B0aW9uc1trZXldKGVsZW1lbnQuYXR0cmlic1trZXldKSl7cmV0dXJuIGZhbHNlfX1yZXR1cm4gdHJ1ZX07dmFyIENoZWNrcz17dGFnX25hbWU6ZnVuY3Rpb24obmFtZSl7aWYodHlwZW9mIG5hbWU9PT1cImZ1bmN0aW9uXCIpe3JldHVybiBmdW5jdGlvbihlbGVtKXtyZXR1cm4gaXNUYWcoZWxlbSkmJm5hbWUoZWxlbS5uYW1lKX19ZWxzZSBpZihuYW1lPT09XCIqXCIpe3JldHVybiBpc1RhZ31lbHNle3JldHVybiBmdW5jdGlvbihlbGVtKXtyZXR1cm4gaXNUYWcoZWxlbSkmJmVsZW0ubmFtZT09PW5hbWV9fX0sdGFnX3R5cGU6ZnVuY3Rpb24odHlwZSl7aWYodHlwZW9mIHR5cGU9PT1cImZ1bmN0aW9uXCIpe3JldHVybiBmdW5jdGlvbihlbGVtKXtyZXR1cm4gdHlwZShlbGVtLnR5cGUpfX1lbHNle3JldHVybiBmdW5jdGlvbihlbGVtKXtyZXR1cm4gZWxlbS50eXBlPT09dHlwZX19fSx0YWdfY29udGFpbnM6ZnVuY3Rpb24oZGF0YSl7aWYodHlwZW9mIGRhdGE9PT1cImZ1bmN0aW9uXCIpe3JldHVybiBmdW5jdGlvbihlbGVtKXtyZXR1cm4haXNUYWcoZWxlbSkmJmRhdGEoZWxlbS5kYXRhKX19ZWxzZXtyZXR1cm4gZnVuY3Rpb24oZWxlbSl7cmV0dXJuIWlzVGFnKGVsZW0pJiZlbGVtLmRhdGE9PT1kYXRhfX19fTtmdW5jdGlvbiBnZXRBdHRyaWJDaGVjayhhdHRyaWIsdmFsdWUpe2lmKHR5cGVvZiB2YWx1ZT09PVwiZnVuY3Rpb25cIil7cmV0dXJuIGZ1bmN0aW9uKGVsZW0pe3JldHVybiBlbGVtLmF0dHJpYnMmJnZhbHVlKGVsZW0uYXR0cmlic1thdHRyaWJdKX19ZWxzZXtyZXR1cm4gZnVuY3Rpb24oZWxlbSl7cmV0dXJuIGVsZW0uYXR0cmlicyYmZWxlbS5hdHRyaWJzW2F0dHJpYl09PT12YWx1ZX19fWZ1bmN0aW9uIGNvbWJpbmVGdW5jcyhhLGIpe3JldHVybiBmdW5jdGlvbihlbGVtKXtyZXR1cm4gYShlbGVtKXx8YihlbGVtKX19ZXhwb3J0cy5nZXRFbGVtZW50cz1mdW5jdGlvbihvcHRpb25zLGVsZW1lbnQscmVjdXJzZSxsaW1pdCl7dmFyIGZ1bmNzPU9iamVjdC5rZXlzKG9wdGlvbnMpLm1hcChmdW5jdGlvbihrZXkpe3ZhciB2YWx1ZT1vcHRpb25zW2tleV07cmV0dXJuIGtleSBpbiBDaGVja3M/Q2hlY2tzW2tleV0odmFsdWUpOmdldEF0dHJpYkNoZWNrKGtleSx2YWx1ZSl9KTtyZXR1cm4gZnVuY3MubGVuZ3RoPT09MD9bXTp0aGlzLmZpbHRlcihmdW5jcy5yZWR1Y2UoY29tYmluZUZ1bmNzKSxlbGVtZW50LHJlY3Vyc2UsbGltaXQpfTtleHBvcnRzLmdldEVsZW1lbnRCeUlkPWZ1bmN0aW9uKGlkLGVsZW1lbnQscmVjdXJzZSl7aWYoIUFycmF5LmlzQXJyYXkoZWxlbWVudCkpZWxlbWVudD1bZWxlbWVudF07cmV0dXJuIHRoaXMuZmluZE9uZShnZXRBdHRyaWJDaGVjayhcImlkXCIsaWQpLGVsZW1lbnQscmVjdXJzZSE9PWZhbHNlKX07ZXhwb3J0cy5nZXRFbGVtZW50c0J5VGFnTmFtZT1mdW5jdGlvbihuYW1lLGVsZW1lbnQscmVjdXJzZSxsaW1pdCl7cmV0dXJuIHRoaXMuZmlsdGVyKENoZWNrcy50YWdfbmFtZShuYW1lKSxlbGVtZW50LHJlY3Vyc2UsbGltaXQpfTtleHBvcnRzLmdldEVsZW1lbnRzQnlUYWdUeXBlPWZ1bmN0aW9uKHR5cGUsZWxlbWVudCxyZWN1cnNlLGxpbWl0KXtyZXR1cm4gdGhpcy5maWx0ZXIoQ2hlY2tzLnRhZ190eXBlKHR5cGUpLGVsZW1lbnQscmVjdXJzZSxsaW1pdCl9fSx7ZG9tZWxlbWVudHR5cGU6OX1dLDE2OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtleHBvcnRzLnJlbW92ZUVsZW1lbnQ9ZnVuY3Rpb24oZWxlbSl7aWYoZWxlbS5wcmV2KWVsZW0ucHJldi5uZXh0PWVsZW0ubmV4dDtpZihlbGVtLm5leHQpZWxlbS5uZXh0LnByZXY9ZWxlbS5wcmV2O2lmKGVsZW0ucGFyZW50KXt2YXIgY2hpbGRzPWVsZW0ucGFyZW50LmNoaWxkcmVuO2NoaWxkcy5zcGxpY2UoY2hpbGRzLmxhc3RJbmRleE9mKGVsZW0pLDEpfX07ZXhwb3J0cy5yZXBsYWNlRWxlbWVudD1mdW5jdGlvbihlbGVtLHJlcGxhY2VtZW50KXt2YXIgcHJldj1yZXBsYWNlbWVudC5wcmV2PWVsZW0ucHJldjtpZihwcmV2KXtwcmV2Lm5leHQ9cmVwbGFjZW1lbnR9dmFyIG5leHQ9cmVwbGFjZW1lbnQubmV4dD1lbGVtLm5leHQ7aWYobmV4dCl7bmV4dC5wcmV2PXJlcGxhY2VtZW50fXZhciBwYXJlbnQ9cmVwbGFjZW1lbnQucGFyZW50PWVsZW0ucGFyZW50O2lmKHBhcmVudCl7dmFyIGNoaWxkcz1wYXJlbnQuY2hpbGRyZW47Y2hpbGRzW2NoaWxkcy5sYXN0SW5kZXhPZihlbGVtKV09cmVwbGFjZW1lbnR9fTtleHBvcnRzLmFwcGVuZENoaWxkPWZ1bmN0aW9uKGVsZW0sY2hpbGQpe2NoaWxkLnBhcmVudD1lbGVtO2lmKGVsZW0uY2hpbGRyZW4ucHVzaChjaGlsZCkhPT0xKXt2YXIgc2libGluZz1lbGVtLmNoaWxkcmVuW2VsZW0uY2hpbGRyZW4ubGVuZ3RoLTJdO3NpYmxpbmcubmV4dD1jaGlsZDtjaGlsZC5wcmV2PXNpYmxpbmc7Y2hpbGQubmV4dD1udWxsfX07ZXhwb3J0cy5hcHBlbmQ9ZnVuY3Rpb24oZWxlbSxuZXh0KXt2YXIgcGFyZW50PWVsZW0ucGFyZW50LGN1cnJOZXh0PWVsZW0ubmV4dDtuZXh0Lm5leHQ9Y3Vyck5leHQ7bmV4dC5wcmV2PWVsZW07ZWxlbS5uZXh0PW5leHQ7bmV4dC5wYXJlbnQ9cGFyZW50O2lmKGN1cnJOZXh0KXtjdXJyTmV4dC5wcmV2PW5leHQ7aWYocGFyZW50KXt2YXIgY2hpbGRzPXBhcmVudC5jaGlsZHJlbjtjaGlsZHMuc3BsaWNlKGNoaWxkcy5sYXN0SW5kZXhPZihjdXJyTmV4dCksMCxuZXh0KX19ZWxzZSBpZihwYXJlbnQpe3BhcmVudC5jaGlsZHJlbi5wdXNoKG5leHQpfX07ZXhwb3J0cy5wcmVwZW5kPWZ1bmN0aW9uKGVsZW0scHJldil7dmFyIHBhcmVudD1lbGVtLnBhcmVudDtpZihwYXJlbnQpe3ZhciBjaGlsZHM9cGFyZW50LmNoaWxkcmVuO2NoaWxkcy5zcGxpY2UoY2hpbGRzLmxhc3RJbmRleE9mKGVsZW0pLDAscHJldil9aWYoZWxlbS5wcmV2KXtlbGVtLnByZXYubmV4dD1wcmV2fXByZXYucGFyZW50PXBhcmVudDtwcmV2LnByZXY9ZWxlbS5wcmV2O3ByZXYubmV4dD1lbGVtO2VsZW0ucHJldj1wcmV2fX0se31dLDE3OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgaXNUYWc9cmVxdWlyZShcImRvbWVsZW1lbnR0eXBlXCIpLmlzVGFnO21vZHVsZS5leHBvcnRzPXtmaWx0ZXI6ZmlsdGVyLGZpbmQ6ZmluZCxmaW5kT25lQ2hpbGQ6ZmluZE9uZUNoaWxkLGZpbmRPbmU6ZmluZE9uZSxleGlzdHNPbmU6ZXhpc3RzT25lLGZpbmRBbGw6ZmluZEFsbH07ZnVuY3Rpb24gZmlsdGVyKHRlc3QsZWxlbWVudCxyZWN1cnNlLGxpbWl0KXtpZighQXJyYXkuaXNBcnJheShlbGVtZW50KSllbGVtZW50PVtlbGVtZW50XTtpZih0eXBlb2YgbGltaXQhPT1cIm51bWJlclwifHwhaXNGaW5pdGUobGltaXQpKXtsaW1pdD1JbmZpbml0eX1yZXR1cm4gZmluZCh0ZXN0LGVsZW1lbnQscmVjdXJzZSE9PWZhbHNlLGxpbWl0KX1mdW5jdGlvbiBmaW5kKHRlc3QsZWxlbXMscmVjdXJzZSxsaW1pdCl7dmFyIHJlc3VsdD1bXSxjaGlsZHM7Zm9yKHZhciBpPTAsaj1lbGVtcy5sZW5ndGg7aTxqO2krKyl7aWYodGVzdChlbGVtc1tpXSkpe3Jlc3VsdC5wdXNoKGVsZW1zW2ldKTtpZigtLWxpbWl0PD0wKWJyZWFrfWNoaWxkcz1lbGVtc1tpXS5jaGlsZHJlbjtpZihyZWN1cnNlJiZjaGlsZHMmJmNoaWxkcy5sZW5ndGg+MCl7Y2hpbGRzPWZpbmQodGVzdCxjaGlsZHMscmVjdXJzZSxsaW1pdCk7cmVzdWx0PXJlc3VsdC5jb25jYXQoY2hpbGRzKTtsaW1pdC09Y2hpbGRzLmxlbmd0aDtpZihsaW1pdDw9MClicmVha319cmV0dXJuIHJlc3VsdH1mdW5jdGlvbiBmaW5kT25lQ2hpbGQodGVzdCxlbGVtcyl7Zm9yKHZhciBpPTAsbD1lbGVtcy5sZW5ndGg7aTxsO2krKyl7aWYodGVzdChlbGVtc1tpXSkpcmV0dXJuIGVsZW1zW2ldfXJldHVybiBudWxsfWZ1bmN0aW9uIGZpbmRPbmUodGVzdCxlbGVtcyl7dmFyIGVsZW09bnVsbDtmb3IodmFyIGk9MCxsPWVsZW1zLmxlbmd0aDtpPGwmJiFlbGVtO2krKyl7aWYoIWlzVGFnKGVsZW1zW2ldKSl7Y29udGludWV9ZWxzZSBpZih0ZXN0KGVsZW1zW2ldKSl7ZWxlbT1lbGVtc1tpXX1lbHNlIGlmKGVsZW1zW2ldLmNoaWxkcmVuLmxlbmd0aD4wKXtlbGVtPWZpbmRPbmUodGVzdCxlbGVtc1tpXS5jaGlsZHJlbil9fXJldHVybiBlbGVtfWZ1bmN0aW9uIGV4aXN0c09uZSh0ZXN0LGVsZW1zKXtmb3IodmFyIGk9MCxsPWVsZW1zLmxlbmd0aDtpPGw7aSsrKXtpZihpc1RhZyhlbGVtc1tpXSkmJih0ZXN0KGVsZW1zW2ldKXx8ZWxlbXNbaV0uY2hpbGRyZW4ubGVuZ3RoPjAmJmV4aXN0c09uZSh0ZXN0LGVsZW1zW2ldLmNoaWxkcmVuKSkpe3JldHVybiB0cnVlfX1yZXR1cm4gZmFsc2V9ZnVuY3Rpb24gZmluZEFsbCh0ZXN0LGVsZW1zKXt2YXIgcmVzdWx0PVtdO2Zvcih2YXIgaT0wLGo9ZWxlbXMubGVuZ3RoO2k8ajtpKyspe2lmKCFpc1RhZyhlbGVtc1tpXSkpY29udGludWU7aWYodGVzdChlbGVtc1tpXSkpcmVzdWx0LnB1c2goZWxlbXNbaV0pO2lmKGVsZW1zW2ldLmNoaWxkcmVuLmxlbmd0aD4wKXtyZXN1bHQ9cmVzdWx0LmNvbmNhdChmaW5kQWxsKHRlc3QsZWxlbXNbaV0uY2hpbGRyZW4pKX19cmV0dXJuIHJlc3VsdH19LHtkb21lbGVtZW50dHlwZTo5fV0sMTg6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe3ZhciBFbGVtZW50VHlwZT1yZXF1aXJlKFwiZG9tZWxlbWVudHR5cGVcIiksZ2V0T3V0ZXJIVE1MPXJlcXVpcmUoXCJkb20tc2VyaWFsaXplclwiKSxpc1RhZz1FbGVtZW50VHlwZS5pc1RhZzttb2R1bGUuZXhwb3J0cz17Z2V0SW5uZXJIVE1MOmdldElubmVySFRNTCxnZXRPdXRlckhUTUw6Z2V0T3V0ZXJIVE1MLGdldFRleHQ6Z2V0VGV4dH07ZnVuY3Rpb24gZ2V0SW5uZXJIVE1MKGVsZW0sb3B0cyl7cmV0dXJuIGVsZW0uY2hpbGRyZW4/ZWxlbS5jaGlsZHJlbi5tYXAoZnVuY3Rpb24oZWxlbSl7cmV0dXJuIGdldE91dGVySFRNTChlbGVtLG9wdHMpfSkuam9pbihcIlwiKTpcIlwifWZ1bmN0aW9uIGdldFRleHQoZWxlbSl7aWYoQXJyYXkuaXNBcnJheShlbGVtKSlyZXR1cm4gZWxlbS5tYXAoZ2V0VGV4dCkuam9pbihcIlwiKTtpZihpc1RhZyhlbGVtKXx8ZWxlbS50eXBlPT09RWxlbWVudFR5cGUuQ0RBVEEpcmV0dXJuIGdldFRleHQoZWxlbS5jaGlsZHJlbik7aWYoZWxlbS50eXBlPT09RWxlbWVudFR5cGUuVGV4dClyZXR1cm4gZWxlbS5kYXRhO3JldHVyblwiXCJ9fSx7XCJkb20tc2VyaWFsaXplclwiOjcsZG9tZWxlbWVudHR5cGU6OX1dLDE5OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgZ2V0Q2hpbGRyZW49ZXhwb3J0cy5nZXRDaGlsZHJlbj1mdW5jdGlvbihlbGVtKXtyZXR1cm4gZWxlbS5jaGlsZHJlbn07dmFyIGdldFBhcmVudD1leHBvcnRzLmdldFBhcmVudD1mdW5jdGlvbihlbGVtKXtyZXR1cm4gZWxlbS5wYXJlbnR9O2V4cG9ydHMuZ2V0U2libGluZ3M9ZnVuY3Rpb24oZWxlbSl7dmFyIHBhcmVudD1nZXRQYXJlbnQoZWxlbSk7cmV0dXJuIHBhcmVudD9nZXRDaGlsZHJlbihwYXJlbnQpOltlbGVtXX07ZXhwb3J0cy5nZXRBdHRyaWJ1dGVWYWx1ZT1mdW5jdGlvbihlbGVtLG5hbWUpe3JldHVybiBlbGVtLmF0dHJpYnMmJmVsZW0uYXR0cmlic1tuYW1lXX07ZXhwb3J0cy5oYXNBdHRyaWI9ZnVuY3Rpb24oZWxlbSxuYW1lKXtyZXR1cm4hIWVsZW0uYXR0cmlicyYmaGFzT3duUHJvcGVydHkuY2FsbChlbGVtLmF0dHJpYnMsbmFtZSl9O2V4cG9ydHMuZ2V0TmFtZT1mdW5jdGlvbihlbGVtKXtyZXR1cm4gZWxlbS5uYW1lfX0se31dLDIwOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgZW5jb2RlPXJlcXVpcmUoXCIuL2xpYi9lbmNvZGUuanNcIiksZGVjb2RlPXJlcXVpcmUoXCIuL2xpYi9kZWNvZGUuanNcIik7ZXhwb3J0cy5kZWNvZGU9ZnVuY3Rpb24oZGF0YSxsZXZlbCl7cmV0dXJuKCFsZXZlbHx8bGV2ZWw8PTA/ZGVjb2RlLlhNTDpkZWNvZGUuSFRNTCkoZGF0YSl9O2V4cG9ydHMuZGVjb2RlU3RyaWN0PWZ1bmN0aW9uKGRhdGEsbGV2ZWwpe3JldHVybighbGV2ZWx8fGxldmVsPD0wP2RlY29kZS5YTUw6ZGVjb2RlLkhUTUxTdHJpY3QpKGRhdGEpfTtleHBvcnRzLmVuY29kZT1mdW5jdGlvbihkYXRhLGxldmVsKXtyZXR1cm4oIWxldmVsfHxsZXZlbDw9MD9lbmNvZGUuWE1MOmVuY29kZS5IVE1MKShkYXRhKX07ZXhwb3J0cy5lbmNvZGVYTUw9ZW5jb2RlLlhNTDtleHBvcnRzLmVuY29kZUhUTUw0PWV4cG9ydHMuZW5jb2RlSFRNTDU9ZXhwb3J0cy5lbmNvZGVIVE1MPWVuY29kZS5IVE1MO2V4cG9ydHMuZGVjb2RlWE1MPWV4cG9ydHMuZGVjb2RlWE1MU3RyaWN0PWRlY29kZS5YTUw7ZXhwb3J0cy5kZWNvZGVIVE1MND1leHBvcnRzLmRlY29kZUhUTUw1PWV4cG9ydHMuZGVjb2RlSFRNTD1kZWNvZGUuSFRNTDtleHBvcnRzLmRlY29kZUhUTUw0U3RyaWN0PWV4cG9ydHMuZGVjb2RlSFRNTDVTdHJpY3Q9ZXhwb3J0cy5kZWNvZGVIVE1MU3RyaWN0PWRlY29kZS5IVE1MU3RyaWN0O2V4cG9ydHMuZXNjYXBlPWVuY29kZS5lc2NhcGV9LHtcIi4vbGliL2RlY29kZS5qc1wiOjIxLFwiLi9saWIvZW5jb2RlLmpzXCI6MjN9XSwyMTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7dmFyIGVudGl0eU1hcD1yZXF1aXJlKFwiLi4vbWFwcy9lbnRpdGllcy5qc29uXCIpLGxlZ2FjeU1hcD1yZXF1aXJlKFwiLi4vbWFwcy9sZWdhY3kuanNvblwiKSx4bWxNYXA9cmVxdWlyZShcIi4uL21hcHMveG1sLmpzb25cIiksZGVjb2RlQ29kZVBvaW50PXJlcXVpcmUoXCIuL2RlY29kZV9jb2RlcG9pbnQuanNcIik7dmFyIGRlY29kZVhNTFN0cmljdD1nZXRTdHJpY3REZWNvZGVyKHhtbE1hcCksZGVjb2RlSFRNTFN0cmljdD1nZXRTdHJpY3REZWNvZGVyKGVudGl0eU1hcCk7ZnVuY3Rpb24gZ2V0U3RyaWN0RGVjb2RlcihtYXApe3ZhciBrZXlzPU9iamVjdC5rZXlzKG1hcCkuam9pbihcInxcIikscmVwbGFjZT1nZXRSZXBsYWNlcihtYXApO2tleXMrPVwifCNbeFhdW1xcXFxkYS1mQS1GXSt8I1xcXFxkK1wiO3ZhciByZT1uZXcgUmVnRXhwKFwiJig/OlwiK2tleXMrXCIpO1wiLFwiZ1wiKTtyZXR1cm4gZnVuY3Rpb24oc3RyKXtyZXR1cm4gU3RyaW5nKHN0cikucmVwbGFjZShyZSxyZXBsYWNlKX19dmFyIGRlY29kZUhUTUw9ZnVuY3Rpb24oKXt2YXIgbGVnYWN5PU9iamVjdC5rZXlzKGxlZ2FjeU1hcCkuc29ydChzb3J0ZXIpO3ZhciBrZXlzPU9iamVjdC5rZXlzKGVudGl0eU1hcCkuc29ydChzb3J0ZXIpO2Zvcih2YXIgaT0wLGo9MDtpPGtleXMubGVuZ3RoO2krKyl7aWYobGVnYWN5W2pdPT09a2V5c1tpXSl7a2V5c1tpXSs9XCI7P1wiO2orK31lbHNle2tleXNbaV0rPVwiO1wifX12YXIgcmU9bmV3IFJlZ0V4cChcIiYoPzpcIitrZXlzLmpvaW4oXCJ8XCIpK1wifCNbeFhdW1xcXFxkYS1mQS1GXSs7P3wjXFxcXGQrOz8pXCIsXCJnXCIpLHJlcGxhY2U9Z2V0UmVwbGFjZXIoZW50aXR5TWFwKTtmdW5jdGlvbiByZXBsYWNlcihzdHIpe2lmKHN0ci5zdWJzdHIoLTEpIT09XCI7XCIpc3RyKz1cIjtcIjtyZXR1cm4gcmVwbGFjZShzdHIpfXJldHVybiBmdW5jdGlvbihzdHIpe3JldHVybiBTdHJpbmcoc3RyKS5yZXBsYWNlKHJlLHJlcGxhY2VyKX19KCk7ZnVuY3Rpb24gc29ydGVyKGEsYil7cmV0dXJuIGE8Yj8xOi0xfWZ1bmN0aW9uIGdldFJlcGxhY2VyKG1hcCl7cmV0dXJuIGZ1bmN0aW9uIHJlcGxhY2Uoc3RyKXtpZihzdHIuY2hhckF0KDEpPT09XCIjXCIpe2lmKHN0ci5jaGFyQXQoMik9PT1cIlhcInx8c3RyLmNoYXJBdCgyKT09PVwieFwiKXtyZXR1cm4gZGVjb2RlQ29kZVBvaW50KHBhcnNlSW50KHN0ci5zdWJzdHIoMyksMTYpKX1yZXR1cm4gZGVjb2RlQ29kZVBvaW50KHBhcnNlSW50KHN0ci5zdWJzdHIoMiksMTApKX1yZXR1cm4gbWFwW3N0ci5zbGljZSgxLC0xKV07XG59fW1vZHVsZS5leHBvcnRzPXtYTUw6ZGVjb2RlWE1MU3RyaWN0LEhUTUw6ZGVjb2RlSFRNTCxIVE1MU3RyaWN0OmRlY29kZUhUTUxTdHJpY3R9fSx7XCIuLi9tYXBzL2VudGl0aWVzLmpzb25cIjoyNSxcIi4uL21hcHMvbGVnYWN5Lmpzb25cIjoyNixcIi4uL21hcHMveG1sLmpzb25cIjoyNyxcIi4vZGVjb2RlX2NvZGVwb2ludC5qc1wiOjIyfV0sMjI6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe3ZhciBkZWNvZGVNYXA9cmVxdWlyZShcIi4uL21hcHMvZGVjb2RlLmpzb25cIik7bW9kdWxlLmV4cG9ydHM9ZGVjb2RlQ29kZVBvaW50O2Z1bmN0aW9uIGRlY29kZUNvZGVQb2ludChjb2RlUG9pbnQpe2lmKGNvZGVQb2ludD49NTUyOTYmJmNvZGVQb2ludDw9NTczNDN8fGNvZGVQb2ludD4xMTE0MTExKXtyZXR1cm5cIu+/vVwifWlmKGNvZGVQb2ludCBpbiBkZWNvZGVNYXApe2NvZGVQb2ludD1kZWNvZGVNYXBbY29kZVBvaW50XX12YXIgb3V0cHV0PVwiXCI7aWYoY29kZVBvaW50PjY1NTM1KXtjb2RlUG9pbnQtPTY1NTM2O291dHB1dCs9U3RyaW5nLmZyb21DaGFyQ29kZShjb2RlUG9pbnQ+Pj4xMCYxMDIzfDU1Mjk2KTtjb2RlUG9pbnQ9NTYzMjB8Y29kZVBvaW50JjEwMjN9b3V0cHV0Kz1TdHJpbmcuZnJvbUNoYXJDb2RlKGNvZGVQb2ludCk7cmV0dXJuIG91dHB1dH19LHtcIi4uL21hcHMvZGVjb2RlLmpzb25cIjoyNH1dLDIzOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgaW52ZXJzZVhNTD1nZXRJbnZlcnNlT2JqKHJlcXVpcmUoXCIuLi9tYXBzL3htbC5qc29uXCIpKSx4bWxSZXBsYWNlcj1nZXRJbnZlcnNlUmVwbGFjZXIoaW52ZXJzZVhNTCk7ZXhwb3J0cy5YTUw9Z2V0SW52ZXJzZShpbnZlcnNlWE1MLHhtbFJlcGxhY2VyKTt2YXIgaW52ZXJzZUhUTUw9Z2V0SW52ZXJzZU9iaihyZXF1aXJlKFwiLi4vbWFwcy9lbnRpdGllcy5qc29uXCIpKSxodG1sUmVwbGFjZXI9Z2V0SW52ZXJzZVJlcGxhY2VyKGludmVyc2VIVE1MKTtleHBvcnRzLkhUTUw9Z2V0SW52ZXJzZShpbnZlcnNlSFRNTCxodG1sUmVwbGFjZXIpO2Z1bmN0aW9uIGdldEludmVyc2VPYmoob2JqKXtyZXR1cm4gT2JqZWN0LmtleXMob2JqKS5zb3J0KCkucmVkdWNlKGZ1bmN0aW9uKGludmVyc2UsbmFtZSl7aW52ZXJzZVtvYmpbbmFtZV1dPVwiJlwiK25hbWUrXCI7XCI7cmV0dXJuIGludmVyc2V9LHt9KX1mdW5jdGlvbiBnZXRJbnZlcnNlUmVwbGFjZXIoaW52ZXJzZSl7dmFyIHNpbmdsZT1bXSxtdWx0aXBsZT1bXTtPYmplY3Qua2V5cyhpbnZlcnNlKS5mb3JFYWNoKGZ1bmN0aW9uKGspe2lmKGsubGVuZ3RoPT09MSl7c2luZ2xlLnB1c2goXCJcXFxcXCIrayl9ZWxzZXttdWx0aXBsZS5wdXNoKGspfX0pO211bHRpcGxlLnVuc2hpZnQoXCJbXCIrc2luZ2xlLmpvaW4oXCJcIikrXCJdXCIpO3JldHVybiBuZXcgUmVnRXhwKG11bHRpcGxlLmpvaW4oXCJ8XCIpLFwiZ1wiKX12YXIgcmVfbm9uQVNDSUk9L1teXFwwLVxceDdGXS9nLHJlX2FzdHJhbFN5bWJvbHM9L1tcXHVEODAwLVxcdURCRkZdW1xcdURDMDAtXFx1REZGRl0vZztmdW5jdGlvbiBzaW5nbGVDaGFyUmVwbGFjZXIoYyl7cmV0dXJuXCImI3hcIitjLmNoYXJDb2RlQXQoMCkudG9TdHJpbmcoMTYpLnRvVXBwZXJDYXNlKCkrXCI7XCJ9ZnVuY3Rpb24gYXN0cmFsUmVwbGFjZXIoYyl7dmFyIGhpZ2g9Yy5jaGFyQ29kZUF0KDApO3ZhciBsb3c9Yy5jaGFyQ29kZUF0KDEpO3ZhciBjb2RlUG9pbnQ9KGhpZ2gtNTUyOTYpKjEwMjQrbG93LTU2MzIwKzY1NTM2O3JldHVyblwiJiN4XCIrY29kZVBvaW50LnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpK1wiO1wifWZ1bmN0aW9uIGdldEludmVyc2UoaW52ZXJzZSxyZSl7ZnVuY3Rpb24gZnVuYyhuYW1lKXtyZXR1cm4gaW52ZXJzZVtuYW1lXX1yZXR1cm4gZnVuY3Rpb24oZGF0YSl7cmV0dXJuIGRhdGEucmVwbGFjZShyZSxmdW5jKS5yZXBsYWNlKHJlX2FzdHJhbFN5bWJvbHMsYXN0cmFsUmVwbGFjZXIpLnJlcGxhY2UocmVfbm9uQVNDSUksc2luZ2xlQ2hhclJlcGxhY2VyKX19dmFyIHJlX3htbENoYXJzPWdldEludmVyc2VSZXBsYWNlcihpbnZlcnNlWE1MKTtmdW5jdGlvbiBlc2NhcGVYTUwoZGF0YSl7cmV0dXJuIGRhdGEucmVwbGFjZShyZV94bWxDaGFycyxzaW5nbGVDaGFyUmVwbGFjZXIpLnJlcGxhY2UocmVfYXN0cmFsU3ltYm9scyxhc3RyYWxSZXBsYWNlcikucmVwbGFjZShyZV9ub25BU0NJSSxzaW5nbGVDaGFyUmVwbGFjZXIpfWV4cG9ydHMuZXNjYXBlPWVzY2FwZVhNTH0se1wiLi4vbWFwcy9lbnRpdGllcy5qc29uXCI6MjUsXCIuLi9tYXBzL3htbC5qc29uXCI6Mjd9XSwyNDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9ezA6NjU1MzMsMTI4OjgzNjQsMTMwOjgyMTgsMTMxOjQwMiwxMzI6ODIyMiwxMzM6ODIzMCwxMzQ6ODIyNCwxMzU6ODIyNSwxMzY6NzEwLDEzNzo4MjQwLDEzODozNTIsMTM5OjgyNDksMTQwOjMzOCwxNDI6MzgxLDE0NTo4MjE2LDE0Njo4MjE3LDE0Nzo4MjIwLDE0ODo4MjIxLDE0OTo4MjI2LDE1MDo4MjExLDE1MTo4MjEyLDE1Mjo3MzIsMTUzOjg0ODIsMTU0OjM1MywxNTU6ODI1MCwxNTY6MzM5LDE1ODozODIsMTU5OjM3Nn19LHt9XSwyNTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9e0FhY3V0ZTpcIsOBXCIsYWFjdXRlOlwiw6FcIixBYnJldmU6XCLEglwiLGFicmV2ZTpcIsSDXCIsYWM6XCLiiL5cIixhY2Q6XCLiiL9cIixhY0U6XCLiiL7Ms1wiLEFjaXJjOlwiw4JcIixhY2lyYzpcIsOiXCIsYWN1dGU6XCLCtFwiLEFjeTpcItCQXCIsYWN5Olwi0LBcIixBRWxpZzpcIsOGXCIsYWVsaWc6XCLDplwiLGFmOlwi4oGhXCIsQWZyOlwi8J2UhFwiLGFmcjpcIvCdlJ5cIixBZ3JhdmU6XCLDgFwiLGFncmF2ZTpcIsOgXCIsYWxlZnN5bTpcIuKEtVwiLGFsZXBoOlwi4oS1XCIsQWxwaGE6XCLOkVwiLGFscGhhOlwizrFcIixBbWFjcjpcIsSAXCIsYW1hY3I6XCLEgVwiLGFtYWxnOlwi4qi/XCIsYW1wOlwiJlwiLEFNUDpcIiZcIixhbmRhbmQ6XCLiqZVcIixBbmQ6XCLiqZNcIixhbmQ6XCLiiKdcIixhbmRkOlwi4qmcXCIsYW5kc2xvcGU6XCLiqZhcIixhbmR2Olwi4qmaXCIsYW5nOlwi4oigXCIsYW5nZTpcIuKmpFwiLGFuZ2xlOlwi4oigXCIsYW5nbXNkYWE6XCLipqhcIixhbmdtc2RhYjpcIuKmqVwiLGFuZ21zZGFjOlwi4qaqXCIsYW5nbXNkYWQ6XCLipqtcIixhbmdtc2RhZTpcIuKmrFwiLGFuZ21zZGFmOlwi4qatXCIsYW5nbXNkYWc6XCLipq5cIixhbmdtc2RhaDpcIuKmr1wiLGFuZ21zZDpcIuKIoVwiLGFuZ3J0Olwi4oifXCIsYW5ncnR2YjpcIuKKvlwiLGFuZ3J0dmJkOlwi4qadXCIsYW5nc3BoOlwi4oiiXCIsYW5nc3Q6XCLDhVwiLGFuZ3phcnI6XCLijbxcIixBb2dvbjpcIsSEXCIsYW9nb246XCLEhVwiLEFvcGY6XCLwnZS4XCIsYW9wZjpcIvCdlZJcIixhcGFjaXI6XCLiqa9cIixhcDpcIuKJiFwiLGFwRTpcIuKpsFwiLGFwZTpcIuKJilwiLGFwaWQ6XCLiiYtcIixhcG9zOlwiJ1wiLEFwcGx5RnVuY3Rpb246XCLigaFcIixhcHByb3g6XCLiiYhcIixhcHByb3hlcTpcIuKJilwiLEFyaW5nOlwiw4VcIixhcmluZzpcIsOlXCIsQXNjcjpcIvCdkpxcIixhc2NyOlwi8J2StlwiLEFzc2lnbjpcIuKJlFwiLGFzdDpcIipcIixhc3ltcDpcIuKJiFwiLGFzeW1wZXE6XCLiiY1cIixBdGlsZGU6XCLDg1wiLGF0aWxkZTpcIsOjXCIsQXVtbDpcIsOEXCIsYXVtbDpcIsOkXCIsYXdjb25pbnQ6XCLiiLNcIixhd2ludDpcIuKokVwiLGJhY2tjb25nOlwi4omMXCIsYmFja2Vwc2lsb246XCLPtlwiLGJhY2twcmltZTpcIuKAtVwiLGJhY2tzaW06XCLiiL1cIixiYWNrc2ltZXE6XCLii41cIixCYWNrc2xhc2g6XCLiiJZcIixCYXJ2Olwi4qunXCIsYmFydmVlOlwi4oq9XCIsYmFyd2VkOlwi4oyFXCIsQmFyd2VkOlwi4oyGXCIsYmFyd2VkZ2U6XCLijIVcIixiYnJrOlwi4o61XCIsYmJya3Ricms6XCLijrZcIixiY29uZzpcIuKJjFwiLEJjeTpcItCRXCIsYmN5Olwi0LFcIixiZHF1bzpcIuKAnlwiLGJlY2F1czpcIuKItVwiLGJlY2F1c2U6XCLiiLVcIixCZWNhdXNlOlwi4oi1XCIsYmVtcHR5djpcIuKmsFwiLGJlcHNpOlwiz7ZcIixiZXJub3U6XCLihKxcIixCZXJub3VsbGlzOlwi4oSsXCIsQmV0YTpcIs6SXCIsYmV0YTpcIs6yXCIsYmV0aDpcIuKEtlwiLGJldHdlZW46XCLiiaxcIixCZnI6XCLwnZSFXCIsYmZyOlwi8J2Un1wiLGJpZ2NhcDpcIuKLglwiLGJpZ2NpcmM6XCLil69cIixiaWdjdXA6XCLii4NcIixiaWdvZG90Olwi4qiAXCIsYmlnb3BsdXM6XCLiqIFcIixiaWdvdGltZXM6XCLiqIJcIixiaWdzcWN1cDpcIuKohlwiLGJpZ3N0YXI6XCLimIVcIixiaWd0cmlhbmdsZWRvd246XCLilr1cIixiaWd0cmlhbmdsZXVwOlwi4pazXCIsYmlndXBsdXM6XCLiqIRcIixiaWd2ZWU6XCLii4FcIixiaWd3ZWRnZTpcIuKLgFwiLGJrYXJvdzpcIuKkjVwiLGJsYWNrbG96ZW5nZTpcIuKnq1wiLGJsYWNrc3F1YXJlOlwi4paqXCIsYmxhY2t0cmlhbmdsZTpcIuKWtFwiLGJsYWNrdHJpYW5nbGVkb3duOlwi4pa+XCIsYmxhY2t0cmlhbmdsZWxlZnQ6XCLil4JcIixibGFja3RyaWFuZ2xlcmlnaHQ6XCLilrhcIixibGFuazpcIuKQo1wiLGJsazEyOlwi4paSXCIsYmxrMTQ6XCLilpFcIixibGszNDpcIuKWk1wiLGJsb2NrOlwi4paIXCIsYm5lOlwiPeKDpVwiLGJuZXF1aXY6XCLiiaHig6VcIixiTm90Olwi4qutXCIsYm5vdDpcIuKMkFwiLEJvcGY6XCLwnZS5XCIsYm9wZjpcIvCdlZNcIixib3Q6XCLiiqVcIixib3R0b206XCLiiqVcIixib3d0aWU6XCLii4hcIixib3hib3g6XCLip4lcIixib3hkbDpcIuKUkFwiLGJveGRMOlwi4pWVXCIsYm94RGw6XCLilZZcIixib3hETDpcIuKVl1wiLGJveGRyOlwi4pSMXCIsYm94ZFI6XCLilZJcIixib3hEcjpcIuKVk1wiLGJveERSOlwi4pWUXCIsYm94aDpcIuKUgFwiLGJveEg6XCLilZBcIixib3hoZDpcIuKUrFwiLGJveEhkOlwi4pWkXCIsYm94aEQ6XCLilaVcIixib3hIRDpcIuKVplwiLGJveGh1Olwi4pS0XCIsYm94SHU6XCLiladcIixib3hoVTpcIuKVqFwiLGJveEhVOlwi4pWpXCIsYm94bWludXM6XCLiip9cIixib3hwbHVzOlwi4oqeXCIsYm94dGltZXM6XCLiiqBcIixib3h1bDpcIuKUmFwiLGJveHVMOlwi4pWbXCIsYm94VWw6XCLilZxcIixib3hVTDpcIuKVnVwiLGJveHVyOlwi4pSUXCIsYm94dVI6XCLilZhcIixib3hVcjpcIuKVmVwiLGJveFVSOlwi4pWaXCIsYm94djpcIuKUglwiLGJveFY6XCLilZFcIixib3h2aDpcIuKUvFwiLGJveHZIOlwi4pWqXCIsYm94Vmg6XCLilatcIixib3hWSDpcIuKVrFwiLGJveHZsOlwi4pSkXCIsYm94dkw6XCLilaFcIixib3hWbDpcIuKVolwiLGJveFZMOlwi4pWjXCIsYm94dnI6XCLilJxcIixib3h2UjpcIuKVnlwiLGJveFZyOlwi4pWfXCIsYm94VlI6XCLilaBcIixicHJpbWU6XCLigLVcIixicmV2ZTpcIsuYXCIsQnJldmU6XCLLmFwiLGJydmJhcjpcIsKmXCIsYnNjcjpcIvCdkrdcIixCc2NyOlwi4oSsXCIsYnNlbWk6XCLigY9cIixic2ltOlwi4oi9XCIsYnNpbWU6XCLii41cIixic29sYjpcIuKnhVwiLGJzb2w6XCJcXFxcXCIsYnNvbGhzdWI6XCLin4hcIixidWxsOlwi4oCiXCIsYnVsbGV0Olwi4oCiXCIsYnVtcDpcIuKJjlwiLGJ1bXBFOlwi4qquXCIsYnVtcGU6XCLiiY9cIixCdW1wZXE6XCLiiY5cIixidW1wZXE6XCLiiY9cIixDYWN1dGU6XCLEhlwiLGNhY3V0ZTpcIsSHXCIsY2FwYW5kOlwi4qmEXCIsY2FwYnJjdXA6XCLiqYlcIixjYXBjYXA6XCLiqYtcIixjYXA6XCLiiKlcIixDYXA6XCLii5JcIixjYXBjdXA6XCLiqYdcIixjYXBkb3Q6XCLiqYBcIixDYXBpdGFsRGlmZmVyZW50aWFsRDpcIuKFhVwiLGNhcHM6XCLiiKnvuIBcIixjYXJldDpcIuKBgVwiLGNhcm9uOlwiy4dcIixDYXlsZXlzOlwi4oStXCIsY2NhcHM6XCLiqY1cIixDY2Fyb246XCLEjFwiLGNjYXJvbjpcIsSNXCIsQ2NlZGlsOlwiw4dcIixjY2VkaWw6XCLDp1wiLENjaXJjOlwixIhcIixjY2lyYzpcIsSJXCIsQ2NvbmludDpcIuKIsFwiLGNjdXBzOlwi4qmMXCIsY2N1cHNzbTpcIuKpkFwiLENkb3Q6XCLEilwiLGNkb3Q6XCLEi1wiLGNlZGlsOlwiwrhcIixDZWRpbGxhOlwiwrhcIixjZW1wdHl2Olwi4qayXCIsY2VudDpcIsKiXCIsY2VudGVyZG90OlwiwrdcIixDZW50ZXJEb3Q6XCLCt1wiLGNmcjpcIvCdlKBcIixDZnI6XCLihK1cIixDSGN5Olwi0KdcIixjaGN5Olwi0YdcIixjaGVjazpcIuKck1wiLGNoZWNrbWFyazpcIuKck1wiLENoaTpcIs6nXCIsY2hpOlwiz4dcIixjaXJjOlwiy4ZcIixjaXJjZXE6XCLiiZdcIixjaXJjbGVhcnJvd2xlZnQ6XCLihrpcIixjaXJjbGVhcnJvd3JpZ2h0Olwi4oa7XCIsY2lyY2xlZGFzdDpcIuKKm1wiLGNpcmNsZWRjaXJjOlwi4oqaXCIsY2lyY2xlZGRhc2g6XCLiip1cIixDaXJjbGVEb3Q6XCLiiplcIixjaXJjbGVkUjpcIsKuXCIsY2lyY2xlZFM6XCLik4hcIixDaXJjbGVNaW51czpcIuKKllwiLENpcmNsZVBsdXM6XCLiipVcIixDaXJjbGVUaW1lczpcIuKKl1wiLGNpcjpcIuKXi1wiLGNpckU6XCLip4NcIixjaXJlOlwi4omXXCIsY2lyZm5pbnQ6XCLiqJBcIixjaXJtaWQ6XCLiq69cIixjaXJzY2lyOlwi4qeCXCIsQ2xvY2t3aXNlQ29udG91ckludGVncmFsOlwi4oiyXCIsQ2xvc2VDdXJseURvdWJsZVF1b3RlOlwi4oCdXCIsQ2xvc2VDdXJseVF1b3RlOlwi4oCZXCIsY2x1YnM6XCLimaNcIixjbHVic3VpdDpcIuKZo1wiLGNvbG9uOlwiOlwiLENvbG9uOlwi4oi3XCIsQ29sb25lOlwi4qm0XCIsY29sb25lOlwi4omUXCIsY29sb25lcTpcIuKJlFwiLGNvbW1hOlwiLFwiLGNvbW1hdDpcIkBcIixjb21wOlwi4oiBXCIsY29tcGZuOlwi4oiYXCIsY29tcGxlbWVudDpcIuKIgVwiLGNvbXBsZXhlczpcIuKEglwiLGNvbmc6XCLiiYVcIixjb25nZG90Olwi4qmtXCIsQ29uZ3J1ZW50Olwi4omhXCIsY29uaW50Olwi4oiuXCIsQ29uaW50Olwi4oivXCIsQ29udG91ckludGVncmFsOlwi4oiuXCIsY29wZjpcIvCdlZRcIixDb3BmOlwi4oSCXCIsY29wcm9kOlwi4oiQXCIsQ29wcm9kdWN0Olwi4oiQXCIsY29weTpcIsKpXCIsQ09QWTpcIsKpXCIsY29weXNyOlwi4oSXXCIsQ291bnRlckNsb2Nrd2lzZUNvbnRvdXJJbnRlZ3JhbDpcIuKIs1wiLGNyYXJyOlwi4oa1XCIsY3Jvc3M6XCLinJdcIixDcm9zczpcIuKor1wiLENzY3I6XCLwnZKeXCIsY3NjcjpcIvCdkrhcIixjc3ViOlwi4quPXCIsY3N1YmU6XCLiq5FcIixjc3VwOlwi4quQXCIsY3N1cGU6XCLiq5JcIixjdGRvdDpcIuKLr1wiLGN1ZGFycmw6XCLipLhcIixjdWRhcnJyOlwi4qS1XCIsY3VlcHI6XCLii55cIixjdWVzYzpcIuKLn1wiLGN1bGFycjpcIuKGtlwiLGN1bGFycnA6XCLipL1cIixjdXBicmNhcDpcIuKpiFwiLGN1cGNhcDpcIuKphlwiLEN1cENhcDpcIuKJjVwiLGN1cDpcIuKIqlwiLEN1cDpcIuKLk1wiLGN1cGN1cDpcIuKpilwiLGN1cGRvdDpcIuKKjVwiLGN1cG9yOlwi4qmFXCIsY3VwczpcIuKIqu+4gFwiLGN1cmFycjpcIuKGt1wiLGN1cmFycm06XCLipLxcIixjdXJseWVxcHJlYzpcIuKLnlwiLGN1cmx5ZXFzdWNjOlwi4oufXCIsY3VybHl2ZWU6XCLii45cIixjdXJseXdlZGdlOlwi4ouPXCIsY3VycmVuOlwiwqRcIixjdXJ2ZWFycm93bGVmdDpcIuKGtlwiLGN1cnZlYXJyb3dyaWdodDpcIuKGt1wiLGN1dmVlOlwi4ouOXCIsY3V3ZWQ6XCLii49cIixjd2NvbmludDpcIuKIslwiLGN3aW50Olwi4oixXCIsY3lsY3R5Olwi4oytXCIsZGFnZ2VyOlwi4oCgXCIsRGFnZ2VyOlwi4oChXCIsZGFsZXRoOlwi4oS4XCIsZGFycjpcIuKGk1wiLERhcnI6XCLihqFcIixkQXJyOlwi4oeTXCIsZGFzaDpcIuKAkFwiLERhc2h2Olwi4qukXCIsZGFzaHY6XCLiiqNcIixkYmthcm93Olwi4qSPXCIsZGJsYWM6XCLLnVwiLERjYXJvbjpcIsSOXCIsZGNhcm9uOlwixI9cIixEY3k6XCLQlFwiLGRjeTpcItC0XCIsZGRhZ2dlcjpcIuKAoVwiLGRkYXJyOlwi4oeKXCIsREQ6XCLihYVcIixkZDpcIuKFhlwiLEREb3RyYWhkOlwi4qSRXCIsZGRvdHNlcTpcIuKpt1wiLGRlZzpcIsKwXCIsRGVsOlwi4oiHXCIsRGVsdGE6XCLOlFwiLGRlbHRhOlwizrRcIixkZW1wdHl2Olwi4qaxXCIsZGZpc2h0Olwi4qW/XCIsRGZyOlwi8J2Uh1wiLGRmcjpcIvCdlKFcIixkSGFyOlwi4qWlXCIsZGhhcmw6XCLih4NcIixkaGFycjpcIuKHglwiLERpYWNyaXRpY2FsQWN1dGU6XCLCtFwiLERpYWNyaXRpY2FsRG90Olwiy5lcIixEaWFjcml0aWNhbERvdWJsZUFjdXRlOlwiy51cIixEaWFjcml0aWNhbEdyYXZlOlwiYFwiLERpYWNyaXRpY2FsVGlsZGU6XCLLnFwiLGRpYW06XCLii4RcIixkaWFtb25kOlwi4ouEXCIsRGlhbW9uZDpcIuKLhFwiLGRpYW1vbmRzdWl0Olwi4pmmXCIsZGlhbXM6XCLimaZcIixkaWU6XCLCqFwiLERpZmZlcmVudGlhbEQ6XCLihYZcIixkaWdhbW1hOlwiz51cIixkaXNpbjpcIuKLslwiLGRpdjpcIsO3XCIsZGl2aWRlOlwiw7dcIixkaXZpZGVvbnRpbWVzOlwi4ouHXCIsZGl2b254Olwi4ouHXCIsREpjeTpcItCCXCIsZGpjeTpcItGSXCIsZGxjb3JuOlwi4oyeXCIsZGxjcm9wOlwi4oyNXCIsZG9sbGFyOlwiJFwiLERvcGY6XCLwnZS7XCIsZG9wZjpcIvCdlZVcIixEb3Q6XCLCqFwiLGRvdDpcIsuZXCIsRG90RG90Olwi4oOcXCIsZG90ZXE6XCLiiZBcIixkb3RlcWRvdDpcIuKJkVwiLERvdEVxdWFsOlwi4omQXCIsZG90bWludXM6XCLiiLhcIixkb3RwbHVzOlwi4oiUXCIsZG90c3F1YXJlOlwi4oqhXCIsZG91YmxlYmFyd2VkZ2U6XCLijIZcIixEb3VibGVDb250b3VySW50ZWdyYWw6XCLiiK9cIixEb3VibGVEb3Q6XCLCqFwiLERvdWJsZURvd25BcnJvdzpcIuKHk1wiLERvdWJsZUxlZnRBcnJvdzpcIuKHkFwiLERvdWJsZUxlZnRSaWdodEFycm93Olwi4oeUXCIsRG91YmxlTGVmdFRlZTpcIuKrpFwiLERvdWJsZUxvbmdMZWZ0QXJyb3c6XCLin7hcIixEb3VibGVMb25nTGVmdFJpZ2h0QXJyb3c6XCLin7pcIixEb3VibGVMb25nUmlnaHRBcnJvdzpcIuKfuVwiLERvdWJsZVJpZ2h0QXJyb3c6XCLih5JcIixEb3VibGVSaWdodFRlZTpcIuKKqFwiLERvdWJsZVVwQXJyb3c6XCLih5FcIixEb3VibGVVcERvd25BcnJvdzpcIuKHlVwiLERvdWJsZVZlcnRpY2FsQmFyOlwi4oilXCIsRG93bkFycm93QmFyOlwi4qSTXCIsZG93bmFycm93Olwi4oaTXCIsRG93bkFycm93Olwi4oaTXCIsRG93bmFycm93Olwi4oeTXCIsRG93bkFycm93VXBBcnJvdzpcIuKHtVwiLERvd25CcmV2ZTpcIsyRXCIsZG93bmRvd25hcnJvd3M6XCLih4pcIixkb3duaGFycG9vbmxlZnQ6XCLih4NcIixkb3duaGFycG9vbnJpZ2h0Olwi4oeCXCIsRG93bkxlZnRSaWdodFZlY3RvcjpcIuKlkFwiLERvd25MZWZ0VGVlVmVjdG9yOlwi4qWeXCIsRG93bkxlZnRWZWN0b3JCYXI6XCLipZZcIixEb3duTGVmdFZlY3RvcjpcIuKGvVwiLERvd25SaWdodFRlZVZlY3RvcjpcIuKln1wiLERvd25SaWdodFZlY3RvckJhcjpcIuKll1wiLERvd25SaWdodFZlY3RvcjpcIuKHgVwiLERvd25UZWVBcnJvdzpcIuKGp1wiLERvd25UZWU6XCLiiqRcIixkcmJrYXJvdzpcIuKkkFwiLGRyY29ybjpcIuKMn1wiLGRyY3JvcDpcIuKMjFwiLERzY3I6XCLwnZKfXCIsZHNjcjpcIvCdkrlcIixEU2N5Olwi0IVcIixkc2N5Olwi0ZVcIixkc29sOlwi4qe2XCIsRHN0cm9rOlwixJBcIixkc3Ryb2s6XCLEkVwiLGR0ZG90Olwi4ouxXCIsZHRyaTpcIuKWv1wiLGR0cmlmOlwi4pa+XCIsZHVhcnI6XCLih7VcIixkdWhhcjpcIuKlr1wiLGR3YW5nbGU6XCLipqZcIixEWmN5Olwi0I9cIixkemN5Olwi0Z9cIixkemlncmFycjpcIuKfv1wiLEVhY3V0ZTpcIsOJXCIsZWFjdXRlOlwiw6lcIixlYXN0ZXI6XCLiqa5cIixFY2Fyb246XCLEmlwiLGVjYXJvbjpcIsSbXCIsRWNpcmM6XCLDilwiLGVjaXJjOlwiw6pcIixlY2lyOlwi4omWXCIsZWNvbG9uOlwi4omVXCIsRWN5Olwi0K1cIixlY3k6XCLRjVwiLGVERG90Olwi4qm3XCIsRWRvdDpcIsSWXCIsZWRvdDpcIsSXXCIsZURvdDpcIuKJkVwiLGVlOlwi4oWHXCIsZWZEb3Q6XCLiiZJcIixFZnI6XCLwnZSIXCIsZWZyOlwi8J2UolwiLGVnOlwi4qqaXCIsRWdyYXZlOlwiw4hcIixlZ3JhdmU6XCLDqFwiLGVnczpcIuKqllwiLGVnc2RvdDpcIuKqmFwiLGVsOlwi4qqZXCIsRWxlbWVudDpcIuKIiFwiLGVsaW50ZXJzOlwi4o+nXCIsZWxsOlwi4oSTXCIsZWxzOlwi4qqVXCIsZWxzZG90Olwi4qqXXCIsRW1hY3I6XCLEklwiLGVtYWNyOlwixJNcIixlbXB0eTpcIuKIhVwiLGVtcHR5c2V0Olwi4oiFXCIsRW1wdHlTbWFsbFNxdWFyZTpcIuKXu1wiLGVtcHR5djpcIuKIhVwiLEVtcHR5VmVyeVNtYWxsU3F1YXJlOlwi4parXCIsZW1zcDEzOlwi4oCEXCIsZW1zcDE0Olwi4oCFXCIsZW1zcDpcIuKAg1wiLEVORzpcIsWKXCIsZW5nOlwixYtcIixlbnNwOlwi4oCCXCIsRW9nb246XCLEmFwiLGVvZ29uOlwixJlcIixFb3BmOlwi8J2UvFwiLGVvcGY6XCLwnZWWXCIsZXBhcjpcIuKLlVwiLGVwYXJzbDpcIuKno1wiLGVwbHVzOlwi4qmxXCIsZXBzaTpcIs61XCIsRXBzaWxvbjpcIs6VXCIsZXBzaWxvbjpcIs61XCIsZXBzaXY6XCLPtVwiLGVxY2lyYzpcIuKJllwiLGVxY29sb246XCLiiZVcIixlcXNpbTpcIuKJglwiLGVxc2xhbnRndHI6XCLiqpZcIixlcXNsYW50bGVzczpcIuKqlVwiLEVxdWFsOlwi4qm1XCIsZXF1YWxzOlwiPVwiLEVxdWFsVGlsZGU6XCLiiYJcIixlcXVlc3Q6XCLiiZ9cIixFcXVpbGlicml1bTpcIuKHjFwiLGVxdWl2Olwi4omhXCIsZXF1aXZERDpcIuKpuFwiLGVxdnBhcnNsOlwi4qelXCIsZXJhcnI6XCLipbFcIixlckRvdDpcIuKJk1wiLGVzY3I6XCLihK9cIixFc2NyOlwi4oSwXCIsZXNkb3Q6XCLiiZBcIixFc2ltOlwi4qmzXCIsZXNpbTpcIuKJglwiLEV0YTpcIs6XXCIsZXRhOlwizrdcIixFVEg6XCLDkFwiLGV0aDpcIsOwXCIsRXVtbDpcIsOLXCIsZXVtbDpcIsOrXCIsZXVybzpcIuKCrFwiLGV4Y2w6XCIhXCIsZXhpc3Q6XCLiiINcIixFeGlzdHM6XCLiiINcIixleHBlY3RhdGlvbjpcIuKEsFwiLGV4cG9uZW50aWFsZTpcIuKFh1wiLEV4cG9uZW50aWFsRTpcIuKFh1wiLGZhbGxpbmdkb3RzZXE6XCLiiZJcIixGY3k6XCLQpFwiLGZjeTpcItGEXCIsZmVtYWxlOlwi4pmAXCIsZmZpbGlnOlwi76yDXCIsZmZsaWc6XCLvrIBcIixmZmxsaWc6XCLvrIRcIixGZnI6XCLwnZSJXCIsZmZyOlwi8J2Uo1wiLGZpbGlnOlwi76yBXCIsRmlsbGVkU21hbGxTcXVhcmU6XCLil7xcIixGaWxsZWRWZXJ5U21hbGxTcXVhcmU6XCLilqpcIixmamxpZzpcImZqXCIsZmxhdDpcIuKZrVwiLGZsbGlnOlwi76yCXCIsZmx0bnM6XCLilrFcIixmbm9mOlwixpJcIixGb3BmOlwi8J2UvVwiLGZvcGY6XCLwnZWXXCIsZm9yYWxsOlwi4oiAXCIsRm9yQWxsOlwi4oiAXCIsZm9yazpcIuKLlFwiLGZvcmt2Olwi4quZXCIsRm91cmllcnRyZjpcIuKEsVwiLGZwYXJ0aW50Olwi4qiNXCIsZnJhYzEyOlwiwr1cIixmcmFjMTM6XCLihZNcIixmcmFjMTQ6XCLCvFwiLGZyYWMxNTpcIuKFlVwiLGZyYWMxNjpcIuKFmVwiLGZyYWMxODpcIuKFm1wiLGZyYWMyMzpcIuKFlFwiLGZyYWMyNTpcIuKFllwiLGZyYWMzNDpcIsK+XCIsZnJhYzM1Olwi4oWXXCIsZnJhYzM4Olwi4oWcXCIsZnJhYzQ1Olwi4oWYXCIsZnJhYzU2Olwi4oWaXCIsZnJhYzU4Olwi4oWdXCIsZnJhYzc4Olwi4oWeXCIsZnJhc2w6XCLigYRcIixmcm93bjpcIuKMolwiLGZzY3I6XCLwnZK7XCIsRnNjcjpcIuKEsVwiLGdhY3V0ZTpcIse1XCIsR2FtbWE6XCLOk1wiLGdhbW1hOlwizrNcIixHYW1tYWQ6XCLPnFwiLGdhbW1hZDpcIs+dXCIsZ2FwOlwi4qqGXCIsR2JyZXZlOlwixJ5cIixnYnJldmU6XCLEn1wiLEdjZWRpbDpcIsSiXCIsR2NpcmM6XCLEnFwiLGdjaXJjOlwixJ1cIixHY3k6XCLQk1wiLGdjeTpcItCzXCIsR2RvdDpcIsSgXCIsZ2RvdDpcIsShXCIsZ2U6XCLiiaVcIixnRTpcIuKJp1wiLGdFbDpcIuKqjFwiLGdlbDpcIuKLm1wiLGdlcTpcIuKJpVwiLGdlcXE6XCLiiadcIixnZXFzbGFudDpcIuKpvlwiLGdlc2NjOlwi4qqpXCIsZ2VzOlwi4qm+XCIsZ2VzZG90Olwi4qqAXCIsZ2VzZG90bzpcIuKqglwiLGdlc2RvdG9sOlwi4qqEXCIsZ2VzbDpcIuKLm++4gFwiLGdlc2xlczpcIuKqlFwiLEdmcjpcIvCdlIpcIixnZnI6XCLwnZSkXCIsZ2c6XCLiiatcIixHZzpcIuKLmVwiLGdnZzpcIuKLmVwiLGdpbWVsOlwi4oS3XCIsR0pjeTpcItCDXCIsZ2pjeTpcItGTXCIsZ2xhOlwi4qqlXCIsZ2w6XCLiibdcIixnbEU6XCLiqpJcIixnbGo6XCLiqqRcIixnbmFwOlwi4qqKXCIsZ25hcHByb3g6XCLiqopcIixnbmU6XCLiqohcIixnbkU6XCLiialcIixnbmVxOlwi4qqIXCIsZ25lcXE6XCLiialcIixnbnNpbTpcIuKLp1wiLEdvcGY6XCLwnZS+XCIsZ29wZjpcIvCdlZhcIixncmF2ZTpcImBcIixHcmVhdGVyRXF1YWw6XCLiiaVcIixHcmVhdGVyRXF1YWxMZXNzOlwi4oubXCIsR3JlYXRlckZ1bGxFcXVhbDpcIuKJp1wiLEdyZWF0ZXJHcmVhdGVyOlwi4qqiXCIsR3JlYXRlckxlc3M6XCLiibdcIixHcmVhdGVyU2xhbnRFcXVhbDpcIuKpvlwiLEdyZWF0ZXJUaWxkZTpcIuKJs1wiLEdzY3I6XCLwnZKiXCIsZ3NjcjpcIuKEilwiLGdzaW06XCLiibNcIixnc2ltZTpcIuKqjlwiLGdzaW1sOlwi4qqQXCIsZ3RjYzpcIuKqp1wiLGd0Y2lyOlwi4qm6XCIsZ3Q6XCI+XCIsR1Q6XCI+XCIsR3Q6XCLiiatcIixndGRvdDpcIuKLl1wiLGd0bFBhcjpcIuKmlVwiLGd0cXVlc3Q6XCLiqbxcIixndHJhcHByb3g6XCLiqoZcIixndHJhcnI6XCLipbhcIixndHJkb3Q6XCLii5dcIixndHJlcWxlc3M6XCLii5tcIixndHJlcXFsZXNzOlwi4qqMXCIsZ3RybGVzczpcIuKJt1wiLGd0cnNpbTpcIuKJs1wiLGd2ZXJ0bmVxcTpcIuKJqe+4gFwiLGd2bkU6XCLiianvuIBcIixIYWNlazpcIsuHXCIsaGFpcnNwOlwi4oCKXCIsaGFsZjpcIsK9XCIsaGFtaWx0Olwi4oSLXCIsSEFSRGN5Olwi0KpcIixoYXJkY3k6XCLRilwiLGhhcnJjaXI6XCLipYhcIixoYXJyOlwi4oaUXCIsaEFycjpcIuKHlFwiLGhhcnJ3Olwi4oatXCIsSGF0OlwiXlwiLGhiYXI6XCLihI9cIixIY2lyYzpcIsSkXCIsaGNpcmM6XCLEpVwiLGhlYXJ0czpcIuKZpVwiLGhlYXJ0c3VpdDpcIuKZpVwiLGhlbGxpcDpcIuKAplwiLGhlcmNvbjpcIuKKuVwiLGhmcjpcIvCdlKVcIixIZnI6XCLihIxcIixIaWxiZXJ0U3BhY2U6XCLihItcIixoa3NlYXJvdzpcIuKkpVwiLGhrc3dhcm93Olwi4qSmXCIsaG9hcnI6XCLih79cIixob210aHQ6XCLiiLtcIixob29rbGVmdGFycm93Olwi4oapXCIsaG9va3JpZ2h0YXJyb3c6XCLihqpcIixob3BmOlwi8J2VmVwiLEhvcGY6XCLihI1cIixob3JiYXI6XCLigJVcIixIb3Jpem9udGFsTGluZTpcIuKUgFwiLGhzY3I6XCLwnZK9XCIsSHNjcjpcIuKEi1wiLGhzbGFzaDpcIuKEj1wiLEhzdHJvazpcIsSmXCIsaHN0cm9rOlwixKdcIixIdW1wRG93bkh1bXA6XCLiiY5cIixIdW1wRXF1YWw6XCLiiY9cIixoeWJ1bGw6XCLigYNcIixoeXBoZW46XCLigJBcIixJYWN1dGU6XCLDjVwiLGlhY3V0ZTpcIsOtXCIsaWM6XCLigaNcIixJY2lyYzpcIsOOXCIsaWNpcmM6XCLDrlwiLEljeTpcItCYXCIsaWN5Olwi0LhcIixJZG90OlwixLBcIixJRWN5Olwi0JVcIixpZWN5Olwi0LVcIixpZXhjbDpcIsKhXCIsaWZmOlwi4oeUXCIsaWZyOlwi8J2UplwiLElmcjpcIuKEkVwiLElncmF2ZTpcIsOMXCIsaWdyYXZlOlwiw6xcIixpaTpcIuKFiFwiLGlpaWludDpcIuKojFwiLGlpaW50Olwi4oitXCIsaWluZmluOlwi4qecXCIsaWlvdGE6XCLihKlcIixJSmxpZzpcIsSyXCIsaWpsaWc6XCLEs1wiLEltYWNyOlwixKpcIixpbWFjcjpcIsSrXCIsaW1hZ2U6XCLihJFcIixJbWFnaW5hcnlJOlwi4oWIXCIsaW1hZ2xpbmU6XCLihJBcIixpbWFncGFydDpcIuKEkVwiLGltYXRoOlwixLFcIixJbTpcIuKEkVwiLGltb2Y6XCLiirdcIixpbXBlZDpcIsa1XCIsSW1wbGllczpcIuKHklwiLGluY2FyZTpcIuKEhVwiLGluOlwi4oiIXCIsaW5maW46XCLiiJ5cIixpbmZpbnRpZTpcIuKnnVwiLGlub2RvdDpcIsSxXCIsaW50Y2FsOlwi4oq6XCIsaW50Olwi4oirXCIsSW50Olwi4oisXCIsaW50ZWdlcnM6XCLihKRcIixJbnRlZ3JhbDpcIuKIq1wiLGludGVyY2FsOlwi4oq6XCIsSW50ZXJzZWN0aW9uOlwi4ouCXCIsaW50bGFyaGs6XCLiqJdcIixpbnRwcm9kOlwi4qi8XCIsSW52aXNpYmxlQ29tbWE6XCLigaNcIixJbnZpc2libGVUaW1lczpcIuKBolwiLElPY3k6XCLQgVwiLGlvY3k6XCLRkVwiLElvZ29uOlwixK5cIixpb2dvbjpcIsSvXCIsSW9wZjpcIvCdlYBcIixpb3BmOlwi8J2VmlwiLElvdGE6XCLOmVwiLGlvdGE6XCLOuVwiLGlwcm9kOlwi4qi8XCIsaXF1ZXN0Olwiwr9cIixpc2NyOlwi8J2SvlwiLElzY3I6XCLihJBcIixpc2luOlwi4oiIXCIsaXNpbmRvdDpcIuKLtVwiLGlzaW5FOlwi4ou5XCIsaXNpbnM6XCLii7RcIixpc2luc3Y6XCLii7NcIixpc2ludjpcIuKIiFwiLGl0Olwi4oGiXCIsSXRpbGRlOlwixKhcIixpdGlsZGU6XCLEqVwiLEl1a2N5Olwi0IZcIixpdWtjeTpcItGWXCIsSXVtbDpcIsOPXCIsaXVtbDpcIsOvXCIsSmNpcmM6XCLEtFwiLGpjaXJjOlwixLVcIixKY3k6XCLQmVwiLGpjeTpcItC5XCIsSmZyOlwi8J2UjVwiLGpmcjpcIvCdlKdcIixqbWF0aDpcIsi3XCIsSm9wZjpcIvCdlYFcIixqb3BmOlwi8J2Vm1wiLEpzY3I6XCLwnZKlXCIsanNjcjpcIvCdkr9cIixKc2VyY3k6XCLQiFwiLGpzZXJjeTpcItGYXCIsSnVrY3k6XCLQhFwiLGp1a2N5Olwi0ZRcIixLYXBwYTpcIs6aXCIsa2FwcGE6XCLOulwiLGthcHBhdjpcIs+wXCIsS2NlZGlsOlwixLZcIixrY2VkaWw6XCLEt1wiLEtjeTpcItCaXCIsa2N5Olwi0LpcIixLZnI6XCLwnZSOXCIsa2ZyOlwi8J2UqFwiLGtncmVlbjpcIsS4XCIsS0hjeTpcItClXCIsa2hjeTpcItGFXCIsS0pjeTpcItCMXCIsa2pjeTpcItGcXCIsS29wZjpcIvCdlYJcIixrb3BmOlwi8J2VnFwiLEtzY3I6XCLwnZKmXCIsa3NjcjpcIvCdk4BcIixsQWFycjpcIuKHmlwiLExhY3V0ZTpcIsS5XCIsbGFjdXRlOlwixLpcIixsYWVtcHR5djpcIuKmtFwiLGxhZ3JhbjpcIuKEklwiLExhbWJkYTpcIs6bXCIsbGFtYmRhOlwizrtcIixsYW5nOlwi4p+oXCIsTGFuZzpcIuKfqlwiLGxhbmdkOlwi4qaRXCIsbGFuZ2xlOlwi4p+oXCIsbGFwOlwi4qqFXCIsTGFwbGFjZXRyZjpcIuKEklwiLGxhcXVvOlwiwqtcIixsYXJyYjpcIuKHpFwiLGxhcnJiZnM6XCLipJ9cIixsYXJyOlwi4oaQXCIsTGFycjpcIuKGnlwiLGxBcnI6XCLih5BcIixsYXJyZnM6XCLipJ1cIixsYXJyaGs6XCLihqlcIixsYXJybHA6XCLihqtcIixsYXJycGw6XCLipLlcIixsYXJyc2ltOlwi4qWzXCIsbGFycnRsOlwi4oaiXCIsbGF0YWlsOlwi4qSZXCIsbEF0YWlsOlwi4qSbXCIsbGF0Olwi4qqrXCIsbGF0ZTpcIuKqrVwiLGxhdGVzOlwi4qqt77iAXCIsbGJhcnI6XCLipIxcIixsQmFycjpcIuKkjlwiLGxiYnJrOlwi4p2yXCIsbGJyYWNlOlwie1wiLGxicmFjazpcIltcIixsYnJrZTpcIuKmi1wiLGxicmtzbGQ6XCLipo9cIixsYnJrc2x1Olwi4qaNXCIsTGNhcm9uOlwixL1cIixsY2Fyb246XCLEvlwiLExjZWRpbDpcIsS7XCIsbGNlZGlsOlwixLxcIixsY2VpbDpcIuKMiFwiLGxjdWI6XCJ7XCIsTGN5Olwi0JtcIixsY3k6XCLQu1wiLGxkY2E6XCLipLZcIixsZHF1bzpcIuKAnFwiLGxkcXVvcjpcIuKAnlwiLGxkcmRoYXI6XCLipadcIixsZHJ1c2hhcjpcIuKli1wiLGxkc2g6XCLihrJcIixsZTpcIuKJpFwiLGxFOlwi4ommXCIsTGVmdEFuZ2xlQnJhY2tldDpcIuKfqFwiLExlZnRBcnJvd0JhcjpcIuKHpFwiLGxlZnRhcnJvdzpcIuKGkFwiLExlZnRBcnJvdzpcIuKGkFwiLExlZnRhcnJvdzpcIuKHkFwiLExlZnRBcnJvd1JpZ2h0QXJyb3c6XCLih4ZcIixsZWZ0YXJyb3d0YWlsOlwi4oaiXCIsTGVmdENlaWxpbmc6XCLijIhcIixMZWZ0RG91YmxlQnJhY2tldDpcIuKfplwiLExlZnREb3duVGVlVmVjdG9yOlwi4qWhXCIsTGVmdERvd25WZWN0b3JCYXI6XCLipZlcIixMZWZ0RG93blZlY3RvcjpcIuKHg1wiLExlZnRGbG9vcjpcIuKMilwiLGxlZnRoYXJwb29uZG93bjpcIuKGvVwiLGxlZnRoYXJwb29udXA6XCLihrxcIixsZWZ0bGVmdGFycm93czpcIuKHh1wiLGxlZnRyaWdodGFycm93Olwi4oaUXCIsTGVmdFJpZ2h0QXJyb3c6XCLihpRcIixMZWZ0cmlnaHRhcnJvdzpcIuKHlFwiLGxlZnRyaWdodGFycm93czpcIuKHhlwiLGxlZnRyaWdodGhhcnBvb25zOlwi4oeLXCIsbGVmdHJpZ2h0c3F1aWdhcnJvdzpcIuKGrVwiLExlZnRSaWdodFZlY3RvcjpcIuKljlwiLExlZnRUZWVBcnJvdzpcIuKGpFwiLExlZnRUZWU6XCLiiqNcIixMZWZ0VGVlVmVjdG9yOlwi4qWaXCIsbGVmdHRocmVldGltZXM6XCLii4tcIixMZWZ0VHJpYW5nbGVCYXI6XCLip49cIixMZWZ0VHJpYW5nbGU6XCLiirJcIixMZWZ0VHJpYW5nbGVFcXVhbDpcIuKKtFwiLExlZnRVcERvd25WZWN0b3I6XCLipZFcIixMZWZ0VXBUZWVWZWN0b3I6XCLipaBcIixMZWZ0VXBWZWN0b3JCYXI6XCLipZhcIixMZWZ0VXBWZWN0b3I6XCLihr9cIixMZWZ0VmVjdG9yQmFyOlwi4qWSXCIsTGVmdFZlY3RvcjpcIuKGvFwiLGxFZzpcIuKqi1wiLGxlZzpcIuKLmlwiLGxlcTpcIuKJpFwiLGxlcXE6XCLiiaZcIixsZXFzbGFudDpcIuKpvVwiLGxlc2NjOlwi4qqoXCIsbGVzOlwi4qm9XCIsbGVzZG90Olwi4qm/XCIsbGVzZG90bzpcIuKqgVwiLGxlc2RvdG9yOlwi4qqDXCIsbGVzZzpcIuKLmu+4gFwiLGxlc2dlczpcIuKqk1wiLGxlc3NhcHByb3g6XCLiqoVcIixsZXNzZG90Olwi4ouWXCIsbGVzc2VxZ3RyOlwi4ouaXCIsbGVzc2VxcWd0cjpcIuKqi1wiLExlc3NFcXVhbEdyZWF0ZXI6XCLii5pcIixMZXNzRnVsbEVxdWFsOlwi4ommXCIsTGVzc0dyZWF0ZXI6XCLiibZcIixsZXNzZ3RyOlwi4om2XCIsTGVzc0xlc3M6XCLiqqFcIixsZXNzc2ltOlwi4omyXCIsTGVzc1NsYW50RXF1YWw6XCLiqb1cIixMZXNzVGlsZGU6XCLiibJcIixsZmlzaHQ6XCLipbxcIixsZmxvb3I6XCLijIpcIixMZnI6XCLwnZSPXCIsbGZyOlwi8J2UqVwiLGxnOlwi4om2XCIsbGdFOlwi4qqRXCIsbEhhcjpcIuKlolwiLGxoYXJkOlwi4oa9XCIsbGhhcnU6XCLihrxcIixsaGFydWw6XCLipapcIixsaGJsazpcIuKWhFwiLExKY3k6XCLQiVwiLGxqY3k6XCLRmVwiLGxsYXJyOlwi4oeHXCIsbGw6XCLiiapcIixMbDpcIuKLmFwiLGxsY29ybmVyOlwi4oyeXCIsTGxlZnRhcnJvdzpcIuKHmlwiLGxsaGFyZDpcIuKlq1wiLGxsdHJpOlwi4pe6XCIsTG1pZG90OlwixL9cIixsbWlkb3Q6XCLFgFwiLGxtb3VzdGFjaGU6XCLijrBcIixsbW91c3Q6XCLijrBcIixsbmFwOlwi4qqJXCIsbG5hcHByb3g6XCLiqolcIixsbmU6XCLiqodcIixsbkU6XCLiiahcIixsbmVxOlwi4qqHXCIsbG5lcXE6XCLiiahcIixsbnNpbTpcIuKLplwiLGxvYW5nOlwi4p+sXCIsbG9hcnI6XCLih71cIixsb2JyazpcIuKfplwiLGxvbmdsZWZ0YXJyb3c6XCLin7VcIixMb25nTGVmdEFycm93Olwi4p+1XCIsTG9uZ2xlZnRhcnJvdzpcIuKfuFwiLGxvbmdsZWZ0cmlnaHRhcnJvdzpcIuKft1wiLExvbmdMZWZ0UmlnaHRBcnJvdzpcIuKft1wiLExvbmdsZWZ0cmlnaHRhcnJvdzpcIuKfulwiLGxvbmdtYXBzdG86XCLin7xcIixsb25ncmlnaHRhcnJvdzpcIuKftlwiLExvbmdSaWdodEFycm93Olwi4p+2XCIsTG9uZ3JpZ2h0YXJyb3c6XCLin7lcIixsb29wYXJyb3dsZWZ0Olwi4oarXCIsbG9vcGFycm93cmlnaHQ6XCLihqxcIixsb3BhcjpcIuKmhVwiLExvcGY6XCLwnZWDXCIsbG9wZjpcIvCdlZ1cIixsb3BsdXM6XCLiqK1cIixsb3RpbWVzOlwi4qi0XCIsbG93YXN0Olwi4oiXXCIsbG93YmFyOlwiX1wiLExvd2VyTGVmdEFycm93Olwi4oaZXCIsTG93ZXJSaWdodEFycm93Olwi4oaYXCIsbG96Olwi4peKXCIsbG96ZW5nZTpcIuKXilwiLGxvemY6XCLip6tcIixscGFyOlwiKFwiLGxwYXJsdDpcIuKmk1wiLGxyYXJyOlwi4oeGXCIsbHJjb3JuZXI6XCLijJ9cIixscmhhcjpcIuKHi1wiLGxyaGFyZDpcIuKlrVwiLGxybTpcIuKAjlwiLGxydHJpOlwi4oq/XCIsbHNhcXVvOlwi4oC5XCIsbHNjcjpcIvCdk4FcIixMc2NyOlwi4oSSXCIsbHNoOlwi4oawXCIsTHNoOlwi4oawXCIsbHNpbTpcIuKJslwiLGxzaW1lOlwi4qqNXCIsbHNpbWc6XCLiqo9cIixsc3FiOlwiW1wiLGxzcXVvOlwi4oCYXCIsbHNxdW9yOlwi4oCaXCIsTHN0cm9rOlwixYFcIixsc3Ryb2s6XCLFglwiLGx0Y2M6XCLiqqZcIixsdGNpcjpcIuKpuVwiLGx0OlwiPFwiLExUOlwiPFwiLEx0Olwi4omqXCIsbHRkb3Q6XCLii5ZcIixsdGhyZWU6XCLii4tcIixsdGltZXM6XCLii4lcIixsdGxhcnI6XCLipbZcIixsdHF1ZXN0Olwi4qm7XCIsbHRyaTpcIuKXg1wiLGx0cmllOlwi4oq0XCIsbHRyaWY6XCLil4JcIixsdHJQYXI6XCLippZcIixsdXJkc2hhcjpcIuKlilwiLGx1cnVoYXI6XCLipaZcIixsdmVydG5lcXE6XCLiiajvuIBcIixsdm5FOlwi4omo77iAXCIsbWFjcjpcIsKvXCIsbWFsZTpcIuKZglwiLG1hbHQ6XCLinKBcIixtYWx0ZXNlOlwi4pygXCIsTWFwOlwi4qSFXCIsbWFwOlwi4oamXCIsbWFwc3RvOlwi4oamXCIsbWFwc3RvZG93bjpcIuKGp1wiLG1hcHN0b2xlZnQ6XCLihqRcIixtYXBzdG91cDpcIuKGpVwiLG1hcmtlcjpcIuKWrlwiLG1jb21tYTpcIuKoqVwiLE1jeTpcItCcXCIsbWN5Olwi0LxcIixtZGFzaDpcIuKAlFwiLG1ERG90Olwi4oi6XCIsbWVhc3VyZWRhbmdsZTpcIuKIoVwiLE1lZGl1bVNwYWNlOlwi4oGfXCIsTWVsbGludHJmOlwi4oSzXCIsTWZyOlwi8J2UkFwiLG1mcjpcIvCdlKpcIixtaG86XCLihKdcIixtaWNybzpcIsK1XCIsbWlkYXN0OlwiKlwiLG1pZGNpcjpcIuKrsFwiLG1pZDpcIuKIo1wiLG1pZGRvdDpcIsK3XCIsbWludXNiOlwi4oqfXCIsbWludXM6XCLiiJJcIixtaW51c2Q6XCLiiLhcIixtaW51c2R1Olwi4qiqXCIsTWludXNQbHVzOlwi4oiTXCIsbWxjcDpcIuKrm1wiLG1sZHI6XCLigKZcIixtbnBsdXM6XCLiiJNcIixtb2RlbHM6XCLiiqdcIixNb3BmOlwi8J2VhFwiLG1vcGY6XCLwnZWeXCIsbXA6XCLiiJNcIixtc2NyOlwi8J2TglwiLE1zY3I6XCLihLNcIixtc3Rwb3M6XCLiiL5cIixNdTpcIs6cXCIsbXU6XCLOvFwiLG11bHRpbWFwOlwi4oq4XCIsbXVtYXA6XCLiirhcIixuYWJsYTpcIuKIh1wiLE5hY3V0ZTpcIsWDXCIsbmFjdXRlOlwixYRcIixuYW5nOlwi4oig4oOSXCIsbmFwOlwi4omJXCIsbmFwRTpcIuKpsMy4XCIsbmFwaWQ6XCLiiYvMuFwiLG5hcG9zOlwixYlcIixuYXBwcm94Olwi4omJXCIsbmF0dXJhbDpcIuKZrlwiLG5hdHVyYWxzOlwi4oSVXCIsbmF0dXI6XCLima5cIixuYnNwOlwiwqBcIixuYnVtcDpcIuKJjsy4XCIsbmJ1bXBlOlwi4omPzLhcIixuY2FwOlwi4qmDXCIsTmNhcm9uOlwixYdcIixuY2Fyb246XCLFiFwiLE5jZWRpbDpcIsWFXCIsbmNlZGlsOlwixYZcIixuY29uZzpcIuKJh1wiLG5jb25nZG90Olwi4qmtzLhcIixuY3VwOlwi4qmCXCIsTmN5Olwi0J1cIixuY3k6XCLQvVwiLG5kYXNoOlwi4oCTXCIsbmVhcmhrOlwi4qSkXCIsbmVhcnI6XCLihpdcIixuZUFycjpcIuKHl1wiLG5lYXJyb3c6XCLihpdcIixuZTpcIuKJoFwiLG5lZG90Olwi4omQzLhcIixOZWdhdGl2ZU1lZGl1bVNwYWNlOlwi4oCLXCIsTmVnYXRpdmVUaGlja1NwYWNlOlwi4oCLXCIsTmVnYXRpdmVUaGluU3BhY2U6XCLigItcIixOZWdhdGl2ZVZlcnlUaGluU3BhY2U6XCLigItcIixuZXF1aXY6XCLiiaJcIixuZXNlYXI6XCLipKhcIixuZXNpbTpcIuKJgsy4XCIsTmVzdGVkR3JlYXRlckdyZWF0ZXI6XCLiiatcIixOZXN0ZWRMZXNzTGVzczpcIuKJqlwiLE5ld0xpbmU6XCJcXG5cIixuZXhpc3Q6XCLiiIRcIixuZXhpc3RzOlwi4oiEXCIsTmZyOlwi8J2UkVwiLG5mcjpcIvCdlKtcIixuZ0U6XCLiiafMuFwiLG5nZTpcIuKJsVwiLG5nZXE6XCLiibFcIixuZ2VxcTpcIuKJp8y4XCIsbmdlcXNsYW50Olwi4qm+zLhcIixuZ2VzOlwi4qm+zLhcIixuR2c6XCLii5nMuFwiLG5nc2ltOlwi4om1XCIsbkd0Olwi4omr4oOSXCIsbmd0Olwi4omvXCIsbmd0cjpcIuKJr1wiLG5HdHY6XCLiiavMuFwiLG5oYXJyOlwi4oauXCIsbmhBcnI6XCLih45cIixuaHBhcjpcIuKrslwiLG5pOlwi4oiLXCIsbmlzOlwi4ou8XCIsbmlzZDpcIuKLulwiLG5pdjpcIuKIi1wiLE5KY3k6XCLQilwiLG5qY3k6XCLRmlwiLG5sYXJyOlwi4oaaXCIsbmxBcnI6XCLih41cIixubGRyOlwi4oClXCIsbmxFOlwi4ommzLhcIixubGU6XCLiibBcIixubGVmdGFycm93Olwi4oaaXCIsbkxlZnRhcnJvdzpcIuKHjVwiLG5sZWZ0cmlnaHRhcnJvdzpcIuKGrlwiLG5MZWZ0cmlnaHRhcnJvdzpcIuKHjlwiLG5sZXE6XCLiibBcIixubGVxcTpcIuKJpsy4XCIsbmxlcXNsYW50Olwi4qm9zLhcIixubGVzOlwi4qm9zLhcIixubGVzczpcIuKJrlwiLG5MbDpcIuKLmMy4XCIsbmxzaW06XCLiibRcIixuTHQ6XCLiiarig5JcIixubHQ6XCLiia5cIixubHRyaTpcIuKLqlwiLG5sdHJpZTpcIuKLrFwiLG5MdHY6XCLiiarMuFwiLG5taWQ6XCLiiKRcIixOb0JyZWFrOlwi4oGgXCIsTm9uQnJlYWtpbmdTcGFjZTpcIsKgXCIsbm9wZjpcIvCdlZ9cIixOb3BmOlwi4oSVXCIsTm90Olwi4qusXCIsbm90OlwiwqxcIixOb3RDb25ncnVlbnQ6XCLiiaJcIixOb3RDdXBDYXA6XCLiia1cIixOb3REb3VibGVWZXJ0aWNhbEJhcjpcIuKIplwiLE5vdEVsZW1lbnQ6XCLiiIlcIixOb3RFcXVhbDpcIuKJoFwiLE5vdEVxdWFsVGlsZGU6XCLiiYLMuFwiLE5vdEV4aXN0czpcIuKIhFwiLE5vdEdyZWF0ZXI6XCLiia9cIixOb3RHcmVhdGVyRXF1YWw6XCLiibFcIixOb3RHcmVhdGVyRnVsbEVxdWFsOlwi4omnzLhcIixOb3RHcmVhdGVyR3JlYXRlcjpcIuKJq8y4XCIsTm90R3JlYXRlckxlc3M6XCLiiblcIixOb3RHcmVhdGVyU2xhbnRFcXVhbDpcIuKpvsy4XCIsTm90R3JlYXRlclRpbGRlOlwi4om1XCIsTm90SHVtcERvd25IdW1wOlwi4omOzLhcIixOb3RIdW1wRXF1YWw6XCLiiY/MuFwiLG5vdGluOlwi4oiJXCIsbm90aW5kb3Q6XCLii7XMuFwiLG5vdGluRTpcIuKLucy4XCIsbm90aW52YTpcIuKIiVwiLG5vdGludmI6XCLii7dcIixub3RpbnZjOlwi4ou2XCIsTm90TGVmdFRyaWFuZ2xlQmFyOlwi4qePzLhcIixOb3RMZWZ0VHJpYW5nbGU6XCLii6pcIixOb3RMZWZ0VHJpYW5nbGVFcXVhbDpcIuKLrFwiLE5vdExlc3M6XCLiia5cIixOb3RMZXNzRXF1YWw6XCLiibBcIixOb3RMZXNzR3JlYXRlcjpcIuKJuFwiLE5vdExlc3NMZXNzOlwi4omqzLhcIixOb3RMZXNzU2xhbnRFcXVhbDpcIuKpvcy4XCIsTm90TGVzc1RpbGRlOlwi4om0XCIsTm90TmVzdGVkR3JlYXRlckdyZWF0ZXI6XCLiqqLMuFwiLE5vdE5lc3RlZExlc3NMZXNzOlwi4qqhzLhcIixub3RuaTpcIuKIjFwiLG5vdG5pdmE6XCLiiIxcIixub3RuaXZiOlwi4ou+XCIsbm90bml2YzpcIuKLvVwiLE5vdFByZWNlZGVzOlwi4oqAXCIsTm90UHJlY2VkZXNFcXVhbDpcIuKqr8y4XCIsTm90UHJlY2VkZXNTbGFudEVxdWFsOlwi4ougXCIsTm90UmV2ZXJzZUVsZW1lbnQ6XCLiiIxcIixOb3RSaWdodFRyaWFuZ2xlQmFyOlwi4qeQzLhcIixOb3RSaWdodFRyaWFuZ2xlOlwi4ourXCIsTm90UmlnaHRUcmlhbmdsZUVxdWFsOlwi4outXCIsTm90U3F1YXJlU3Vic2V0Olwi4oqPzLhcIixOb3RTcXVhcmVTdWJzZXRFcXVhbDpcIuKLolwiLE5vdFNxdWFyZVN1cGVyc2V0Olwi4oqQzLhcIixOb3RTcXVhcmVTdXBlcnNldEVxdWFsOlwi4oujXCIsTm90U3Vic2V0Olwi4oqC4oOSXCIsTm90U3Vic2V0RXF1YWw6XCLiiohcIixOb3RTdWNjZWVkczpcIuKKgVwiLE5vdFN1Y2NlZWRzRXF1YWw6XCLiqrDMuFwiLE5vdFN1Y2NlZWRzU2xhbnRFcXVhbDpcIuKLoVwiLE5vdFN1Y2NlZWRzVGlsZGU6XCLiib/MuFwiLE5vdFN1cGVyc2V0Olwi4oqD4oOSXCIsTm90U3VwZXJzZXRFcXVhbDpcIuKKiVwiLE5vdFRpbGRlOlwi4omBXCIsTm90VGlsZGVFcXVhbDpcIuKJhFwiLE5vdFRpbGRlRnVsbEVxdWFsOlwi4omHXCIsTm90VGlsZGVUaWxkZTpcIuKJiVwiLE5vdFZlcnRpY2FsQmFyOlwi4oikXCIsbnBhcmFsbGVsOlwi4oimXCIsbnBhcjpcIuKIplwiLG5wYXJzbDpcIuKrveKDpVwiLG5wYXJ0Olwi4oiCzLhcIixucG9saW50Olwi4qiUXCIsbnByOlwi4oqAXCIsbnByY3VlOlwi4ougXCIsbnByZWM6XCLiioBcIixucHJlY2VxOlwi4qqvzLhcIixucHJlOlwi4qqvzLhcIixucmFycmM6XCLipLPMuFwiLG5yYXJyOlwi4oabXCIsbnJBcnI6XCLih49cIixucmFycnc6XCLihp3MuFwiLG5yaWdodGFycm93Olwi4oabXCIsblJpZ2h0YXJyb3c6XCLih49cIixucnRyaTpcIuKLq1wiLG5ydHJpZTpcIuKLrVwiLG5zYzpcIuKKgVwiLG5zY2N1ZTpcIuKLoVwiLG5zY2U6XCLiqrDMuFwiLE5zY3I6XCLwnZKpXCIsbnNjcjpcIvCdk4NcIixuc2hvcnRtaWQ6XCLiiKRcIixuc2hvcnRwYXJhbGxlbDpcIuKIplwiLG5zaW06XCLiiYFcIixuc2ltZTpcIuKJhFwiLG5zaW1lcTpcIuKJhFwiLG5zbWlkOlwi4oikXCIsbnNwYXI6XCLiiKZcIixuc3FzdWJlOlwi4ouiXCIsbnNxc3VwZTpcIuKLo1wiLG5zdWI6XCLiioRcIixuc3ViRTpcIuKrhcy4XCIsbnN1YmU6XCLiiohcIixuc3Vic2V0Olwi4oqC4oOSXCIsbnN1YnNldGVxOlwi4oqIXCIsbnN1YnNldGVxcTpcIuKrhcy4XCIsbnN1Y2M6XCLiioFcIixuc3VjY2VxOlwi4qqwzLhcIixuc3VwOlwi4oqFXCIsbnN1cEU6XCLiq4bMuFwiLG5zdXBlOlwi4oqJXCIsbnN1cHNldDpcIuKKg+KDklwiLG5zdXBzZXRlcTpcIuKKiVwiLG5zdXBzZXRlcXE6XCLiq4bMuFwiLG50Z2w6XCLiiblcIixOdGlsZGU6XCLDkVwiLG50aWxkZTpcIsOxXCIsbnRsZzpcIuKJuFwiLG50cmlhbmdsZWxlZnQ6XCLii6pcIixudHJpYW5nbGVsZWZ0ZXE6XCLii6xcIixudHJpYW5nbGVyaWdodDpcIuKLq1wiLG50cmlhbmdsZXJpZ2h0ZXE6XCLii61cIixOdTpcIs6dXCIsbnU6XCLOvVwiLG51bTpcIiNcIixudW1lcm86XCLihJZcIixudW1zcDpcIuKAh1wiLG52YXA6XCLiiY3ig5JcIixudmRhc2g6XCLiiqxcIixudkRhc2g6XCLiiq1cIixuVmRhc2g6XCLiiq5cIixuVkRhc2g6XCLiiq9cIixudmdlOlwi4oml4oOSXCIsbnZndDpcIj7ig5JcIixudkhhcnI6XCLipIRcIixudmluZmluOlwi4qeeXCIsbnZsQXJyOlwi4qSCXCIsbnZsZTpcIuKJpOKDklwiLG52bHQ6XCI84oOSXCIsbnZsdHJpZTpcIuKKtOKDklwiLG52ckFycjpcIuKkg1wiLG52cnRyaWU6XCLiirXig5JcIixudnNpbTpcIuKIvOKDklwiLG53YXJoazpcIuKko1wiLG53YXJyOlwi4oaWXCIsbndBcnI6XCLih5ZcIixud2Fycm93Olwi4oaWXCIsbnduZWFyOlwi4qSnXCIsT2FjdXRlOlwiw5NcIixvYWN1dGU6XCLDs1wiLG9hc3Q6XCLiiptcIixPY2lyYzpcIsOUXCIsb2NpcmM6XCLDtFwiLG9jaXI6XCLiippcIixPY3k6XCLQnlwiLG9jeTpcItC+XCIsb2Rhc2g6XCLiip1cIixPZGJsYWM6XCLFkFwiLG9kYmxhYzpcIsWRXCIsb2RpdjpcIuKouFwiLG9kb3Q6XCLiiplcIixvZHNvbGQ6XCLiprxcIixPRWxpZzpcIsWSXCIsb2VsaWc6XCLFk1wiLG9mY2lyOlwi4qa/XCIsT2ZyOlwi8J2UklwiLG9mcjpcIvCdlKxcIixvZ29uOlwiy5tcIixPZ3JhdmU6XCLDklwiLG9ncmF2ZTpcIsOyXCIsb2d0Olwi4qeBXCIsb2hiYXI6XCLiprVcIixvaG06XCLOqVwiLG9pbnQ6XCLiiK5cIixvbGFycjpcIuKGulwiLG9sY2lyOlwi4qa+XCIsb2xjcm9zczpcIuKmu1wiLG9saW5lOlwi4oC+XCIsb2x0Olwi4qeAXCIsT21hY3I6XCLFjFwiLG9tYWNyOlwixY1cIixPbWVnYTpcIs6pXCIsb21lZ2E6XCLPiVwiLE9taWNyb246XCLOn1wiLG9taWNyb246XCLOv1wiLG9taWQ6XCLiprZcIixvbWludXM6XCLiipZcIixPb3BmOlwi8J2VhlwiLG9vcGY6XCLwnZWgXCIsb3BhcjpcIuKmt1wiLE9wZW5DdXJseURvdWJsZVF1b3RlOlwi4oCcXCIsT3BlbkN1cmx5UXVvdGU6XCLigJhcIixvcGVycDpcIuKmuVwiLG9wbHVzOlwi4oqVXCIsb3JhcnI6XCLihrtcIixPcjpcIuKplFwiLG9yOlwi4oioXCIsb3JkOlwi4qmdXCIsb3JkZXI6XCLihLRcIixvcmRlcm9mOlwi4oS0XCIsb3JkZjpcIsKqXCIsb3JkbTpcIsK6XCIsb3JpZ29mOlwi4oq2XCIsb3JvcjpcIuKpllwiLG9yc2xvcGU6XCLiqZdcIixvcnY6XCLiqZtcIixvUzpcIuKTiFwiLE9zY3I6XCLwnZKqXCIsb3NjcjpcIuKEtFwiLE9zbGFzaDpcIsOYXCIsb3NsYXNoOlwiw7hcIixvc29sOlwi4oqYXCIsT3RpbGRlOlwiw5VcIixvdGlsZGU6XCLDtVwiLG90aW1lc2FzOlwi4qi2XCIsT3RpbWVzOlwi4qi3XCIsb3RpbWVzOlwi4oqXXCIsT3VtbDpcIsOWXCIsb3VtbDpcIsO2XCIsb3ZiYXI6XCLijL1cIixPdmVyQmFyOlwi4oC+XCIsT3ZlckJyYWNlOlwi4o+eXCIsT3ZlckJyYWNrZXQ6XCLijrRcIixPdmVyUGFyZW50aGVzaXM6XCLij5xcIixwYXJhOlwiwrZcIixwYXJhbGxlbDpcIuKIpVwiLHBhcjpcIuKIpVwiLHBhcnNpbTpcIuKrs1wiLHBhcnNsOlwi4qu9XCIscGFydDpcIuKIglwiLFBhcnRpYWxEOlwi4oiCXCIsUGN5Olwi0J9cIixwY3k6XCLQv1wiLHBlcmNudDpcIiVcIixwZXJpb2Q6XCIuXCIscGVybWlsOlwi4oCwXCIscGVycDpcIuKKpVwiLHBlcnRlbms6XCLigLFcIixQZnI6XCLwnZSTXCIscGZyOlwi8J2UrVwiLFBoaTpcIs6mXCIscGhpOlwiz4ZcIixwaGl2Olwiz5VcIixwaG1tYXQ6XCLihLNcIixwaG9uZTpcIuKYjlwiLFBpOlwizqBcIixwaTpcIs+AXCIscGl0Y2hmb3JrOlwi4ouUXCIscGl2Olwiz5ZcIixwbGFuY2s6XCLihI9cIixwbGFuY2toOlwi4oSOXCIscGxhbmt2Olwi4oSPXCIscGx1c2FjaXI6XCLiqKNcIixwbHVzYjpcIuKKnlwiLHBsdXNjaXI6XCLiqKJcIixwbHVzOlwiK1wiLHBsdXNkbzpcIuKIlFwiLHBsdXNkdTpcIuKopVwiLHBsdXNlOlwi4qmyXCIsUGx1c01pbnVzOlwiwrFcIixwbHVzbW46XCLCsVwiLHBsdXNzaW06XCLiqKZcIixwbHVzdHdvOlwi4qinXCIscG06XCLCsVwiLFBvaW5jYXJlcGxhbmU6XCLihIxcIixwb2ludGludDpcIuKolVwiLHBvcGY6XCLwnZWhXCIsUG9wZjpcIuKEmVwiLHBvdW5kOlwiwqNcIixwcmFwOlwi4qq3XCIsUHI6XCLiqrtcIixwcjpcIuKJulwiLHByY3VlOlwi4om8XCIscHJlY2FwcHJveDpcIuKqt1wiLHByZWM6XCLiibpcIixwcmVjY3VybHllcTpcIuKJvFwiLFByZWNlZGVzOlwi4om6XCIsUHJlY2VkZXNFcXVhbDpcIuKqr1wiLFByZWNlZGVzU2xhbnRFcXVhbDpcIuKJvFwiLFByZWNlZGVzVGlsZGU6XCLiib5cIixwcmVjZXE6XCLiqq9cIixwcmVjbmFwcHJveDpcIuKquVwiLHByZWNuZXFxOlwi4qq1XCIscHJlY25zaW06XCLii6hcIixwcmU6XCLiqq9cIixwckU6XCLiqrNcIixwcmVjc2ltOlwi4om+XCIscHJpbWU6XCLigLJcIixQcmltZTpcIuKAs1wiLHByaW1lczpcIuKEmVwiLHBybmFwOlwi4qq5XCIscHJuRTpcIuKqtVwiLHBybnNpbTpcIuKLqFwiLHByb2Q6XCLiiI9cIixQcm9kdWN0Olwi4oiPXCIscHJvZmFsYXI6XCLijK5cIixwcm9mbGluZTpcIuKMklwiLHByb2ZzdXJmOlwi4oyTXCIscHJvcDpcIuKInVwiLFByb3BvcnRpb25hbDpcIuKInVwiLFByb3BvcnRpb246XCLiiLdcIixwcm9wdG86XCLiiJ1cIixwcnNpbTpcIuKJvlwiLHBydXJlbDpcIuKKsFwiLFBzY3I6XCLwnZKrXCIscHNjcjpcIvCdk4VcIixQc2k6XCLOqFwiLHBzaTpcIs+IXCIscHVuY3NwOlwi4oCIXCIsUWZyOlwi8J2UlFwiLHFmcjpcIvCdlK5cIixxaW50Olwi4qiMXCIscW9wZjpcIvCdlaJcIixRb3BmOlwi4oSaXCIscXByaW1lOlwi4oGXXCIsUXNjcjpcIvCdkqxcIixxc2NyOlwi8J2ThlwiLHF1YXRlcm5pb25zOlwi4oSNXCIscXVhdGludDpcIuKollwiLHF1ZXN0OlwiP1wiLHF1ZXN0ZXE6XCLiiZ9cIixxdW90OidcIicsUVVPVDonXCInLHJBYXJyOlwi4oebXCIscmFjZTpcIuKIvcyxXCIsUmFjdXRlOlwixZRcIixyYWN1dGU6XCLFlVwiLHJhZGljOlwi4oiaXCIscmFlbXB0eXY6XCLiprNcIixyYW5nOlwi4p+pXCIsUmFuZzpcIuKfq1wiLHJhbmdkOlwi4qaSXCIscmFuZ2U6XCLipqVcIixyYW5nbGU6XCLin6lcIixyYXF1bzpcIsK7XCIscmFycmFwOlwi4qW1XCIscmFycmI6XCLih6VcIixyYXJyYmZzOlwi4qSgXCIscmFycmM6XCLipLNcIixyYXJyOlwi4oaSXCIsUmFycjpcIuKGoFwiLHJBcnI6XCLih5JcIixyYXJyZnM6XCLipJ5cIixyYXJyaGs6XCLihqpcIixyYXJybHA6XCLihqxcIixyYXJycGw6XCLipYVcIixyYXJyc2ltOlwi4qW0XCIsUmFycnRsOlwi4qSWXCIscmFycnRsOlwi4oajXCIscmFycnc6XCLihp1cIixyYXRhaWw6XCLipJpcIixyQXRhaWw6XCLipJxcIixyYXRpbzpcIuKItlwiLHJhdGlvbmFsczpcIuKEmlwiLHJiYXJyOlwi4qSNXCIsckJhcnI6XCLipI9cIixSQmFycjpcIuKkkFwiLHJiYnJrOlwi4p2zXCIscmJyYWNlOlwifVwiLHJicmFjazpcIl1cIixyYnJrZTpcIuKmjFwiLHJicmtzbGQ6XCLipo5cIixyYnJrc2x1Olwi4qaQXCIsUmNhcm9uOlwixZhcIixyY2Fyb246XCLFmVwiLFJjZWRpbDpcIsWWXCIscmNlZGlsOlwixZdcIixyY2VpbDpcIuKMiVwiLHJjdWI6XCJ9XCIsUmN5Olwi0KBcIixyY3k6XCLRgFwiLHJkY2E6XCLipLdcIixyZGxkaGFyOlwi4qWpXCIscmRxdW86XCLigJ1cIixyZHF1b3I6XCLigJ1cIixyZHNoOlwi4oazXCIscmVhbDpcIuKEnFwiLHJlYWxpbmU6XCLihJtcIixyZWFscGFydDpcIuKEnFwiLHJlYWxzOlwi4oSdXCIsUmU6XCLihJxcIixyZWN0Olwi4patXCIscmVnOlwiwq5cIixSRUc6XCLCrlwiLFJldmVyc2VFbGVtZW50Olwi4oiLXCIsUmV2ZXJzZUVxdWlsaWJyaXVtOlwi4oeLXCIsUmV2ZXJzZVVwRXF1aWxpYnJpdW06XCLipa9cIixyZmlzaHQ6XCLipb1cIixyZmxvb3I6XCLijItcIixyZnI6XCLwnZSvXCIsUmZyOlwi4oScXCIsckhhcjpcIuKlpFwiLHJoYXJkOlwi4oeBXCIscmhhcnU6XCLih4BcIixyaGFydWw6XCLipaxcIixSaG86XCLOoVwiLHJobzpcIs+BXCIscmhvdjpcIs+xXCIsUmlnaHRBbmdsZUJyYWNrZXQ6XCLin6lcIixSaWdodEFycm93QmFyOlwi4oelXCIscmlnaHRhcnJvdzpcIuKGklwiLFJpZ2h0QXJyb3c6XCLihpJcIixSaWdodGFycm93Olwi4oeSXCIsUmlnaHRBcnJvd0xlZnRBcnJvdzpcIuKHhFwiLHJpZ2h0YXJyb3d0YWlsOlwi4oajXCIsUmlnaHRDZWlsaW5nOlwi4oyJXCIsUmlnaHREb3VibGVCcmFja2V0Olwi4p+nXCIsUmlnaHREb3duVGVlVmVjdG9yOlwi4qWdXCIsUmlnaHREb3duVmVjdG9yQmFyOlwi4qWVXCIsUmlnaHREb3duVmVjdG9yOlwi4oeCXCIsUmlnaHRGbG9vcjpcIuKMi1wiLHJpZ2h0aGFycG9vbmRvd246XCLih4FcIixyaWdodGhhcnBvb251cDpcIuKHgFwiLHJpZ2h0bGVmdGFycm93czpcIuKHhFwiLHJpZ2h0bGVmdGhhcnBvb25zOlwi4oeMXCIscmlnaHRyaWdodGFycm93czpcIuKHiVwiLHJpZ2h0c3F1aWdhcnJvdzpcIuKGnVwiLFJpZ2h0VGVlQXJyb3c6XCLihqZcIixSaWdodFRlZTpcIuKKolwiLFJpZ2h0VGVlVmVjdG9yOlwi4qWbXCIscmlnaHR0aHJlZXRpbWVzOlwi4ouMXCIsUmlnaHRUcmlhbmdsZUJhcjpcIuKnkFwiLFJpZ2h0VHJpYW5nbGU6XCLiirNcIixSaWdodFRyaWFuZ2xlRXF1YWw6XCLiirVcIixSaWdodFVwRG93blZlY3RvcjpcIuKlj1wiLFJpZ2h0VXBUZWVWZWN0b3I6XCLipZxcIixSaWdodFVwVmVjdG9yQmFyOlwi4qWUXCIsUmlnaHRVcFZlY3RvcjpcIuKGvlwiLFJpZ2h0VmVjdG9yQmFyOlwi4qWTXCIsUmlnaHRWZWN0b3I6XCLih4BcIixyaW5nOlwiy5pcIixyaXNpbmdkb3RzZXE6XCLiiZNcIixybGFycjpcIuKHhFwiLHJsaGFyOlwi4oeMXCIscmxtOlwi4oCPXCIscm1vdXN0YWNoZTpcIuKOsVwiLHJtb3VzdDpcIuKOsVwiLHJubWlkOlwi4quuXCIscm9hbmc6XCLin61cIixyb2FycjpcIuKHvlwiLHJvYnJrOlwi4p+nXCIscm9wYXI6XCLipoZcIixyb3BmOlwi8J2Vo1wiLFJvcGY6XCLihJ1cIixyb3BsdXM6XCLiqK5cIixyb3RpbWVzOlwi4qi1XCIsUm91bmRJbXBsaWVzOlwi4qWwXCIscnBhcjpcIilcIixycGFyZ3Q6XCLippRcIixycHBvbGludDpcIuKoklwiLHJyYXJyOlwi4oeJXCIsUnJpZ2h0YXJyb3c6XCLih5tcIixyc2FxdW86XCLigLpcIixyc2NyOlwi8J2Th1wiLFJzY3I6XCLihJtcIixyc2g6XCLihrFcIixSc2g6XCLihrFcIixyc3FiOlwiXVwiLHJzcXVvOlwi4oCZXCIscnNxdW9yOlwi4oCZXCIscnRocmVlOlwi4ouMXCIscnRpbWVzOlwi4ouKXCIscnRyaTpcIuKWuVwiLHJ0cmllOlwi4oq1XCIscnRyaWY6XCLilrhcIixydHJpbHRyaTpcIuKnjlwiLFJ1bGVEZWxheWVkOlwi4qe0XCIscnVsdWhhcjpcIuKlqFwiLHJ4Olwi4oSeXCIsU2FjdXRlOlwixZpcIixzYWN1dGU6XCLFm1wiLHNicXVvOlwi4oCaXCIsc2NhcDpcIuKquFwiLFNjYXJvbjpcIsWgXCIsc2Nhcm9uOlwixaFcIixTYzpcIuKqvFwiLHNjOlwi4om7XCIsc2NjdWU6XCLiib1cIixzY2U6XCLiqrBcIixzY0U6XCLiqrRcIixTY2VkaWw6XCLFnlwiLHNjZWRpbDpcIsWfXCIsU2NpcmM6XCLFnFwiLHNjaXJjOlwixZ1cIixzY25hcDpcIuKqulwiLHNjbkU6XCLiqrZcIixzY25zaW06XCLii6lcIixzY3BvbGludDpcIuKok1wiLHNjc2ltOlwi4om/XCIsU2N5Olwi0KFcIixzY3k6XCLRgVwiLHNkb3RiOlwi4oqhXCIsc2RvdDpcIuKLhVwiLHNkb3RlOlwi4qmmXCIsc2VhcmhrOlwi4qSlXCIsc2VhcnI6XCLihphcIixzZUFycjpcIuKHmFwiLHNlYXJyb3c6XCLihphcIixzZWN0OlwiwqdcIixzZW1pOlwiO1wiLHNlc3dhcjpcIuKkqVwiLHNldG1pbnVzOlwi4oiWXCIsc2V0bW46XCLiiJZcIixzZXh0Olwi4py2XCIsU2ZyOlwi8J2UllwiLHNmcjpcIvCdlLBcIixzZnJvd246XCLijKJcIixzaGFycDpcIuKZr1wiLFNIQ0hjeTpcItCpXCIsc2hjaGN5Olwi0YlcIixTSGN5Olwi0KhcIixzaGN5Olwi0YhcIixTaG9ydERvd25BcnJvdzpcIuKGk1wiLFNob3J0TGVmdEFycm93Olwi4oaQXCIsc2hvcnRtaWQ6XCLiiKNcIixzaG9ydHBhcmFsbGVsOlwi4oilXCIsU2hvcnRSaWdodEFycm93Olwi4oaSXCIsU2hvcnRVcEFycm93Olwi4oaRXCIsc2h5Olwiwq1cIixTaWdtYTpcIs6jXCIsc2lnbWE6XCLPg1wiLHNpZ21hZjpcIs+CXCIsc2lnbWF2Olwiz4JcIixzaW06XCLiiLxcIixzaW1kb3Q6XCLiqapcIixzaW1lOlwi4omDXCIsc2ltZXE6XCLiiYNcIixzaW1nOlwi4qqeXCIsc2ltZ0U6XCLiqqBcIixzaW1sOlwi4qqdXCIsc2ltbEU6XCLiqp9cIixzaW1uZTpcIuKJhlwiLHNpbXBsdXM6XCLiqKRcIixzaW1yYXJyOlwi4qWyXCIsc2xhcnI6XCLihpBcIixTbWFsbENpcmNsZTpcIuKImFwiLHNtYWxsc2V0bWludXM6XCLiiJZcIixzbWFzaHA6XCLiqLNcIixzbWVwYXJzbDpcIuKnpFwiLHNtaWQ6XCLiiKNcIixzbWlsZTpcIuKMo1wiLHNtdDpcIuKqqlwiLHNtdGU6XCLiqqxcIixzbXRlczpcIuKqrO+4gFwiLFNPRlRjeTpcItCsXCIsc29mdGN5Olwi0YxcIixzb2xiYXI6XCLijL9cIixzb2xiOlwi4qeEXCIsc29sOlwiL1wiLFNvcGY6XCLwnZWKXCIsc29wZjpcIvCdlaRcIixzcGFkZXM6XCLimaBcIixzcGFkZXN1aXQ6XCLimaBcIixzcGFyOlwi4oilXCIsc3FjYXA6XCLiipNcIixzcWNhcHM6XCLiipPvuIBcIixzcWN1cDpcIuKKlFwiLHNxY3VwczpcIuKKlO+4gFwiLFNxcnQ6XCLiiJpcIixzcXN1YjpcIuKKj1wiLHNxc3ViZTpcIuKKkVwiLHNxc3Vic2V0Olwi4oqPXCIsc3FzdWJzZXRlcTpcIuKKkVwiLHNxc3VwOlwi4oqQXCIsc3FzdXBlOlwi4oqSXCIsc3FzdXBzZXQ6XCLiipBcIixzcXN1cHNldGVxOlwi4oqSXCIsc3F1YXJlOlwi4pahXCIsU3F1YXJlOlwi4pahXCIsU3F1YXJlSW50ZXJzZWN0aW9uOlwi4oqTXCIsU3F1YXJlU3Vic2V0Olwi4oqPXCIsU3F1YXJlU3Vic2V0RXF1YWw6XCLiipFcIixTcXVhcmVTdXBlcnNldDpcIuKKkFwiLFNxdWFyZVN1cGVyc2V0RXF1YWw6XCLiipJcIixTcXVhcmVVbmlvbjpcIuKKlFwiLHNxdWFyZjpcIuKWqlwiLHNxdTpcIuKWoVwiLHNxdWY6XCLilqpcIixzcmFycjpcIuKGklwiLFNzY3I6XCLwnZKuXCIsc3NjcjpcIvCdk4hcIixzc2V0bW46XCLiiJZcIixzc21pbGU6XCLijKNcIixzc3RhcmY6XCLii4ZcIixTdGFyOlwi4ouGXCIsc3RhcjpcIuKYhlwiLHN0YXJmOlwi4piFXCIsc3RyYWlnaHRlcHNpbG9uOlwiz7VcIixzdHJhaWdodHBoaTpcIs+VXCIsc3RybnM6XCLCr1wiLHN1YjpcIuKKglwiLFN1YjpcIuKLkFwiLHN1YmRvdDpcIuKqvVwiLHN1YkU6XCLiq4VcIixzdWJlOlwi4oqGXCIsc3ViZWRvdDpcIuKrg1wiLHN1Ym11bHQ6XCLiq4FcIixzdWJuRTpcIuKri1wiLHN1Ym5lOlwi4oqKXCIsc3VicGx1czpcIuKqv1wiLHN1YnJhcnI6XCLipblcIixzdWJzZXQ6XCLiioJcIixTdWJzZXQ6XCLii5BcIixzdWJzZXRlcTpcIuKKhlwiLHN1YnNldGVxcTpcIuKrhVwiLFN1YnNldEVxdWFsOlwi4oqGXCIsc3Vic2V0bmVxOlwi4oqKXCIsc3Vic2V0bmVxcTpcIuKri1wiLHN1YnNpbTpcIuKrh1wiLHN1YnN1YjpcIuKrlVwiLHN1YnN1cDpcIuKrk1wiLHN1Y2NhcHByb3g6XCLiqrhcIixzdWNjOlwi4om7XCIsc3VjY2N1cmx5ZXE6XCLiib1cIixTdWNjZWVkczpcIuKJu1wiLFN1Y2NlZWRzRXF1YWw6XCLiqrBcIixTdWNjZWVkc1NsYW50RXF1YWw6XCLiib1cIixTdWNjZWVkc1RpbGRlOlwi4om/XCIsc3VjY2VxOlwi4qqwXCIsc3VjY25hcHByb3g6XCLiqrpcIixzdWNjbmVxcTpcIuKqtlwiLHN1Y2Nuc2ltOlwi4oupXCIsc3VjY3NpbTpcIuKJv1wiLFN1Y2hUaGF0Olwi4oiLXCIsc3VtOlwi4oiRXCIsU3VtOlwi4oiRXCIsc3VuZzpcIuKZqlwiLHN1cDE6XCLCuVwiLHN1cDI6XCLCslwiLHN1cDM6XCLCs1wiLHN1cDpcIuKKg1wiLFN1cDpcIuKLkVwiLHN1cGRvdDpcIuKqvlwiLHN1cGRzdWI6XCLiq5hcIixzdXBFOlwi4quGXCIsc3VwZTpcIuKKh1wiLHN1cGVkb3Q6XCLiq4RcIixTdXBlcnNldDpcIuKKg1wiLFN1cGVyc2V0RXF1YWw6XCLiiodcIixzdXBoc29sOlwi4p+JXCIsc3VwaHN1YjpcIuKrl1wiLHN1cGxhcnI6XCLipbtcIixzdXBtdWx0Olwi4quCXCIsc3VwbkU6XCLiq4xcIixzdXBuZTpcIuKKi1wiLHN1cHBsdXM6XCLiq4BcIixzdXBzZXQ6XCLiioNcIixTdXBzZXQ6XCLii5FcIixzdXBzZXRlcTpcIuKKh1wiLHN1cHNldGVxcTpcIuKrhlwiLHN1cHNldG5lcTpcIuKKi1wiLHN1cHNldG5lcXE6XCLiq4xcIixzdXBzaW06XCLiq4hcIixzdXBzdWI6XCLiq5RcIixzdXBzdXA6XCLiq5ZcIixzd2FyaGs6XCLipKZcIixzd2FycjpcIuKGmVwiLHN3QXJyOlwi4oeZXCIsc3dhcnJvdzpcIuKGmVwiLHN3bndhcjpcIuKkqlwiLHN6bGlnOlwiw59cIixUYWI6XCJcXHRcIix0YXJnZXQ6XCLijJZcIixUYXU6XCLOpFwiLHRhdTpcIs+EXCIsdGJyazpcIuKOtFwiLFRjYXJvbjpcIsWkXCIsdGNhcm9uOlwixaVcIixUY2VkaWw6XCLFolwiLHRjZWRpbDpcIsWjXCIsVGN5Olwi0KJcIix0Y3k6XCLRglwiLHRkb3Q6XCLig5tcIix0ZWxyZWM6XCLijJVcIixUZnI6XCLwnZSXXCIsdGZyOlwi8J2UsVwiLHRoZXJlNDpcIuKItFwiLHRoZXJlZm9yZTpcIuKItFwiLFRoZXJlZm9yZTpcIuKItFwiLFRoZXRhOlwizphcIix0aGV0YTpcIs64XCIsdGhldGFzeW06XCLPkVwiLHRoZXRhdjpcIs+RXCIsdGhpY2thcHByb3g6XCLiiYhcIix0aGlja3NpbTpcIuKIvFwiLFRoaWNrU3BhY2U6XCLigZ/igIpcIixUaGluU3BhY2U6XCLigIlcIix0aGluc3A6XCLigIlcIix0aGthcDpcIuKJiFwiLHRoa3NpbTpcIuKIvFwiLFRIT1JOOlwiw55cIix0aG9ybjpcIsO+XCIsdGlsZGU6XCLLnFwiLFRpbGRlOlwi4oi8XCIsVGlsZGVFcXVhbDpcIuKJg1wiLFRpbGRlRnVsbEVxdWFsOlwi4omFXCIsVGlsZGVUaWxkZTpcIuKJiFwiLHRpbWVzYmFyOlwi4qixXCIsdGltZXNiOlwi4oqgXCIsdGltZXM6XCLDl1wiLHRpbWVzZDpcIuKosFwiLHRpbnQ6XCLiiK1cIix0b2VhOlwi4qSoXCIsdG9wYm90Olwi4oy2XCIsdG9wY2lyOlwi4quxXCIsdG9wOlwi4oqkXCIsVG9wZjpcIvCdlYtcIix0b3BmOlwi8J2VpVwiLHRvcGZvcms6XCLiq5pcIix0b3NhOlwi4qSpXCIsdHByaW1lOlwi4oC0XCIsdHJhZGU6XCLihKJcIixUUkFERTpcIuKEolwiLHRyaWFuZ2xlOlwi4pa1XCIsdHJpYW5nbGVkb3duOlwi4pa/XCIsdHJpYW5nbGVsZWZ0Olwi4peDXCIsdHJpYW5nbGVsZWZ0ZXE6XCLiirRcIix0cmlhbmdsZXE6XCLiiZxcIix0cmlhbmdsZXJpZ2h0Olwi4pa5XCIsdHJpYW5nbGVyaWdodGVxOlwi4oq1XCIsdHJpZG90Olwi4pesXCIsdHJpZTpcIuKJnFwiLHRyaW1pbnVzOlwi4qi6XCIsVHJpcGxlRG90Olwi4oObXCIsdHJpcGx1czpcIuKouVwiLHRyaXNiOlwi4qeNXCIsdHJpdGltZTpcIuKou1wiLHRycGV6aXVtOlwi4o+iXCIsVHNjcjpcIvCdkq9cIix0c2NyOlwi8J2TiVwiLFRTY3k6XCLQplwiLHRzY3k6XCLRhlwiLFRTSGN5Olwi0ItcIix0c2hjeTpcItGbXCIsVHN0cm9rOlwixaZcIix0c3Ryb2s6XCLFp1wiLHR3aXh0Olwi4omsXCIsdHdvaGVhZGxlZnRhcnJvdzpcIuKGnlwiLHR3b2hlYWRyaWdodGFycm93Olwi4oagXCIsVWFjdXRlOlwiw5pcIix1YWN1dGU6XCLDulwiLHVhcnI6XCLihpFcIixVYXJyOlwi4oafXCIsdUFycjpcIuKHkVwiLFVhcnJvY2lyOlwi4qWJXCIsVWJyY3k6XCLQjlwiLHVicmN5Olwi0Z5cIixVYnJldmU6XCLFrFwiLHVicmV2ZTpcIsWtXCIsVWNpcmM6XCLDm1wiLHVjaXJjOlwiw7tcIixVY3k6XCLQo1wiLHVjeTpcItGDXCIsdWRhcnI6XCLih4VcIixVZGJsYWM6XCLFsFwiLHVkYmxhYzpcIsWxXCIsdWRoYXI6XCLipa5cIix1ZmlzaHQ6XCLipb5cIixVZnI6XCLwnZSYXCIsdWZyOlwi8J2UslwiLFVncmF2ZTpcIsOZXCIsdWdyYXZlOlwiw7lcIix1SGFyOlwi4qWjXCIsdWhhcmw6XCLihr9cIix1aGFycjpcIuKGvlwiLHVoYmxrOlwi4paAXCIsdWxjb3JuOlwi4oycXCIsdWxjb3JuZXI6XCLijJxcIix1bGNyb3A6XCLijI9cIix1bHRyaTpcIuKXuFwiLFVtYWNyOlwixapcIix1bWFjcjpcIsWrXCIsdW1sOlwiwqhcIixVbmRlckJhcjpcIl9cIixVbmRlckJyYWNlOlwi4o+fXCIsVW5kZXJCcmFja2V0Olwi4o61XCIsVW5kZXJQYXJlbnRoZXNpczpcIuKPnVwiLFVuaW9uOlwi4ouDXCIsVW5pb25QbHVzOlwi4oqOXCIsVW9nb246XCLFslwiLHVvZ29uOlwixbNcIixVb3BmOlwi8J2VjFwiLHVvcGY6XCLwnZWmXCIsVXBBcnJvd0JhcjpcIuKkklwiLHVwYXJyb3c6XCLihpFcIixVcEFycm93Olwi4oaRXCIsVXBhcnJvdzpcIuKHkVwiLFVwQXJyb3dEb3duQXJyb3c6XCLih4VcIix1cGRvd25hcnJvdzpcIuKGlVwiLFVwRG93bkFycm93Olwi4oaVXCIsVXBkb3duYXJyb3c6XCLih5VcIixVcEVxdWlsaWJyaXVtOlwi4qWuXCIsdXBoYXJwb29ubGVmdDpcIuKGv1wiLHVwaGFycG9vbnJpZ2h0Olwi4oa+XCIsdXBsdXM6XCLiio5cIixVcHBlckxlZnRBcnJvdzpcIuKGllwiLFVwcGVyUmlnaHRBcnJvdzpcIuKGl1wiLHVwc2k6XCLPhVwiLFVwc2k6XCLPklwiLHVwc2loOlwiz5JcIixVcHNpbG9uOlwizqVcIix1cHNpbG9uOlwiz4VcIixVcFRlZUFycm93Olwi4oalXCIsVXBUZWU6XCLiiqVcIix1cHVwYXJyb3dzOlwi4oeIXCIsdXJjb3JuOlwi4oydXCIsdXJjb3JuZXI6XCLijJ1cIix1cmNyb3A6XCLijI5cIixVcmluZzpcIsWuXCIsdXJpbmc6XCLFr1wiLHVydHJpOlwi4pe5XCIsVXNjcjpcIvCdkrBcIix1c2NyOlwi8J2TilwiLHV0ZG90Olwi4ouwXCIsVXRpbGRlOlwixahcIix1dGlsZGU6XCLFqVwiLHV0cmk6XCLilrVcIix1dHJpZjpcIuKWtFwiLHV1YXJyOlwi4oeIXCIsVXVtbDpcIsOcXCIsdXVtbDpcIsO8XCIsdXdhbmdsZTpcIuKmp1wiLHZhbmdydDpcIuKmnFwiLHZhcmVwc2lsb246XCLPtVwiLHZhcmthcHBhOlwiz7BcIix2YXJub3RoaW5nOlwi4oiFXCIsdmFycGhpOlwiz5VcIix2YXJwaTpcIs+WXCIsdmFycHJvcHRvOlwi4oidXCIsdmFycjpcIuKGlVwiLHZBcnI6XCLih5VcIix2YXJyaG86XCLPsVwiLHZhcnNpZ21hOlwiz4JcIix2YXJzdWJzZXRuZXE6XCLiiorvuIBcIix2YXJzdWJzZXRuZXFxOlwi4quL77iAXCIsdmFyc3Vwc2V0bmVxOlwi4oqL77iAXCIsdmFyc3Vwc2V0bmVxcTpcIuKrjO+4gFwiLHZhcnRoZXRhOlwiz5FcIix2YXJ0cmlhbmdsZWxlZnQ6XCLiirJcIix2YXJ0cmlhbmdsZXJpZ2h0Olwi4oqzXCIsdkJhcjpcIuKrqFwiLFZiYXI6XCLiq6tcIix2QmFydjpcIuKrqVwiLFZjeTpcItCSXCIsdmN5Olwi0LJcIix2ZGFzaDpcIuKKolwiLHZEYXNoOlwi4oqoXCIsVmRhc2g6XCLiiqlcIixWRGFzaDpcIuKKq1wiLFZkYXNobDpcIuKrplwiLHZlZWJhcjpcIuKKu1wiLHZlZTpcIuKIqFwiLFZlZTpcIuKLgVwiLHZlZWVxOlwi4omaXCIsdmVsbGlwOlwi4ouuXCIsdmVyYmFyOlwifFwiLFZlcmJhcjpcIuKAllwiLHZlcnQ6XCJ8XCIsVmVydDpcIuKAllwiLFZlcnRpY2FsQmFyOlwi4oijXCIsVmVydGljYWxMaW5lOlwifFwiLFZlcnRpY2FsU2VwYXJhdG9yOlwi4p2YXCIsVmVydGljYWxUaWxkZTpcIuKJgFwiLFZlcnlUaGluU3BhY2U6XCLigIpcIixWZnI6XCLwnZSZXCIsdmZyOlwi8J2Us1wiLHZsdHJpOlwi4oqyXCIsdm5zdWI6XCLiioLig5JcIix2bnN1cDpcIuKKg+KDklwiLFZvcGY6XCLwnZWNXCIsdm9wZjpcIvCdladcIix2cHJvcDpcIuKInVwiLHZydHJpOlwi4oqzXCIsVnNjcjpcIvCdkrFcIix2c2NyOlwi8J2Ti1wiLHZzdWJuRTpcIuKri++4gFwiLHZzdWJuZTpcIuKKiu+4gFwiLHZzdXBuRTpcIuKrjO+4gFwiLHZzdXBuZTpcIuKKi++4gFwiLFZ2ZGFzaDpcIuKKqlwiLHZ6aWd6YWc6XCLipppcIixXY2lyYzpcIsW0XCIsd2NpcmM6XCLFtVwiLHdlZGJhcjpcIuKpn1wiLHdlZGdlOlwi4oinXCIsV2VkZ2U6XCLii4BcIix3ZWRnZXE6XCLiiZlcIix3ZWllcnA6XCLihJhcIixXZnI6XCLwnZSaXCIsd2ZyOlwi8J2UtFwiLFdvcGY6XCLwnZWOXCIsd29wZjpcIvCdlahcIix3cDpcIuKEmFwiLHdyOlwi4omAXCIsd3JlYXRoOlwi4omAXCIsV3NjcjpcIvCdkrJcIix3c2NyOlwi8J2TjFwiLHhjYXA6XCLii4JcIix4Y2lyYzpcIuKXr1wiLHhjdXA6XCLii4NcIix4ZHRyaTpcIuKWvVwiLFhmcjpcIvCdlJtcIix4ZnI6XCLwnZS1XCIseGhhcnI6XCLin7dcIix4aEFycjpcIuKfulwiLFhpOlwizp5cIix4aTpcIs6+XCIseGxhcnI6XCLin7VcIix4bEFycjpcIuKfuFwiLHhtYXA6XCLin7xcIix4bmlzOlwi4ou7XCIseG9kb3Q6XCLiqIBcIixYb3BmOlwi8J2Vj1wiLHhvcGY6XCLwnZWpXCIseG9wbHVzOlwi4qiBXCIseG90aW1lOlwi4qiCXCIseHJhcnI6XCLin7ZcIix4ckFycjpcIuKfuVwiLFhzY3I6XCLwnZKzXCIseHNjcjpcIvCdk41cIix4c3FjdXA6XCLiqIZcIix4dXBsdXM6XCLiqIRcIix4dXRyaTpcIuKWs1wiLHh2ZWU6XCLii4FcIix4d2VkZ2U6XCLii4BcIixZYWN1dGU6XCLDnVwiLHlhY3V0ZTpcIsO9XCIsWUFjeTpcItCvXCIseWFjeTpcItGPXCIsWWNpcmM6XCLFtlwiLHljaXJjOlwixbdcIixZY3k6XCLQq1wiLHljeTpcItGLXCIseWVuOlwiwqVcIixZZnI6XCLwnZScXCIseWZyOlwi8J2UtlwiLFlJY3k6XCLQh1wiLHlpY3k6XCLRl1wiLFlvcGY6XCLwnZWQXCIseW9wZjpcIvCdlapcIixZc2NyOlwi8J2StFwiLHlzY3I6XCLwnZOOXCIsWVVjeTpcItCuXCIseXVjeTpcItGOXCIseXVtbDpcIsO/XCIsWXVtbDpcIsW4XCIsWmFjdXRlOlwixblcIix6YWN1dGU6XCLFulwiLFpjYXJvbjpcIsW9XCIsemNhcm9uOlwixb5cIixaY3k6XCLQl1wiLHpjeTpcItC3XCIsWmRvdDpcIsW7XCIsemRvdDpcIsW8XCIsemVldHJmOlwi4oSoXCIsWmVyb1dpZHRoU3BhY2U6XCLigItcIixaZXRhOlwizpZcIix6ZXRhOlwizrZcIix6ZnI6XCLwnZS3XCIsWmZyOlwi4oSoXCIsWkhjeTpcItCWXCIsemhjeTpcItC2XCIsemlncmFycjpcIuKHnVwiLHpvcGY6XCLwnZWrXCIsWm9wZjpcIuKEpFwiLFpzY3I6XCLwnZK1XCIsenNjcjpcIvCdk49cIix6d2o6XCLigI1cIix6d25qOlwi4oCMXCJ9fSx7fV0sMjY6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe21vZHVsZS5leHBvcnRzPXtBYWN1dGU6XCLDgVwiLGFhY3V0ZTpcIsOhXCIsQWNpcmM6XCLDglwiLGFjaXJjOlwiw6JcIixhY3V0ZTpcIsK0XCIsQUVsaWc6XCLDhlwiLGFlbGlnOlwiw6ZcIixBZ3JhdmU6XCLDgFwiLGFncmF2ZTpcIsOgXCIsYW1wOlwiJlwiLEFNUDpcIiZcIixBcmluZzpcIsOFXCIsYXJpbmc6XCLDpVwiLEF0aWxkZTpcIsODXCIsYXRpbGRlOlwiw6NcIixBdW1sOlwiw4RcIixhdW1sOlwiw6RcIixicnZiYXI6XCLCplwiLENjZWRpbDpcIsOHXCIsY2NlZGlsOlwiw6dcIixjZWRpbDpcIsK4XCIsY2VudDpcIsKiXCIsY29weTpcIsKpXCIsQ09QWTpcIsKpXCIsY3VycmVuOlwiwqRcIixkZWc6XCLCsFwiLGRpdmlkZTpcIsO3XCIsRWFjdXRlOlwiw4lcIixlYWN1dGU6XCLDqVwiLEVjaXJjOlwiw4pcIixlY2lyYzpcIsOqXCIsRWdyYXZlOlwiw4hcIixlZ3JhdmU6XCLDqFwiLEVUSDpcIsOQXCIsZXRoOlwiw7BcIixFdW1sOlwiw4tcIixldW1sOlwiw6tcIixmcmFjMTI6XCLCvVwiLGZyYWMxNDpcIsK8XCIsZnJhYzM0Olwiwr5cIixndDpcIj5cIixHVDpcIj5cIixJYWN1dGU6XCLDjVwiLGlhY3V0ZTpcIsOtXCIsSWNpcmM6XCLDjlwiLGljaXJjOlwiw65cIixpZXhjbDpcIsKhXCIsSWdyYXZlOlwiw4xcIixpZ3JhdmU6XCLDrFwiLGlxdWVzdDpcIsK/XCIsSXVtbDpcIsOPXCIsaXVtbDpcIsOvXCIsbGFxdW86XCLCq1wiLGx0OlwiPFwiLExUOlwiPFwiLG1hY3I6XCLCr1wiLG1pY3JvOlwiwrVcIixtaWRkb3Q6XCLCt1wiLG5ic3A6XCLCoFwiLG5vdDpcIsKsXCIsTnRpbGRlOlwiw5FcIixudGlsZGU6XCLDsVwiLE9hY3V0ZTpcIsOTXCIsb2FjdXRlOlwiw7NcIixPY2lyYzpcIsOUXCIsb2NpcmM6XCLDtFwiLE9ncmF2ZTpcIsOSXCIsb2dyYXZlOlwiw7JcIixvcmRmOlwiwqpcIixvcmRtOlwiwrpcIixPc2xhc2g6XCLDmFwiLG9zbGFzaDpcIsO4XCIsT3RpbGRlOlwiw5VcIixvdGlsZGU6XCLDtVwiLE91bWw6XCLDllwiLG91bWw6XCLDtlwiLHBhcmE6XCLCtlwiLHBsdXNtbjpcIsKxXCIscG91bmQ6XCLCo1wiLHF1b3Q6J1wiJyxRVU9UOidcIicscmFxdW86XCLCu1wiLHJlZzpcIsKuXCIsUkVHOlwiwq5cIixzZWN0OlwiwqdcIixzaHk6XCLCrVwiLHN1cDE6XCLCuVwiLHN1cDI6XCLCslwiLHN1cDM6XCLCs1wiLHN6bGlnOlwiw59cIixUSE9STjpcIsOeXCIsdGhvcm46XCLDvlwiLHRpbWVzOlwiw5dcIixVYWN1dGU6XCLDmlwiLHVhY3V0ZTpcIsO6XCIsVWNpcmM6XCLDm1wiLHVjaXJjOlwiw7tcIixVZ3JhdmU6XCLDmVwiLHVncmF2ZTpcIsO5XCIsdW1sOlwiwqhcIixVdW1sOlwiw5xcIix1dW1sOlwiw7xcIixZYWN1dGU6XCLDnVwiLHlhY3V0ZTpcIsO9XCIseWVuOlwiwqVcIix5dW1sOlwiw79cIn19LHt9XSwyNzpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9e2FtcDpcIiZcIixhcG9zOlwiJ1wiLGd0OlwiPlwiLGx0OlwiPFwiLHF1b3Q6J1wiJ319LHt9XSwyODpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7ZnVuY3Rpb24gRXZlbnRFbWl0dGVyKCl7dGhpcy5fZXZlbnRzPXRoaXMuX2V2ZW50c3x8e307dGhpcy5fbWF4TGlzdGVuZXJzPXRoaXMuX21heExpc3RlbmVyc3x8dW5kZWZpbmVkfW1vZHVsZS5leHBvcnRzPUV2ZW50RW1pdHRlcjtFdmVudEVtaXR0ZXIuRXZlbnRFbWl0dGVyPUV2ZW50RW1pdHRlcjtFdmVudEVtaXR0ZXIucHJvdG90eXBlLl9ldmVudHM9dW5kZWZpbmVkO0V2ZW50RW1pdHRlci5wcm90b3R5cGUuX21heExpc3RlbmVycz11bmRlZmluZWQ7RXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnM9MTA7RXZlbnRFbWl0dGVyLnByb3RvdHlwZS5zZXRNYXhMaXN0ZW5lcnM9ZnVuY3Rpb24obil7aWYoIWlzTnVtYmVyKG4pfHxuPDB8fGlzTmFOKG4pKXRocm93IFR5cGVFcnJvcihcIm4gbXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlclwiKTt0aGlzLl9tYXhMaXN0ZW5lcnM9bjtyZXR1cm4gdGhpc307RXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0PWZ1bmN0aW9uKHR5cGUpe3ZhciBlcixoYW5kbGVyLGxlbixhcmdzLGksbGlzdGVuZXJzO2lmKCF0aGlzLl9ldmVudHMpdGhpcy5fZXZlbnRzPXt9O2lmKHR5cGU9PT1cImVycm9yXCIpe2lmKCF0aGlzLl9ldmVudHMuZXJyb3J8fGlzT2JqZWN0KHRoaXMuX2V2ZW50cy5lcnJvcikmJiF0aGlzLl9ldmVudHMuZXJyb3IubGVuZ3RoKXtlcj1hcmd1bWVudHNbMV07aWYoZXIgaW5zdGFuY2VvZiBFcnJvcil7dGhyb3cgZXJ9ZWxzZXt2YXIgZXJyPW5ldyBFcnJvcignVW5jYXVnaHQsIHVuc3BlY2lmaWVkIFwiZXJyb3JcIiBldmVudC4gKCcrZXIrXCIpXCIpO2Vyci5jb250ZXh0PWVyO3Rocm93IGVycn19fWhhbmRsZXI9dGhpcy5fZXZlbnRzW3R5cGVdO2lmKGlzVW5kZWZpbmVkKGhhbmRsZXIpKXJldHVybiBmYWxzZTtpZihpc0Z1bmN0aW9uKGhhbmRsZXIpKXtzd2l0Y2goYXJndW1lbnRzLmxlbmd0aCl7Y2FzZSAxOmhhbmRsZXIuY2FsbCh0aGlzKTticmVhaztjYXNlIDI6aGFuZGxlci5jYWxsKHRoaXMsYXJndW1lbnRzWzFdKTticmVhaztjYXNlIDM6aGFuZGxlci5jYWxsKHRoaXMsYXJndW1lbnRzWzFdLGFyZ3VtZW50c1syXSk7YnJlYWs7ZGVmYXVsdDphcmdzPUFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywxKTtoYW5kbGVyLmFwcGx5KHRoaXMsYXJncyl9fWVsc2UgaWYoaXNPYmplY3QoaGFuZGxlcikpe2FyZ3M9QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLDEpO2xpc3RlbmVycz1oYW5kbGVyLnNsaWNlKCk7bGVuPWxpc3RlbmVycy5sZW5ndGg7Zm9yKGk9MDtpPGxlbjtpKyspbGlzdGVuZXJzW2ldLmFwcGx5KHRoaXMsYXJncyl9cmV0dXJuIHRydWV9O0V2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXI9ZnVuY3Rpb24odHlwZSxsaXN0ZW5lcil7dmFyIG07aWYoIWlzRnVuY3Rpb24obGlzdGVuZXIpKXRocm93IFR5cGVFcnJvcihcImxpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvblwiKTtpZighdGhpcy5fZXZlbnRzKXRoaXMuX2V2ZW50cz17fTtpZih0aGlzLl9ldmVudHMubmV3TGlzdGVuZXIpdGhpcy5lbWl0KFwibmV3TGlzdGVuZXJcIix0eXBlLGlzRnVuY3Rpb24obGlzdGVuZXIubGlzdGVuZXIpP2xpc3RlbmVyLmxpc3RlbmVyOmxpc3RlbmVyKTtpZighdGhpcy5fZXZlbnRzW3R5cGVdKXRoaXMuX2V2ZW50c1t0eXBlXT1saXN0ZW5lcjtlbHNlIGlmKGlzT2JqZWN0KHRoaXMuX2V2ZW50c1t0eXBlXSkpdGhpcy5fZXZlbnRzW3R5cGVdLnB1c2gobGlzdGVuZXIpO2Vsc2UgdGhpcy5fZXZlbnRzW3R5cGVdPVt0aGlzLl9ldmVudHNbdHlwZV0sbGlzdGVuZXJdO2lmKGlzT2JqZWN0KHRoaXMuX2V2ZW50c1t0eXBlXSkmJiF0aGlzLl9ldmVudHNbdHlwZV0ud2FybmVkKXtpZighaXNVbmRlZmluZWQodGhpcy5fbWF4TGlzdGVuZXJzKSl7bT10aGlzLl9tYXhMaXN0ZW5lcnN9ZWxzZXttPUV2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzfWlmKG0mJm0+MCYmdGhpcy5fZXZlbnRzW3R5cGVdLmxlbmd0aD5tKXt0aGlzLl9ldmVudHNbdHlwZV0ud2FybmVkPXRydWU7Y29uc29sZS5lcnJvcihcIihub2RlKSB3YXJuaW5nOiBwb3NzaWJsZSBFdmVudEVtaXR0ZXIgbWVtb3J5IFwiK1wibGVhayBkZXRlY3RlZC4gJWQgbGlzdGVuZXJzIGFkZGVkLiBcIitcIlVzZSBlbWl0dGVyLnNldE1heExpc3RlbmVycygpIHRvIGluY3JlYXNlIGxpbWl0LlwiLHRoaXMuX2V2ZW50c1t0eXBlXS5sZW5ndGgpO2lmKHR5cGVvZiBjb25zb2xlLnRyYWNlPT09XCJmdW5jdGlvblwiKXtjb25zb2xlLnRyYWNlKCl9fX1yZXR1cm4gdGhpc307RXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbj1FdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyO0V2ZW50RW1pdHRlci5wcm90b3R5cGUub25jZT1mdW5jdGlvbih0eXBlLGxpc3RlbmVyKXtpZighaXNGdW5jdGlvbihsaXN0ZW5lcikpdGhyb3cgVHlwZUVycm9yKFwibGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uXCIpO3ZhciBmaXJlZD1mYWxzZTtmdW5jdGlvbiBnKCl7dGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLGcpO2lmKCFmaXJlZCl7ZmlyZWQ9dHJ1ZTtsaXN0ZW5lci5hcHBseSh0aGlzLGFyZ3VtZW50cyl9fWcubGlzdGVuZXI9bGlzdGVuZXI7dGhpcy5vbih0eXBlLGcpO3JldHVybiB0aGlzfTtFdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyPWZ1bmN0aW9uKHR5cGUsbGlzdGVuZXIpe3ZhciBsaXN0LHBvc2l0aW9uLGxlbmd0aCxpO2lmKCFpc0Z1bmN0aW9uKGxpc3RlbmVyKSl0aHJvdyBUeXBlRXJyb3IoXCJsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb25cIik7aWYoIXRoaXMuX2V2ZW50c3x8IXRoaXMuX2V2ZW50c1t0eXBlXSlyZXR1cm4gdGhpcztsaXN0PXRoaXMuX2V2ZW50c1t0eXBlXTtsZW5ndGg9bGlzdC5sZW5ndGg7cG9zaXRpb249LTE7aWYobGlzdD09PWxpc3RlbmVyfHxpc0Z1bmN0aW9uKGxpc3QubGlzdGVuZXIpJiZsaXN0Lmxpc3RlbmVyPT09bGlzdGVuZXIpe2RlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07aWYodGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKXRoaXMuZW1pdChcInJlbW92ZUxpc3RlbmVyXCIsdHlwZSxsaXN0ZW5lcil9ZWxzZSBpZihpc09iamVjdChsaXN0KSl7Zm9yKGk9bGVuZ3RoO2ktLSA+MDspe2lmKGxpc3RbaV09PT1saXN0ZW5lcnx8bGlzdFtpXS5saXN0ZW5lciYmbGlzdFtpXS5saXN0ZW5lcj09PWxpc3RlbmVyKXtwb3NpdGlvbj1pO2JyZWFrfX1pZihwb3NpdGlvbjwwKXJldHVybiB0aGlzO2lmKGxpc3QubGVuZ3RoPT09MSl7bGlzdC5sZW5ndGg9MDtkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdfWVsc2V7bGlzdC5zcGxpY2UocG9zaXRpb24sMSk7XG59aWYodGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKXRoaXMuZW1pdChcInJlbW92ZUxpc3RlbmVyXCIsdHlwZSxsaXN0ZW5lcil9cmV0dXJuIHRoaXN9O0V2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlQWxsTGlzdGVuZXJzPWZ1bmN0aW9uKHR5cGUpe3ZhciBrZXksbGlzdGVuZXJzO2lmKCF0aGlzLl9ldmVudHMpcmV0dXJuIHRoaXM7aWYoIXRoaXMuX2V2ZW50cy5yZW1vdmVMaXN0ZW5lcil7aWYoYXJndW1lbnRzLmxlbmd0aD09PTApdGhpcy5fZXZlbnRzPXt9O2Vsc2UgaWYodGhpcy5fZXZlbnRzW3R5cGVdKWRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07cmV0dXJuIHRoaXN9aWYoYXJndW1lbnRzLmxlbmd0aD09PTApe2ZvcihrZXkgaW4gdGhpcy5fZXZlbnRzKXtpZihrZXk9PT1cInJlbW92ZUxpc3RlbmVyXCIpY29udGludWU7dGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoa2V5KX10aGlzLnJlbW92ZUFsbExpc3RlbmVycyhcInJlbW92ZUxpc3RlbmVyXCIpO3RoaXMuX2V2ZW50cz17fTtyZXR1cm4gdGhpc31saXN0ZW5lcnM9dGhpcy5fZXZlbnRzW3R5cGVdO2lmKGlzRnVuY3Rpb24obGlzdGVuZXJzKSl7dGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLGxpc3RlbmVycyl9ZWxzZSBpZihsaXN0ZW5lcnMpe3doaWxlKGxpc3RlbmVycy5sZW5ndGgpdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLGxpc3RlbmVyc1tsaXN0ZW5lcnMubGVuZ3RoLTFdKX1kZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO3JldHVybiB0aGlzfTtFdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycz1mdW5jdGlvbih0eXBlKXt2YXIgcmV0O2lmKCF0aGlzLl9ldmVudHN8fCF0aGlzLl9ldmVudHNbdHlwZV0pcmV0PVtdO2Vsc2UgaWYoaXNGdW5jdGlvbih0aGlzLl9ldmVudHNbdHlwZV0pKXJldD1bdGhpcy5fZXZlbnRzW3R5cGVdXTtlbHNlIHJldD10aGlzLl9ldmVudHNbdHlwZV0uc2xpY2UoKTtyZXR1cm4gcmV0fTtFdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVyQ291bnQ9ZnVuY3Rpb24odHlwZSl7aWYodGhpcy5fZXZlbnRzKXt2YXIgZXZsaXN0ZW5lcj10aGlzLl9ldmVudHNbdHlwZV07aWYoaXNGdW5jdGlvbihldmxpc3RlbmVyKSlyZXR1cm4gMTtlbHNlIGlmKGV2bGlzdGVuZXIpcmV0dXJuIGV2bGlzdGVuZXIubGVuZ3RofXJldHVybiAwfTtFdmVudEVtaXR0ZXIubGlzdGVuZXJDb3VudD1mdW5jdGlvbihlbWl0dGVyLHR5cGUpe3JldHVybiBlbWl0dGVyLmxpc3RlbmVyQ291bnQodHlwZSl9O2Z1bmN0aW9uIGlzRnVuY3Rpb24oYXJnKXtyZXR1cm4gdHlwZW9mIGFyZz09PVwiZnVuY3Rpb25cIn1mdW5jdGlvbiBpc051bWJlcihhcmcpe3JldHVybiB0eXBlb2YgYXJnPT09XCJudW1iZXJcIn1mdW5jdGlvbiBpc09iamVjdChhcmcpe3JldHVybiB0eXBlb2YgYXJnPT09XCJvYmplY3RcIiYmYXJnIT09bnVsbH1mdW5jdGlvbiBpc1VuZGVmaW5lZChhcmcpe3JldHVybiBhcmc9PT12b2lkIDB9fSx7fV0sMjk6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe21vZHVsZS5leHBvcnRzPUNvbGxlY3RpbmdIYW5kbGVyO2Z1bmN0aW9uIENvbGxlY3RpbmdIYW5kbGVyKGNicyl7dGhpcy5fY2JzPWNic3x8e307dGhpcy5ldmVudHM9W119dmFyIEVWRU5UUz1yZXF1aXJlKFwiLi9cIikuRVZFTlRTO09iamVjdC5rZXlzKEVWRU5UUykuZm9yRWFjaChmdW5jdGlvbihuYW1lKXtpZihFVkVOVFNbbmFtZV09PT0wKXtuYW1lPVwib25cIituYW1lO0NvbGxlY3RpbmdIYW5kbGVyLnByb3RvdHlwZVtuYW1lXT1mdW5jdGlvbigpe3RoaXMuZXZlbnRzLnB1c2goW25hbWVdKTtpZih0aGlzLl9jYnNbbmFtZV0pdGhpcy5fY2JzW25hbWVdKCl9fWVsc2UgaWYoRVZFTlRTW25hbWVdPT09MSl7bmFtZT1cIm9uXCIrbmFtZTtDb2xsZWN0aW5nSGFuZGxlci5wcm90b3R5cGVbbmFtZV09ZnVuY3Rpb24oYSl7dGhpcy5ldmVudHMucHVzaChbbmFtZSxhXSk7aWYodGhpcy5fY2JzW25hbWVdKXRoaXMuX2Nic1tuYW1lXShhKX19ZWxzZSBpZihFVkVOVFNbbmFtZV09PT0yKXtuYW1lPVwib25cIituYW1lO0NvbGxlY3RpbmdIYW5kbGVyLnByb3RvdHlwZVtuYW1lXT1mdW5jdGlvbihhLGIpe3RoaXMuZXZlbnRzLnB1c2goW25hbWUsYSxiXSk7aWYodGhpcy5fY2JzW25hbWVdKXRoaXMuX2Nic1tuYW1lXShhLGIpfX1lbHNle3Rocm93IEVycm9yKFwid3JvbmcgbnVtYmVyIG9mIGFyZ3VtZW50c1wiKX19KTtDb2xsZWN0aW5nSGFuZGxlci5wcm90b3R5cGUub25yZXNldD1mdW5jdGlvbigpe3RoaXMuZXZlbnRzPVtdO2lmKHRoaXMuX2Nicy5vbnJlc2V0KXRoaXMuX2Nicy5vbnJlc2V0KCl9O0NvbGxlY3RpbmdIYW5kbGVyLnByb3RvdHlwZS5yZXN0YXJ0PWZ1bmN0aW9uKCl7aWYodGhpcy5fY2JzLm9ucmVzZXQpdGhpcy5fY2JzLm9ucmVzZXQoKTtmb3IodmFyIGk9MCxsZW49dGhpcy5ldmVudHMubGVuZ3RoO2k8bGVuO2krKyl7aWYodGhpcy5fY2JzW3RoaXMuZXZlbnRzW2ldWzBdXSl7dmFyIG51bT10aGlzLmV2ZW50c1tpXS5sZW5ndGg7aWYobnVtPT09MSl7dGhpcy5fY2JzW3RoaXMuZXZlbnRzW2ldWzBdXSgpfWVsc2UgaWYobnVtPT09Mil7dGhpcy5fY2JzW3RoaXMuZXZlbnRzW2ldWzBdXSh0aGlzLmV2ZW50c1tpXVsxXSl9ZWxzZXt0aGlzLl9jYnNbdGhpcy5ldmVudHNbaV1bMF1dKHRoaXMuZXZlbnRzW2ldWzFdLHRoaXMuZXZlbnRzW2ldWzJdKX19fX19LHtcIi4vXCI6MzZ9XSwzMDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7dmFyIGluZGV4PXJlcXVpcmUoXCIuL2luZGV4LmpzXCIpLERvbUhhbmRsZXI9aW5kZXguRG9tSGFuZGxlcixEb21VdGlscz1pbmRleC5Eb21VdGlscztmdW5jdGlvbiBGZWVkSGFuZGxlcihjYWxsYmFjayxvcHRpb25zKXt0aGlzLmluaXQoY2FsbGJhY2ssb3B0aW9ucyl9cmVxdWlyZShcImluaGVyaXRzXCIpKEZlZWRIYW5kbGVyLERvbUhhbmRsZXIpO0ZlZWRIYW5kbGVyLnByb3RvdHlwZS5pbml0PURvbUhhbmRsZXI7ZnVuY3Rpb24gZ2V0RWxlbWVudHMod2hhdCx3aGVyZSl7cmV0dXJuIERvbVV0aWxzLmdldEVsZW1lbnRzQnlUYWdOYW1lKHdoYXQsd2hlcmUsdHJ1ZSl9ZnVuY3Rpb24gZ2V0T25lRWxlbWVudCh3aGF0LHdoZXJlKXtyZXR1cm4gRG9tVXRpbHMuZ2V0RWxlbWVudHNCeVRhZ05hbWUod2hhdCx3aGVyZSx0cnVlLDEpWzBdfWZ1bmN0aW9uIGZldGNoKHdoYXQsd2hlcmUscmVjdXJzZSl7cmV0dXJuIERvbVV0aWxzLmdldFRleHQoRG9tVXRpbHMuZ2V0RWxlbWVudHNCeVRhZ05hbWUod2hhdCx3aGVyZSxyZWN1cnNlLDEpKS50cmltKCl9ZnVuY3Rpb24gYWRkQ29uZGl0aW9uYWxseShvYmoscHJvcCx3aGF0LHdoZXJlLHJlY3Vyc2Upe3ZhciB0bXA9ZmV0Y2god2hhdCx3aGVyZSxyZWN1cnNlKTtpZih0bXApb2JqW3Byb3BdPXRtcH12YXIgaXNWYWxpZEZlZWQ9ZnVuY3Rpb24odmFsdWUpe3JldHVybiB2YWx1ZT09PVwicnNzXCJ8fHZhbHVlPT09XCJmZWVkXCJ8fHZhbHVlPT09XCJyZGY6UkRGXCJ9O0ZlZWRIYW5kbGVyLnByb3RvdHlwZS5vbmVuZD1mdW5jdGlvbigpe3ZhciBmZWVkPXt9LGZlZWRSb290PWdldE9uZUVsZW1lbnQoaXNWYWxpZEZlZWQsdGhpcy5kb20pLHRtcCxjaGlsZHM7aWYoZmVlZFJvb3Qpe2lmKGZlZWRSb290Lm5hbWU9PT1cImZlZWRcIil7Y2hpbGRzPWZlZWRSb290LmNoaWxkcmVuO2ZlZWQudHlwZT1cImF0b21cIjthZGRDb25kaXRpb25hbGx5KGZlZWQsXCJpZFwiLFwiaWRcIixjaGlsZHMpO2FkZENvbmRpdGlvbmFsbHkoZmVlZCxcInRpdGxlXCIsXCJ0aXRsZVwiLGNoaWxkcyk7aWYoKHRtcD1nZXRPbmVFbGVtZW50KFwibGlua1wiLGNoaWxkcykpJiYodG1wPXRtcC5hdHRyaWJzKSYmKHRtcD10bXAuaHJlZikpZmVlZC5saW5rPXRtcDthZGRDb25kaXRpb25hbGx5KGZlZWQsXCJkZXNjcmlwdGlvblwiLFwic3VidGl0bGVcIixjaGlsZHMpO2lmKHRtcD1mZXRjaChcInVwZGF0ZWRcIixjaGlsZHMpKWZlZWQudXBkYXRlZD1uZXcgRGF0ZSh0bXApO2FkZENvbmRpdGlvbmFsbHkoZmVlZCxcImF1dGhvclwiLFwiZW1haWxcIixjaGlsZHMsdHJ1ZSk7ZmVlZC5pdGVtcz1nZXRFbGVtZW50cyhcImVudHJ5XCIsY2hpbGRzKS5tYXAoZnVuY3Rpb24oaXRlbSl7dmFyIGVudHJ5PXt9LHRtcDtpdGVtPWl0ZW0uY2hpbGRyZW47YWRkQ29uZGl0aW9uYWxseShlbnRyeSxcImlkXCIsXCJpZFwiLGl0ZW0pO2FkZENvbmRpdGlvbmFsbHkoZW50cnksXCJ0aXRsZVwiLFwidGl0bGVcIixpdGVtKTtpZigodG1wPWdldE9uZUVsZW1lbnQoXCJsaW5rXCIsaXRlbSkpJiYodG1wPXRtcC5hdHRyaWJzKSYmKHRtcD10bXAuaHJlZikpZW50cnkubGluaz10bXA7aWYodG1wPWZldGNoKFwic3VtbWFyeVwiLGl0ZW0pfHxmZXRjaChcImNvbnRlbnRcIixpdGVtKSllbnRyeS5kZXNjcmlwdGlvbj10bXA7aWYodG1wPWZldGNoKFwidXBkYXRlZFwiLGl0ZW0pKWVudHJ5LnB1YkRhdGU9bmV3IERhdGUodG1wKTtyZXR1cm4gZW50cnl9KX1lbHNle2NoaWxkcz1nZXRPbmVFbGVtZW50KFwiY2hhbm5lbFwiLGZlZWRSb290LmNoaWxkcmVuKS5jaGlsZHJlbjtmZWVkLnR5cGU9ZmVlZFJvb3QubmFtZS5zdWJzdHIoMCwzKTtmZWVkLmlkPVwiXCI7YWRkQ29uZGl0aW9uYWxseShmZWVkLFwidGl0bGVcIixcInRpdGxlXCIsY2hpbGRzKTthZGRDb25kaXRpb25hbGx5KGZlZWQsXCJsaW5rXCIsXCJsaW5rXCIsY2hpbGRzKTthZGRDb25kaXRpb25hbGx5KGZlZWQsXCJkZXNjcmlwdGlvblwiLFwiZGVzY3JpcHRpb25cIixjaGlsZHMpO2lmKHRtcD1mZXRjaChcImxhc3RCdWlsZERhdGVcIixjaGlsZHMpKWZlZWQudXBkYXRlZD1uZXcgRGF0ZSh0bXApO2FkZENvbmRpdGlvbmFsbHkoZmVlZCxcImF1dGhvclwiLFwibWFuYWdpbmdFZGl0b3JcIixjaGlsZHMsdHJ1ZSk7ZmVlZC5pdGVtcz1nZXRFbGVtZW50cyhcIml0ZW1cIixmZWVkUm9vdC5jaGlsZHJlbikubWFwKGZ1bmN0aW9uKGl0ZW0pe3ZhciBlbnRyeT17fSx0bXA7aXRlbT1pdGVtLmNoaWxkcmVuO2FkZENvbmRpdGlvbmFsbHkoZW50cnksXCJpZFwiLFwiZ3VpZFwiLGl0ZW0pO2FkZENvbmRpdGlvbmFsbHkoZW50cnksXCJ0aXRsZVwiLFwidGl0bGVcIixpdGVtKTthZGRDb25kaXRpb25hbGx5KGVudHJ5LFwibGlua1wiLFwibGlua1wiLGl0ZW0pO2FkZENvbmRpdGlvbmFsbHkoZW50cnksXCJkZXNjcmlwdGlvblwiLFwiZGVzY3JpcHRpb25cIixpdGVtKTtpZih0bXA9ZmV0Y2goXCJwdWJEYXRlXCIsaXRlbSkpZW50cnkucHViRGF0ZT1uZXcgRGF0ZSh0bXApO3JldHVybiBlbnRyeX0pfX10aGlzLmRvbT1mZWVkO0RvbUhhbmRsZXIucHJvdG90eXBlLl9oYW5kbGVDYWxsYmFjay5jYWxsKHRoaXMsZmVlZFJvb3Q/bnVsbDpFcnJvcihcImNvdWxkbid0IGZpbmQgcm9vdCBvZiBmZWVkXCIpKX07bW9kdWxlLmV4cG9ydHM9RmVlZEhhbmRsZXJ9LHtcIi4vaW5kZXguanNcIjozNixpbmhlcml0czozOH1dLDMxOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgVG9rZW5pemVyPXJlcXVpcmUoXCIuL1Rva2VuaXplci5qc1wiKTt2YXIgZm9ybVRhZ3M9e2lucHV0OnRydWUsb3B0aW9uOnRydWUsb3B0Z3JvdXA6dHJ1ZSxzZWxlY3Q6dHJ1ZSxidXR0b246dHJ1ZSxkYXRhbGlzdDp0cnVlLHRleHRhcmVhOnRydWV9O3ZhciBvcGVuSW1wbGllc0Nsb3NlPXt0cjp7dHI6dHJ1ZSx0aDp0cnVlLHRkOnRydWV9LHRoOnt0aDp0cnVlfSx0ZDp7dGhlYWQ6dHJ1ZSx0aDp0cnVlLHRkOnRydWV9LGJvZHk6e2hlYWQ6dHJ1ZSxsaW5rOnRydWUsc2NyaXB0OnRydWV9LGxpOntsaTp0cnVlfSxwOntwOnRydWV9LGgxOntwOnRydWV9LGgyOntwOnRydWV9LGgzOntwOnRydWV9LGg0OntwOnRydWV9LGg1OntwOnRydWV9LGg2OntwOnRydWV9LHNlbGVjdDpmb3JtVGFncyxpbnB1dDpmb3JtVGFncyxvdXRwdXQ6Zm9ybVRhZ3MsYnV0dG9uOmZvcm1UYWdzLGRhdGFsaXN0OmZvcm1UYWdzLHRleHRhcmVhOmZvcm1UYWdzLG9wdGlvbjp7b3B0aW9uOnRydWV9LG9wdGdyb3VwOntvcHRncm91cDp0cnVlfX07dmFyIHZvaWRFbGVtZW50cz17X19wcm90b19fOm51bGwsYXJlYTp0cnVlLGJhc2U6dHJ1ZSxiYXNlZm9udDp0cnVlLGJyOnRydWUsY29sOnRydWUsY29tbWFuZDp0cnVlLGVtYmVkOnRydWUsZnJhbWU6dHJ1ZSxocjp0cnVlLGltZzp0cnVlLGlucHV0OnRydWUsaXNpbmRleDp0cnVlLGtleWdlbjp0cnVlLGxpbms6dHJ1ZSxtZXRhOnRydWUscGFyYW06dHJ1ZSxzb3VyY2U6dHJ1ZSx0cmFjazp0cnVlLHdicjp0cnVlLHBhdGg6dHJ1ZSxjaXJjbGU6dHJ1ZSxlbGxpcHNlOnRydWUsbGluZTp0cnVlLHJlY3Q6dHJ1ZSx1c2U6dHJ1ZSxzdG9wOnRydWUscG9seWxpbmU6dHJ1ZSxwb2x5Z29uOnRydWV9O3ZhciByZV9uYW1lRW5kPS9cXHN8XFwvLztmdW5jdGlvbiBQYXJzZXIoY2JzLG9wdGlvbnMpe3RoaXMuX29wdGlvbnM9b3B0aW9uc3x8e307dGhpcy5fY2JzPWNic3x8e307dGhpcy5fdGFnbmFtZT1cIlwiO3RoaXMuX2F0dHJpYm5hbWU9XCJcIjt0aGlzLl9hdHRyaWJ2YWx1ZT1cIlwiO3RoaXMuX2F0dHJpYnM9bnVsbDt0aGlzLl9zdGFjaz1bXTt0aGlzLnN0YXJ0SW5kZXg9MDt0aGlzLmVuZEluZGV4PW51bGw7dGhpcy5fbG93ZXJDYXNlVGFnTmFtZXM9XCJsb3dlckNhc2VUYWdzXCJpbiB0aGlzLl9vcHRpb25zPyEhdGhpcy5fb3B0aW9ucy5sb3dlckNhc2VUYWdzOiF0aGlzLl9vcHRpb25zLnhtbE1vZGU7dGhpcy5fbG93ZXJDYXNlQXR0cmlidXRlTmFtZXM9XCJsb3dlckNhc2VBdHRyaWJ1dGVOYW1lc1wiaW4gdGhpcy5fb3B0aW9ucz8hIXRoaXMuX29wdGlvbnMubG93ZXJDYXNlQXR0cmlidXRlTmFtZXM6IXRoaXMuX29wdGlvbnMueG1sTW9kZTtpZih0aGlzLl9vcHRpb25zLlRva2VuaXplcil7VG9rZW5pemVyPXRoaXMuX29wdGlvbnMuVG9rZW5pemVyfXRoaXMuX3Rva2VuaXplcj1uZXcgVG9rZW5pemVyKHRoaXMuX29wdGlvbnMsdGhpcyk7aWYodGhpcy5fY2JzLm9ucGFyc2VyaW5pdCl0aGlzLl9jYnMub25wYXJzZXJpbml0KHRoaXMpfXJlcXVpcmUoXCJpbmhlcml0c1wiKShQYXJzZXIscmVxdWlyZShcImV2ZW50c1wiKS5FdmVudEVtaXR0ZXIpO1BhcnNlci5wcm90b3R5cGUuX3VwZGF0ZVBvc2l0aW9uPWZ1bmN0aW9uKGluaXRpYWxPZmZzZXQpe2lmKHRoaXMuZW5kSW5kZXg9PT1udWxsKXtpZih0aGlzLl90b2tlbml6ZXIuX3NlY3Rpb25TdGFydDw9aW5pdGlhbE9mZnNldCl7dGhpcy5zdGFydEluZGV4PTB9ZWxzZXt0aGlzLnN0YXJ0SW5kZXg9dGhpcy5fdG9rZW5pemVyLl9zZWN0aW9uU3RhcnQtaW5pdGlhbE9mZnNldH19ZWxzZSB0aGlzLnN0YXJ0SW5kZXg9dGhpcy5lbmRJbmRleCsxO3RoaXMuZW5kSW5kZXg9dGhpcy5fdG9rZW5pemVyLmdldEFic29sdXRlSW5kZXgoKX07UGFyc2VyLnByb3RvdHlwZS5vbnRleHQ9ZnVuY3Rpb24oZGF0YSl7dGhpcy5fdXBkYXRlUG9zaXRpb24oMSk7dGhpcy5lbmRJbmRleC0tO2lmKHRoaXMuX2Nicy5vbnRleHQpdGhpcy5fY2JzLm9udGV4dChkYXRhKX07UGFyc2VyLnByb3RvdHlwZS5vbm9wZW50YWduYW1lPWZ1bmN0aW9uKG5hbWUpe2lmKHRoaXMuX2xvd2VyQ2FzZVRhZ05hbWVzKXtuYW1lPW5hbWUudG9Mb3dlckNhc2UoKX10aGlzLl90YWduYW1lPW5hbWU7aWYoIXRoaXMuX29wdGlvbnMueG1sTW9kZSYmbmFtZSBpbiBvcGVuSW1wbGllc0Nsb3NlKXtmb3IodmFyIGVsOyhlbD10aGlzLl9zdGFja1t0aGlzLl9zdGFjay5sZW5ndGgtMV0paW4gb3BlbkltcGxpZXNDbG9zZVtuYW1lXTt0aGlzLm9uY2xvc2V0YWcoZWwpKTt9aWYodGhpcy5fb3B0aW9ucy54bWxNb2RlfHwhKG5hbWUgaW4gdm9pZEVsZW1lbnRzKSl7dGhpcy5fc3RhY2sucHVzaChuYW1lKX1pZih0aGlzLl9jYnMub25vcGVudGFnbmFtZSl0aGlzLl9jYnMub25vcGVudGFnbmFtZShuYW1lKTtpZih0aGlzLl9jYnMub25vcGVudGFnKXRoaXMuX2F0dHJpYnM9e319O1BhcnNlci5wcm90b3R5cGUub25vcGVudGFnZW5kPWZ1bmN0aW9uKCl7dGhpcy5fdXBkYXRlUG9zaXRpb24oMSk7aWYodGhpcy5fYXR0cmlicyl7aWYodGhpcy5fY2JzLm9ub3BlbnRhZyl0aGlzLl9jYnMub25vcGVudGFnKHRoaXMuX3RhZ25hbWUsdGhpcy5fYXR0cmlicyk7dGhpcy5fYXR0cmlicz1udWxsfWlmKCF0aGlzLl9vcHRpb25zLnhtbE1vZGUmJnRoaXMuX2Nicy5vbmNsb3NldGFnJiZ0aGlzLl90YWduYW1lIGluIHZvaWRFbGVtZW50cyl7dGhpcy5fY2JzLm9uY2xvc2V0YWcodGhpcy5fdGFnbmFtZSl9dGhpcy5fdGFnbmFtZT1cIlwifTtQYXJzZXIucHJvdG90eXBlLm9uY2xvc2V0YWc9ZnVuY3Rpb24obmFtZSl7dGhpcy5fdXBkYXRlUG9zaXRpb24oMSk7aWYodGhpcy5fbG93ZXJDYXNlVGFnTmFtZXMpe25hbWU9bmFtZS50b0xvd2VyQ2FzZSgpfWlmKHRoaXMuX3N0YWNrLmxlbmd0aCYmKCEobmFtZSBpbiB2b2lkRWxlbWVudHMpfHx0aGlzLl9vcHRpb25zLnhtbE1vZGUpKXt2YXIgcG9zPXRoaXMuX3N0YWNrLmxhc3RJbmRleE9mKG5hbWUpO2lmKHBvcyE9PS0xKXtpZih0aGlzLl9jYnMub25jbG9zZXRhZyl7cG9zPXRoaXMuX3N0YWNrLmxlbmd0aC1wb3M7d2hpbGUocG9zLS0pdGhpcy5fY2JzLm9uY2xvc2V0YWcodGhpcy5fc3RhY2sucG9wKCkpfWVsc2UgdGhpcy5fc3RhY2subGVuZ3RoPXBvc31lbHNlIGlmKG5hbWU9PT1cInBcIiYmIXRoaXMuX29wdGlvbnMueG1sTW9kZSl7dGhpcy5vbm9wZW50YWduYW1lKG5hbWUpO3RoaXMuX2Nsb3NlQ3VycmVudFRhZygpfX1lbHNlIGlmKCF0aGlzLl9vcHRpb25zLnhtbE1vZGUmJihuYW1lPT09XCJiclwifHxuYW1lPT09XCJwXCIpKXt0aGlzLm9ub3BlbnRhZ25hbWUobmFtZSk7dGhpcy5fY2xvc2VDdXJyZW50VGFnKCl9fTtQYXJzZXIucHJvdG90eXBlLm9uc2VsZmNsb3Npbmd0YWc9ZnVuY3Rpb24oKXtpZih0aGlzLl9vcHRpb25zLnhtbE1vZGV8fHRoaXMuX29wdGlvbnMucmVjb2duaXplU2VsZkNsb3Npbmcpe3RoaXMuX2Nsb3NlQ3VycmVudFRhZygpfWVsc2V7dGhpcy5vbm9wZW50YWdlbmQoKX19O1BhcnNlci5wcm90b3R5cGUuX2Nsb3NlQ3VycmVudFRhZz1mdW5jdGlvbigpe3ZhciBuYW1lPXRoaXMuX3RhZ25hbWU7dGhpcy5vbm9wZW50YWdlbmQoKTtpZih0aGlzLl9zdGFja1t0aGlzLl9zdGFjay5sZW5ndGgtMV09PT1uYW1lKXtpZih0aGlzLl9jYnMub25jbG9zZXRhZyl7dGhpcy5fY2JzLm9uY2xvc2V0YWcobmFtZSl9dGhpcy5fc3RhY2sucG9wKCl9fTtQYXJzZXIucHJvdG90eXBlLm9uYXR0cmlibmFtZT1mdW5jdGlvbihuYW1lKXtpZih0aGlzLl9sb3dlckNhc2VBdHRyaWJ1dGVOYW1lcyl7bmFtZT1uYW1lLnRvTG93ZXJDYXNlKCl9dGhpcy5fYXR0cmlibmFtZT1uYW1lfTtQYXJzZXIucHJvdG90eXBlLm9uYXR0cmliZGF0YT1mdW5jdGlvbih2YWx1ZSl7dGhpcy5fYXR0cmlidmFsdWUrPXZhbHVlfTtQYXJzZXIucHJvdG90eXBlLm9uYXR0cmliZW5kPWZ1bmN0aW9uKCl7aWYodGhpcy5fY2JzLm9uYXR0cmlidXRlKXRoaXMuX2Nicy5vbmF0dHJpYnV0ZSh0aGlzLl9hdHRyaWJuYW1lLHRoaXMuX2F0dHJpYnZhbHVlKTtpZih0aGlzLl9hdHRyaWJzJiYhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHRoaXMuX2F0dHJpYnMsdGhpcy5fYXR0cmlibmFtZSkpe3RoaXMuX2F0dHJpYnNbdGhpcy5fYXR0cmlibmFtZV09dGhpcy5fYXR0cmlidmFsdWV9dGhpcy5fYXR0cmlibmFtZT1cIlwiO3RoaXMuX2F0dHJpYnZhbHVlPVwiXCJ9O1BhcnNlci5wcm90b3R5cGUuX2dldEluc3RydWN0aW9uTmFtZT1mdW5jdGlvbih2YWx1ZSl7dmFyIGlkeD12YWx1ZS5zZWFyY2gocmVfbmFtZUVuZCksbmFtZT1pZHg8MD92YWx1ZTp2YWx1ZS5zdWJzdHIoMCxpZHgpO2lmKHRoaXMuX2xvd2VyQ2FzZVRhZ05hbWVzKXtuYW1lPW5hbWUudG9Mb3dlckNhc2UoKX1yZXR1cm4gbmFtZX07UGFyc2VyLnByb3RvdHlwZS5vbmRlY2xhcmF0aW9uPWZ1bmN0aW9uKHZhbHVlKXtpZih0aGlzLl9jYnMub25wcm9jZXNzaW5naW5zdHJ1Y3Rpb24pe3ZhciBuYW1lPXRoaXMuX2dldEluc3RydWN0aW9uTmFtZSh2YWx1ZSk7dGhpcy5fY2JzLm9ucHJvY2Vzc2luZ2luc3RydWN0aW9uKFwiIVwiK25hbWUsXCIhXCIrdmFsdWUpfX07UGFyc2VyLnByb3RvdHlwZS5vbnByb2Nlc3NpbmdpbnN0cnVjdGlvbj1mdW5jdGlvbih2YWx1ZSl7aWYodGhpcy5fY2JzLm9ucHJvY2Vzc2luZ2luc3RydWN0aW9uKXt2YXIgbmFtZT10aGlzLl9nZXRJbnN0cnVjdGlvbk5hbWUodmFsdWUpO3RoaXMuX2Nicy5vbnByb2Nlc3NpbmdpbnN0cnVjdGlvbihcIj9cIituYW1lLFwiP1wiK3ZhbHVlKX19O1BhcnNlci5wcm90b3R5cGUub25jb21tZW50PWZ1bmN0aW9uKHZhbHVlKXt0aGlzLl91cGRhdGVQb3NpdGlvbig0KTtpZih0aGlzLl9jYnMub25jb21tZW50KXRoaXMuX2Nicy5vbmNvbW1lbnQodmFsdWUpO2lmKHRoaXMuX2Nicy5vbmNvbW1lbnRlbmQpdGhpcy5fY2JzLm9uY29tbWVudGVuZCgpfTtQYXJzZXIucHJvdG90eXBlLm9uY2RhdGE9ZnVuY3Rpb24odmFsdWUpe3RoaXMuX3VwZGF0ZVBvc2l0aW9uKDEpO2lmKHRoaXMuX29wdGlvbnMueG1sTW9kZXx8dGhpcy5fb3B0aW9ucy5yZWNvZ25pemVDREFUQSl7aWYodGhpcy5fY2JzLm9uY2RhdGFzdGFydCl0aGlzLl9jYnMub25jZGF0YXN0YXJ0KCk7aWYodGhpcy5fY2JzLm9udGV4dCl0aGlzLl9jYnMub250ZXh0KHZhbHVlKTtpZih0aGlzLl9jYnMub25jZGF0YWVuZCl0aGlzLl9jYnMub25jZGF0YWVuZCgpfWVsc2V7dGhpcy5vbmNvbW1lbnQoXCJbQ0RBVEFbXCIrdmFsdWUrXCJdXVwiKX19O1BhcnNlci5wcm90b3R5cGUub25lcnJvcj1mdW5jdGlvbihlcnIpe2lmKHRoaXMuX2Nicy5vbmVycm9yKXRoaXMuX2Nicy5vbmVycm9yKGVycil9O1BhcnNlci5wcm90b3R5cGUub25lbmQ9ZnVuY3Rpb24oKXtpZih0aGlzLl9jYnMub25jbG9zZXRhZyl7Zm9yKHZhciBpPXRoaXMuX3N0YWNrLmxlbmd0aDtpPjA7dGhpcy5fY2JzLm9uY2xvc2V0YWcodGhpcy5fc3RhY2tbLS1pXSkpO31pZih0aGlzLl9jYnMub25lbmQpdGhpcy5fY2JzLm9uZW5kKCl9O1BhcnNlci5wcm90b3R5cGUucmVzZXQ9ZnVuY3Rpb24oKXtpZih0aGlzLl9jYnMub25yZXNldCl0aGlzLl9jYnMub25yZXNldCgpO3RoaXMuX3Rva2VuaXplci5yZXNldCgpO3RoaXMuX3RhZ25hbWU9XCJcIjt0aGlzLl9hdHRyaWJuYW1lPVwiXCI7dGhpcy5fYXR0cmlicz1udWxsO3RoaXMuX3N0YWNrPVtdO2lmKHRoaXMuX2Nicy5vbnBhcnNlcmluaXQpdGhpcy5fY2JzLm9ucGFyc2VyaW5pdCh0aGlzKX07UGFyc2VyLnByb3RvdHlwZS5wYXJzZUNvbXBsZXRlPWZ1bmN0aW9uKGRhdGEpe3RoaXMucmVzZXQoKTt0aGlzLmVuZChkYXRhKX07UGFyc2VyLnByb3RvdHlwZS53cml0ZT1mdW5jdGlvbihjaHVuayl7dGhpcy5fdG9rZW5pemVyLndyaXRlKGNodW5rKX07UGFyc2VyLnByb3RvdHlwZS5lbmQ9ZnVuY3Rpb24oY2h1bmspe3RoaXMuX3Rva2VuaXplci5lbmQoY2h1bmspfTtQYXJzZXIucHJvdG90eXBlLnBhdXNlPWZ1bmN0aW9uKCl7dGhpcy5fdG9rZW5pemVyLnBhdXNlKCl9O1BhcnNlci5wcm90b3R5cGUucmVzdW1lPWZ1bmN0aW9uKCl7dGhpcy5fdG9rZW5pemVyLnJlc3VtZSgpfTtQYXJzZXIucHJvdG90eXBlLnBhcnNlQ2h1bms9UGFyc2VyLnByb3RvdHlwZS53cml0ZTtQYXJzZXIucHJvdG90eXBlLmRvbmU9UGFyc2VyLnByb3RvdHlwZS5lbmQ7bW9kdWxlLmV4cG9ydHM9UGFyc2VyfSx7XCIuL1Rva2VuaXplci5qc1wiOjM0LGV2ZW50czoyOCxpbmhlcml0czozOH1dLDMyOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXttb2R1bGUuZXhwb3J0cz1Qcm94eUhhbmRsZXI7ZnVuY3Rpb24gUHJveHlIYW5kbGVyKGNicyl7dGhpcy5fY2JzPWNic3x8e319dmFyIEVWRU5UUz1yZXF1aXJlKFwiLi9cIikuRVZFTlRTO09iamVjdC5rZXlzKEVWRU5UUykuZm9yRWFjaChmdW5jdGlvbihuYW1lKXtpZihFVkVOVFNbbmFtZV09PT0wKXtuYW1lPVwib25cIituYW1lO1Byb3h5SGFuZGxlci5wcm90b3R5cGVbbmFtZV09ZnVuY3Rpb24oKXtpZih0aGlzLl9jYnNbbmFtZV0pdGhpcy5fY2JzW25hbWVdKCl9fWVsc2UgaWYoRVZFTlRTW25hbWVdPT09MSl7bmFtZT1cIm9uXCIrbmFtZTtQcm94eUhhbmRsZXIucHJvdG90eXBlW25hbWVdPWZ1bmN0aW9uKGEpe2lmKHRoaXMuX2Nic1tuYW1lXSl0aGlzLl9jYnNbbmFtZV0oYSl9fWVsc2UgaWYoRVZFTlRTW25hbWVdPT09Mil7bmFtZT1cIm9uXCIrbmFtZTtQcm94eUhhbmRsZXIucHJvdG90eXBlW25hbWVdPWZ1bmN0aW9uKGEsYil7aWYodGhpcy5fY2JzW25hbWVdKXRoaXMuX2Nic1tuYW1lXShhLGIpfX1lbHNle3Rocm93IEVycm9yKFwid3JvbmcgbnVtYmVyIG9mIGFyZ3VtZW50c1wiKX19KX0se1wiLi9cIjozNn1dLDMzOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXttb2R1bGUuZXhwb3J0cz1TdHJlYW07dmFyIFBhcnNlcj1yZXF1aXJlKFwiLi9Xcml0YWJsZVN0cmVhbS5qc1wiKTtmdW5jdGlvbiBTdHJlYW0ob3B0aW9ucyl7UGFyc2VyLmNhbGwodGhpcyxuZXcgQ2JzKHRoaXMpLG9wdGlvbnMpfXJlcXVpcmUoXCJpbmhlcml0c1wiKShTdHJlYW0sUGFyc2VyKTtTdHJlYW0ucHJvdG90eXBlLnJlYWRhYmxlPXRydWU7ZnVuY3Rpb24gQ2JzKHNjb3BlKXt0aGlzLnNjb3BlPXNjb3BlfXZhciBFVkVOVFM9cmVxdWlyZShcIi4uL1wiKS5FVkVOVFM7T2JqZWN0LmtleXMoRVZFTlRTKS5mb3JFYWNoKGZ1bmN0aW9uKG5hbWUpe2lmKEVWRU5UU1tuYW1lXT09PTApe0Nicy5wcm90b3R5cGVbXCJvblwiK25hbWVdPWZ1bmN0aW9uKCl7dGhpcy5zY29wZS5lbWl0KG5hbWUpfX1lbHNlIGlmKEVWRU5UU1tuYW1lXT09PTEpe0Nicy5wcm90b3R5cGVbXCJvblwiK25hbWVdPWZ1bmN0aW9uKGEpe3RoaXMuc2NvcGUuZW1pdChuYW1lLGEpfX1lbHNlIGlmKEVWRU5UU1tuYW1lXT09PTIpe0Nicy5wcm90b3R5cGVbXCJvblwiK25hbWVdPWZ1bmN0aW9uKGEsYil7dGhpcy5zY29wZS5lbWl0KG5hbWUsYSxiKX19ZWxzZXt0aHJvdyBFcnJvcihcIndyb25nIG51bWJlciBvZiBhcmd1bWVudHMhXCIpfX0pfSx7XCIuLi9cIjozNixcIi4vV3JpdGFibGVTdHJlYW0uanNcIjozNSxpbmhlcml0czozOH1dLDM0OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXttb2R1bGUuZXhwb3J0cz1Ub2tlbml6ZXI7dmFyIGRlY29kZUNvZGVQb2ludD1yZXF1aXJlKFwiZW50aXRpZXMvbGliL2RlY29kZV9jb2RlcG9pbnQuanNcIiksZW50aXR5TWFwPXJlcXVpcmUoXCJlbnRpdGllcy9tYXBzL2VudGl0aWVzLmpzb25cIiksbGVnYWN5TWFwPXJlcXVpcmUoXCJlbnRpdGllcy9tYXBzL2xlZ2FjeS5qc29uXCIpLHhtbE1hcD1yZXF1aXJlKFwiZW50aXRpZXMvbWFwcy94bWwuanNvblwiKSxpPTAsVEVYVD1pKyssQkVGT1JFX1RBR19OQU1FPWkrKyxJTl9UQUdfTkFNRT1pKyssSU5fU0VMRl9DTE9TSU5HX1RBRz1pKyssQkVGT1JFX0NMT1NJTkdfVEFHX05BTUU9aSsrLElOX0NMT1NJTkdfVEFHX05BTUU9aSsrLEFGVEVSX0NMT1NJTkdfVEFHX05BTUU9aSsrLEJFRk9SRV9BVFRSSUJVVEVfTkFNRT1pKyssSU5fQVRUUklCVVRFX05BTUU9aSsrLEFGVEVSX0FUVFJJQlVURV9OQU1FPWkrKyxCRUZPUkVfQVRUUklCVVRFX1ZBTFVFPWkrKyxJTl9BVFRSSUJVVEVfVkFMVUVfRFE9aSsrLElOX0FUVFJJQlVURV9WQUxVRV9TUT1pKyssSU5fQVRUUklCVVRFX1ZBTFVFX05RPWkrKyxCRUZPUkVfREVDTEFSQVRJT049aSsrLElOX0RFQ0xBUkFUSU9OPWkrKyxJTl9QUk9DRVNTSU5HX0lOU1RSVUNUSU9OPWkrKyxCRUZPUkVfQ09NTUVOVD1pKyssSU5fQ09NTUVOVD1pKyssQUZURVJfQ09NTUVOVF8xPWkrKyxBRlRFUl9DT01NRU5UXzI9aSsrLEJFRk9SRV9DREFUQV8xPWkrKyxCRUZPUkVfQ0RBVEFfMj1pKyssQkVGT1JFX0NEQVRBXzM9aSsrLEJFRk9SRV9DREFUQV80PWkrKyxCRUZPUkVfQ0RBVEFfNT1pKyssQkVGT1JFX0NEQVRBXzY9aSsrLElOX0NEQVRBPWkrKyxBRlRFUl9DREFUQV8xPWkrKyxBRlRFUl9DREFUQV8yPWkrKyxCRUZPUkVfU1BFQ0lBTD1pKyssQkVGT1JFX1NQRUNJQUxfRU5EPWkrKyxCRUZPUkVfU0NSSVBUXzE9aSsrLEJFRk9SRV9TQ1JJUFRfMj1pKyssQkVGT1JFX1NDUklQVF8zPWkrKyxCRUZPUkVfU0NSSVBUXzQ9aSsrLEJFRk9SRV9TQ1JJUFRfNT1pKyssQUZURVJfU0NSSVBUXzE9aSsrLEFGVEVSX1NDUklQVF8yPWkrKyxBRlRFUl9TQ1JJUFRfMz1pKyssQUZURVJfU0NSSVBUXzQ9aSsrLEFGVEVSX1NDUklQVF81PWkrKyxCRUZPUkVfU1RZTEVfMT1pKyssQkVGT1JFX1NUWUxFXzI9aSsrLEJFRk9SRV9TVFlMRV8zPWkrKyxCRUZPUkVfU1RZTEVfND1pKyssQUZURVJfU1RZTEVfMT1pKyssQUZURVJfU1RZTEVfMj1pKyssQUZURVJfU1RZTEVfMz1pKyssQUZURVJfU1RZTEVfND1pKyssQkVGT1JFX0VOVElUWT1pKyssQkVGT1JFX05VTUVSSUNfRU5USVRZPWkrKyxJTl9OQU1FRF9FTlRJVFk9aSsrLElOX05VTUVSSUNfRU5USVRZPWkrKyxJTl9IRVhfRU5USVRZPWkrKyxqPTAsU1BFQ0lBTF9OT05FPWorKyxTUEVDSUFMX1NDUklQVD1qKyssU1BFQ0lBTF9TVFlMRT1qKys7ZnVuY3Rpb24gd2hpdGVzcGFjZShjKXtyZXR1cm4gYz09PVwiIFwifHxjPT09XCJcXG5cInx8Yz09PVwiXFx0XCJ8fGM9PT1cIlxcZlwifHxjPT09XCJcXHJcIn1mdW5jdGlvbiBjaGFyYWN0ZXJTdGF0ZShjaGFyLFNVQ0NFU1Mpe3JldHVybiBmdW5jdGlvbihjKXtpZihjPT09Y2hhcil0aGlzLl9zdGF0ZT1TVUNDRVNTfX1mdW5jdGlvbiBpZkVsc2VTdGF0ZSh1cHBlcixTVUNDRVNTLEZBSUxVUkUpe3ZhciBsb3dlcj11cHBlci50b0xvd2VyQ2FzZSgpO2lmKHVwcGVyPT09bG93ZXIpe3JldHVybiBmdW5jdGlvbihjKXtpZihjPT09bG93ZXIpe3RoaXMuX3N0YXRlPVNVQ0NFU1N9ZWxzZXt0aGlzLl9zdGF0ZT1GQUlMVVJFO3RoaXMuX2luZGV4LS19fX1lbHNle3JldHVybiBmdW5jdGlvbihjKXtpZihjPT09bG93ZXJ8fGM9PT11cHBlcil7dGhpcy5fc3RhdGU9U1VDQ0VTU31lbHNle3RoaXMuX3N0YXRlPUZBSUxVUkU7dGhpcy5faW5kZXgtLX19fX1mdW5jdGlvbiBjb25zdW1lU3BlY2lhbE5hbWVDaGFyKHVwcGVyLE5FWFRfU1RBVEUpe3ZhciBsb3dlcj11cHBlci50b0xvd2VyQ2FzZSgpO3JldHVybiBmdW5jdGlvbihjKXtpZihjPT09bG93ZXJ8fGM9PT11cHBlcil7dGhpcy5fc3RhdGU9TkVYVF9TVEFURX1lbHNle3RoaXMuX3N0YXRlPUlOX1RBR19OQU1FO3RoaXMuX2luZGV4LS19fX1mdW5jdGlvbiBUb2tlbml6ZXIob3B0aW9ucyxjYnMpe3RoaXMuX3N0YXRlPVRFWFQ7dGhpcy5fYnVmZmVyPVwiXCI7dGhpcy5fc2VjdGlvblN0YXJ0PTA7dGhpcy5faW5kZXg9MDt0aGlzLl9idWZmZXJPZmZzZXQ9MDt0aGlzLl9iYXNlU3RhdGU9VEVYVDt0aGlzLl9zcGVjaWFsPVNQRUNJQUxfTk9ORTt0aGlzLl9jYnM9Y2JzO3RoaXMuX3J1bm5pbmc9dHJ1ZTt0aGlzLl9lbmRlZD1mYWxzZTt0aGlzLl94bWxNb2RlPSEhKG9wdGlvbnMmJm9wdGlvbnMueG1sTW9kZSk7dGhpcy5fZGVjb2RlRW50aXRpZXM9ISEob3B0aW9ucyYmb3B0aW9ucy5kZWNvZGVFbnRpdGllcyl9VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVUZXh0PWZ1bmN0aW9uKGMpe2lmKGM9PT1cIjxcIil7aWYodGhpcy5faW5kZXg+dGhpcy5fc2VjdGlvblN0YXJ0KXt0aGlzLl9jYnMub250ZXh0KHRoaXMuX2dldFNlY3Rpb24oKSl9dGhpcy5fc3RhdGU9QkVGT1JFX1RBR19OQU1FO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleH1lbHNlIGlmKHRoaXMuX2RlY29kZUVudGl0aWVzJiZ0aGlzLl9zcGVjaWFsPT09U1BFQ0lBTF9OT05FJiZjPT09XCImXCIpe2lmKHRoaXMuX2luZGV4PnRoaXMuX3NlY3Rpb25TdGFydCl7dGhpcy5fY2JzLm9udGV4dCh0aGlzLl9nZXRTZWN0aW9uKCkpfXRoaXMuX2Jhc2VTdGF0ZT1URVhUO3RoaXMuX3N0YXRlPUJFRk9SRV9FTlRJVFk7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4fX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVUYWdOYW1lPWZ1bmN0aW9uKGMpe2lmKGM9PT1cIi9cIil7dGhpcy5fc3RhdGU9QkVGT1JFX0NMT1NJTkdfVEFHX05BTUV9ZWxzZSBpZihjPT09XCI8XCIpe3RoaXMuX2Nicy5vbnRleHQodGhpcy5fZ2V0U2VjdGlvbigpKTt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXh9ZWxzZSBpZihjPT09XCI+XCJ8fHRoaXMuX3NwZWNpYWwhPT1TUEVDSUFMX05PTkV8fHdoaXRlc3BhY2UoYykpe3RoaXMuX3N0YXRlPVRFWFR9ZWxzZSBpZihjPT09XCIhXCIpe3RoaXMuX3N0YXRlPUJFRk9SRV9ERUNMQVJBVElPTjt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXgrMX1lbHNlIGlmKGM9PT1cIj9cIil7dGhpcy5fc3RhdGU9SU5fUFJPQ0VTU0lOR19JTlNUUlVDVElPTjt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXgrMX1lbHNle3RoaXMuX3N0YXRlPSF0aGlzLl94bWxNb2RlJiYoYz09PVwic1wifHxjPT09XCJTXCIpP0JFRk9SRV9TUEVDSUFMOklOX1RBR19OQU1FO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleH19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5UYWdOYW1lPWZ1bmN0aW9uKGMpe2lmKGM9PT1cIi9cInx8Yz09PVwiPlwifHx3aGl0ZXNwYWNlKGMpKXt0aGlzLl9lbWl0VG9rZW4oXCJvbm9wZW50YWduYW1lXCIpO3RoaXMuX3N0YXRlPUJFRk9SRV9BVFRSSUJVVEVfTkFNRTt0aGlzLl9pbmRleC0tfX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVDbG9zZWluZ1RhZ05hbWU9ZnVuY3Rpb24oYyl7aWYod2hpdGVzcGFjZShjKSk7ZWxzZSBpZihjPT09XCI+XCIpe3RoaXMuX3N0YXRlPVRFWFR9ZWxzZSBpZih0aGlzLl9zcGVjaWFsIT09U1BFQ0lBTF9OT05FKXtpZihjPT09XCJzXCJ8fGM9PT1cIlNcIil7dGhpcy5fc3RhdGU9QkVGT1JFX1NQRUNJQUxfRU5EfWVsc2V7dGhpcy5fc3RhdGU9VEVYVDt0aGlzLl9pbmRleC0tfX1lbHNle3RoaXMuX3N0YXRlPUlOX0NMT1NJTkdfVEFHX05BTUU7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4fX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJbkNsb3NlaW5nVGFnTmFtZT1mdW5jdGlvbihjKXtpZihjPT09XCI+XCJ8fHdoaXRlc3BhY2UoYykpe3RoaXMuX2VtaXRUb2tlbihcIm9uY2xvc2V0YWdcIik7dGhpcy5fc3RhdGU9QUZURVJfQ0xPU0lOR19UQUdfTkFNRTt0aGlzLl9pbmRleC0tfX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVBZnRlckNsb3NlaW5nVGFnTmFtZT1mdW5jdGlvbihjKXtpZihjPT09XCI+XCIpe3RoaXMuX3N0YXRlPVRFWFQ7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4KzF9fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZUF0dHJpYnV0ZU5hbWU9ZnVuY3Rpb24oYyl7aWYoYz09PVwiPlwiKXt0aGlzLl9jYnMub25vcGVudGFnZW5kKCk7dGhpcy5fc3RhdGU9VEVYVDt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXgrMX1lbHNlIGlmKGM9PT1cIi9cIil7dGhpcy5fc3RhdGU9SU5fU0VMRl9DTE9TSU5HX1RBR31lbHNlIGlmKCF3aGl0ZXNwYWNlKGMpKXt0aGlzLl9zdGF0ZT1JTl9BVFRSSUJVVEVfTkFNRTt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXh9fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUluU2VsZkNsb3NpbmdUYWc9ZnVuY3Rpb24oYyl7aWYoYz09PVwiPlwiKXt0aGlzLl9jYnMub25zZWxmY2xvc2luZ3RhZygpO3RoaXMuX3N0YXRlPVRFWFQ7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4KzF9ZWxzZSBpZighd2hpdGVzcGFjZShjKSl7dGhpcy5fc3RhdGU9QkVGT1JFX0FUVFJJQlVURV9OQU1FO3RoaXMuX2luZGV4LS19fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUluQXR0cmlidXRlTmFtZT1mdW5jdGlvbihjKXtpZihjPT09XCI9XCJ8fGM9PT1cIi9cInx8Yz09PVwiPlwifHx3aGl0ZXNwYWNlKGMpKXt0aGlzLl9jYnMub25hdHRyaWJuYW1lKHRoaXMuX2dldFNlY3Rpb24oKSk7dGhpcy5fc2VjdGlvblN0YXJ0PS0xO3RoaXMuX3N0YXRlPUFGVEVSX0FUVFJJQlVURV9OQU1FO3RoaXMuX2luZGV4LS19fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUFmdGVyQXR0cmlidXRlTmFtZT1mdW5jdGlvbihjKXtpZihjPT09XCI9XCIpe3RoaXMuX3N0YXRlPUJFRk9SRV9BVFRSSUJVVEVfVkFMVUV9ZWxzZSBpZihjPT09XCIvXCJ8fGM9PT1cIj5cIil7dGhpcy5fY2JzLm9uYXR0cmliZW5kKCk7dGhpcy5fc3RhdGU9QkVGT1JFX0FUVFJJQlVURV9OQU1FO3RoaXMuX2luZGV4LS19ZWxzZSBpZighd2hpdGVzcGFjZShjKSl7dGhpcy5fY2JzLm9uYXR0cmliZW5kKCk7dGhpcy5fc3RhdGU9SU5fQVRUUklCVVRFX05BTUU7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4fX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVBdHRyaWJ1dGVWYWx1ZT1mdW5jdGlvbihjKXtpZihjPT09J1wiJyl7dGhpcy5fc3RhdGU9SU5fQVRUUklCVVRFX1ZBTFVFX0RRO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleCsxfWVsc2UgaWYoYz09PVwiJ1wiKXt0aGlzLl9zdGF0ZT1JTl9BVFRSSUJVVEVfVkFMVUVfU1E7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4KzF9ZWxzZSBpZighd2hpdGVzcGFjZShjKSl7dGhpcy5fc3RhdGU9SU5fQVRUUklCVVRFX1ZBTFVFX05RO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleDt0aGlzLl9pbmRleC0tfX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJbkF0dHJpYnV0ZVZhbHVlRG91YmxlUXVvdGVzPWZ1bmN0aW9uKGMpe2lmKGM9PT0nXCInKXt0aGlzLl9lbWl0VG9rZW4oXCJvbmF0dHJpYmRhdGFcIik7dGhpcy5fY2JzLm9uYXR0cmliZW5kKCk7dGhpcy5fc3RhdGU9QkVGT1JFX0FUVFJJQlVURV9OQU1FfWVsc2UgaWYodGhpcy5fZGVjb2RlRW50aXRpZXMmJmM9PT1cIiZcIil7dGhpcy5fZW1pdFRva2VuKFwib25hdHRyaWJkYXRhXCIpO3RoaXMuX2Jhc2VTdGF0ZT10aGlzLl9zdGF0ZTt0aGlzLl9zdGF0ZT1CRUZPUkVfRU5USVRZO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleH19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5BdHRyaWJ1dGVWYWx1ZVNpbmdsZVF1b3Rlcz1mdW5jdGlvbihjKXtpZihjPT09XCInXCIpe3RoaXMuX2VtaXRUb2tlbihcIm9uYXR0cmliZGF0YVwiKTt0aGlzLl9jYnMub25hdHRyaWJlbmQoKTt0aGlzLl9zdGF0ZT1CRUZPUkVfQVRUUklCVVRFX05BTUV9ZWxzZSBpZih0aGlzLl9kZWNvZGVFbnRpdGllcyYmYz09PVwiJlwiKXt0aGlzLl9lbWl0VG9rZW4oXCJvbmF0dHJpYmRhdGFcIik7dGhpcy5fYmFzZVN0YXRlPXRoaXMuX3N0YXRlO3RoaXMuX3N0YXRlPUJFRk9SRV9FTlRJVFk7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4fX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJbkF0dHJpYnV0ZVZhbHVlTm9RdW90ZXM9ZnVuY3Rpb24oYyl7aWYod2hpdGVzcGFjZShjKXx8Yz09PVwiPlwiKXt0aGlzLl9lbWl0VG9rZW4oXCJvbmF0dHJpYmRhdGFcIik7dGhpcy5fY2JzLm9uYXR0cmliZW5kKCk7dGhpcy5fc3RhdGU9QkVGT1JFX0FUVFJJQlVURV9OQU1FO3RoaXMuX2luZGV4LS19ZWxzZSBpZih0aGlzLl9kZWNvZGVFbnRpdGllcyYmYz09PVwiJlwiKXt0aGlzLl9lbWl0VG9rZW4oXCJvbmF0dHJpYmRhdGFcIik7dGhpcy5fYmFzZVN0YXRlPXRoaXMuX3N0YXRlO3RoaXMuX3N0YXRlPUJFRk9SRV9FTlRJVFk7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4fX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVEZWNsYXJhdGlvbj1mdW5jdGlvbihjKXt0aGlzLl9zdGF0ZT1jPT09XCJbXCI/QkVGT1JFX0NEQVRBXzE6Yz09PVwiLVwiP0JFRk9SRV9DT01NRU5UOklOX0RFQ0xBUkFUSU9OfTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUluRGVjbGFyYXRpb249ZnVuY3Rpb24oYyl7aWYoYz09PVwiPlwiKXt0aGlzLl9jYnMub25kZWNsYXJhdGlvbih0aGlzLl9nZXRTZWN0aW9uKCkpO3RoaXMuX3N0YXRlPVRFWFQ7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4KzF9fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUluUHJvY2Vzc2luZ0luc3RydWN0aW9uPWZ1bmN0aW9uKGMpe2lmKGM9PT1cIj5cIil7dGhpcy5fY2JzLm9ucHJvY2Vzc2luZ2luc3RydWN0aW9uKHRoaXMuX2dldFNlY3Rpb24oKSk7dGhpcy5fc3RhdGU9VEVYVDt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXgrMX19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlQ29tbWVudD1mdW5jdGlvbihjKXtpZihjPT09XCItXCIpe3RoaXMuX3N0YXRlPUlOX0NPTU1FTlQ7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4KzF9ZWxzZXt0aGlzLl9zdGF0ZT1JTl9ERUNMQVJBVElPTn19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5Db21tZW50PWZ1bmN0aW9uKGMpe2lmKGM9PT1cIi1cIil0aGlzLl9zdGF0ZT1BRlRFUl9DT01NRU5UXzF9O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJDb21tZW50MT1mdW5jdGlvbihjKXtpZihjPT09XCItXCIpe3RoaXMuX3N0YXRlPUFGVEVSX0NPTU1FTlRfMn1lbHNle3RoaXMuX3N0YXRlPUlOX0NPTU1FTlR9fTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUFmdGVyQ29tbWVudDI9ZnVuY3Rpb24oYyl7aWYoYz09PVwiPlwiKXt0aGlzLl9jYnMub25jb21tZW50KHRoaXMuX2J1ZmZlci5zdWJzdHJpbmcodGhpcy5fc2VjdGlvblN0YXJ0LHRoaXMuX2luZGV4LTIpKTt0aGlzLl9zdGF0ZT1URVhUO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleCsxfWVsc2UgaWYoYyE9PVwiLVwiKXt0aGlzLl9zdGF0ZT1JTl9DT01NRU5UfX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVDZGF0YTE9aWZFbHNlU3RhdGUoXCJDXCIsQkVGT1JFX0NEQVRBXzIsSU5fREVDTEFSQVRJT04pO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlQ2RhdGEyPWlmRWxzZVN0YXRlKFwiRFwiLEJFRk9SRV9DREFUQV8zLElOX0RFQ0xBUkFUSU9OKTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZUNkYXRhMz1pZkVsc2VTdGF0ZShcIkFcIixCRUZPUkVfQ0RBVEFfNCxJTl9ERUNMQVJBVElPTik7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVDZGF0YTQ9aWZFbHNlU3RhdGUoXCJUXCIsQkVGT1JFX0NEQVRBXzUsSU5fREVDTEFSQVRJT04pO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlQ2RhdGE1PWlmRWxzZVN0YXRlKFwiQVwiLEJFRk9SRV9DREFUQV82LElOX0RFQ0xBUkFUSU9OKTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZUNkYXRhNj1mdW5jdGlvbihjKXtpZihjPT09XCJbXCIpe3RoaXMuX3N0YXRlPUlOX0NEQVRBO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleCsxfWVsc2V7dGhpcy5fc3RhdGU9SU5fREVDTEFSQVRJT047dGhpcy5faW5kZXgtLX19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5DZGF0YT1mdW5jdGlvbihjKXtpZihjPT09XCJdXCIpdGhpcy5fc3RhdGU9QUZURVJfQ0RBVEFfMX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVBZnRlckNkYXRhMT1jaGFyYWN0ZXJTdGF0ZShcIl1cIixBRlRFUl9DREFUQV8yKTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUFmdGVyQ2RhdGEyPWZ1bmN0aW9uKGMpe2lmKGM9PT1cIj5cIil7dGhpcy5fY2JzLm9uY2RhdGEodGhpcy5fYnVmZmVyLnN1YnN0cmluZyh0aGlzLl9zZWN0aW9uU3RhcnQsdGhpcy5faW5kZXgtMikpO3RoaXMuX3N0YXRlPVRFWFQ7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4KzF9ZWxzZSBpZihjIT09XCJdXCIpe3RoaXMuX3N0YXRlPUlOX0NEQVRBfX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVTcGVjaWFsPWZ1bmN0aW9uKGMpe2lmKGM9PT1cImNcInx8Yz09PVwiQ1wiKXt0aGlzLl9zdGF0ZT1CRUZPUkVfU0NSSVBUXzF9ZWxzZSBpZihjPT09XCJ0XCJ8fGM9PT1cIlRcIil7dGhpcy5fc3RhdGU9QkVGT1JFX1NUWUxFXzF9ZWxzZXt0aGlzLl9zdGF0ZT1JTl9UQUdfTkFNRTt0aGlzLl9pbmRleC0tfX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVTcGVjaWFsRW5kPWZ1bmN0aW9uKGMpe2lmKHRoaXMuX3NwZWNpYWw9PT1TUEVDSUFMX1NDUklQVCYmKGM9PT1cImNcInx8Yz09PVwiQ1wiKSl7dGhpcy5fc3RhdGU9QUZURVJfU0NSSVBUXzF9ZWxzZSBpZih0aGlzLl9zcGVjaWFsPT09U1BFQ0lBTF9TVFlMRSYmKGM9PT1cInRcInx8Yz09PVwiVFwiKSl7dGhpcy5fc3RhdGU9QUZURVJfU1RZTEVfMX1lbHNlIHRoaXMuX3N0YXRlPVRFWFR9O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlU2NyaXB0MT1jb25zdW1lU3BlY2lhbE5hbWVDaGFyKFwiUlwiLEJFRk9SRV9TQ1JJUFRfMik7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVTY3JpcHQyPWNvbnN1bWVTcGVjaWFsTmFtZUNoYXIoXCJJXCIsQkVGT1JFX1NDUklQVF8zKTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUJlZm9yZVNjcmlwdDM9Y29uc3VtZVNwZWNpYWxOYW1lQ2hhcihcIlBcIixCRUZPUkVfU0NSSVBUXzQpO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQmVmb3JlU2NyaXB0ND1jb25zdW1lU3BlY2lhbE5hbWVDaGFyKFwiVFwiLEJFRk9SRV9TQ1JJUFRfNSk7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVTY3JpcHQ1PWZ1bmN0aW9uKGMpe2lmKGM9PT1cIi9cInx8Yz09PVwiPlwifHx3aGl0ZXNwYWNlKGMpKXt0aGlzLl9zcGVjaWFsPVNQRUNJQUxfU0NSSVBUfXRoaXMuX3N0YXRlPUlOX1RBR19OQU1FO3RoaXMuX2luZGV4LS19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJTY3JpcHQxPWlmRWxzZVN0YXRlKFwiUlwiLEFGVEVSX1NDUklQVF8yLFRFWFQpO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJTY3JpcHQyPWlmRWxzZVN0YXRlKFwiSVwiLEFGVEVSX1NDUklQVF8zLFRFWFQpO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJTY3JpcHQzPWlmRWxzZVN0YXRlKFwiUFwiLEFGVEVSX1NDUklQVF80LFRFWFQpO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJTY3JpcHQ0PWlmRWxzZVN0YXRlKFwiVFwiLEFGVEVSX1NDUklQVF81LFRFWFQpO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJTY3JpcHQ1PWZ1bmN0aW9uKGMpe2lmKGM9PT1cIj5cInx8d2hpdGVzcGFjZShjKSl7dGhpcy5fc3BlY2lhbD1TUEVDSUFMX05PTkU7dGhpcy5fc3RhdGU9SU5fQ0xPU0lOR19UQUdfTkFNRTt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXgtNjt0aGlzLl9pbmRleC0tfWVsc2UgdGhpcy5fc3RhdGU9VEVYVH07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVTdHlsZTE9Y29uc3VtZVNwZWNpYWxOYW1lQ2hhcihcIllcIixCRUZPUkVfU1RZTEVfMik7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVTdHlsZTI9Y29uc3VtZVNwZWNpYWxOYW1lQ2hhcihcIkxcIixCRUZPUkVfU1RZTEVfMyk7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVTdHlsZTM9Y29uc3VtZVNwZWNpYWxOYW1lQ2hhcihcIkVcIixCRUZPUkVfU1RZTEVfNCk7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVTdHlsZTQ9ZnVuY3Rpb24oYyl7aWYoYz09PVwiL1wifHxjPT09XCI+XCJ8fHdoaXRlc3BhY2UoYykpe3RoaXMuX3NwZWNpYWw9U1BFQ0lBTF9TVFlMRX10aGlzLl9zdGF0ZT1JTl9UQUdfTkFNRTt0aGlzLl9pbmRleC0tfTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUFmdGVyU3R5bGUxPWlmRWxzZVN0YXRlKFwiWVwiLEFGVEVSX1NUWUxFXzIsVEVYVCk7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVBZnRlclN0eWxlMj1pZkVsc2VTdGF0ZShcIkxcIixBRlRFUl9TVFlMRV8zLFRFWFQpO1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlQWZ0ZXJTdHlsZTM9aWZFbHNlU3RhdGUoXCJFXCIsQUZURVJfU1RZTEVfNCxURVhUKTtUb2tlbml6ZXIucHJvdG90eXBlLl9zdGF0ZUFmdGVyU3R5bGU0PWZ1bmN0aW9uKGMpe2lmKGM9PT1cIj5cInx8d2hpdGVzcGFjZShjKSl7dGhpcy5fc3BlY2lhbD1TUEVDSUFMX05PTkU7dGhpcy5fc3RhdGU9SU5fQ0xPU0lOR19UQUdfTkFNRTt0aGlzLl9zZWN0aW9uU3RhcnQ9dGhpcy5faW5kZXgtNTt0aGlzLl9pbmRleC0tfWVsc2UgdGhpcy5fc3RhdGU9VEVYVH07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVFbnRpdHk9aWZFbHNlU3RhdGUoXCIjXCIsQkVGT1JFX05VTUVSSUNfRU5USVRZLElOX05BTUVEX0VOVElUWSk7VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVCZWZvcmVOdW1lcmljRW50aXR5PWlmRWxzZVN0YXRlKFwiWFwiLElOX0hFWF9FTlRJVFksSU5fTlVNRVJJQ19FTlRJVFkpO1Rva2VuaXplci5wcm90b3R5cGUuX3BhcnNlTmFtZWRFbnRpdHlTdHJpY3Q9ZnVuY3Rpb24oKXtpZih0aGlzLl9zZWN0aW9uU3RhcnQrMTx0aGlzLl9pbmRleCl7dmFyIGVudGl0eT10aGlzLl9idWZmZXIuc3Vic3RyaW5nKHRoaXMuX3NlY3Rpb25TdGFydCsxLHRoaXMuX2luZGV4KSxtYXA9dGhpcy5feG1sTW9kZT94bWxNYXA6ZW50aXR5TWFwO2lmKG1hcC5oYXNPd25Qcm9wZXJ0eShlbnRpdHkpKXt0aGlzLl9lbWl0UGFydGlhbChtYXBbZW50aXR5XSk7dGhpcy5fc2VjdGlvblN0YXJ0PXRoaXMuX2luZGV4KzF9fX07VG9rZW5pemVyLnByb3RvdHlwZS5fcGFyc2VMZWdhY3lFbnRpdHk9ZnVuY3Rpb24oKXt2YXIgc3RhcnQ9dGhpcy5fc2VjdGlvblN0YXJ0KzEsbGltaXQ9dGhpcy5faW5kZXgtc3RhcnQ7aWYobGltaXQ+NilsaW1pdD02O3doaWxlKGxpbWl0Pj0yKXt2YXIgZW50aXR5PXRoaXMuX2J1ZmZlci5zdWJzdHIoc3RhcnQsbGltaXQpO2lmKGxlZ2FjeU1hcC5oYXNPd25Qcm9wZXJ0eShlbnRpdHkpKXt0aGlzLl9lbWl0UGFydGlhbChsZWdhY3lNYXBbZW50aXR5XSk7dGhpcy5fc2VjdGlvblN0YXJ0Kz1saW1pdCsxO3JldHVybn1lbHNle2xpbWl0LS19fX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJbk5hbWVkRW50aXR5PWZ1bmN0aW9uKGMpe2lmKGM9PT1cIjtcIil7dGhpcy5fcGFyc2VOYW1lZEVudGl0eVN0cmljdCgpO2lmKHRoaXMuX3NlY3Rpb25TdGFydCsxPHRoaXMuX2luZGV4JiYhdGhpcy5feG1sTW9kZSl7dGhpcy5fcGFyc2VMZWdhY3lFbnRpdHkoKX10aGlzLl9zdGF0ZT10aGlzLl9iYXNlU3RhdGV9ZWxzZSBpZigoYzxcImFcInx8Yz5cInpcIikmJihjPFwiQVwifHxjPlwiWlwiKSYmKGM8XCIwXCJ8fGM+XCI5XCIpKXtpZih0aGlzLl94bWxNb2RlKTtlbHNlIGlmKHRoaXMuX3NlY3Rpb25TdGFydCsxPT09dGhpcy5faW5kZXgpO2Vsc2UgaWYodGhpcy5fYmFzZVN0YXRlIT09VEVYVCl7aWYoYyE9PVwiPVwiKXt0aGlzLl9wYXJzZU5hbWVkRW50aXR5U3RyaWN0KCl9fWVsc2V7dGhpcy5fcGFyc2VMZWdhY3lFbnRpdHkoKX10aGlzLl9zdGF0ZT10aGlzLl9iYXNlU3RhdGU7dGhpcy5faW5kZXgtLX19O1Rva2VuaXplci5wcm90b3R5cGUuX2RlY29kZU51bWVyaWNFbnRpdHk9ZnVuY3Rpb24ob2Zmc2V0LGJhc2Upe3ZhciBzZWN0aW9uU3RhcnQ9dGhpcy5fc2VjdGlvblN0YXJ0K29mZnNldDtpZihzZWN0aW9uU3RhcnQhPT10aGlzLl9pbmRleCl7dmFyIGVudGl0eT10aGlzLl9idWZmZXIuc3Vic3RyaW5nKHNlY3Rpb25TdGFydCx0aGlzLl9pbmRleCk7dmFyIHBhcnNlZD1wYXJzZUludChlbnRpdHksYmFzZSk7dGhpcy5fZW1pdFBhcnRpYWwoZGVjb2RlQ29kZVBvaW50KHBhcnNlZCkpO3RoaXMuX3NlY3Rpb25TdGFydD10aGlzLl9pbmRleH1lbHNle3RoaXMuX3NlY3Rpb25TdGFydC0tfXRoaXMuX3N0YXRlPXRoaXMuX2Jhc2VTdGF0ZX07VG9rZW5pemVyLnByb3RvdHlwZS5fc3RhdGVJbk51bWVyaWNFbnRpdHk9ZnVuY3Rpb24oYyl7aWYoYz09PVwiO1wiKXt0aGlzLl9kZWNvZGVOdW1lcmljRW50aXR5KDIsMTApO3RoaXMuX3NlY3Rpb25TdGFydCsrfWVsc2UgaWYoYzxcIjBcInx8Yz5cIjlcIil7aWYoIXRoaXMuX3htbE1vZGUpe3RoaXMuX2RlY29kZU51bWVyaWNFbnRpdHkoMiwxMCl9ZWxzZXt0aGlzLl9zdGF0ZT10aGlzLl9iYXNlU3RhdGV9dGhpcy5faW5kZXgtLX19O1Rva2VuaXplci5wcm90b3R5cGUuX3N0YXRlSW5IZXhFbnRpdHk9ZnVuY3Rpb24oYyl7aWYoYz09PVwiO1wiKXt0aGlzLl9kZWNvZGVOdW1lcmljRW50aXR5KDMsMTYpO3RoaXMuX3NlY3Rpb25TdGFydCsrfWVsc2UgaWYoKGM8XCJhXCJ8fGM+XCJmXCIpJiYoYzxcIkFcInx8Yz5cIkZcIikmJihjPFwiMFwifHxjPlwiOVwiKSl7aWYoIXRoaXMuX3htbE1vZGUpe3RoaXMuX2RlY29kZU51bWVyaWNFbnRpdHkoMywxNil9ZWxzZXt0aGlzLl9zdGF0ZT10aGlzLl9iYXNlU3RhdGV9dGhpcy5faW5kZXgtLX19O1Rva2VuaXplci5wcm90b3R5cGUuX2NsZWFudXA9ZnVuY3Rpb24oKXtpZih0aGlzLl9zZWN0aW9uU3RhcnQ8MCl7dGhpcy5fYnVmZmVyPVwiXCI7dGhpcy5faW5kZXg9MDt0aGlzLl9idWZmZXJPZmZzZXQrPXRoaXMuX2luZGV4fWVsc2UgaWYodGhpcy5fcnVubmluZyl7aWYodGhpcy5fc3RhdGU9PT1URVhUKXtpZih0aGlzLl9zZWN0aW9uU3RhcnQhPT10aGlzLl9pbmRleCl7dGhpcy5fY2JzLm9udGV4dCh0aGlzLl9idWZmZXIuc3Vic3RyKHRoaXMuX3NlY3Rpb25TdGFydCkpfXRoaXMuX2J1ZmZlcj1cIlwiO3RoaXMuX2J1ZmZlck9mZnNldCs9dGhpcy5faW5kZXg7dGhpcy5faW5kZXg9MH1lbHNlIGlmKHRoaXMuX3NlY3Rpb25TdGFydD09PXRoaXMuX2luZGV4KXt0aGlzLl9idWZmZXI9XCJcIjt0aGlzLl9idWZmZXJPZmZzZXQrPXRoaXMuX2luZGV4O3RoaXMuX2luZGV4PTB9ZWxzZXt0aGlzLl9idWZmZXI9dGhpcy5fYnVmZmVyLnN1YnN0cih0aGlzLl9zZWN0aW9uU3RhcnQpO3RoaXMuX2luZGV4LT10aGlzLl9zZWN0aW9uU3RhcnQ7dGhpcy5fYnVmZmVyT2Zmc2V0Kz10aGlzLl9zZWN0aW9uU3RhcnR9dGhpcy5fc2VjdGlvblN0YXJ0PTB9fTtUb2tlbml6ZXIucHJvdG90eXBlLndyaXRlPWZ1bmN0aW9uKGNodW5rKXtpZih0aGlzLl9lbmRlZCl0aGlzLl9jYnMub25lcnJvcihFcnJvcihcIi53cml0ZSgpIGFmdGVyIGRvbmUhXCIpKTt0aGlzLl9idWZmZXIrPWNodW5rO3RoaXMuX3BhcnNlKCl9O1Rva2VuaXplci5wcm90b3R5cGUuX3BhcnNlPWZ1bmN0aW9uKCl7d2hpbGUodGhpcy5faW5kZXg8dGhpcy5fYnVmZmVyLmxlbmd0aCYmdGhpcy5fcnVubmluZyl7dmFyIGM9dGhpcy5fYnVmZmVyLmNoYXJBdCh0aGlzLl9pbmRleCk7aWYodGhpcy5fc3RhdGU9PT1URVhUKXt0aGlzLl9zdGF0ZVRleHQoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9UQUdfTkFNRSl7dGhpcy5fc3RhdGVCZWZvcmVUYWdOYW1lKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1JTl9UQUdfTkFNRSl7dGhpcy5fc3RhdGVJblRhZ05hbWUoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9DTE9TSU5HX1RBR19OQU1FKXt0aGlzLl9zdGF0ZUJlZm9yZUNsb3NlaW5nVGFnTmFtZShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09SU5fQ0xPU0lOR19UQUdfTkFNRSl7dGhpcy5fc3RhdGVJbkNsb3NlaW5nVGFnTmFtZShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QUZURVJfQ0xPU0lOR19UQUdfTkFNRSl7dGhpcy5fc3RhdGVBZnRlckNsb3NlaW5nVGFnTmFtZShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09SU5fU0VMRl9DTE9TSU5HX1RBRyl7dGhpcy5fc3RhdGVJblNlbGZDbG9zaW5nVGFnKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfQVRUUklCVVRFX05BTUUpe3RoaXMuX3N0YXRlQmVmb3JlQXR0cmlidXRlTmFtZShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09SU5fQVRUUklCVVRFX05BTUUpe3RoaXMuX3N0YXRlSW5BdHRyaWJ1dGVOYW1lKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1BRlRFUl9BVFRSSUJVVEVfTkFNRSl7dGhpcy5fc3RhdGVBZnRlckF0dHJpYnV0ZU5hbWUoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9BVFRSSUJVVEVfVkFMVUUpe3RoaXMuX3N0YXRlQmVmb3JlQXR0cmlidXRlVmFsdWUoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUlOX0FUVFJJQlVURV9WQUxVRV9EUSl7dGhpcy5fc3RhdGVJbkF0dHJpYnV0ZVZhbHVlRG91YmxlUXVvdGVzKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1JTl9BVFRSSUJVVEVfVkFMVUVfU1Epe3RoaXMuX3N0YXRlSW5BdHRyaWJ1dGVWYWx1ZVNpbmdsZVF1b3RlcyhjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09SU5fQVRUUklCVVRFX1ZBTFVFX05RKXt0aGlzLl9zdGF0ZUluQXR0cmlidXRlVmFsdWVOb1F1b3RlcyhjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX0RFQ0xBUkFUSU9OKXt0aGlzLl9zdGF0ZUJlZm9yZURlY2xhcmF0aW9uKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1JTl9ERUNMQVJBVElPTil7dGhpcy5fc3RhdGVJbkRlY2xhcmF0aW9uKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1JTl9QUk9DRVNTSU5HX0lOU1RSVUNUSU9OKXt0aGlzLl9zdGF0ZUluUHJvY2Vzc2luZ0luc3RydWN0aW9uKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfQ09NTUVOVCl7dGhpcy5fc3RhdGVCZWZvcmVDb21tZW50KGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1JTl9DT01NRU5UKXt0aGlzLl9zdGF0ZUluQ29tbWVudChjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QUZURVJfQ09NTUVOVF8xKXt0aGlzLl9zdGF0ZUFmdGVyQ29tbWVudDEoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUFGVEVSX0NPTU1FTlRfMil7dGhpcy5fc3RhdGVBZnRlckNvbW1lbnQyKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfQ0RBVEFfMSl7dGhpcy5fc3RhdGVCZWZvcmVDZGF0YTEoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9DREFUQV8yKXt0aGlzLl9zdGF0ZUJlZm9yZUNkYXRhMihjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX0NEQVRBXzMpe3RoaXMuX3N0YXRlQmVmb3JlQ2RhdGEzKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfQ0RBVEFfNCl7dGhpcy5fc3RhdGVCZWZvcmVDZGF0YTQoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9DREFUQV81KXt0aGlzLl9zdGF0ZUJlZm9yZUNkYXRhNShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX0NEQVRBXzYpe3RoaXMuX3N0YXRlQmVmb3JlQ2RhdGE2KGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1JTl9DREFUQSl7dGhpcy5fc3RhdGVJbkNkYXRhKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1BRlRFUl9DREFUQV8xKXt0aGlzLl9zdGF0ZUFmdGVyQ2RhdGExKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1BRlRFUl9DREFUQV8yKXt0aGlzLl9zdGF0ZUFmdGVyQ2RhdGEyKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfU1BFQ0lBTCl7dGhpcy5fc3RhdGVCZWZvcmVTcGVjaWFsKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfU1BFQ0lBTF9FTkQpe3RoaXMuX3N0YXRlQmVmb3JlU3BlY2lhbEVuZChjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX1NDUklQVF8xKXt0aGlzLl9zdGF0ZUJlZm9yZVNjcmlwdDEoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9TQ1JJUFRfMil7dGhpcy5fc3RhdGVCZWZvcmVTY3JpcHQyKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfU0NSSVBUXzMpe3RoaXMuX3N0YXRlQmVmb3JlU2NyaXB0MyhjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX1NDUklQVF80KXt0aGlzLl9zdGF0ZUJlZm9yZVNjcmlwdDQoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9TQ1JJUFRfNSl7dGhpcy5fc3RhdGVCZWZvcmVTY3JpcHQ1KGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1BRlRFUl9TQ1JJUFRfMSl7dGhpcy5fc3RhdGVBZnRlclNjcmlwdDEoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUFGVEVSX1NDUklQVF8yKXt0aGlzLl9zdGF0ZUFmdGVyU2NyaXB0MihjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QUZURVJfU0NSSVBUXzMpe3RoaXMuX3N0YXRlQWZ0ZXJTY3JpcHQzKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1BRlRFUl9TQ1JJUFRfNCl7dGhpcy5fc3RhdGVBZnRlclNjcmlwdDQoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUFGVEVSX1NDUklQVF81KXt0aGlzLl9zdGF0ZUFmdGVyU2NyaXB0NShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX1NUWUxFXzEpe3RoaXMuX3N0YXRlQmVmb3JlU3R5bGUxKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfU1RZTEVfMil7dGhpcy5fc3RhdGVCZWZvcmVTdHlsZTIoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUJFRk9SRV9TVFlMRV8zKXt0aGlzLl9zdGF0ZUJlZm9yZVN0eWxlMyhjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX1NUWUxFXzQpe3RoaXMuX3N0YXRlQmVmb3JlU3R5bGU0KGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1BRlRFUl9TVFlMRV8xKXt0aGlzLl9zdGF0ZUFmdGVyU3R5bGUxKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1BRlRFUl9TVFlMRV8yKXt0aGlzLl9zdGF0ZUFmdGVyU3R5bGUyKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1BRlRFUl9TVFlMRV8zKXt0aGlzLl9zdGF0ZUFmdGVyU3R5bGUzKGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1BRlRFUl9TVFlMRV80KXt0aGlzLl9zdGF0ZUFmdGVyU3R5bGU0KGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1CRUZPUkVfRU5USVRZKXt0aGlzLl9zdGF0ZUJlZm9yZUVudGl0eShjKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09QkVGT1JFX05VTUVSSUNfRU5USVRZKXt0aGlzLl9zdGF0ZUJlZm9yZU51bWVyaWNFbnRpdHkoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUlOX05BTUVEX0VOVElUWSl7dGhpcy5fc3RhdGVJbk5hbWVkRW50aXR5KGMpfWVsc2UgaWYodGhpcy5fc3RhdGU9PT1JTl9OVU1FUklDX0VOVElUWSl7dGhpcy5fc3RhdGVJbk51bWVyaWNFbnRpdHkoYyl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUlOX0hFWF9FTlRJVFkpe3RoaXMuX3N0YXRlSW5IZXhFbnRpdHkoYyl9ZWxzZXt0aGlzLl9jYnMub25lcnJvcihFcnJvcihcInVua25vd24gX3N0YXRlXCIpLHRoaXMuX3N0YXRlKX10aGlzLl9pbmRleCsrfXRoaXMuX2NsZWFudXAoKX07VG9rZW5pemVyLnByb3RvdHlwZS5wYXVzZT1mdW5jdGlvbigpe3RoaXMuX3J1bm5pbmc9ZmFsc2V9O1Rva2VuaXplci5wcm90b3R5cGUucmVzdW1lPWZ1bmN0aW9uKCl7dGhpcy5fcnVubmluZz10cnVlO2lmKHRoaXMuX2luZGV4PHRoaXMuX2J1ZmZlci5sZW5ndGgpe3RoaXMuX3BhcnNlKCl9aWYodGhpcy5fZW5kZWQpe3RoaXMuX2ZpbmlzaCgpfX07VG9rZW5pemVyLnByb3RvdHlwZS5lbmQ9ZnVuY3Rpb24oY2h1bmspe2lmKHRoaXMuX2VuZGVkKXRoaXMuX2Nicy5vbmVycm9yKEVycm9yKFwiLmVuZCgpIGFmdGVyIGRvbmUhXCIpKTtpZihjaHVuayl0aGlzLndyaXRlKGNodW5rKTt0aGlzLl9lbmRlZD10cnVlO2lmKHRoaXMuX3J1bm5pbmcpdGhpcy5fZmluaXNoKCl9O1Rva2VuaXplci5wcm90b3R5cGUuX2ZpbmlzaD1mdW5jdGlvbigpe2lmKHRoaXMuX3NlY3Rpb25TdGFydDx0aGlzLl9pbmRleCl7dGhpcy5faGFuZGxlVHJhaWxpbmdEYXRhKCl9dGhpcy5fY2JzLm9uZW5kKCl9O1Rva2VuaXplci5wcm90b3R5cGUuX2hhbmRsZVRyYWlsaW5nRGF0YT1mdW5jdGlvbigpe3ZhciBkYXRhPXRoaXMuX2J1ZmZlci5zdWJzdHIodGhpcy5fc2VjdGlvblN0YXJ0KTtpZih0aGlzLl9zdGF0ZT09PUlOX0NEQVRBfHx0aGlzLl9zdGF0ZT09PUFGVEVSX0NEQVRBXzF8fHRoaXMuX3N0YXRlPT09QUZURVJfQ0RBVEFfMil7dGhpcy5fY2JzLm9uY2RhdGEoZGF0YSl9ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUlOX0NPTU1FTlR8fHRoaXMuX3N0YXRlPT09QUZURVJfQ09NTUVOVF8xfHx0aGlzLl9zdGF0ZT09PUFGVEVSX0NPTU1FTlRfMil7dGhpcy5fY2JzLm9uY29tbWVudChkYXRhKX1lbHNlIGlmKHRoaXMuX3N0YXRlPT09SU5fTkFNRURfRU5USVRZJiYhdGhpcy5feG1sTW9kZSl7dGhpcy5fcGFyc2VMZWdhY3lFbnRpdHkoKTtpZih0aGlzLl9zZWN0aW9uU3RhcnQ8dGhpcy5faW5kZXgpe3RoaXMuX3N0YXRlPXRoaXMuX2Jhc2VTdGF0ZTt0aGlzLl9oYW5kbGVUcmFpbGluZ0RhdGEoKX19ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUlOX05VTUVSSUNfRU5USVRZJiYhdGhpcy5feG1sTW9kZSl7dGhpcy5fZGVjb2RlTnVtZXJpY0VudGl0eSgyLDEwKTtpZih0aGlzLl9zZWN0aW9uU3RhcnQ8dGhpcy5faW5kZXgpe3RoaXMuX3N0YXRlPXRoaXMuX2Jhc2VTdGF0ZTt0aGlzLl9oYW5kbGVUcmFpbGluZ0RhdGEoKX19ZWxzZSBpZih0aGlzLl9zdGF0ZT09PUlOX0hFWF9FTlRJVFkmJiF0aGlzLl94bWxNb2RlKXt0aGlzLl9kZWNvZGVOdW1lcmljRW50aXR5KDMsMTYpO2lmKHRoaXMuX3NlY3Rpb25TdGFydDx0aGlzLl9pbmRleCl7dGhpcy5fc3RhdGU9dGhpcy5fYmFzZVN0YXRlO3RoaXMuX2hhbmRsZVRyYWlsaW5nRGF0YSgpfX1lbHNlIGlmKHRoaXMuX3N0YXRlIT09SU5fVEFHX05BTUUmJnRoaXMuX3N0YXRlIT09QkVGT1JFX0FUVFJJQlVURV9OQU1FJiZ0aGlzLl9zdGF0ZSE9PUJFRk9SRV9BVFRSSUJVVEVfVkFMVUUmJnRoaXMuX3N0YXRlIT09QUZURVJfQVRUUklCVVRFX05BTUUmJnRoaXMuX3N0YXRlIT09SU5fQVRUUklCVVRFX05BTUUmJnRoaXMuX3N0YXRlIT09SU5fQVRUUklCVVRFX1ZBTFVFX1NRJiZ0aGlzLl9zdGF0ZSE9PUlOX0FUVFJJQlVURV9WQUxVRV9EUSYmdGhpcy5fc3RhdGUhPT1JTl9BVFRSSUJVVEVfVkFMVUVfTlEmJnRoaXMuX3N0YXRlIT09SU5fQ0xPU0lOR19UQUdfTkFNRSl7XG50aGlzLl9jYnMub250ZXh0KGRhdGEpfX07VG9rZW5pemVyLnByb3RvdHlwZS5yZXNldD1mdW5jdGlvbigpe1Rva2VuaXplci5jYWxsKHRoaXMse3htbE1vZGU6dGhpcy5feG1sTW9kZSxkZWNvZGVFbnRpdGllczp0aGlzLl9kZWNvZGVFbnRpdGllc30sdGhpcy5fY2JzKX07VG9rZW5pemVyLnByb3RvdHlwZS5nZXRBYnNvbHV0ZUluZGV4PWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuX2J1ZmZlck9mZnNldCt0aGlzLl9pbmRleH07VG9rZW5pemVyLnByb3RvdHlwZS5fZ2V0U2VjdGlvbj1mdW5jdGlvbigpe3JldHVybiB0aGlzLl9idWZmZXIuc3Vic3RyaW5nKHRoaXMuX3NlY3Rpb25TdGFydCx0aGlzLl9pbmRleCl9O1Rva2VuaXplci5wcm90b3R5cGUuX2VtaXRUb2tlbj1mdW5jdGlvbihuYW1lKXt0aGlzLl9jYnNbbmFtZV0odGhpcy5fZ2V0U2VjdGlvbigpKTt0aGlzLl9zZWN0aW9uU3RhcnQ9LTF9O1Rva2VuaXplci5wcm90b3R5cGUuX2VtaXRQYXJ0aWFsPWZ1bmN0aW9uKHZhbHVlKXtpZih0aGlzLl9iYXNlU3RhdGUhPT1URVhUKXt0aGlzLl9jYnMub25hdHRyaWJkYXRhKHZhbHVlKX1lbHNle3RoaXMuX2Nicy5vbnRleHQodmFsdWUpfX19LHtcImVudGl0aWVzL2xpYi9kZWNvZGVfY29kZXBvaW50LmpzXCI6MjIsXCJlbnRpdGllcy9tYXBzL2VudGl0aWVzLmpzb25cIjoyNSxcImVudGl0aWVzL21hcHMvbGVnYWN5Lmpzb25cIjoyNixcImVudGl0aWVzL21hcHMveG1sLmpzb25cIjoyN31dLDM1OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXttb2R1bGUuZXhwb3J0cz1TdHJlYW07dmFyIFBhcnNlcj1yZXF1aXJlKFwiLi9QYXJzZXIuanNcIiksV3JpdGFibGVTdHJlYW09cmVxdWlyZShcInN0cmVhbVwiKS5Xcml0YWJsZXx8cmVxdWlyZShcInJlYWRhYmxlLXN0cmVhbVwiKS5Xcml0YWJsZSxTdHJpbmdEZWNvZGVyPXJlcXVpcmUoXCJzdHJpbmdfZGVjb2RlclwiKS5TdHJpbmdEZWNvZGVyLEJ1ZmZlcj1yZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcjtmdW5jdGlvbiBTdHJlYW0oY2JzLG9wdGlvbnMpe3ZhciBwYXJzZXI9dGhpcy5fcGFyc2VyPW5ldyBQYXJzZXIoY2JzLG9wdGlvbnMpO3ZhciBkZWNvZGVyPXRoaXMuX2RlY29kZXI9bmV3IFN0cmluZ0RlY29kZXI7V3JpdGFibGVTdHJlYW0uY2FsbCh0aGlzLHtkZWNvZGVTdHJpbmdzOmZhbHNlfSk7dGhpcy5vbmNlKFwiZmluaXNoXCIsZnVuY3Rpb24oKXtwYXJzZXIuZW5kKGRlY29kZXIuZW5kKCkpfSl9cmVxdWlyZShcImluaGVyaXRzXCIpKFN0cmVhbSxXcml0YWJsZVN0cmVhbSk7V3JpdGFibGVTdHJlYW0ucHJvdG90eXBlLl93cml0ZT1mdW5jdGlvbihjaHVuayxlbmNvZGluZyxjYil7aWYoY2h1bmsgaW5zdGFuY2VvZiBCdWZmZXIpY2h1bms9dGhpcy5fZGVjb2Rlci53cml0ZShjaHVuayk7dGhpcy5fcGFyc2VyLndyaXRlKGNodW5rKTtjYigpfX0se1wiLi9QYXJzZXIuanNcIjozMSxidWZmZXI6NSxpbmhlcml0czozOCxcInJlYWRhYmxlLXN0cmVhbVwiOjMsc3RyZWFtOjU1LHN0cmluZ19kZWNvZGVyOjU2fV0sMzY6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe3ZhciBQYXJzZXI9cmVxdWlyZShcIi4vUGFyc2VyLmpzXCIpLERvbUhhbmRsZXI9cmVxdWlyZShcImRvbWhhbmRsZXJcIik7ZnVuY3Rpb24gZGVmaW5lUHJvcChuYW1lLHZhbHVlKXtkZWxldGUgbW9kdWxlLmV4cG9ydHNbbmFtZV07bW9kdWxlLmV4cG9ydHNbbmFtZV09dmFsdWU7cmV0dXJuIHZhbHVlfW1vZHVsZS5leHBvcnRzPXtQYXJzZXI6UGFyc2VyLFRva2VuaXplcjpyZXF1aXJlKFwiLi9Ub2tlbml6ZXIuanNcIiksRWxlbWVudFR5cGU6cmVxdWlyZShcImRvbWVsZW1lbnR0eXBlXCIpLERvbUhhbmRsZXI6RG9tSGFuZGxlcixnZXQgRmVlZEhhbmRsZXIoKXtyZXR1cm4gZGVmaW5lUHJvcChcIkZlZWRIYW5kbGVyXCIscmVxdWlyZShcIi4vRmVlZEhhbmRsZXIuanNcIikpfSxnZXQgU3RyZWFtKCl7cmV0dXJuIGRlZmluZVByb3AoXCJTdHJlYW1cIixyZXF1aXJlKFwiLi9TdHJlYW0uanNcIikpfSxnZXQgV3JpdGFibGVTdHJlYW0oKXtyZXR1cm4gZGVmaW5lUHJvcChcIldyaXRhYmxlU3RyZWFtXCIscmVxdWlyZShcIi4vV3JpdGFibGVTdHJlYW0uanNcIikpfSxnZXQgUHJveHlIYW5kbGVyKCl7cmV0dXJuIGRlZmluZVByb3AoXCJQcm94eUhhbmRsZXJcIixyZXF1aXJlKFwiLi9Qcm94eUhhbmRsZXIuanNcIikpfSxnZXQgRG9tVXRpbHMoKXtyZXR1cm4gZGVmaW5lUHJvcChcIkRvbVV0aWxzXCIscmVxdWlyZShcImRvbXV0aWxzXCIpKX0sZ2V0IENvbGxlY3RpbmdIYW5kbGVyKCl7cmV0dXJuIGRlZmluZVByb3AoXCJDb2xsZWN0aW5nSGFuZGxlclwiLHJlcXVpcmUoXCIuL0NvbGxlY3RpbmdIYW5kbGVyLmpzXCIpKX0sRGVmYXVsdEhhbmRsZXI6RG9tSGFuZGxlcixnZXQgUnNzSGFuZGxlcigpe3JldHVybiBkZWZpbmVQcm9wKFwiUnNzSGFuZGxlclwiLHRoaXMuRmVlZEhhbmRsZXIpfSxwYXJzZURPTTpmdW5jdGlvbihkYXRhLG9wdGlvbnMpe3ZhciBoYW5kbGVyPW5ldyBEb21IYW5kbGVyKG9wdGlvbnMpO25ldyBQYXJzZXIoaGFuZGxlcixvcHRpb25zKS5lbmQoZGF0YSk7cmV0dXJuIGhhbmRsZXIuZG9tfSxwYXJzZUZlZWQ6ZnVuY3Rpb24oZmVlZCxvcHRpb25zKXt2YXIgaGFuZGxlcj1uZXcgbW9kdWxlLmV4cG9ydHMuRmVlZEhhbmRsZXIob3B0aW9ucyk7bmV3IFBhcnNlcihoYW5kbGVyLG9wdGlvbnMpLmVuZChmZWVkKTtyZXR1cm4gaGFuZGxlci5kb219LGNyZWF0ZURvbVN0cmVhbTpmdW5jdGlvbihjYixvcHRpb25zLGVsZW1lbnRDYil7dmFyIGhhbmRsZXI9bmV3IERvbUhhbmRsZXIoY2Isb3B0aW9ucyxlbGVtZW50Q2IpO3JldHVybiBuZXcgUGFyc2VyKGhhbmRsZXIsb3B0aW9ucyl9LEVWRU5UUzp7YXR0cmlidXRlOjIsY2RhdGFzdGFydDowLGNkYXRhZW5kOjAsdGV4dDoxLHByb2Nlc3NpbmdpbnN0cnVjdGlvbjoyLGNvbW1lbnQ6MSxjb21tZW50ZW5kOjAsY2xvc2V0YWc6MSxvcGVudGFnOjIsb3BlbnRhZ25hbWU6MSxlcnJvcjoxLGVuZDowfX19LHtcIi4vQ29sbGVjdGluZ0hhbmRsZXIuanNcIjoyOSxcIi4vRmVlZEhhbmRsZXIuanNcIjozMCxcIi4vUGFyc2VyLmpzXCI6MzEsXCIuL1Byb3h5SGFuZGxlci5qc1wiOjMyLFwiLi9TdHJlYW0uanNcIjozMyxcIi4vVG9rZW5pemVyLmpzXCI6MzQsXCIuL1dyaXRhYmxlU3RyZWFtLmpzXCI6MzUsZG9tZWxlbWVudHR5cGU6OSxkb21oYW5kbGVyOjEwLGRvbXV0aWxzOjEzfV0sMzc6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe2V4cG9ydHMucmVhZD1mdW5jdGlvbihidWZmZXIsb2Zmc2V0LGlzTEUsbUxlbixuQnl0ZXMpe3ZhciBlLG07dmFyIGVMZW49bkJ5dGVzKjgtbUxlbi0xO3ZhciBlTWF4PSgxPDxlTGVuKS0xO3ZhciBlQmlhcz1lTWF4Pj4xO3ZhciBuQml0cz0tNzt2YXIgaT1pc0xFP25CeXRlcy0xOjA7dmFyIGQ9aXNMRT8tMToxO3ZhciBzPWJ1ZmZlcltvZmZzZXQraV07aSs9ZDtlPXMmKDE8PC1uQml0cyktMTtzPj49LW5CaXRzO25CaXRzKz1lTGVuO2Zvcig7bkJpdHM+MDtlPWUqMjU2K2J1ZmZlcltvZmZzZXQraV0saSs9ZCxuQml0cy09OCl7fW09ZSYoMTw8LW5CaXRzKS0xO2U+Pj0tbkJpdHM7bkJpdHMrPW1MZW47Zm9yKDtuQml0cz4wO209bSoyNTYrYnVmZmVyW29mZnNldCtpXSxpKz1kLG5CaXRzLT04KXt9aWYoZT09PTApe2U9MS1lQmlhc31lbHNlIGlmKGU9PT1lTWF4KXtyZXR1cm4gbT9OYU46KHM/LTE6MSkqSW5maW5pdHl9ZWxzZXttPW0rTWF0aC5wb3coMixtTGVuKTtlPWUtZUJpYXN9cmV0dXJuKHM/LTE6MSkqbSpNYXRoLnBvdygyLGUtbUxlbil9O2V4cG9ydHMud3JpdGU9ZnVuY3Rpb24oYnVmZmVyLHZhbHVlLG9mZnNldCxpc0xFLG1MZW4sbkJ5dGVzKXt2YXIgZSxtLGM7dmFyIGVMZW49bkJ5dGVzKjgtbUxlbi0xO3ZhciBlTWF4PSgxPDxlTGVuKS0xO3ZhciBlQmlhcz1lTWF4Pj4xO3ZhciBydD1tTGVuPT09MjM/TWF0aC5wb3coMiwtMjQpLU1hdGgucG93KDIsLTc3KTowO3ZhciBpPWlzTEU/MDpuQnl0ZXMtMTt2YXIgZD1pc0xFPzE6LTE7dmFyIHM9dmFsdWU8MHx8dmFsdWU9PT0wJiYxL3ZhbHVlPDA/MTowO3ZhbHVlPU1hdGguYWJzKHZhbHVlKTtpZihpc05hTih2YWx1ZSl8fHZhbHVlPT09SW5maW5pdHkpe209aXNOYU4odmFsdWUpPzE6MDtlPWVNYXh9ZWxzZXtlPU1hdGguZmxvb3IoTWF0aC5sb2codmFsdWUpL01hdGguTE4yKTtpZih2YWx1ZSooYz1NYXRoLnBvdygyLC1lKSk8MSl7ZS0tO2MqPTJ9aWYoZStlQmlhcz49MSl7dmFsdWUrPXJ0L2N9ZWxzZXt2YWx1ZSs9cnQqTWF0aC5wb3coMiwxLWVCaWFzKX1pZih2YWx1ZSpjPj0yKXtlKys7Yy89Mn1pZihlK2VCaWFzPj1lTWF4KXttPTA7ZT1lTWF4fWVsc2UgaWYoZStlQmlhcz49MSl7bT0odmFsdWUqYy0xKSpNYXRoLnBvdygyLG1MZW4pO2U9ZStlQmlhc31lbHNle209dmFsdWUqTWF0aC5wb3coMixlQmlhcy0xKSpNYXRoLnBvdygyLG1MZW4pO2U9MH19Zm9yKDttTGVuPj04O2J1ZmZlcltvZmZzZXQraV09bSYyNTUsaSs9ZCxtLz0yNTYsbUxlbi09OCl7fWU9ZTw8bUxlbnxtO2VMZW4rPW1MZW47Zm9yKDtlTGVuPjA7YnVmZmVyW29mZnNldCtpXT1lJjI1NSxpKz1kLGUvPTI1NixlTGVuLT04KXt9YnVmZmVyW29mZnNldCtpLWRdfD1zKjEyOH19LHt9XSwzODpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7aWYodHlwZW9mIE9iamVjdC5jcmVhdGU9PT1cImZ1bmN0aW9uXCIpe21vZHVsZS5leHBvcnRzPWZ1bmN0aW9uIGluaGVyaXRzKGN0b3Isc3VwZXJDdG9yKXtjdG9yLnN1cGVyXz1zdXBlckN0b3I7Y3Rvci5wcm90b3R5cGU9T2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLHtjb25zdHJ1Y3Rvcjp7dmFsdWU6Y3RvcixlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29uZmlndXJhYmxlOnRydWV9fSl9fWVsc2V7bW9kdWxlLmV4cG9ydHM9ZnVuY3Rpb24gaW5oZXJpdHMoY3RvcixzdXBlckN0b3Ipe2N0b3Iuc3VwZXJfPXN1cGVyQ3Rvcjt2YXIgVGVtcEN0b3I9ZnVuY3Rpb24oKXt9O1RlbXBDdG9yLnByb3RvdHlwZT1zdXBlckN0b3IucHJvdG90eXBlO2N0b3IucHJvdG90eXBlPW5ldyBUZW1wQ3RvcjtjdG9yLnByb3RvdHlwZS5jb25zdHJ1Y3Rvcj1jdG9yfX19LHt9XSwzOTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9ZnVuY3Rpb24ob2JqKXtyZXR1cm4gb2JqIT1udWxsJiYoaXNCdWZmZXIob2JqKXx8aXNTbG93QnVmZmVyKG9iail8fCEhb2JqLl9pc0J1ZmZlcil9O2Z1bmN0aW9uIGlzQnVmZmVyKG9iail7cmV0dXJuISFvYmouY29uc3RydWN0b3ImJnR5cGVvZiBvYmouY29uc3RydWN0b3IuaXNCdWZmZXI9PT1cImZ1bmN0aW9uXCImJm9iai5jb25zdHJ1Y3Rvci5pc0J1ZmZlcihvYmopfWZ1bmN0aW9uIGlzU2xvd0J1ZmZlcihvYmope3JldHVybiB0eXBlb2Ygb2JqLnJlYWRGbG9hdExFPT09XCJmdW5jdGlvblwiJiZ0eXBlb2Ygb2JqLnNsaWNlPT09XCJmdW5jdGlvblwiJiZpc0J1ZmZlcihvYmouc2xpY2UoMCwwKSl9fSx7fV0sNDA6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe3ZhciB0b1N0cmluZz17fS50b1N0cmluZzttb2R1bGUuZXhwb3J0cz1BcnJheS5pc0FycmF5fHxmdW5jdGlvbihhcnIpe3JldHVybiB0b1N0cmluZy5jYWxsKGFycik9PVwiW29iamVjdCBBcnJheV1cIn19LHt9XSw0MTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7KGZ1bmN0aW9uKHByb2Nlc3Mpe1widXNlIHN0cmljdFwiO2lmKCFwcm9jZXNzLnZlcnNpb258fHByb2Nlc3MudmVyc2lvbi5pbmRleE9mKFwidjAuXCIpPT09MHx8cHJvY2Vzcy52ZXJzaW9uLmluZGV4T2YoXCJ2MS5cIik9PT0wJiZwcm9jZXNzLnZlcnNpb24uaW5kZXhPZihcInYxLjguXCIpIT09MCl7bW9kdWxlLmV4cG9ydHM9bmV4dFRpY2t9ZWxzZXttb2R1bGUuZXhwb3J0cz1wcm9jZXNzLm5leHRUaWNrfWZ1bmN0aW9uIG5leHRUaWNrKGZuLGFyZzEsYXJnMixhcmczKXtpZih0eXBlb2YgZm4hPT1cImZ1bmN0aW9uXCIpe3Rocm93IG5ldyBUeXBlRXJyb3IoJ1wiY2FsbGJhY2tcIiBhcmd1bWVudCBtdXN0IGJlIGEgZnVuY3Rpb24nKX12YXIgbGVuPWFyZ3VtZW50cy5sZW5ndGg7dmFyIGFyZ3MsaTtzd2l0Y2gobGVuKXtjYXNlIDA6Y2FzZSAxOnJldHVybiBwcm9jZXNzLm5leHRUaWNrKGZuKTtjYXNlIDI6cmV0dXJuIHByb2Nlc3MubmV4dFRpY2soZnVuY3Rpb24gYWZ0ZXJUaWNrT25lKCl7Zm4uY2FsbChudWxsLGFyZzEpfSk7Y2FzZSAzOnJldHVybiBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uIGFmdGVyVGlja1R3bygpe2ZuLmNhbGwobnVsbCxhcmcxLGFyZzIpfSk7Y2FzZSA0OnJldHVybiBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uIGFmdGVyVGlja1RocmVlKCl7Zm4uY2FsbChudWxsLGFyZzEsYXJnMixhcmczKX0pO2RlZmF1bHQ6YXJncz1uZXcgQXJyYXkobGVuLTEpO2k9MDt3aGlsZShpPGFyZ3MubGVuZ3RoKXthcmdzW2krK109YXJndW1lbnRzW2ldfXJldHVybiBwcm9jZXNzLm5leHRUaWNrKGZ1bmN0aW9uIGFmdGVyVGljaygpe2ZuLmFwcGx5KG51bGwsYXJncyl9KX19fSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJfcHJvY2Vzc1wiKSl9LHtfcHJvY2Vzczo0Mn1dLDQyOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgcHJvY2Vzcz1tb2R1bGUuZXhwb3J0cz17fTt2YXIgY2FjaGVkU2V0VGltZW91dDt2YXIgY2FjaGVkQ2xlYXJUaW1lb3V0O2Z1bmN0aW9uIGRlZmF1bHRTZXRUaW1vdXQoKXt0aHJvdyBuZXcgRXJyb3IoXCJzZXRUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkXCIpfWZ1bmN0aW9uIGRlZmF1bHRDbGVhclRpbWVvdXQoKXt0aHJvdyBuZXcgRXJyb3IoXCJjbGVhclRpbWVvdXQgaGFzIG5vdCBiZWVuIGRlZmluZWRcIil9KGZ1bmN0aW9uKCl7dHJ5e2lmKHR5cGVvZiBzZXRUaW1lb3V0PT09XCJmdW5jdGlvblwiKXtjYWNoZWRTZXRUaW1lb3V0PXNldFRpbWVvdXR9ZWxzZXtjYWNoZWRTZXRUaW1lb3V0PWRlZmF1bHRTZXRUaW1vdXR9fWNhdGNoKGUpe2NhY2hlZFNldFRpbWVvdXQ9ZGVmYXVsdFNldFRpbW91dH10cnl7aWYodHlwZW9mIGNsZWFyVGltZW91dD09PVwiZnVuY3Rpb25cIil7Y2FjaGVkQ2xlYXJUaW1lb3V0PWNsZWFyVGltZW91dH1lbHNle2NhY2hlZENsZWFyVGltZW91dD1kZWZhdWx0Q2xlYXJUaW1lb3V0fX1jYXRjaChlKXtjYWNoZWRDbGVhclRpbWVvdXQ9ZGVmYXVsdENsZWFyVGltZW91dH19KSgpO2Z1bmN0aW9uIHJ1blRpbWVvdXQoZnVuKXtpZihjYWNoZWRTZXRUaW1lb3V0PT09c2V0VGltZW91dCl7cmV0dXJuIHNldFRpbWVvdXQoZnVuLDApfWlmKChjYWNoZWRTZXRUaW1lb3V0PT09ZGVmYXVsdFNldFRpbW91dHx8IWNhY2hlZFNldFRpbWVvdXQpJiZzZXRUaW1lb3V0KXtjYWNoZWRTZXRUaW1lb3V0PXNldFRpbWVvdXQ7cmV0dXJuIHNldFRpbWVvdXQoZnVuLDApfXRyeXtyZXR1cm4gY2FjaGVkU2V0VGltZW91dChmdW4sMCl9Y2F0Y2goZSl7dHJ5e3JldHVybiBjYWNoZWRTZXRUaW1lb3V0LmNhbGwobnVsbCxmdW4sMCl9Y2F0Y2goZSl7cmV0dXJuIGNhY2hlZFNldFRpbWVvdXQuY2FsbCh0aGlzLGZ1biwwKX19fWZ1bmN0aW9uIHJ1bkNsZWFyVGltZW91dChtYXJrZXIpe2lmKGNhY2hlZENsZWFyVGltZW91dD09PWNsZWFyVGltZW91dCl7cmV0dXJuIGNsZWFyVGltZW91dChtYXJrZXIpfWlmKChjYWNoZWRDbGVhclRpbWVvdXQ9PT1kZWZhdWx0Q2xlYXJUaW1lb3V0fHwhY2FjaGVkQ2xlYXJUaW1lb3V0KSYmY2xlYXJUaW1lb3V0KXtjYWNoZWRDbGVhclRpbWVvdXQ9Y2xlYXJUaW1lb3V0O3JldHVybiBjbGVhclRpbWVvdXQobWFya2VyKX10cnl7cmV0dXJuIGNhY2hlZENsZWFyVGltZW91dChtYXJrZXIpfWNhdGNoKGUpe3RyeXtyZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0LmNhbGwobnVsbCxtYXJrZXIpfWNhdGNoKGUpe3JldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbCh0aGlzLG1hcmtlcil9fX12YXIgcXVldWU9W107dmFyIGRyYWluaW5nPWZhbHNlO3ZhciBjdXJyZW50UXVldWU7dmFyIHF1ZXVlSW5kZXg9LTE7ZnVuY3Rpb24gY2xlYW5VcE5leHRUaWNrKCl7aWYoIWRyYWluaW5nfHwhY3VycmVudFF1ZXVlKXtyZXR1cm59ZHJhaW5pbmc9ZmFsc2U7aWYoY3VycmVudFF1ZXVlLmxlbmd0aCl7cXVldWU9Y3VycmVudFF1ZXVlLmNvbmNhdChxdWV1ZSl9ZWxzZXtxdWV1ZUluZGV4PS0xfWlmKHF1ZXVlLmxlbmd0aCl7ZHJhaW5RdWV1ZSgpfX1mdW5jdGlvbiBkcmFpblF1ZXVlKCl7aWYoZHJhaW5pbmcpe3JldHVybn12YXIgdGltZW91dD1ydW5UaW1lb3V0KGNsZWFuVXBOZXh0VGljayk7ZHJhaW5pbmc9dHJ1ZTt2YXIgbGVuPXF1ZXVlLmxlbmd0aDt3aGlsZShsZW4pe2N1cnJlbnRRdWV1ZT1xdWV1ZTtxdWV1ZT1bXTt3aGlsZSgrK3F1ZXVlSW5kZXg8bGVuKXtpZihjdXJyZW50UXVldWUpe2N1cnJlbnRRdWV1ZVtxdWV1ZUluZGV4XS5ydW4oKX19cXVldWVJbmRleD0tMTtsZW49cXVldWUubGVuZ3RofWN1cnJlbnRRdWV1ZT1udWxsO2RyYWluaW5nPWZhbHNlO3J1bkNsZWFyVGltZW91dCh0aW1lb3V0KX1wcm9jZXNzLm5leHRUaWNrPWZ1bmN0aW9uKGZ1bil7dmFyIGFyZ3M9bmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGgtMSk7aWYoYXJndW1lbnRzLmxlbmd0aD4xKXtmb3IodmFyIGk9MTtpPGFyZ3VtZW50cy5sZW5ndGg7aSsrKXthcmdzW2ktMV09YXJndW1lbnRzW2ldfX1xdWV1ZS5wdXNoKG5ldyBJdGVtKGZ1bixhcmdzKSk7aWYocXVldWUubGVuZ3RoPT09MSYmIWRyYWluaW5nKXtydW5UaW1lb3V0KGRyYWluUXVldWUpfX07ZnVuY3Rpb24gSXRlbShmdW4sYXJyYXkpe3RoaXMuZnVuPWZ1bjt0aGlzLmFycmF5PWFycmF5fUl0ZW0ucHJvdG90eXBlLnJ1bj1mdW5jdGlvbigpe3RoaXMuZnVuLmFwcGx5KG51bGwsdGhpcy5hcnJheSl9O3Byb2Nlc3MudGl0bGU9XCJicm93c2VyXCI7cHJvY2Vzcy5icm93c2VyPXRydWU7cHJvY2Vzcy5lbnY9e307cHJvY2Vzcy5hcmd2PVtdO3Byb2Nlc3MudmVyc2lvbj1cIlwiO3Byb2Nlc3MudmVyc2lvbnM9e307ZnVuY3Rpb24gbm9vcCgpe31wcm9jZXNzLm9uPW5vb3A7cHJvY2Vzcy5hZGRMaXN0ZW5lcj1ub29wO3Byb2Nlc3Mub25jZT1ub29wO3Byb2Nlc3Mub2ZmPW5vb3A7cHJvY2Vzcy5yZW1vdmVMaXN0ZW5lcj1ub29wO3Byb2Nlc3MucmVtb3ZlQWxsTGlzdGVuZXJzPW5vb3A7cHJvY2Vzcy5lbWl0PW5vb3A7cHJvY2Vzcy5iaW5kaW5nPWZ1bmN0aW9uKG5hbWUpe3Rocm93IG5ldyBFcnJvcihcInByb2Nlc3MuYmluZGluZyBpcyBub3Qgc3VwcG9ydGVkXCIpfTtwcm9jZXNzLmN3ZD1mdW5jdGlvbigpe3JldHVyblwiL1wifTtwcm9jZXNzLmNoZGlyPWZ1bmN0aW9uKGRpcil7dGhyb3cgbmV3IEVycm9yKFwicHJvY2Vzcy5jaGRpciBpcyBub3Qgc3VwcG9ydGVkXCIpfTtwcm9jZXNzLnVtYXNrPWZ1bmN0aW9uKCl7cmV0dXJuIDB9fSx7fV0sNDM6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe21vZHVsZS5leHBvcnRzPXJlcXVpcmUoXCIuL2xpYi9fc3RyZWFtX2R1cGxleC5qc1wiKX0se1wiLi9saWIvX3N0cmVhbV9kdXBsZXguanNcIjo0NH1dLDQ0OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcInVzZSBzdHJpY3RcIjt2YXIgb2JqZWN0S2V5cz1PYmplY3Qua2V5c3x8ZnVuY3Rpb24ob2JqKXt2YXIga2V5cz1bXTtmb3IodmFyIGtleSBpbiBvYmope2tleXMucHVzaChrZXkpfXJldHVybiBrZXlzfTttb2R1bGUuZXhwb3J0cz1EdXBsZXg7dmFyIHByb2Nlc3NOZXh0VGljaz1yZXF1aXJlKFwicHJvY2Vzcy1uZXh0aWNrLWFyZ3NcIik7dmFyIHV0aWw9cmVxdWlyZShcImNvcmUtdXRpbC1pc1wiKTt1dGlsLmluaGVyaXRzPXJlcXVpcmUoXCJpbmhlcml0c1wiKTt2YXIgUmVhZGFibGU9cmVxdWlyZShcIi4vX3N0cmVhbV9yZWFkYWJsZVwiKTt2YXIgV3JpdGFibGU9cmVxdWlyZShcIi4vX3N0cmVhbV93cml0YWJsZVwiKTt1dGlsLmluaGVyaXRzKER1cGxleCxSZWFkYWJsZSk7dmFyIGtleXM9b2JqZWN0S2V5cyhXcml0YWJsZS5wcm90b3R5cGUpO2Zvcih2YXIgdj0wO3Y8a2V5cy5sZW5ndGg7disrKXt2YXIgbWV0aG9kPWtleXNbdl07aWYoIUR1cGxleC5wcm90b3R5cGVbbWV0aG9kXSlEdXBsZXgucHJvdG90eXBlW21ldGhvZF09V3JpdGFibGUucHJvdG90eXBlW21ldGhvZF19ZnVuY3Rpb24gRHVwbGV4KG9wdGlvbnMpe2lmKCEodGhpcyBpbnN0YW5jZW9mIER1cGxleCkpcmV0dXJuIG5ldyBEdXBsZXgob3B0aW9ucyk7UmVhZGFibGUuY2FsbCh0aGlzLG9wdGlvbnMpO1dyaXRhYmxlLmNhbGwodGhpcyxvcHRpb25zKTtpZihvcHRpb25zJiZvcHRpb25zLnJlYWRhYmxlPT09ZmFsc2UpdGhpcy5yZWFkYWJsZT1mYWxzZTtpZihvcHRpb25zJiZvcHRpb25zLndyaXRhYmxlPT09ZmFsc2UpdGhpcy53cml0YWJsZT1mYWxzZTt0aGlzLmFsbG93SGFsZk9wZW49dHJ1ZTtpZihvcHRpb25zJiZvcHRpb25zLmFsbG93SGFsZk9wZW49PT1mYWxzZSl0aGlzLmFsbG93SGFsZk9wZW49ZmFsc2U7dGhpcy5vbmNlKFwiZW5kXCIsb25lbmQpfWZ1bmN0aW9uIG9uZW5kKCl7aWYodGhpcy5hbGxvd0hhbGZPcGVufHx0aGlzLl93cml0YWJsZVN0YXRlLmVuZGVkKXJldHVybjtwcm9jZXNzTmV4dFRpY2sob25FbmROVCx0aGlzKX1mdW5jdGlvbiBvbkVuZE5UKHNlbGYpe3NlbGYuZW5kKCl9ZnVuY3Rpb24gZm9yRWFjaCh4cyxmKXtmb3IodmFyIGk9MCxsPXhzLmxlbmd0aDtpPGw7aSsrKXtmKHhzW2ldLGkpfX19LHtcIi4vX3N0cmVhbV9yZWFkYWJsZVwiOjQ2LFwiLi9fc3RyZWFtX3dyaXRhYmxlXCI6NDgsXCJjb3JlLXV0aWwtaXNcIjo2LGluaGVyaXRzOjM4LFwicHJvY2Vzcy1uZXh0aWNrLWFyZ3NcIjo0MX1dLDQ1OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcInVzZSBzdHJpY3RcIjttb2R1bGUuZXhwb3J0cz1QYXNzVGhyb3VnaDt2YXIgVHJhbnNmb3JtPXJlcXVpcmUoXCIuL19zdHJlYW1fdHJhbnNmb3JtXCIpO3ZhciB1dGlsPXJlcXVpcmUoXCJjb3JlLXV0aWwtaXNcIik7dXRpbC5pbmhlcml0cz1yZXF1aXJlKFwiaW5oZXJpdHNcIik7dXRpbC5pbmhlcml0cyhQYXNzVGhyb3VnaCxUcmFuc2Zvcm0pO2Z1bmN0aW9uIFBhc3NUaHJvdWdoKG9wdGlvbnMpe2lmKCEodGhpcyBpbnN0YW5jZW9mIFBhc3NUaHJvdWdoKSlyZXR1cm4gbmV3IFBhc3NUaHJvdWdoKG9wdGlvbnMpO1RyYW5zZm9ybS5jYWxsKHRoaXMsb3B0aW9ucyl9UGFzc1Rocm91Z2gucHJvdG90eXBlLl90cmFuc2Zvcm09ZnVuY3Rpb24oY2h1bmssZW5jb2RpbmcsY2Ipe2NiKG51bGwsY2h1bmspfX0se1wiLi9fc3RyZWFtX3RyYW5zZm9ybVwiOjQ3LFwiY29yZS11dGlsLWlzXCI6Nixpbmhlcml0czozOH1dLDQ2OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsoZnVuY3Rpb24ocHJvY2Vzcyl7XCJ1c2Ugc3RyaWN0XCI7bW9kdWxlLmV4cG9ydHM9UmVhZGFibGU7dmFyIHByb2Nlc3NOZXh0VGljaz1yZXF1aXJlKFwicHJvY2Vzcy1uZXh0aWNrLWFyZ3NcIik7dmFyIGlzQXJyYXk9cmVxdWlyZShcImlzYXJyYXlcIik7UmVhZGFibGUuUmVhZGFibGVTdGF0ZT1SZWFkYWJsZVN0YXRlO3ZhciBFRT1yZXF1aXJlKFwiZXZlbnRzXCIpLkV2ZW50RW1pdHRlcjt2YXIgRUVsaXN0ZW5lckNvdW50PWZ1bmN0aW9uKGVtaXR0ZXIsdHlwZSl7cmV0dXJuIGVtaXR0ZXIubGlzdGVuZXJzKHR5cGUpLmxlbmd0aH07dmFyIFN0cmVhbTsoZnVuY3Rpb24oKXt0cnl7U3RyZWFtPXJlcXVpcmUoXCJzdFwiK1wicmVhbVwiKX1jYXRjaChfKXt9ZmluYWxseXtpZighU3RyZWFtKVN0cmVhbT1yZXF1aXJlKFwiZXZlbnRzXCIpLkV2ZW50RW1pdHRlcn19KSgpO3ZhciBCdWZmZXI9cmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXI7dmFyIGJ1ZmZlclNoaW09cmVxdWlyZShcImJ1ZmZlci1zaGltc1wiKTt2YXIgdXRpbD1yZXF1aXJlKFwiY29yZS11dGlsLWlzXCIpO3V0aWwuaW5oZXJpdHM9cmVxdWlyZShcImluaGVyaXRzXCIpO3ZhciBkZWJ1Z1V0aWw9cmVxdWlyZShcInV0aWxcIik7dmFyIGRlYnVnPXZvaWQgMDtpZihkZWJ1Z1V0aWwmJmRlYnVnVXRpbC5kZWJ1Z2xvZyl7ZGVidWc9ZGVidWdVdGlsLmRlYnVnbG9nKFwic3RyZWFtXCIpfWVsc2V7ZGVidWc9ZnVuY3Rpb24oKXt9fXZhciBCdWZmZXJMaXN0PXJlcXVpcmUoXCIuL2ludGVybmFsL3N0cmVhbXMvQnVmZmVyTGlzdFwiKTt2YXIgU3RyaW5nRGVjb2Rlcjt1dGlsLmluaGVyaXRzKFJlYWRhYmxlLFN0cmVhbSk7ZnVuY3Rpb24gcHJlcGVuZExpc3RlbmVyKGVtaXR0ZXIsZXZlbnQsZm4pe2lmKHR5cGVvZiBlbWl0dGVyLnByZXBlbmRMaXN0ZW5lcj09PVwiZnVuY3Rpb25cIil7cmV0dXJuIGVtaXR0ZXIucHJlcGVuZExpc3RlbmVyKGV2ZW50LGZuKX1lbHNle2lmKCFlbWl0dGVyLl9ldmVudHN8fCFlbWl0dGVyLl9ldmVudHNbZXZlbnRdKWVtaXR0ZXIub24oZXZlbnQsZm4pO2Vsc2UgaWYoaXNBcnJheShlbWl0dGVyLl9ldmVudHNbZXZlbnRdKSllbWl0dGVyLl9ldmVudHNbZXZlbnRdLnVuc2hpZnQoZm4pO2Vsc2UgZW1pdHRlci5fZXZlbnRzW2V2ZW50XT1bZm4sZW1pdHRlci5fZXZlbnRzW2V2ZW50XV19fXZhciBEdXBsZXg7ZnVuY3Rpb24gUmVhZGFibGVTdGF0ZShvcHRpb25zLHN0cmVhbSl7RHVwbGV4PUR1cGxleHx8cmVxdWlyZShcIi4vX3N0cmVhbV9kdXBsZXhcIik7b3B0aW9ucz1vcHRpb25zfHx7fTt0aGlzLm9iamVjdE1vZGU9ISFvcHRpb25zLm9iamVjdE1vZGU7aWYoc3RyZWFtIGluc3RhbmNlb2YgRHVwbGV4KXRoaXMub2JqZWN0TW9kZT10aGlzLm9iamVjdE1vZGV8fCEhb3B0aW9ucy5yZWFkYWJsZU9iamVjdE1vZGU7dmFyIGh3bT1vcHRpb25zLmhpZ2hXYXRlck1hcms7dmFyIGRlZmF1bHRId209dGhpcy5vYmplY3RNb2RlPzE2OjE2KjEwMjQ7dGhpcy5oaWdoV2F0ZXJNYXJrPWh3bXx8aHdtPT09MD9od206ZGVmYXVsdEh3bTt0aGlzLmhpZ2hXYXRlck1hcms9fn50aGlzLmhpZ2hXYXRlck1hcms7dGhpcy5idWZmZXI9bmV3IEJ1ZmZlckxpc3Q7dGhpcy5sZW5ndGg9MDt0aGlzLnBpcGVzPW51bGw7dGhpcy5waXBlc0NvdW50PTA7dGhpcy5mbG93aW5nPW51bGw7dGhpcy5lbmRlZD1mYWxzZTt0aGlzLmVuZEVtaXR0ZWQ9ZmFsc2U7dGhpcy5yZWFkaW5nPWZhbHNlO3RoaXMuc3luYz10cnVlO3RoaXMubmVlZFJlYWRhYmxlPWZhbHNlO3RoaXMuZW1pdHRlZFJlYWRhYmxlPWZhbHNlO3RoaXMucmVhZGFibGVMaXN0ZW5pbmc9ZmFsc2U7dGhpcy5yZXN1bWVTY2hlZHVsZWQ9ZmFsc2U7dGhpcy5kZWZhdWx0RW5jb2Rpbmc9b3B0aW9ucy5kZWZhdWx0RW5jb2Rpbmd8fFwidXRmOFwiO3RoaXMucmFuT3V0PWZhbHNlO3RoaXMuYXdhaXREcmFpbj0wO3RoaXMucmVhZGluZ01vcmU9ZmFsc2U7dGhpcy5kZWNvZGVyPW51bGw7dGhpcy5lbmNvZGluZz1udWxsO2lmKG9wdGlvbnMuZW5jb2Rpbmcpe2lmKCFTdHJpbmdEZWNvZGVyKVN0cmluZ0RlY29kZXI9cmVxdWlyZShcInN0cmluZ19kZWNvZGVyL1wiKS5TdHJpbmdEZWNvZGVyO3RoaXMuZGVjb2Rlcj1uZXcgU3RyaW5nRGVjb2RlcihvcHRpb25zLmVuY29kaW5nKTt0aGlzLmVuY29kaW5nPW9wdGlvbnMuZW5jb2Rpbmd9fXZhciBEdXBsZXg7ZnVuY3Rpb24gUmVhZGFibGUob3B0aW9ucyl7RHVwbGV4PUR1cGxleHx8cmVxdWlyZShcIi4vX3N0cmVhbV9kdXBsZXhcIik7aWYoISh0aGlzIGluc3RhbmNlb2YgUmVhZGFibGUpKXJldHVybiBuZXcgUmVhZGFibGUob3B0aW9ucyk7dGhpcy5fcmVhZGFibGVTdGF0ZT1uZXcgUmVhZGFibGVTdGF0ZShvcHRpb25zLHRoaXMpO3RoaXMucmVhZGFibGU9dHJ1ZTtpZihvcHRpb25zJiZ0eXBlb2Ygb3B0aW9ucy5yZWFkPT09XCJmdW5jdGlvblwiKXRoaXMuX3JlYWQ9b3B0aW9ucy5yZWFkO1N0cmVhbS5jYWxsKHRoaXMpfVJlYWRhYmxlLnByb3RvdHlwZS5wdXNoPWZ1bmN0aW9uKGNodW5rLGVuY29kaW5nKXt2YXIgc3RhdGU9dGhpcy5fcmVhZGFibGVTdGF0ZTtpZighc3RhdGUub2JqZWN0TW9kZSYmdHlwZW9mIGNodW5rPT09XCJzdHJpbmdcIil7ZW5jb2Rpbmc9ZW5jb2Rpbmd8fHN0YXRlLmRlZmF1bHRFbmNvZGluZztpZihlbmNvZGluZyE9PXN0YXRlLmVuY29kaW5nKXtjaHVuaz1idWZmZXJTaGltLmZyb20oY2h1bmssZW5jb2RpbmcpO2VuY29kaW5nPVwiXCJ9fXJldHVybiByZWFkYWJsZUFkZENodW5rKHRoaXMsc3RhdGUsY2h1bmssZW5jb2RpbmcsZmFsc2UpfTtSZWFkYWJsZS5wcm90b3R5cGUudW5zaGlmdD1mdW5jdGlvbihjaHVuayl7dmFyIHN0YXRlPXRoaXMuX3JlYWRhYmxlU3RhdGU7cmV0dXJuIHJlYWRhYmxlQWRkQ2h1bmsodGhpcyxzdGF0ZSxjaHVuayxcIlwiLHRydWUpfTtSZWFkYWJsZS5wcm90b3R5cGUuaXNQYXVzZWQ9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nPT09ZmFsc2V9O2Z1bmN0aW9uIHJlYWRhYmxlQWRkQ2h1bmsoc3RyZWFtLHN0YXRlLGNodW5rLGVuY29kaW5nLGFkZFRvRnJvbnQpe3ZhciBlcj1jaHVua0ludmFsaWQoc3RhdGUsY2h1bmspO2lmKGVyKXtzdHJlYW0uZW1pdChcImVycm9yXCIsZXIpfWVsc2UgaWYoY2h1bms9PT1udWxsKXtzdGF0ZS5yZWFkaW5nPWZhbHNlO29uRW9mQ2h1bmsoc3RyZWFtLHN0YXRlKX1lbHNlIGlmKHN0YXRlLm9iamVjdE1vZGV8fGNodW5rJiZjaHVuay5sZW5ndGg+MCl7aWYoc3RhdGUuZW5kZWQmJiFhZGRUb0Zyb250KXt2YXIgZT1uZXcgRXJyb3IoXCJzdHJlYW0ucHVzaCgpIGFmdGVyIEVPRlwiKTtzdHJlYW0uZW1pdChcImVycm9yXCIsZSl9ZWxzZSBpZihzdGF0ZS5lbmRFbWl0dGVkJiZhZGRUb0Zyb250KXt2YXIgX2U9bmV3IEVycm9yKFwic3RyZWFtLnVuc2hpZnQoKSBhZnRlciBlbmQgZXZlbnRcIik7c3RyZWFtLmVtaXQoXCJlcnJvclwiLF9lKX1lbHNle3ZhciBza2lwQWRkO2lmKHN0YXRlLmRlY29kZXImJiFhZGRUb0Zyb250JiYhZW5jb2Rpbmcpe2NodW5rPXN0YXRlLmRlY29kZXIud3JpdGUoY2h1bmspO3NraXBBZGQ9IXN0YXRlLm9iamVjdE1vZGUmJmNodW5rLmxlbmd0aD09PTB9aWYoIWFkZFRvRnJvbnQpc3RhdGUucmVhZGluZz1mYWxzZTtpZighc2tpcEFkZCl7aWYoc3RhdGUuZmxvd2luZyYmc3RhdGUubGVuZ3RoPT09MCYmIXN0YXRlLnN5bmMpe3N0cmVhbS5lbWl0KFwiZGF0YVwiLGNodW5rKTtzdHJlYW0ucmVhZCgwKX1lbHNle3N0YXRlLmxlbmd0aCs9c3RhdGUub2JqZWN0TW9kZT8xOmNodW5rLmxlbmd0aDtpZihhZGRUb0Zyb250KXN0YXRlLmJ1ZmZlci51bnNoaWZ0KGNodW5rKTtlbHNlIHN0YXRlLmJ1ZmZlci5wdXNoKGNodW5rKTtpZihzdGF0ZS5uZWVkUmVhZGFibGUpZW1pdFJlYWRhYmxlKHN0cmVhbSl9fW1heWJlUmVhZE1vcmUoc3RyZWFtLHN0YXRlKX19ZWxzZSBpZighYWRkVG9Gcm9udCl7c3RhdGUucmVhZGluZz1mYWxzZX1yZXR1cm4gbmVlZE1vcmVEYXRhKHN0YXRlKX1mdW5jdGlvbiBuZWVkTW9yZURhdGEoc3RhdGUpe3JldHVybiFzdGF0ZS5lbmRlZCYmKHN0YXRlLm5lZWRSZWFkYWJsZXx8c3RhdGUubGVuZ3RoPHN0YXRlLmhpZ2hXYXRlck1hcmt8fHN0YXRlLmxlbmd0aD09PTApfVJlYWRhYmxlLnByb3RvdHlwZS5zZXRFbmNvZGluZz1mdW5jdGlvbihlbmMpe2lmKCFTdHJpbmdEZWNvZGVyKVN0cmluZ0RlY29kZXI9cmVxdWlyZShcInN0cmluZ19kZWNvZGVyL1wiKS5TdHJpbmdEZWNvZGVyO3RoaXMuX3JlYWRhYmxlU3RhdGUuZGVjb2Rlcj1uZXcgU3RyaW5nRGVjb2RlcihlbmMpO3RoaXMuX3JlYWRhYmxlU3RhdGUuZW5jb2Rpbmc9ZW5jO3JldHVybiB0aGlzfTt2YXIgTUFYX0hXTT04Mzg4NjA4O2Z1bmN0aW9uIGNvbXB1dGVOZXdIaWdoV2F0ZXJNYXJrKG4pe2lmKG4+PU1BWF9IV00pe249TUFYX0hXTX1lbHNle24tLTtufD1uPj4+MTtufD1uPj4+MjtufD1uPj4+NDtufD1uPj4+ODtufD1uPj4+MTY7bisrfXJldHVybiBufWZ1bmN0aW9uIGhvd011Y2hUb1JlYWQobixzdGF0ZSl7aWYobjw9MHx8c3RhdGUubGVuZ3RoPT09MCYmc3RhdGUuZW5kZWQpcmV0dXJuIDA7aWYoc3RhdGUub2JqZWN0TW9kZSlyZXR1cm4gMTtpZihuIT09bil7aWYoc3RhdGUuZmxvd2luZyYmc3RhdGUubGVuZ3RoKXJldHVybiBzdGF0ZS5idWZmZXIuaGVhZC5kYXRhLmxlbmd0aDtlbHNlIHJldHVybiBzdGF0ZS5sZW5ndGh9aWYobj5zdGF0ZS5oaWdoV2F0ZXJNYXJrKXN0YXRlLmhpZ2hXYXRlck1hcms9Y29tcHV0ZU5ld0hpZ2hXYXRlck1hcmsobik7aWYobjw9c3RhdGUubGVuZ3RoKXJldHVybiBuO2lmKCFzdGF0ZS5lbmRlZCl7c3RhdGUubmVlZFJlYWRhYmxlPXRydWU7cmV0dXJuIDB9cmV0dXJuIHN0YXRlLmxlbmd0aH1SZWFkYWJsZS5wcm90b3R5cGUucmVhZD1mdW5jdGlvbihuKXtkZWJ1ZyhcInJlYWRcIixuKTtuPXBhcnNlSW50KG4sMTApO3ZhciBzdGF0ZT10aGlzLl9yZWFkYWJsZVN0YXRlO3ZhciBuT3JpZz1uO2lmKG4hPT0wKXN0YXRlLmVtaXR0ZWRSZWFkYWJsZT1mYWxzZTtpZihuPT09MCYmc3RhdGUubmVlZFJlYWRhYmxlJiYoc3RhdGUubGVuZ3RoPj1zdGF0ZS5oaWdoV2F0ZXJNYXJrfHxzdGF0ZS5lbmRlZCkpe2RlYnVnKFwicmVhZDogZW1pdFJlYWRhYmxlXCIsc3RhdGUubGVuZ3RoLHN0YXRlLmVuZGVkKTtpZihzdGF0ZS5sZW5ndGg9PT0wJiZzdGF0ZS5lbmRlZCllbmRSZWFkYWJsZSh0aGlzKTtlbHNlIGVtaXRSZWFkYWJsZSh0aGlzKTtyZXR1cm4gbnVsbH1uPWhvd011Y2hUb1JlYWQobixzdGF0ZSk7aWYobj09PTAmJnN0YXRlLmVuZGVkKXtpZihzdGF0ZS5sZW5ndGg9PT0wKWVuZFJlYWRhYmxlKHRoaXMpO3JldHVybiBudWxsfXZhciBkb1JlYWQ9c3RhdGUubmVlZFJlYWRhYmxlO2RlYnVnKFwibmVlZCByZWFkYWJsZVwiLGRvUmVhZCk7aWYoc3RhdGUubGVuZ3RoPT09MHx8c3RhdGUubGVuZ3RoLW48c3RhdGUuaGlnaFdhdGVyTWFyayl7ZG9SZWFkPXRydWU7ZGVidWcoXCJsZW5ndGggbGVzcyB0aGFuIHdhdGVybWFya1wiLGRvUmVhZCl9aWYoc3RhdGUuZW5kZWR8fHN0YXRlLnJlYWRpbmcpe2RvUmVhZD1mYWxzZTtkZWJ1ZyhcInJlYWRpbmcgb3IgZW5kZWRcIixkb1JlYWQpfWVsc2UgaWYoZG9SZWFkKXtkZWJ1ZyhcImRvIHJlYWRcIik7c3RhdGUucmVhZGluZz10cnVlO3N0YXRlLnN5bmM9dHJ1ZTtpZihzdGF0ZS5sZW5ndGg9PT0wKXN0YXRlLm5lZWRSZWFkYWJsZT10cnVlO3RoaXMuX3JlYWQoc3RhdGUuaGlnaFdhdGVyTWFyayk7c3RhdGUuc3luYz1mYWxzZTtpZighc3RhdGUucmVhZGluZyluPWhvd011Y2hUb1JlYWQobk9yaWcsc3RhdGUpfXZhciByZXQ7aWYobj4wKXJldD1mcm9tTGlzdChuLHN0YXRlKTtlbHNlIHJldD1udWxsO2lmKHJldD09PW51bGwpe3N0YXRlLm5lZWRSZWFkYWJsZT10cnVlO249MH1lbHNle3N0YXRlLmxlbmd0aC09bn1pZihzdGF0ZS5sZW5ndGg9PT0wKXtpZighc3RhdGUuZW5kZWQpc3RhdGUubmVlZFJlYWRhYmxlPXRydWU7aWYobk9yaWchPT1uJiZzdGF0ZS5lbmRlZCllbmRSZWFkYWJsZSh0aGlzKX1pZihyZXQhPT1udWxsKXRoaXMuZW1pdChcImRhdGFcIixyZXQpO3JldHVybiByZXR9O2Z1bmN0aW9uIGNodW5rSW52YWxpZChzdGF0ZSxjaHVuayl7dmFyIGVyPW51bGw7aWYoIUJ1ZmZlci5pc0J1ZmZlcihjaHVuaykmJnR5cGVvZiBjaHVuayE9PVwic3RyaW5nXCImJmNodW5rIT09bnVsbCYmY2h1bmshPT11bmRlZmluZWQmJiFzdGF0ZS5vYmplY3RNb2RlKXtlcj1uZXcgVHlwZUVycm9yKFwiSW52YWxpZCBub24tc3RyaW5nL2J1ZmZlciBjaHVua1wiKX1yZXR1cm4gZXJ9ZnVuY3Rpb24gb25Fb2ZDaHVuayhzdHJlYW0sc3RhdGUpe2lmKHN0YXRlLmVuZGVkKXJldHVybjtpZihzdGF0ZS5kZWNvZGVyKXt2YXIgY2h1bms9c3RhdGUuZGVjb2Rlci5lbmQoKTtpZihjaHVuayYmY2h1bmsubGVuZ3RoKXtzdGF0ZS5idWZmZXIucHVzaChjaHVuayk7c3RhdGUubGVuZ3RoKz1zdGF0ZS5vYmplY3RNb2RlPzE6Y2h1bmsubGVuZ3RofX1zdGF0ZS5lbmRlZD10cnVlO2VtaXRSZWFkYWJsZShzdHJlYW0pfWZ1bmN0aW9uIGVtaXRSZWFkYWJsZShzdHJlYW0pe3ZhciBzdGF0ZT1zdHJlYW0uX3JlYWRhYmxlU3RhdGU7c3RhdGUubmVlZFJlYWRhYmxlPWZhbHNlO2lmKCFzdGF0ZS5lbWl0dGVkUmVhZGFibGUpe2RlYnVnKFwiZW1pdFJlYWRhYmxlXCIsc3RhdGUuZmxvd2luZyk7c3RhdGUuZW1pdHRlZFJlYWRhYmxlPXRydWU7aWYoc3RhdGUuc3luYylwcm9jZXNzTmV4dFRpY2soZW1pdFJlYWRhYmxlXyxzdHJlYW0pO2Vsc2UgZW1pdFJlYWRhYmxlXyhzdHJlYW0pfX1mdW5jdGlvbiBlbWl0UmVhZGFibGVfKHN0cmVhbSl7ZGVidWcoXCJlbWl0IHJlYWRhYmxlXCIpO3N0cmVhbS5lbWl0KFwicmVhZGFibGVcIik7ZmxvdyhzdHJlYW0pfWZ1bmN0aW9uIG1heWJlUmVhZE1vcmUoc3RyZWFtLHN0YXRlKXtpZighc3RhdGUucmVhZGluZ01vcmUpe3N0YXRlLnJlYWRpbmdNb3JlPXRydWU7cHJvY2Vzc05leHRUaWNrKG1heWJlUmVhZE1vcmVfLHN0cmVhbSxzdGF0ZSl9fWZ1bmN0aW9uIG1heWJlUmVhZE1vcmVfKHN0cmVhbSxzdGF0ZSl7dmFyIGxlbj1zdGF0ZS5sZW5ndGg7d2hpbGUoIXN0YXRlLnJlYWRpbmcmJiFzdGF0ZS5mbG93aW5nJiYhc3RhdGUuZW5kZWQmJnN0YXRlLmxlbmd0aDxzdGF0ZS5oaWdoV2F0ZXJNYXJrKXtkZWJ1ZyhcIm1heWJlUmVhZE1vcmUgcmVhZCAwXCIpO3N0cmVhbS5yZWFkKDApO2lmKGxlbj09PXN0YXRlLmxlbmd0aClicmVhaztlbHNlIGxlbj1zdGF0ZS5sZW5ndGh9c3RhdGUucmVhZGluZ01vcmU9ZmFsc2V9UmVhZGFibGUucHJvdG90eXBlLl9yZWFkPWZ1bmN0aW9uKG4pe3RoaXMuZW1pdChcImVycm9yXCIsbmV3IEVycm9yKFwibm90IGltcGxlbWVudGVkXCIpKX07UmVhZGFibGUucHJvdG90eXBlLnBpcGU9ZnVuY3Rpb24oZGVzdCxwaXBlT3B0cyl7dmFyIHNyYz10aGlzO3ZhciBzdGF0ZT10aGlzLl9yZWFkYWJsZVN0YXRlO3N3aXRjaChzdGF0ZS5waXBlc0NvdW50KXtjYXNlIDA6c3RhdGUucGlwZXM9ZGVzdDticmVhaztjYXNlIDE6c3RhdGUucGlwZXM9W3N0YXRlLnBpcGVzLGRlc3RdO2JyZWFrO2RlZmF1bHQ6c3RhdGUucGlwZXMucHVzaChkZXN0KTticmVha31zdGF0ZS5waXBlc0NvdW50Kz0xO2RlYnVnKFwicGlwZSBjb3VudD0lZCBvcHRzPSVqXCIsc3RhdGUucGlwZXNDb3VudCxwaXBlT3B0cyk7dmFyIGRvRW5kPSghcGlwZU9wdHN8fHBpcGVPcHRzLmVuZCE9PWZhbHNlKSYmZGVzdCE9PXByb2Nlc3Muc3Rkb3V0JiZkZXN0IT09cHJvY2Vzcy5zdGRlcnI7dmFyIGVuZEZuPWRvRW5kP29uZW5kOmNsZWFudXA7aWYoc3RhdGUuZW5kRW1pdHRlZClwcm9jZXNzTmV4dFRpY2soZW5kRm4pO2Vsc2Ugc3JjLm9uY2UoXCJlbmRcIixlbmRGbik7ZGVzdC5vbihcInVucGlwZVwiLG9udW5waXBlKTtmdW5jdGlvbiBvbnVucGlwZShyZWFkYWJsZSl7ZGVidWcoXCJvbnVucGlwZVwiKTtpZihyZWFkYWJsZT09PXNyYyl7Y2xlYW51cCgpfX1mdW5jdGlvbiBvbmVuZCgpe2RlYnVnKFwib25lbmRcIik7ZGVzdC5lbmQoKX12YXIgb25kcmFpbj1waXBlT25EcmFpbihzcmMpO2Rlc3Qub24oXCJkcmFpblwiLG9uZHJhaW4pO3ZhciBjbGVhbmVkVXA9ZmFsc2U7ZnVuY3Rpb24gY2xlYW51cCgpe2RlYnVnKFwiY2xlYW51cFwiKTtkZXN0LnJlbW92ZUxpc3RlbmVyKFwiY2xvc2VcIixvbmNsb3NlKTtkZXN0LnJlbW92ZUxpc3RlbmVyKFwiZmluaXNoXCIsb25maW5pc2gpO2Rlc3QucmVtb3ZlTGlzdGVuZXIoXCJkcmFpblwiLG9uZHJhaW4pO2Rlc3QucmVtb3ZlTGlzdGVuZXIoXCJlcnJvclwiLG9uZXJyb3IpO2Rlc3QucmVtb3ZlTGlzdGVuZXIoXCJ1bnBpcGVcIixvbnVucGlwZSk7c3JjLnJlbW92ZUxpc3RlbmVyKFwiZW5kXCIsb25lbmQpO3NyYy5yZW1vdmVMaXN0ZW5lcihcImVuZFwiLGNsZWFudXApO3NyYy5yZW1vdmVMaXN0ZW5lcihcImRhdGFcIixvbmRhdGEpO2NsZWFuZWRVcD10cnVlO2lmKHN0YXRlLmF3YWl0RHJhaW4mJighZGVzdC5fd3JpdGFibGVTdGF0ZXx8ZGVzdC5fd3JpdGFibGVTdGF0ZS5uZWVkRHJhaW4pKW9uZHJhaW4oKX12YXIgaW5jcmVhc2VkQXdhaXREcmFpbj1mYWxzZTtzcmMub24oXCJkYXRhXCIsb25kYXRhKTtmdW5jdGlvbiBvbmRhdGEoY2h1bmspe2RlYnVnKFwib25kYXRhXCIpO2luY3JlYXNlZEF3YWl0RHJhaW49ZmFsc2U7dmFyIHJldD1kZXN0LndyaXRlKGNodW5rKTtpZihmYWxzZT09PXJldCYmIWluY3JlYXNlZEF3YWl0RHJhaW4pe2lmKChzdGF0ZS5waXBlc0NvdW50PT09MSYmc3RhdGUucGlwZXM9PT1kZXN0fHxzdGF0ZS5waXBlc0NvdW50PjEmJmluZGV4T2Yoc3RhdGUucGlwZXMsZGVzdCkhPT0tMSkmJiFjbGVhbmVkVXApe2RlYnVnKFwiZmFsc2Ugd3JpdGUgcmVzcG9uc2UsIHBhdXNlXCIsc3JjLl9yZWFkYWJsZVN0YXRlLmF3YWl0RHJhaW4pO3NyYy5fcmVhZGFibGVTdGF0ZS5hd2FpdERyYWluKys7aW5jcmVhc2VkQXdhaXREcmFpbj10cnVlfXNyYy5wYXVzZSgpfX1mdW5jdGlvbiBvbmVycm9yKGVyKXtkZWJ1ZyhcIm9uZXJyb3JcIixlcik7dW5waXBlKCk7ZGVzdC5yZW1vdmVMaXN0ZW5lcihcImVycm9yXCIsb25lcnJvcik7aWYoRUVsaXN0ZW5lckNvdW50KGRlc3QsXCJlcnJvclwiKT09PTApZGVzdC5lbWl0KFwiZXJyb3JcIixlcil9cHJlcGVuZExpc3RlbmVyKGRlc3QsXCJlcnJvclwiLG9uZXJyb3IpO2Z1bmN0aW9uIG9uY2xvc2UoKXtkZXN0LnJlbW92ZUxpc3RlbmVyKFwiZmluaXNoXCIsb25maW5pc2gpO3VucGlwZSgpfWRlc3Qub25jZShcImNsb3NlXCIsb25jbG9zZSk7ZnVuY3Rpb24gb25maW5pc2goKXtkZWJ1ZyhcIm9uZmluaXNoXCIpO2Rlc3QucmVtb3ZlTGlzdGVuZXIoXCJjbG9zZVwiLG9uY2xvc2UpO3VucGlwZSgpfWRlc3Qub25jZShcImZpbmlzaFwiLG9uZmluaXNoKTtmdW5jdGlvbiB1bnBpcGUoKXtkZWJ1ZyhcInVucGlwZVwiKTtzcmMudW5waXBlKGRlc3QpfWRlc3QuZW1pdChcInBpcGVcIixzcmMpO2lmKCFzdGF0ZS5mbG93aW5nKXtkZWJ1ZyhcInBpcGUgcmVzdW1lXCIpO3NyYy5yZXN1bWUoKX1yZXR1cm4gZGVzdH07ZnVuY3Rpb24gcGlwZU9uRHJhaW4oc3JjKXtyZXR1cm4gZnVuY3Rpb24oKXt2YXIgc3RhdGU9c3JjLl9yZWFkYWJsZVN0YXRlO2RlYnVnKFwicGlwZU9uRHJhaW5cIixzdGF0ZS5hd2FpdERyYWluKTtpZihzdGF0ZS5hd2FpdERyYWluKXN0YXRlLmF3YWl0RHJhaW4tLTtpZihzdGF0ZS5hd2FpdERyYWluPT09MCYmRUVsaXN0ZW5lckNvdW50KHNyYyxcImRhdGFcIikpe3N0YXRlLmZsb3dpbmc9dHJ1ZTtmbG93KHNyYyl9fX1SZWFkYWJsZS5wcm90b3R5cGUudW5waXBlPWZ1bmN0aW9uKGRlc3Qpe3ZhciBzdGF0ZT10aGlzLl9yZWFkYWJsZVN0YXRlO2lmKHN0YXRlLnBpcGVzQ291bnQ9PT0wKXJldHVybiB0aGlzO2lmKHN0YXRlLnBpcGVzQ291bnQ9PT0xKXtpZihkZXN0JiZkZXN0IT09c3RhdGUucGlwZXMpcmV0dXJuIHRoaXM7aWYoIWRlc3QpZGVzdD1zdGF0ZS5waXBlcztzdGF0ZS5waXBlcz1udWxsO3N0YXRlLnBpcGVzQ291bnQ9MDtzdGF0ZS5mbG93aW5nPWZhbHNlO2lmKGRlc3QpZGVzdC5lbWl0KFwidW5waXBlXCIsdGhpcyk7cmV0dXJuIHRoaXN9aWYoIWRlc3Qpe3ZhciBkZXN0cz1zdGF0ZS5waXBlczt2YXIgbGVuPXN0YXRlLnBpcGVzQ291bnQ7c3RhdGUucGlwZXM9bnVsbDtzdGF0ZS5waXBlc0NvdW50PTA7c3RhdGUuZmxvd2luZz1mYWxzZTtmb3IodmFyIF9pPTA7X2k8bGVuO19pKyspe2Rlc3RzW19pXS5lbWl0KFwidW5waXBlXCIsdGhpcyl9cmV0dXJuIHRoaXN9dmFyIGk9aW5kZXhPZihzdGF0ZS5waXBlcyxkZXN0KTtpZihpPT09LTEpcmV0dXJuIHRoaXM7c3RhdGUucGlwZXMuc3BsaWNlKGksMSk7c3RhdGUucGlwZXNDb3VudC09MTtpZihzdGF0ZS5waXBlc0NvdW50PT09MSlzdGF0ZS5waXBlcz1zdGF0ZS5waXBlc1swXTtkZXN0LmVtaXQoXCJ1bnBpcGVcIix0aGlzKTtyZXR1cm4gdGhpc307UmVhZGFibGUucHJvdG90eXBlLm9uPWZ1bmN0aW9uKGV2LGZuKXt2YXIgcmVzPVN0cmVhbS5wcm90b3R5cGUub24uY2FsbCh0aGlzLGV2LGZuKTtpZihldj09PVwiZGF0YVwiKXtpZih0aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmchPT1mYWxzZSl0aGlzLnJlc3VtZSgpfWVsc2UgaWYoZXY9PT1cInJlYWRhYmxlXCIpe3ZhciBzdGF0ZT10aGlzLl9yZWFkYWJsZVN0YXRlO2lmKCFzdGF0ZS5lbmRFbWl0dGVkJiYhc3RhdGUucmVhZGFibGVMaXN0ZW5pbmcpe3N0YXRlLnJlYWRhYmxlTGlzdGVuaW5nPXN0YXRlLm5lZWRSZWFkYWJsZT10cnVlO3N0YXRlLmVtaXR0ZWRSZWFkYWJsZT1mYWxzZTtpZighc3RhdGUucmVhZGluZyl7cHJvY2Vzc05leHRUaWNrKG5SZWFkaW5nTmV4dFRpY2ssdGhpcyl9ZWxzZSBpZihzdGF0ZS5sZW5ndGgpe2VtaXRSZWFkYWJsZSh0aGlzLHN0YXRlKX19fXJldHVybiByZXN9O1JlYWRhYmxlLnByb3RvdHlwZS5hZGRMaXN0ZW5lcj1SZWFkYWJsZS5wcm90b3R5cGUub247ZnVuY3Rpb24gblJlYWRpbmdOZXh0VGljayhzZWxmKXtkZWJ1ZyhcInJlYWRhYmxlIG5leHR0aWNrIHJlYWQgMFwiKTtzZWxmLnJlYWQoMCl9UmVhZGFibGUucHJvdG90eXBlLnJlc3VtZT1mdW5jdGlvbigpe3ZhciBzdGF0ZT10aGlzLl9yZWFkYWJsZVN0YXRlO2lmKCFzdGF0ZS5mbG93aW5nKXtkZWJ1ZyhcInJlc3VtZVwiKTtzdGF0ZS5mbG93aW5nPXRydWU7cmVzdW1lKHRoaXMsc3RhdGUpfXJldHVybiB0aGlzfTtmdW5jdGlvbiByZXN1bWUoc3RyZWFtLHN0YXRlKXtpZighc3RhdGUucmVzdW1lU2NoZWR1bGVkKXtzdGF0ZS5yZXN1bWVTY2hlZHVsZWQ9dHJ1ZTtwcm9jZXNzTmV4dFRpY2socmVzdW1lXyxzdHJlYW0sc3RhdGUpfX1mdW5jdGlvbiByZXN1bWVfKHN0cmVhbSxzdGF0ZSl7aWYoIXN0YXRlLnJlYWRpbmcpe2RlYnVnKFwicmVzdW1lIHJlYWQgMFwiKTtzdHJlYW0ucmVhZCgwKX1zdGF0ZS5yZXN1bWVTY2hlZHVsZWQ9ZmFsc2U7c3RhdGUuYXdhaXREcmFpbj0wO3N0cmVhbS5lbWl0KFwicmVzdW1lXCIpO2Zsb3coc3RyZWFtKTtpZihzdGF0ZS5mbG93aW5nJiYhc3RhdGUucmVhZGluZylzdHJlYW0ucmVhZCgwKX1SZWFkYWJsZS5wcm90b3R5cGUucGF1c2U9ZnVuY3Rpb24oKXtkZWJ1ZyhcImNhbGwgcGF1c2UgZmxvd2luZz0lalwiLHRoaXMuX3JlYWRhYmxlU3RhdGUuZmxvd2luZyk7aWYoZmFsc2UhPT10aGlzLl9yZWFkYWJsZVN0YXRlLmZsb3dpbmcpe2RlYnVnKFwicGF1c2VcIik7dGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nPWZhbHNlO3RoaXMuZW1pdChcInBhdXNlXCIpfXJldHVybiB0aGlzfTtmdW5jdGlvbiBmbG93KHN0cmVhbSl7dmFyIHN0YXRlPXN0cmVhbS5fcmVhZGFibGVTdGF0ZTtkZWJ1ZyhcImZsb3dcIixzdGF0ZS5mbG93aW5nKTt3aGlsZShzdGF0ZS5mbG93aW5nJiZzdHJlYW0ucmVhZCgpIT09bnVsbCl7fX1SZWFkYWJsZS5wcm90b3R5cGUud3JhcD1mdW5jdGlvbihzdHJlYW0pe3ZhciBzdGF0ZT10aGlzLl9yZWFkYWJsZVN0YXRlO3ZhciBwYXVzZWQ9ZmFsc2U7dmFyIHNlbGY9dGhpcztzdHJlYW0ub24oXCJlbmRcIixmdW5jdGlvbigpe2RlYnVnKFwid3JhcHBlZCBlbmRcIik7aWYoc3RhdGUuZGVjb2RlciYmIXN0YXRlLmVuZGVkKXt2YXIgY2h1bms9c3RhdGUuZGVjb2Rlci5lbmQoKTtpZihjaHVuayYmY2h1bmsubGVuZ3RoKXNlbGYucHVzaChjaHVuayl9c2VsZi5wdXNoKG51bGwpfSk7c3RyZWFtLm9uKFwiZGF0YVwiLGZ1bmN0aW9uKGNodW5rKXtkZWJ1ZyhcIndyYXBwZWQgZGF0YVwiKTtpZihzdGF0ZS5kZWNvZGVyKWNodW5rPXN0YXRlLmRlY29kZXIud3JpdGUoY2h1bmspO2lmKHN0YXRlLm9iamVjdE1vZGUmJihjaHVuaz09PW51bGx8fGNodW5rPT09dW5kZWZpbmVkKSlyZXR1cm47ZWxzZSBpZighc3RhdGUub2JqZWN0TW9kZSYmKCFjaHVua3x8IWNodW5rLmxlbmd0aCkpcmV0dXJuO3ZhciByZXQ9c2VsZi5wdXNoKGNodW5rKTtpZighcmV0KXtwYXVzZWQ9dHJ1ZTtzdHJlYW0ucGF1c2UoKX19KTtmb3IodmFyIGkgaW4gc3RyZWFtKXtpZih0aGlzW2ldPT09dW5kZWZpbmVkJiZ0eXBlb2Ygc3RyZWFtW2ldPT09XCJmdW5jdGlvblwiKXt0aGlzW2ldPWZ1bmN0aW9uKG1ldGhvZCl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIHN0cmVhbVttZXRob2RdLmFwcGx5KHN0cmVhbSxhcmd1bWVudHMpfX0oaSl9fXZhciBldmVudHM9W1wiZXJyb3JcIixcImNsb3NlXCIsXCJkZXN0cm95XCIsXCJwYXVzZVwiLFwicmVzdW1lXCJdO2ZvckVhY2goZXZlbnRzLGZ1bmN0aW9uKGV2KXtzdHJlYW0ub24oZXYsc2VsZi5lbWl0LmJpbmQoc2VsZixldikpfSk7c2VsZi5fcmVhZD1mdW5jdGlvbihuKXtkZWJ1ZyhcIndyYXBwZWQgX3JlYWRcIixuKTtpZihwYXVzZWQpe3BhdXNlZD1mYWxzZTtzdHJlYW0ucmVzdW1lKCl9fTtyZXR1cm4gc2VsZn07UmVhZGFibGUuX2Zyb21MaXN0PWZyb21MaXN0O2Z1bmN0aW9uIGZyb21MaXN0KG4sc3RhdGUpe2lmKHN0YXRlLmxlbmd0aD09PTApcmV0dXJuIG51bGw7dmFyIHJldDtpZihzdGF0ZS5vYmplY3RNb2RlKXJldD1zdGF0ZS5idWZmZXIuc2hpZnQoKTtlbHNlIGlmKCFufHxuPj1zdGF0ZS5sZW5ndGgpe2lmKHN0YXRlLmRlY29kZXIpcmV0PXN0YXRlLmJ1ZmZlci5qb2luKFwiXCIpO2Vsc2UgaWYoc3RhdGUuYnVmZmVyLmxlbmd0aD09PTEpcmV0PXN0YXRlLmJ1ZmZlci5oZWFkLmRhdGE7ZWxzZSByZXQ9c3RhdGUuYnVmZmVyLmNvbmNhdChzdGF0ZS5sZW5ndGgpO3N0YXRlLmJ1ZmZlci5jbGVhcigpfWVsc2V7cmV0PWZyb21MaXN0UGFydGlhbChuLHN0YXRlLmJ1ZmZlcixzdGF0ZS5kZWNvZGVyKX1yZXR1cm4gcmV0fWZ1bmN0aW9uIGZyb21MaXN0UGFydGlhbChuLGxpc3QsaGFzU3RyaW5ncyl7dmFyIHJldDtpZihuPGxpc3QuaGVhZC5kYXRhLmxlbmd0aCl7cmV0PWxpc3QuaGVhZC5kYXRhLnNsaWNlKDAsbik7bGlzdC5oZWFkLmRhdGE9bGlzdC5oZWFkLmRhdGEuc2xpY2Uobil9ZWxzZSBpZihuPT09bGlzdC5oZWFkLmRhdGEubGVuZ3RoKXtyZXQ9bGlzdC5zaGlmdCgpfWVsc2V7cmV0PWhhc1N0cmluZ3M/Y29weUZyb21CdWZmZXJTdHJpbmcobixsaXN0KTpjb3B5RnJvbUJ1ZmZlcihuLGxpc3QpfXJldHVybiByZXR9ZnVuY3Rpb24gY29weUZyb21CdWZmZXJTdHJpbmcobixsaXN0KXt2YXIgcD1saXN0LmhlYWQ7dmFyIGM9MTt2YXIgcmV0PXAuZGF0YTtuLT1yZXQubGVuZ3RoO3doaWxlKHA9cC5uZXh0KXt2YXIgc3RyPXAuZGF0YTt2YXIgbmI9bj5zdHIubGVuZ3RoP3N0ci5sZW5ndGg6bjtpZihuYj09PXN0ci5sZW5ndGgpcmV0Kz1zdHI7ZWxzZSByZXQrPXN0ci5zbGljZSgwLG4pO24tPW5iO2lmKG49PT0wKXtpZihuYj09PXN0ci5sZW5ndGgpeysrYztpZihwLm5leHQpbGlzdC5oZWFkPXAubmV4dDtlbHNlIGxpc3QuaGVhZD1saXN0LnRhaWw9bnVsbH1lbHNle2xpc3QuaGVhZD1wO3AuZGF0YT1zdHIuc2xpY2UobmIpfWJyZWFrfSsrY31saXN0Lmxlbmd0aC09YztyZXR1cm4gcmV0fWZ1bmN0aW9uIGNvcHlGcm9tQnVmZmVyKG4sbGlzdCl7dmFyIHJldD1idWZmZXJTaGltLmFsbG9jVW5zYWZlKG4pO3ZhciBwPWxpc3QuaGVhZDt2YXIgYz0xO3AuZGF0YS5jb3B5KHJldCk7bi09cC5kYXRhLmxlbmd0aDt3aGlsZShwPXAubmV4dCl7dmFyIGJ1Zj1wLmRhdGE7dmFyIG5iPW4+YnVmLmxlbmd0aD9idWYubGVuZ3RoOm47YnVmLmNvcHkocmV0LHJldC5sZW5ndGgtbiwwLG5iKTtuLT1uYjtpZihuPT09MCl7aWYobmI9PT1idWYubGVuZ3RoKXsrK2M7aWYocC5uZXh0KWxpc3QuaGVhZD1wLm5leHQ7ZWxzZSBsaXN0LmhlYWQ9bGlzdC50YWlsPW51bGx9ZWxzZXtsaXN0LmhlYWQ9cDtwLmRhdGE9YnVmLnNsaWNlKG5iKX1icmVha30rK2N9bGlzdC5sZW5ndGgtPWM7cmV0dXJuIHJldH1mdW5jdGlvbiBlbmRSZWFkYWJsZShzdHJlYW0pe3ZhciBzdGF0ZT1zdHJlYW0uX3JlYWRhYmxlU3RhdGU7aWYoc3RhdGUubGVuZ3RoPjApdGhyb3cgbmV3IEVycm9yKCdcImVuZFJlYWRhYmxlKClcIiBjYWxsZWQgb24gbm9uLWVtcHR5IHN0cmVhbScpO2lmKCFzdGF0ZS5lbmRFbWl0dGVkKXtzdGF0ZS5lbmRlZD10cnVlO3Byb2Nlc3NOZXh0VGljayhlbmRSZWFkYWJsZU5ULHN0YXRlLHN0cmVhbSl9fWZ1bmN0aW9uIGVuZFJlYWRhYmxlTlQoc3RhdGUsc3RyZWFtKXtpZighc3RhdGUuZW5kRW1pdHRlZCYmc3RhdGUubGVuZ3RoPT09MCl7c3RhdGUuZW5kRW1pdHRlZD10cnVlO3N0cmVhbS5yZWFkYWJsZT1mYWxzZTtzdHJlYW0uZW1pdChcImVuZFwiKX19ZnVuY3Rpb24gZm9yRWFjaCh4cyxmKXtmb3IodmFyIGk9MCxsPXhzLmxlbmd0aDtpPGw7aSsrKXtmKHhzW2ldLGkpfX1mdW5jdGlvbiBpbmRleE9mKHhzLHgpe2Zvcih2YXIgaT0wLGw9eHMubGVuZ3RoO2k8bDtpKyspe2lmKHhzW2ldPT09eClyZXR1cm4gaX1yZXR1cm4tMX19KS5jYWxsKHRoaXMscmVxdWlyZShcIl9wcm9jZXNzXCIpKX0se1wiLi9fc3RyZWFtX2R1cGxleFwiOjQ0LFwiLi9pbnRlcm5hbC9zdHJlYW1zL0J1ZmZlckxpc3RcIjo0OSxfcHJvY2Vzczo0MixidWZmZXI6NSxcImJ1ZmZlci1zaGltc1wiOjQsXCJjb3JlLXV0aWwtaXNcIjo2LGV2ZW50czoyOCxpbmhlcml0czozOCxpc2FycmF5OjQwLFwicHJvY2Vzcy1uZXh0aWNrLWFyZ3NcIjo0MSxcInN0cmluZ19kZWNvZGVyL1wiOjU2LHV0aWw6M31dLDQ3OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcInVzZSBzdHJpY3RcIjttb2R1bGUuZXhwb3J0cz1UcmFuc2Zvcm07dmFyIER1cGxleD1yZXF1aXJlKFwiLi9fc3RyZWFtX2R1cGxleFwiKTt2YXIgdXRpbD1yZXF1aXJlKFwiY29yZS11dGlsLWlzXCIpO3V0aWwuaW5oZXJpdHM9cmVxdWlyZShcImluaGVyaXRzXCIpO3V0aWwuaW5oZXJpdHMoVHJhbnNmb3JtLER1cGxleCk7ZnVuY3Rpb24gVHJhbnNmb3JtU3RhdGUoc3RyZWFtKXt0aGlzLmFmdGVyVHJhbnNmb3JtPWZ1bmN0aW9uKGVyLGRhdGEpe3JldHVybiBhZnRlclRyYW5zZm9ybShzdHJlYW0sZXIsZGF0YSl9O3RoaXMubmVlZFRyYW5zZm9ybT1mYWxzZTt0aGlzLnRyYW5zZm9ybWluZz1mYWxzZTt0aGlzLndyaXRlY2I9bnVsbDt0aGlzLndyaXRlY2h1bms9bnVsbDt0aGlzLndyaXRlZW5jb2Rpbmc9bnVsbH1mdW5jdGlvbiBhZnRlclRyYW5zZm9ybShzdHJlYW0sZXIsZGF0YSl7dmFyIHRzPXN0cmVhbS5fdHJhbnNmb3JtU3RhdGU7dHMudHJhbnNmb3JtaW5nPWZhbHNlO3ZhciBjYj10cy53cml0ZWNiO2lmKCFjYilyZXR1cm4gc3RyZWFtLmVtaXQoXCJlcnJvclwiLG5ldyBFcnJvcihcIm5vIHdyaXRlY2IgaW4gVHJhbnNmb3JtIGNsYXNzXCIpKTt0cy53cml0ZWNodW5rPW51bGw7dHMud3JpdGVjYj1udWxsO2lmKGRhdGEhPT1udWxsJiZkYXRhIT09dW5kZWZpbmVkKXN0cmVhbS5wdXNoKGRhdGEpO2NiKGVyKTt2YXIgcnM9c3RyZWFtLl9yZWFkYWJsZVN0YXRlO3JzLnJlYWRpbmc9ZmFsc2U7aWYocnMubmVlZFJlYWRhYmxlfHxycy5sZW5ndGg8cnMuaGlnaFdhdGVyTWFyayl7c3RyZWFtLl9yZWFkKHJzLmhpZ2hXYXRlck1hcmspfX1mdW5jdGlvbiBUcmFuc2Zvcm0ob3B0aW9ucyl7aWYoISh0aGlzIGluc3RhbmNlb2YgVHJhbnNmb3JtKSlyZXR1cm4gbmV3IFRyYW5zZm9ybShvcHRpb25zKTtEdXBsZXguY2FsbCh0aGlzLG9wdGlvbnMpO3RoaXMuX3RyYW5zZm9ybVN0YXRlPW5ldyBUcmFuc2Zvcm1TdGF0ZSh0aGlzKTt2YXIgc3RyZWFtPXRoaXM7dGhpcy5fcmVhZGFibGVTdGF0ZS5uZWVkUmVhZGFibGU9dHJ1ZTt0aGlzLl9yZWFkYWJsZVN0YXRlLnN5bmM9ZmFsc2U7aWYob3B0aW9ucyl7aWYodHlwZW9mIG9wdGlvbnMudHJhbnNmb3JtPT09XCJmdW5jdGlvblwiKXRoaXMuX3RyYW5zZm9ybT1vcHRpb25zLnRyYW5zZm9ybTtpZih0eXBlb2Ygb3B0aW9ucy5mbHVzaD09PVwiZnVuY3Rpb25cIil0aGlzLl9mbHVzaD1vcHRpb25zLmZsdXNofXRoaXMub25jZShcInByZWZpbmlzaFwiLGZ1bmN0aW9uKCl7aWYodHlwZW9mIHRoaXMuX2ZsdXNoPT09XCJmdW5jdGlvblwiKXRoaXMuX2ZsdXNoKGZ1bmN0aW9uKGVyKXtkb25lKHN0cmVhbSxlcil9KTtlbHNlIGRvbmUoc3RyZWFtKX0pfVRyYW5zZm9ybS5wcm90b3R5cGUucHVzaD1mdW5jdGlvbihjaHVuayxlbmNvZGluZyl7dGhpcy5fdHJhbnNmb3JtU3RhdGUubmVlZFRyYW5zZm9ybT1mYWxzZTtyZXR1cm4gRHVwbGV4LnByb3RvdHlwZS5wdXNoLmNhbGwodGhpcyxjaHVuayxlbmNvZGluZyl9O1RyYW5zZm9ybS5wcm90b3R5cGUuX3RyYW5zZm9ybT1mdW5jdGlvbihjaHVuayxlbmNvZGluZyxjYil7dGhyb3cgbmV3IEVycm9yKFwiTm90IGltcGxlbWVudGVkXCIpfTtUcmFuc2Zvcm0ucHJvdG90eXBlLl93cml0ZT1mdW5jdGlvbihjaHVuayxlbmNvZGluZyxjYil7dmFyIHRzPXRoaXMuX3RyYW5zZm9ybVN0YXRlO3RzLndyaXRlY2I9Y2I7dHMud3JpdGVjaHVuaz1jaHVuazt0cy53cml0ZWVuY29kaW5nPWVuY29kaW5nO2lmKCF0cy50cmFuc2Zvcm1pbmcpe3ZhciBycz10aGlzLl9yZWFkYWJsZVN0YXRlO2lmKHRzLm5lZWRUcmFuc2Zvcm18fHJzLm5lZWRSZWFkYWJsZXx8cnMubGVuZ3RoPHJzLmhpZ2hXYXRlck1hcmspdGhpcy5fcmVhZChycy5oaWdoV2F0ZXJNYXJrKX19O1RyYW5zZm9ybS5wcm90b3R5cGUuX3JlYWQ9ZnVuY3Rpb24obil7dmFyIHRzPXRoaXMuX3RyYW5zZm9ybVN0YXRlO2lmKHRzLndyaXRlY2h1bmshPT1udWxsJiZ0cy53cml0ZWNiJiYhdHMudHJhbnNmb3JtaW5nKXt0cy50cmFuc2Zvcm1pbmc9dHJ1ZTt0aGlzLl90cmFuc2Zvcm0odHMud3JpdGVjaHVuayx0cy53cml0ZWVuY29kaW5nLHRzLmFmdGVyVHJhbnNmb3JtKX1lbHNle3RzLm5lZWRUcmFuc2Zvcm09dHJ1ZX19O2Z1bmN0aW9uIGRvbmUoc3RyZWFtLGVyKXtpZihlcilyZXR1cm4gc3RyZWFtLmVtaXQoXCJlcnJvclwiLGVyKTt2YXIgd3M9c3RyZWFtLl93cml0YWJsZVN0YXRlO3ZhciB0cz1zdHJlYW0uX3RyYW5zZm9ybVN0YXRlO2lmKHdzLmxlbmd0aCl0aHJvdyBuZXcgRXJyb3IoXCJDYWxsaW5nIHRyYW5zZm9ybSBkb25lIHdoZW4gd3MubGVuZ3RoICE9IDBcIik7aWYodHMudHJhbnNmb3JtaW5nKXRocm93IG5ldyBFcnJvcihcIkNhbGxpbmcgdHJhbnNmb3JtIGRvbmUgd2hlbiBzdGlsbCB0cmFuc2Zvcm1pbmdcIik7cmV0dXJuIHN0cmVhbS5wdXNoKG51bGwpfX0se1wiLi9fc3RyZWFtX2R1cGxleFwiOjQ0LFwiY29yZS11dGlsLWlzXCI6Nixpbmhlcml0czozOH1dLDQ4OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsoZnVuY3Rpb24ocHJvY2Vzcyl7XCJ1c2Ugc3RyaWN0XCI7bW9kdWxlLmV4cG9ydHM9V3JpdGFibGU7dmFyIHByb2Nlc3NOZXh0VGljaz1yZXF1aXJlKFwicHJvY2Vzcy1uZXh0aWNrLWFyZ3NcIik7dmFyIGFzeW5jV3JpdGU9IXByb2Nlc3MuYnJvd3NlciYmW1widjAuMTBcIixcInYwLjkuXCJdLmluZGV4T2YocHJvY2Vzcy52ZXJzaW9uLnNsaWNlKDAsNSkpPi0xP3NldEltbWVkaWF0ZTpwcm9jZXNzTmV4dFRpY2s7V3JpdGFibGUuV3JpdGFibGVTdGF0ZT1Xcml0YWJsZVN0YXRlO3ZhciB1dGlsPXJlcXVpcmUoXCJjb3JlLXV0aWwtaXNcIik7dXRpbC5pbmhlcml0cz1yZXF1aXJlKFwiaW5oZXJpdHNcIik7dmFyIGludGVybmFsVXRpbD17ZGVwcmVjYXRlOnJlcXVpcmUoXCJ1dGlsLWRlcHJlY2F0ZVwiKX07dmFyIFN0cmVhbTsoZnVuY3Rpb24oKXt0cnl7U3RyZWFtPXJlcXVpcmUoXCJzdFwiK1wicmVhbVwiKX1jYXRjaChfKXt9ZmluYWxseXtpZighU3RyZWFtKVN0cmVhbT1yZXF1aXJlKFwiZXZlbnRzXCIpLkV2ZW50RW1pdHRlcn19KSgpO3ZhciBCdWZmZXI9cmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXI7dmFyIGJ1ZmZlclNoaW09cmVxdWlyZShcImJ1ZmZlci1zaGltc1wiKTt1dGlsLmluaGVyaXRzKFdyaXRhYmxlLFN0cmVhbSk7ZnVuY3Rpb24gbm9wKCl7fWZ1bmN0aW9uIFdyaXRlUmVxKGNodW5rLGVuY29kaW5nLGNiKXt0aGlzLmNodW5rPWNodW5rO3RoaXMuZW5jb2Rpbmc9ZW5jb2Rpbmc7dGhpcy5jYWxsYmFjaz1jYjt0aGlzLm5leHQ9bnVsbH12YXIgRHVwbGV4O2Z1bmN0aW9uIFdyaXRhYmxlU3RhdGUob3B0aW9ucyxzdHJlYW0pe0R1cGxleD1EdXBsZXh8fHJlcXVpcmUoXCIuL19zdHJlYW1fZHVwbGV4XCIpO29wdGlvbnM9b3B0aW9uc3x8e307dGhpcy5vYmplY3RNb2RlPSEhb3B0aW9ucy5vYmplY3RNb2RlO2lmKHN0cmVhbSBpbnN0YW5jZW9mIER1cGxleCl0aGlzLm9iamVjdE1vZGU9dGhpcy5vYmplY3RNb2RlfHwhIW9wdGlvbnMud3JpdGFibGVPYmplY3RNb2RlO3ZhciBod209b3B0aW9ucy5oaWdoV2F0ZXJNYXJrO3ZhciBkZWZhdWx0SHdtPXRoaXMub2JqZWN0TW9kZT8xNjoxNioxMDI0O3RoaXMuaGlnaFdhdGVyTWFyaz1od218fGh3bT09PTA/aHdtOmRlZmF1bHRId207dGhpcy5oaWdoV2F0ZXJNYXJrPX5+dGhpcy5oaWdoV2F0ZXJNYXJrO3RoaXMubmVlZERyYWluPWZhbHNlO3RoaXMuZW5kaW5nPWZhbHNlO3RoaXMuZW5kZWQ9ZmFsc2U7dGhpcy5maW5pc2hlZD1mYWxzZTt2YXIgbm9EZWNvZGU9b3B0aW9ucy5kZWNvZGVTdHJpbmdzPT09ZmFsc2U7dGhpcy5kZWNvZGVTdHJpbmdzPSFub0RlY29kZTt0aGlzLmRlZmF1bHRFbmNvZGluZz1vcHRpb25zLmRlZmF1bHRFbmNvZGluZ3x8XCJ1dGY4XCI7dGhpcy5sZW5ndGg9MDt0aGlzLndyaXRpbmc9ZmFsc2U7dGhpcy5jb3JrZWQ9MDt0aGlzLnN5bmM9dHJ1ZTt0aGlzLmJ1ZmZlclByb2Nlc3Npbmc9ZmFsc2U7dGhpcy5vbndyaXRlPWZ1bmN0aW9uKGVyKXtvbndyaXRlKHN0cmVhbSxlcil9O3RoaXMud3JpdGVjYj1udWxsO3RoaXMud3JpdGVsZW49MDt0aGlzLmJ1ZmZlcmVkUmVxdWVzdD1udWxsO3RoaXMubGFzdEJ1ZmZlcmVkUmVxdWVzdD1udWxsO3RoaXMucGVuZGluZ2NiPTA7dGhpcy5wcmVmaW5pc2hlZD1mYWxzZTt0aGlzLmVycm9yRW1pdHRlZD1mYWxzZTt0aGlzLmJ1ZmZlcmVkUmVxdWVzdENvdW50PTA7dGhpcy5jb3JrZWRSZXF1ZXN0c0ZyZWU9bmV3IENvcmtlZFJlcXVlc3QodGhpcyl9V3JpdGFibGVTdGF0ZS5wcm90b3R5cGUuZ2V0QnVmZmVyPWZ1bmN0aW9uIHdyaXRhYmxlU3RhdGVHZXRCdWZmZXIoKXt2YXIgY3VycmVudD10aGlzLmJ1ZmZlcmVkUmVxdWVzdDt2YXIgb3V0PVtdO3doaWxlKGN1cnJlbnQpe291dC5wdXNoKGN1cnJlbnQpO2N1cnJlbnQ9Y3VycmVudC5uZXh0fXJldHVybiBvdXR9OyhmdW5jdGlvbigpe3RyeXtPYmplY3QuZGVmaW5lUHJvcGVydHkoV3JpdGFibGVTdGF0ZS5wcm90b3R5cGUsXCJidWZmZXJcIix7Z2V0OmludGVybmFsVXRpbC5kZXByZWNhdGUoZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5nZXRCdWZmZXIoKX0sXCJfd3JpdGFibGVTdGF0ZS5idWZmZXIgaXMgZGVwcmVjYXRlZC4gVXNlIF93cml0YWJsZVN0YXRlLmdldEJ1ZmZlciBcIitcImluc3RlYWQuXCIpfSl9Y2F0Y2goXyl7fX0pKCk7dmFyIER1cGxleDtmdW5jdGlvbiBXcml0YWJsZShvcHRpb25zKXtEdXBsZXg9RHVwbGV4fHxyZXF1aXJlKFwiLi9fc3RyZWFtX2R1cGxleFwiKTtpZighKHRoaXMgaW5zdGFuY2VvZiBXcml0YWJsZSkmJiEodGhpcyBpbnN0YW5jZW9mIER1cGxleCkpcmV0dXJuIG5ldyBXcml0YWJsZShvcHRpb25zKTt0aGlzLl93cml0YWJsZVN0YXRlPW5ldyBXcml0YWJsZVN0YXRlKG9wdGlvbnMsdGhpcyk7dGhpcy53cml0YWJsZT10cnVlO2lmKG9wdGlvbnMpe2lmKHR5cGVvZiBvcHRpb25zLndyaXRlPT09XCJmdW5jdGlvblwiKXRoaXMuX3dyaXRlPW9wdGlvbnMud3JpdGU7aWYodHlwZW9mIG9wdGlvbnMud3JpdGV2PT09XCJmdW5jdGlvblwiKXRoaXMuX3dyaXRldj1vcHRpb25zLndyaXRldn1TdHJlYW0uY2FsbCh0aGlzKX1Xcml0YWJsZS5wcm90b3R5cGUucGlwZT1mdW5jdGlvbigpe3RoaXMuZW1pdChcImVycm9yXCIsbmV3IEVycm9yKFwiQ2Fubm90IHBpcGUsIG5vdCByZWFkYWJsZVwiKSl9O2Z1bmN0aW9uIHdyaXRlQWZ0ZXJFbmQoc3RyZWFtLGNiKXt2YXIgZXI9bmV3IEVycm9yKFwid3JpdGUgYWZ0ZXIgZW5kXCIpO3N0cmVhbS5lbWl0KFwiZXJyb3JcIixlcik7cHJvY2Vzc05leHRUaWNrKGNiLGVyKX1mdW5jdGlvbiB2YWxpZENodW5rKHN0cmVhbSxzdGF0ZSxjaHVuayxjYil7dmFyIHZhbGlkPXRydWU7dmFyIGVyPWZhbHNlO2lmKGNodW5rPT09bnVsbCl7ZXI9bmV3IFR5cGVFcnJvcihcIk1heSBub3Qgd3JpdGUgbnVsbCB2YWx1ZXMgdG8gc3RyZWFtXCIpfWVsc2UgaWYoIUJ1ZmZlci5pc0J1ZmZlcihjaHVuaykmJnR5cGVvZiBjaHVuayE9PVwic3RyaW5nXCImJmNodW5rIT09dW5kZWZpbmVkJiYhc3RhdGUub2JqZWN0TW9kZSl7ZXI9bmV3IFR5cGVFcnJvcihcIkludmFsaWQgbm9uLXN0cmluZy9idWZmZXIgY2h1bmtcIil9aWYoZXIpe3N0cmVhbS5lbWl0KFwiZXJyb3JcIixlcik7cHJvY2Vzc05leHRUaWNrKGNiLGVyKTt2YWxpZD1mYWxzZX1yZXR1cm4gdmFsaWR9V3JpdGFibGUucHJvdG90eXBlLndyaXRlPWZ1bmN0aW9uKGNodW5rLGVuY29kaW5nLGNiKXt2YXIgc3RhdGU9dGhpcy5fd3JpdGFibGVTdGF0ZTt2YXIgcmV0PWZhbHNlO2lmKHR5cGVvZiBlbmNvZGluZz09PVwiZnVuY3Rpb25cIil7Y2I9ZW5jb2Rpbmc7ZW5jb2Rpbmc9bnVsbH1pZihCdWZmZXIuaXNCdWZmZXIoY2h1bmspKWVuY29kaW5nPVwiYnVmZmVyXCI7ZWxzZSBpZighZW5jb2RpbmcpZW5jb2Rpbmc9c3RhdGUuZGVmYXVsdEVuY29kaW5nO2lmKHR5cGVvZiBjYiE9PVwiZnVuY3Rpb25cIiljYj1ub3A7aWYoc3RhdGUuZW5kZWQpd3JpdGVBZnRlckVuZCh0aGlzLGNiKTtlbHNlIGlmKHZhbGlkQ2h1bmsodGhpcyxzdGF0ZSxjaHVuayxjYikpe1xuc3RhdGUucGVuZGluZ2NiKys7cmV0PXdyaXRlT3JCdWZmZXIodGhpcyxzdGF0ZSxjaHVuayxlbmNvZGluZyxjYil9cmV0dXJuIHJldH07V3JpdGFibGUucHJvdG90eXBlLmNvcms9ZnVuY3Rpb24oKXt2YXIgc3RhdGU9dGhpcy5fd3JpdGFibGVTdGF0ZTtzdGF0ZS5jb3JrZWQrK307V3JpdGFibGUucHJvdG90eXBlLnVuY29yaz1mdW5jdGlvbigpe3ZhciBzdGF0ZT10aGlzLl93cml0YWJsZVN0YXRlO2lmKHN0YXRlLmNvcmtlZCl7c3RhdGUuY29ya2VkLS07aWYoIXN0YXRlLndyaXRpbmcmJiFzdGF0ZS5jb3JrZWQmJiFzdGF0ZS5maW5pc2hlZCYmIXN0YXRlLmJ1ZmZlclByb2Nlc3NpbmcmJnN0YXRlLmJ1ZmZlcmVkUmVxdWVzdCljbGVhckJ1ZmZlcih0aGlzLHN0YXRlKX19O1dyaXRhYmxlLnByb3RvdHlwZS5zZXREZWZhdWx0RW5jb2Rpbmc9ZnVuY3Rpb24gc2V0RGVmYXVsdEVuY29kaW5nKGVuY29kaW5nKXtpZih0eXBlb2YgZW5jb2Rpbmc9PT1cInN0cmluZ1wiKWVuY29kaW5nPWVuY29kaW5nLnRvTG93ZXJDYXNlKCk7aWYoIShbXCJoZXhcIixcInV0ZjhcIixcInV0Zi04XCIsXCJhc2NpaVwiLFwiYmluYXJ5XCIsXCJiYXNlNjRcIixcInVjczJcIixcInVjcy0yXCIsXCJ1dGYxNmxlXCIsXCJ1dGYtMTZsZVwiLFwicmF3XCJdLmluZGV4T2YoKGVuY29kaW5nK1wiXCIpLnRvTG93ZXJDYXNlKCkpPi0xKSl0aHJvdyBuZXcgVHlwZUVycm9yKFwiVW5rbm93biBlbmNvZGluZzogXCIrZW5jb2RpbmcpO3RoaXMuX3dyaXRhYmxlU3RhdGUuZGVmYXVsdEVuY29kaW5nPWVuY29kaW5nO3JldHVybiB0aGlzfTtmdW5jdGlvbiBkZWNvZGVDaHVuayhzdGF0ZSxjaHVuayxlbmNvZGluZyl7aWYoIXN0YXRlLm9iamVjdE1vZGUmJnN0YXRlLmRlY29kZVN0cmluZ3MhPT1mYWxzZSYmdHlwZW9mIGNodW5rPT09XCJzdHJpbmdcIil7Y2h1bms9YnVmZmVyU2hpbS5mcm9tKGNodW5rLGVuY29kaW5nKX1yZXR1cm4gY2h1bmt9ZnVuY3Rpb24gd3JpdGVPckJ1ZmZlcihzdHJlYW0sc3RhdGUsY2h1bmssZW5jb2RpbmcsY2Ipe2NodW5rPWRlY29kZUNodW5rKHN0YXRlLGNodW5rLGVuY29kaW5nKTtpZihCdWZmZXIuaXNCdWZmZXIoY2h1bmspKWVuY29kaW5nPVwiYnVmZmVyXCI7dmFyIGxlbj1zdGF0ZS5vYmplY3RNb2RlPzE6Y2h1bmsubGVuZ3RoO3N0YXRlLmxlbmd0aCs9bGVuO3ZhciByZXQ9c3RhdGUubGVuZ3RoPHN0YXRlLmhpZ2hXYXRlck1hcms7aWYoIXJldClzdGF0ZS5uZWVkRHJhaW49dHJ1ZTtpZihzdGF0ZS53cml0aW5nfHxzdGF0ZS5jb3JrZWQpe3ZhciBsYXN0PXN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3Q7c3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdD1uZXcgV3JpdGVSZXEoY2h1bmssZW5jb2RpbmcsY2IpO2lmKGxhc3Qpe2xhc3QubmV4dD1zdGF0ZS5sYXN0QnVmZmVyZWRSZXF1ZXN0fWVsc2V7c3RhdGUuYnVmZmVyZWRSZXF1ZXN0PXN0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3R9c3RhdGUuYnVmZmVyZWRSZXF1ZXN0Q291bnQrPTF9ZWxzZXtkb1dyaXRlKHN0cmVhbSxzdGF0ZSxmYWxzZSxsZW4sY2h1bmssZW5jb2RpbmcsY2IpfXJldHVybiByZXR9ZnVuY3Rpb24gZG9Xcml0ZShzdHJlYW0sc3RhdGUsd3JpdGV2LGxlbixjaHVuayxlbmNvZGluZyxjYil7c3RhdGUud3JpdGVsZW49bGVuO3N0YXRlLndyaXRlY2I9Y2I7c3RhdGUud3JpdGluZz10cnVlO3N0YXRlLnN5bmM9dHJ1ZTtpZih3cml0ZXYpc3RyZWFtLl93cml0ZXYoY2h1bmssc3RhdGUub253cml0ZSk7ZWxzZSBzdHJlYW0uX3dyaXRlKGNodW5rLGVuY29kaW5nLHN0YXRlLm9ud3JpdGUpO3N0YXRlLnN5bmM9ZmFsc2V9ZnVuY3Rpb24gb253cml0ZUVycm9yKHN0cmVhbSxzdGF0ZSxzeW5jLGVyLGNiKXstLXN0YXRlLnBlbmRpbmdjYjtpZihzeW5jKXByb2Nlc3NOZXh0VGljayhjYixlcik7ZWxzZSBjYihlcik7c3RyZWFtLl93cml0YWJsZVN0YXRlLmVycm9yRW1pdHRlZD10cnVlO3N0cmVhbS5lbWl0KFwiZXJyb3JcIixlcil9ZnVuY3Rpb24gb253cml0ZVN0YXRlVXBkYXRlKHN0YXRlKXtzdGF0ZS53cml0aW5nPWZhbHNlO3N0YXRlLndyaXRlY2I9bnVsbDtzdGF0ZS5sZW5ndGgtPXN0YXRlLndyaXRlbGVuO3N0YXRlLndyaXRlbGVuPTB9ZnVuY3Rpb24gb253cml0ZShzdHJlYW0sZXIpe3ZhciBzdGF0ZT1zdHJlYW0uX3dyaXRhYmxlU3RhdGU7dmFyIHN5bmM9c3RhdGUuc3luYzt2YXIgY2I9c3RhdGUud3JpdGVjYjtvbndyaXRlU3RhdGVVcGRhdGUoc3RhdGUpO2lmKGVyKW9ud3JpdGVFcnJvcihzdHJlYW0sc3RhdGUsc3luYyxlcixjYik7ZWxzZXt2YXIgZmluaXNoZWQ9bmVlZEZpbmlzaChzdGF0ZSk7aWYoIWZpbmlzaGVkJiYhc3RhdGUuY29ya2VkJiYhc3RhdGUuYnVmZmVyUHJvY2Vzc2luZyYmc3RhdGUuYnVmZmVyZWRSZXF1ZXN0KXtjbGVhckJ1ZmZlcihzdHJlYW0sc3RhdGUpfWlmKHN5bmMpe2FzeW5jV3JpdGUoYWZ0ZXJXcml0ZSxzdHJlYW0sc3RhdGUsZmluaXNoZWQsY2IpfWVsc2V7YWZ0ZXJXcml0ZShzdHJlYW0sc3RhdGUsZmluaXNoZWQsY2IpfX19ZnVuY3Rpb24gYWZ0ZXJXcml0ZShzdHJlYW0sc3RhdGUsZmluaXNoZWQsY2Ipe2lmKCFmaW5pc2hlZClvbndyaXRlRHJhaW4oc3RyZWFtLHN0YXRlKTtzdGF0ZS5wZW5kaW5nY2ItLTtjYigpO2ZpbmlzaE1heWJlKHN0cmVhbSxzdGF0ZSl9ZnVuY3Rpb24gb253cml0ZURyYWluKHN0cmVhbSxzdGF0ZSl7aWYoc3RhdGUubGVuZ3RoPT09MCYmc3RhdGUubmVlZERyYWluKXtzdGF0ZS5uZWVkRHJhaW49ZmFsc2U7c3RyZWFtLmVtaXQoXCJkcmFpblwiKX19ZnVuY3Rpb24gY2xlYXJCdWZmZXIoc3RyZWFtLHN0YXRlKXtzdGF0ZS5idWZmZXJQcm9jZXNzaW5nPXRydWU7dmFyIGVudHJ5PXN0YXRlLmJ1ZmZlcmVkUmVxdWVzdDtpZihzdHJlYW0uX3dyaXRldiYmZW50cnkmJmVudHJ5Lm5leHQpe3ZhciBsPXN0YXRlLmJ1ZmZlcmVkUmVxdWVzdENvdW50O3ZhciBidWZmZXI9bmV3IEFycmF5KGwpO3ZhciBob2xkZXI9c3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlO2hvbGRlci5lbnRyeT1lbnRyeTt2YXIgY291bnQ9MDt3aGlsZShlbnRyeSl7YnVmZmVyW2NvdW50XT1lbnRyeTtlbnRyeT1lbnRyeS5uZXh0O2NvdW50Kz0xfWRvV3JpdGUoc3RyZWFtLHN0YXRlLHRydWUsc3RhdGUubGVuZ3RoLGJ1ZmZlcixcIlwiLGhvbGRlci5maW5pc2gpO3N0YXRlLnBlbmRpbmdjYisrO3N0YXRlLmxhc3RCdWZmZXJlZFJlcXVlc3Q9bnVsbDtpZihob2xkZXIubmV4dCl7c3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlPWhvbGRlci5uZXh0O2hvbGRlci5uZXh0PW51bGx9ZWxzZXtzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWU9bmV3IENvcmtlZFJlcXVlc3Qoc3RhdGUpfX1lbHNle3doaWxlKGVudHJ5KXt2YXIgY2h1bms9ZW50cnkuY2h1bms7dmFyIGVuY29kaW5nPWVudHJ5LmVuY29kaW5nO3ZhciBjYj1lbnRyeS5jYWxsYmFjazt2YXIgbGVuPXN0YXRlLm9iamVjdE1vZGU/MTpjaHVuay5sZW5ndGg7ZG9Xcml0ZShzdHJlYW0sc3RhdGUsZmFsc2UsbGVuLGNodW5rLGVuY29kaW5nLGNiKTtlbnRyeT1lbnRyeS5uZXh0O2lmKHN0YXRlLndyaXRpbmcpe2JyZWFrfX1pZihlbnRyeT09PW51bGwpc3RhdGUubGFzdEJ1ZmZlcmVkUmVxdWVzdD1udWxsfXN0YXRlLmJ1ZmZlcmVkUmVxdWVzdENvdW50PTA7c3RhdGUuYnVmZmVyZWRSZXF1ZXN0PWVudHJ5O3N0YXRlLmJ1ZmZlclByb2Nlc3Npbmc9ZmFsc2V9V3JpdGFibGUucHJvdG90eXBlLl93cml0ZT1mdW5jdGlvbihjaHVuayxlbmNvZGluZyxjYil7Y2IobmV3IEVycm9yKFwibm90IGltcGxlbWVudGVkXCIpKX07V3JpdGFibGUucHJvdG90eXBlLl93cml0ZXY9bnVsbDtXcml0YWJsZS5wcm90b3R5cGUuZW5kPWZ1bmN0aW9uKGNodW5rLGVuY29kaW5nLGNiKXt2YXIgc3RhdGU9dGhpcy5fd3JpdGFibGVTdGF0ZTtpZih0eXBlb2YgY2h1bms9PT1cImZ1bmN0aW9uXCIpe2NiPWNodW5rO2NodW5rPW51bGw7ZW5jb2Rpbmc9bnVsbH1lbHNlIGlmKHR5cGVvZiBlbmNvZGluZz09PVwiZnVuY3Rpb25cIil7Y2I9ZW5jb2Rpbmc7ZW5jb2Rpbmc9bnVsbH1pZihjaHVuayE9PW51bGwmJmNodW5rIT09dW5kZWZpbmVkKXRoaXMud3JpdGUoY2h1bmssZW5jb2RpbmcpO2lmKHN0YXRlLmNvcmtlZCl7c3RhdGUuY29ya2VkPTE7dGhpcy51bmNvcmsoKX1pZighc3RhdGUuZW5kaW5nJiYhc3RhdGUuZmluaXNoZWQpZW5kV3JpdGFibGUodGhpcyxzdGF0ZSxjYil9O2Z1bmN0aW9uIG5lZWRGaW5pc2goc3RhdGUpe3JldHVybiBzdGF0ZS5lbmRpbmcmJnN0YXRlLmxlbmd0aD09PTAmJnN0YXRlLmJ1ZmZlcmVkUmVxdWVzdD09PW51bGwmJiFzdGF0ZS5maW5pc2hlZCYmIXN0YXRlLndyaXRpbmd9ZnVuY3Rpb24gcHJlZmluaXNoKHN0cmVhbSxzdGF0ZSl7aWYoIXN0YXRlLnByZWZpbmlzaGVkKXtzdGF0ZS5wcmVmaW5pc2hlZD10cnVlO3N0cmVhbS5lbWl0KFwicHJlZmluaXNoXCIpfX1mdW5jdGlvbiBmaW5pc2hNYXliZShzdHJlYW0sc3RhdGUpe3ZhciBuZWVkPW5lZWRGaW5pc2goc3RhdGUpO2lmKG5lZWQpe2lmKHN0YXRlLnBlbmRpbmdjYj09PTApe3ByZWZpbmlzaChzdHJlYW0sc3RhdGUpO3N0YXRlLmZpbmlzaGVkPXRydWU7c3RyZWFtLmVtaXQoXCJmaW5pc2hcIil9ZWxzZXtwcmVmaW5pc2goc3RyZWFtLHN0YXRlKX19cmV0dXJuIG5lZWR9ZnVuY3Rpb24gZW5kV3JpdGFibGUoc3RyZWFtLHN0YXRlLGNiKXtzdGF0ZS5lbmRpbmc9dHJ1ZTtmaW5pc2hNYXliZShzdHJlYW0sc3RhdGUpO2lmKGNiKXtpZihzdGF0ZS5maW5pc2hlZClwcm9jZXNzTmV4dFRpY2soY2IpO2Vsc2Ugc3RyZWFtLm9uY2UoXCJmaW5pc2hcIixjYil9c3RhdGUuZW5kZWQ9dHJ1ZTtzdHJlYW0ud3JpdGFibGU9ZmFsc2V9ZnVuY3Rpb24gQ29ya2VkUmVxdWVzdChzdGF0ZSl7dmFyIF90aGlzPXRoaXM7dGhpcy5uZXh0PW51bGw7dGhpcy5lbnRyeT1udWxsO3RoaXMuZmluaXNoPWZ1bmN0aW9uKGVycil7dmFyIGVudHJ5PV90aGlzLmVudHJ5O190aGlzLmVudHJ5PW51bGw7d2hpbGUoZW50cnkpe3ZhciBjYj1lbnRyeS5jYWxsYmFjaztzdGF0ZS5wZW5kaW5nY2ItLTtjYihlcnIpO2VudHJ5PWVudHJ5Lm5leHR9aWYoc3RhdGUuY29ya2VkUmVxdWVzdHNGcmVlKXtzdGF0ZS5jb3JrZWRSZXF1ZXN0c0ZyZWUubmV4dD1fdGhpc31lbHNle3N0YXRlLmNvcmtlZFJlcXVlc3RzRnJlZT1fdGhpc319fX0pLmNhbGwodGhpcyxyZXF1aXJlKFwiX3Byb2Nlc3NcIikpfSx7XCIuL19zdHJlYW1fZHVwbGV4XCI6NDQsX3Byb2Nlc3M6NDIsYnVmZmVyOjUsXCJidWZmZXItc2hpbXNcIjo0LFwiY29yZS11dGlsLWlzXCI6NixldmVudHM6MjgsaW5oZXJpdHM6MzgsXCJwcm9jZXNzLW5leHRpY2stYXJnc1wiOjQxLFwidXRpbC1kZXByZWNhdGVcIjo1N31dLDQ5OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcInVzZSBzdHJpY3RcIjt2YXIgQnVmZmVyPXJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyO3ZhciBidWZmZXJTaGltPXJlcXVpcmUoXCJidWZmZXItc2hpbXNcIik7bW9kdWxlLmV4cG9ydHM9QnVmZmVyTGlzdDtmdW5jdGlvbiBCdWZmZXJMaXN0KCl7dGhpcy5oZWFkPW51bGw7dGhpcy50YWlsPW51bGw7dGhpcy5sZW5ndGg9MH1CdWZmZXJMaXN0LnByb3RvdHlwZS5wdXNoPWZ1bmN0aW9uKHYpe3ZhciBlbnRyeT17ZGF0YTp2LG5leHQ6bnVsbH07aWYodGhpcy5sZW5ndGg+MCl0aGlzLnRhaWwubmV4dD1lbnRyeTtlbHNlIHRoaXMuaGVhZD1lbnRyeTt0aGlzLnRhaWw9ZW50cnk7Kyt0aGlzLmxlbmd0aH07QnVmZmVyTGlzdC5wcm90b3R5cGUudW5zaGlmdD1mdW5jdGlvbih2KXt2YXIgZW50cnk9e2RhdGE6dixuZXh0OnRoaXMuaGVhZH07aWYodGhpcy5sZW5ndGg9PT0wKXRoaXMudGFpbD1lbnRyeTt0aGlzLmhlYWQ9ZW50cnk7Kyt0aGlzLmxlbmd0aH07QnVmZmVyTGlzdC5wcm90b3R5cGUuc2hpZnQ9ZnVuY3Rpb24oKXtpZih0aGlzLmxlbmd0aD09PTApcmV0dXJuO3ZhciByZXQ9dGhpcy5oZWFkLmRhdGE7aWYodGhpcy5sZW5ndGg9PT0xKXRoaXMuaGVhZD10aGlzLnRhaWw9bnVsbDtlbHNlIHRoaXMuaGVhZD10aGlzLmhlYWQubmV4dDstLXRoaXMubGVuZ3RoO3JldHVybiByZXR9O0J1ZmZlckxpc3QucHJvdG90eXBlLmNsZWFyPWZ1bmN0aW9uKCl7dGhpcy5oZWFkPXRoaXMudGFpbD1udWxsO3RoaXMubGVuZ3RoPTB9O0J1ZmZlckxpc3QucHJvdG90eXBlLmpvaW49ZnVuY3Rpb24ocyl7aWYodGhpcy5sZW5ndGg9PT0wKXJldHVyblwiXCI7dmFyIHA9dGhpcy5oZWFkO3ZhciByZXQ9XCJcIitwLmRhdGE7d2hpbGUocD1wLm5leHQpe3JldCs9cytwLmRhdGF9cmV0dXJuIHJldH07QnVmZmVyTGlzdC5wcm90b3R5cGUuY29uY2F0PWZ1bmN0aW9uKG4pe2lmKHRoaXMubGVuZ3RoPT09MClyZXR1cm4gYnVmZmVyU2hpbS5hbGxvYygwKTtpZih0aGlzLmxlbmd0aD09PTEpcmV0dXJuIHRoaXMuaGVhZC5kYXRhO3ZhciByZXQ9YnVmZmVyU2hpbS5hbGxvY1Vuc2FmZShuPj4+MCk7dmFyIHA9dGhpcy5oZWFkO3ZhciBpPTA7d2hpbGUocCl7cC5kYXRhLmNvcHkocmV0LGkpO2krPXAuZGF0YS5sZW5ndGg7cD1wLm5leHR9cmV0dXJuIHJldH19LHtidWZmZXI6NSxcImJ1ZmZlci1zaGltc1wiOjR9XSw1MDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9cmVxdWlyZShcIi4vbGliL19zdHJlYW1fcGFzc3Rocm91Z2guanNcIil9LHtcIi4vbGliL19zdHJlYW1fcGFzc3Rocm91Z2guanNcIjo0NX1dLDUxOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsoZnVuY3Rpb24ocHJvY2Vzcyl7dmFyIFN0cmVhbT1mdW5jdGlvbigpe3RyeXtyZXR1cm4gcmVxdWlyZShcInN0XCIrXCJyZWFtXCIpfWNhdGNoKF8pe319KCk7ZXhwb3J0cz1tb2R1bGUuZXhwb3J0cz1yZXF1aXJlKFwiLi9saWIvX3N0cmVhbV9yZWFkYWJsZS5qc1wiKTtleHBvcnRzLlN0cmVhbT1TdHJlYW18fGV4cG9ydHM7ZXhwb3J0cy5SZWFkYWJsZT1leHBvcnRzO2V4cG9ydHMuV3JpdGFibGU9cmVxdWlyZShcIi4vbGliL19zdHJlYW1fd3JpdGFibGUuanNcIik7ZXhwb3J0cy5EdXBsZXg9cmVxdWlyZShcIi4vbGliL19zdHJlYW1fZHVwbGV4LmpzXCIpO2V4cG9ydHMuVHJhbnNmb3JtPXJlcXVpcmUoXCIuL2xpYi9fc3RyZWFtX3RyYW5zZm9ybS5qc1wiKTtleHBvcnRzLlBhc3NUaHJvdWdoPXJlcXVpcmUoXCIuL2xpYi9fc3RyZWFtX3Bhc3N0aHJvdWdoLmpzXCIpO2lmKCFwcm9jZXNzLmJyb3dzZXImJnByb2Nlc3MuZW52LlJFQURBQkxFX1NUUkVBTT09PVwiZGlzYWJsZVwiJiZTdHJlYW0pe21vZHVsZS5leHBvcnRzPVN0cmVhbX19KS5jYWxsKHRoaXMscmVxdWlyZShcIl9wcm9jZXNzXCIpKX0se1wiLi9saWIvX3N0cmVhbV9kdXBsZXguanNcIjo0NCxcIi4vbGliL19zdHJlYW1fcGFzc3Rocm91Z2guanNcIjo0NSxcIi4vbGliL19zdHJlYW1fcmVhZGFibGUuanNcIjo0NixcIi4vbGliL19zdHJlYW1fdHJhbnNmb3JtLmpzXCI6NDcsXCIuL2xpYi9fc3RyZWFtX3dyaXRhYmxlLmpzXCI6NDgsX3Byb2Nlc3M6NDJ9XSw1MjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9cmVxdWlyZShcIi4vbGliL19zdHJlYW1fdHJhbnNmb3JtLmpzXCIpfSx7XCIuL2xpYi9fc3RyZWFtX3RyYW5zZm9ybS5qc1wiOjQ3fV0sNTM6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe21vZHVsZS5leHBvcnRzPXJlcXVpcmUoXCIuL2xpYi9fc3RyZWFtX3dyaXRhYmxlLmpzXCIpfSx7XCIuL2xpYi9fc3RyZWFtX3dyaXRhYmxlLmpzXCI6NDh9XSw1NDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9ZnVuY3Rpb24oc3RyaW5nKXtyZXR1cm4gc3RyaW5nLnJlcGxhY2UoL1stXFxcXF4kKis/LigpfFtcXF17fV0vZyxcIlxcXFwkJlwiKX19LHt9XSw1NTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9U3RyZWFtO3ZhciBFRT1yZXF1aXJlKFwiZXZlbnRzXCIpLkV2ZW50RW1pdHRlcjt2YXIgaW5oZXJpdHM9cmVxdWlyZShcImluaGVyaXRzXCIpO2luaGVyaXRzKFN0cmVhbSxFRSk7U3RyZWFtLlJlYWRhYmxlPXJlcXVpcmUoXCJyZWFkYWJsZS1zdHJlYW0vcmVhZGFibGUuanNcIik7U3RyZWFtLldyaXRhYmxlPXJlcXVpcmUoXCJyZWFkYWJsZS1zdHJlYW0vd3JpdGFibGUuanNcIik7U3RyZWFtLkR1cGxleD1yZXF1aXJlKFwicmVhZGFibGUtc3RyZWFtL2R1cGxleC5qc1wiKTtTdHJlYW0uVHJhbnNmb3JtPXJlcXVpcmUoXCJyZWFkYWJsZS1zdHJlYW0vdHJhbnNmb3JtLmpzXCIpO1N0cmVhbS5QYXNzVGhyb3VnaD1yZXF1aXJlKFwicmVhZGFibGUtc3RyZWFtL3Bhc3N0aHJvdWdoLmpzXCIpO1N0cmVhbS5TdHJlYW09U3RyZWFtO2Z1bmN0aW9uIFN0cmVhbSgpe0VFLmNhbGwodGhpcyl9U3RyZWFtLnByb3RvdHlwZS5waXBlPWZ1bmN0aW9uKGRlc3Qsb3B0aW9ucyl7dmFyIHNvdXJjZT10aGlzO2Z1bmN0aW9uIG9uZGF0YShjaHVuayl7aWYoZGVzdC53cml0YWJsZSl7aWYoZmFsc2U9PT1kZXN0LndyaXRlKGNodW5rKSYmc291cmNlLnBhdXNlKXtzb3VyY2UucGF1c2UoKX19fXNvdXJjZS5vbihcImRhdGFcIixvbmRhdGEpO2Z1bmN0aW9uIG9uZHJhaW4oKXtpZihzb3VyY2UucmVhZGFibGUmJnNvdXJjZS5yZXN1bWUpe3NvdXJjZS5yZXN1bWUoKX19ZGVzdC5vbihcImRyYWluXCIsb25kcmFpbik7aWYoIWRlc3QuX2lzU3RkaW8mJighb3B0aW9uc3x8b3B0aW9ucy5lbmQhPT1mYWxzZSkpe3NvdXJjZS5vbihcImVuZFwiLG9uZW5kKTtzb3VyY2Uub24oXCJjbG9zZVwiLG9uY2xvc2UpfXZhciBkaWRPbkVuZD1mYWxzZTtmdW5jdGlvbiBvbmVuZCgpe2lmKGRpZE9uRW5kKXJldHVybjtkaWRPbkVuZD10cnVlO2Rlc3QuZW5kKCl9ZnVuY3Rpb24gb25jbG9zZSgpe2lmKGRpZE9uRW5kKXJldHVybjtkaWRPbkVuZD10cnVlO2lmKHR5cGVvZiBkZXN0LmRlc3Ryb3k9PT1cImZ1bmN0aW9uXCIpZGVzdC5kZXN0cm95KCl9ZnVuY3Rpb24gb25lcnJvcihlcil7Y2xlYW51cCgpO2lmKEVFLmxpc3RlbmVyQ291bnQodGhpcyxcImVycm9yXCIpPT09MCl7dGhyb3cgZXJ9fXNvdXJjZS5vbihcImVycm9yXCIsb25lcnJvcik7ZGVzdC5vbihcImVycm9yXCIsb25lcnJvcik7ZnVuY3Rpb24gY2xlYW51cCgpe3NvdXJjZS5yZW1vdmVMaXN0ZW5lcihcImRhdGFcIixvbmRhdGEpO2Rlc3QucmVtb3ZlTGlzdGVuZXIoXCJkcmFpblwiLG9uZHJhaW4pO3NvdXJjZS5yZW1vdmVMaXN0ZW5lcihcImVuZFwiLG9uZW5kKTtzb3VyY2UucmVtb3ZlTGlzdGVuZXIoXCJjbG9zZVwiLG9uY2xvc2UpO3NvdXJjZS5yZW1vdmVMaXN0ZW5lcihcImVycm9yXCIsb25lcnJvcik7ZGVzdC5yZW1vdmVMaXN0ZW5lcihcImVycm9yXCIsb25lcnJvcik7c291cmNlLnJlbW92ZUxpc3RlbmVyKFwiZW5kXCIsY2xlYW51cCk7c291cmNlLnJlbW92ZUxpc3RlbmVyKFwiY2xvc2VcIixjbGVhbnVwKTtkZXN0LnJlbW92ZUxpc3RlbmVyKFwiY2xvc2VcIixjbGVhbnVwKX1zb3VyY2Uub24oXCJlbmRcIixjbGVhbnVwKTtzb3VyY2Uub24oXCJjbG9zZVwiLGNsZWFudXApO2Rlc3Qub24oXCJjbG9zZVwiLGNsZWFudXApO2Rlc3QuZW1pdChcInBpcGVcIixzb3VyY2UpO3JldHVybiBkZXN0fX0se2V2ZW50czoyOCxpbmhlcml0czozOCxcInJlYWRhYmxlLXN0cmVhbS9kdXBsZXguanNcIjo0MyxcInJlYWRhYmxlLXN0cmVhbS9wYXNzdGhyb3VnaC5qc1wiOjUwLFwicmVhZGFibGUtc3RyZWFtL3JlYWRhYmxlLmpzXCI6NTEsXCJyZWFkYWJsZS1zdHJlYW0vdHJhbnNmb3JtLmpzXCI6NTIsXCJyZWFkYWJsZS1zdHJlYW0vd3JpdGFibGUuanNcIjo1M31dLDU2OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXt2YXIgQnVmZmVyPXJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyO3ZhciBpc0J1ZmZlckVuY29kaW5nPUJ1ZmZlci5pc0VuY29kaW5nfHxmdW5jdGlvbihlbmNvZGluZyl7c3dpdGNoKGVuY29kaW5nJiZlbmNvZGluZy50b0xvd2VyQ2FzZSgpKXtjYXNlXCJoZXhcIjpjYXNlXCJ1dGY4XCI6Y2FzZVwidXRmLThcIjpjYXNlXCJhc2NpaVwiOmNhc2VcImJpbmFyeVwiOmNhc2VcImJhc2U2NFwiOmNhc2VcInVjczJcIjpjYXNlXCJ1Y3MtMlwiOmNhc2VcInV0ZjE2bGVcIjpjYXNlXCJ1dGYtMTZsZVwiOmNhc2VcInJhd1wiOnJldHVybiB0cnVlO2RlZmF1bHQ6cmV0dXJuIGZhbHNlfX07ZnVuY3Rpb24gYXNzZXJ0RW5jb2RpbmcoZW5jb2Rpbmcpe2lmKGVuY29kaW5nJiYhaXNCdWZmZXJFbmNvZGluZyhlbmNvZGluZykpe3Rocm93IG5ldyBFcnJvcihcIlVua25vd24gZW5jb2Rpbmc6IFwiK2VuY29kaW5nKX19dmFyIFN0cmluZ0RlY29kZXI9ZXhwb3J0cy5TdHJpbmdEZWNvZGVyPWZ1bmN0aW9uKGVuY29kaW5nKXt0aGlzLmVuY29kaW5nPShlbmNvZGluZ3x8XCJ1dGY4XCIpLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvWy1fXS8sXCJcIik7YXNzZXJ0RW5jb2RpbmcoZW5jb2RpbmcpO3N3aXRjaCh0aGlzLmVuY29kaW5nKXtjYXNlXCJ1dGY4XCI6dGhpcy5zdXJyb2dhdGVTaXplPTM7YnJlYWs7Y2FzZVwidWNzMlwiOmNhc2VcInV0ZjE2bGVcIjp0aGlzLnN1cnJvZ2F0ZVNpemU9Mjt0aGlzLmRldGVjdEluY29tcGxldGVDaGFyPXV0ZjE2RGV0ZWN0SW5jb21wbGV0ZUNoYXI7YnJlYWs7Y2FzZVwiYmFzZTY0XCI6dGhpcy5zdXJyb2dhdGVTaXplPTM7dGhpcy5kZXRlY3RJbmNvbXBsZXRlQ2hhcj1iYXNlNjREZXRlY3RJbmNvbXBsZXRlQ2hhcjticmVhaztkZWZhdWx0OnRoaXMud3JpdGU9cGFzc1Rocm91Z2hXcml0ZTtyZXR1cm59dGhpcy5jaGFyQnVmZmVyPW5ldyBCdWZmZXIoNik7dGhpcy5jaGFyUmVjZWl2ZWQ9MDt0aGlzLmNoYXJMZW5ndGg9MH07U3RyaW5nRGVjb2Rlci5wcm90b3R5cGUud3JpdGU9ZnVuY3Rpb24oYnVmZmVyKXt2YXIgY2hhclN0cj1cIlwiO3doaWxlKHRoaXMuY2hhckxlbmd0aCl7dmFyIGF2YWlsYWJsZT1idWZmZXIubGVuZ3RoPj10aGlzLmNoYXJMZW5ndGgtdGhpcy5jaGFyUmVjZWl2ZWQ/dGhpcy5jaGFyTGVuZ3RoLXRoaXMuY2hhclJlY2VpdmVkOmJ1ZmZlci5sZW5ndGg7YnVmZmVyLmNvcHkodGhpcy5jaGFyQnVmZmVyLHRoaXMuY2hhclJlY2VpdmVkLDAsYXZhaWxhYmxlKTt0aGlzLmNoYXJSZWNlaXZlZCs9YXZhaWxhYmxlO2lmKHRoaXMuY2hhclJlY2VpdmVkPHRoaXMuY2hhckxlbmd0aCl7cmV0dXJuXCJcIn1idWZmZXI9YnVmZmVyLnNsaWNlKGF2YWlsYWJsZSxidWZmZXIubGVuZ3RoKTtjaGFyU3RyPXRoaXMuY2hhckJ1ZmZlci5zbGljZSgwLHRoaXMuY2hhckxlbmd0aCkudG9TdHJpbmcodGhpcy5lbmNvZGluZyk7dmFyIGNoYXJDb2RlPWNoYXJTdHIuY2hhckNvZGVBdChjaGFyU3RyLmxlbmd0aC0xKTtpZihjaGFyQ29kZT49NTUyOTYmJmNoYXJDb2RlPD01NjMxOSl7dGhpcy5jaGFyTGVuZ3RoKz10aGlzLnN1cnJvZ2F0ZVNpemU7Y2hhclN0cj1cIlwiO2NvbnRpbnVlfXRoaXMuY2hhclJlY2VpdmVkPXRoaXMuY2hhckxlbmd0aD0wO2lmKGJ1ZmZlci5sZW5ndGg9PT0wKXtyZXR1cm4gY2hhclN0cn1icmVha310aGlzLmRldGVjdEluY29tcGxldGVDaGFyKGJ1ZmZlcik7dmFyIGVuZD1idWZmZXIubGVuZ3RoO2lmKHRoaXMuY2hhckxlbmd0aCl7YnVmZmVyLmNvcHkodGhpcy5jaGFyQnVmZmVyLDAsYnVmZmVyLmxlbmd0aC10aGlzLmNoYXJSZWNlaXZlZCxlbmQpO2VuZC09dGhpcy5jaGFyUmVjZWl2ZWR9Y2hhclN0cis9YnVmZmVyLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcsMCxlbmQpO3ZhciBlbmQ9Y2hhclN0ci5sZW5ndGgtMTt2YXIgY2hhckNvZGU9Y2hhclN0ci5jaGFyQ29kZUF0KGVuZCk7aWYoY2hhckNvZGU+PTU1Mjk2JiZjaGFyQ29kZTw9NTYzMTkpe3ZhciBzaXplPXRoaXMuc3Vycm9nYXRlU2l6ZTt0aGlzLmNoYXJMZW5ndGgrPXNpemU7dGhpcy5jaGFyUmVjZWl2ZWQrPXNpemU7dGhpcy5jaGFyQnVmZmVyLmNvcHkodGhpcy5jaGFyQnVmZmVyLHNpemUsMCxzaXplKTtidWZmZXIuY29weSh0aGlzLmNoYXJCdWZmZXIsMCwwLHNpemUpO3JldHVybiBjaGFyU3RyLnN1YnN0cmluZygwLGVuZCl9cmV0dXJuIGNoYXJTdHJ9O1N0cmluZ0RlY29kZXIucHJvdG90eXBlLmRldGVjdEluY29tcGxldGVDaGFyPWZ1bmN0aW9uKGJ1ZmZlcil7dmFyIGk9YnVmZmVyLmxlbmd0aD49Mz8zOmJ1ZmZlci5sZW5ndGg7Zm9yKDtpPjA7aS0tKXt2YXIgYz1idWZmZXJbYnVmZmVyLmxlbmd0aC1pXTtpZihpPT0xJiZjPj41PT02KXt0aGlzLmNoYXJMZW5ndGg9MjticmVha31pZihpPD0yJiZjPj40PT0xNCl7dGhpcy5jaGFyTGVuZ3RoPTM7YnJlYWt9aWYoaTw9MyYmYz4+Mz09MzApe3RoaXMuY2hhckxlbmd0aD00O2JyZWFrfX10aGlzLmNoYXJSZWNlaXZlZD1pfTtTdHJpbmdEZWNvZGVyLnByb3RvdHlwZS5lbmQ9ZnVuY3Rpb24oYnVmZmVyKXt2YXIgcmVzPVwiXCI7aWYoYnVmZmVyJiZidWZmZXIubGVuZ3RoKXJlcz10aGlzLndyaXRlKGJ1ZmZlcik7aWYodGhpcy5jaGFyUmVjZWl2ZWQpe3ZhciBjcj10aGlzLmNoYXJSZWNlaXZlZDt2YXIgYnVmPXRoaXMuY2hhckJ1ZmZlcjt2YXIgZW5jPXRoaXMuZW5jb2Rpbmc7cmVzKz1idWYuc2xpY2UoMCxjcikudG9TdHJpbmcoZW5jKX1yZXR1cm4gcmVzfTtmdW5jdGlvbiBwYXNzVGhyb3VnaFdyaXRlKGJ1ZmZlcil7cmV0dXJuIGJ1ZmZlci50b1N0cmluZyh0aGlzLmVuY29kaW5nKX1mdW5jdGlvbiB1dGYxNkRldGVjdEluY29tcGxldGVDaGFyKGJ1ZmZlcil7dGhpcy5jaGFyUmVjZWl2ZWQ9YnVmZmVyLmxlbmd0aCUyO3RoaXMuY2hhckxlbmd0aD10aGlzLmNoYXJSZWNlaXZlZD8yOjB9ZnVuY3Rpb24gYmFzZTY0RGV0ZWN0SW5jb21wbGV0ZUNoYXIoYnVmZmVyKXt0aGlzLmNoYXJSZWNlaXZlZD1idWZmZXIubGVuZ3RoJTM7dGhpcy5jaGFyTGVuZ3RoPXRoaXMuY2hhclJlY2VpdmVkPzM6MH19LHtidWZmZXI6NX1dLDU3OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXsoZnVuY3Rpb24oZ2xvYmFsKXttb2R1bGUuZXhwb3J0cz1kZXByZWNhdGU7ZnVuY3Rpb24gZGVwcmVjYXRlKGZuLG1zZyl7aWYoY29uZmlnKFwibm9EZXByZWNhdGlvblwiKSl7cmV0dXJuIGZufXZhciB3YXJuZWQ9ZmFsc2U7ZnVuY3Rpb24gZGVwcmVjYXRlZCgpe2lmKCF3YXJuZWQpe2lmKGNvbmZpZyhcInRocm93RGVwcmVjYXRpb25cIikpe3Rocm93IG5ldyBFcnJvcihtc2cpfWVsc2UgaWYoY29uZmlnKFwidHJhY2VEZXByZWNhdGlvblwiKSl7Y29uc29sZS50cmFjZShtc2cpfWVsc2V7Y29uc29sZS53YXJuKG1zZyl9d2FybmVkPXRydWV9cmV0dXJuIGZuLmFwcGx5KHRoaXMsYXJndW1lbnRzKX1yZXR1cm4gZGVwcmVjYXRlZH1mdW5jdGlvbiBjb25maWcobmFtZSl7dHJ5e2lmKCFnbG9iYWwubG9jYWxTdG9yYWdlKXJldHVybiBmYWxzZX1jYXRjaChfKXtyZXR1cm4gZmFsc2V9dmFyIHZhbD1nbG9iYWwubG9jYWxTdG9yYWdlW25hbWVdO2lmKG51bGw9PXZhbClyZXR1cm4gZmFsc2U7cmV0dXJuIFN0cmluZyh2YWwpLnRvTG93ZXJDYXNlKCk9PT1cInRydWVcIn19KS5jYWxsKHRoaXMsdHlwZW9mIGdsb2JhbCE9PVwidW5kZWZpbmVkXCI/Z2xvYmFsOnR5cGVvZiBzZWxmIT09XCJ1bmRlZmluZWRcIj9zZWxmOnR5cGVvZiB3aW5kb3chPT1cInVuZGVmaW5lZFwiP3dpbmRvdzp7fSl9LHt9XSw1ODpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7bW9kdWxlLmV4cG9ydHM9ZXh0ZW5kO3ZhciBoYXNPd25Qcm9wZXJ0eT1PYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O2Z1bmN0aW9uIGV4dGVuZCgpe3ZhciB0YXJnZXQ9e307Zm9yKHZhciBpPTA7aTxhcmd1bWVudHMubGVuZ3RoO2krKyl7dmFyIHNvdXJjZT1hcmd1bWVudHNbaV07Zm9yKHZhciBrZXkgaW4gc291cmNlKXtpZihoYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSxrZXkpKXt0YXJnZXRba2V5XT1zb3VyY2Vba2V5XX19fXJldHVybiB0YXJnZXR9fSx7fV19LHt9LFsxXSkoMSl9KTtcbiIsIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYXV0aCA9IHJlcXVpcmUoJy4vbGliL2F1dGgnKTtcbnZhciBoZWxwZXJzID0gcmVxdWlyZSgnLi9saWIvaGVscGVycycpO1xudmFyIFN3YWdnZXJDbGllbnQgPSByZXF1aXJlKCcuL2xpYi9jbGllbnQnKTtcbnZhciBkZXByZWNhdGlvbldyYXBwZXIgPSBmdW5jdGlvbiAodXJsLCBvcHRpb25zKSB7XG4gIGhlbHBlcnMubG9nKCdUaGlzIGlzIGRlcHJlY2F0ZWQsIHVzZSBcIm5ldyBTd2FnZ2VyQ2xpZW50XCIgaW5zdGVhZC4nKTtcblxuICByZXR1cm4gbmV3IFN3YWdnZXJDbGllbnQodXJsLCBvcHRpb25zKTtcbn07XG5cbi8qIEhlcmUgZm9yIElFOCBTdXBwb3J0ICovXG5pZiAoIUFycmF5LnByb3RvdHlwZS5pbmRleE9mKSB7XG4gIEFycmF5LnByb3RvdHlwZS5pbmRleE9mID0gZnVuY3Rpb24ob2JqLCBzdGFydCkge1xuICAgIGZvciAodmFyIGkgPSAoc3RhcnQgfHwgMCksIGogPSB0aGlzLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuICAgICAgaWYgKHRoaXNbaV0gPT09IG9iaikgeyByZXR1cm4gaTsgfVxuICAgIH1cbiAgICByZXR1cm4gLTE7XG4gIH07XG59XG5cbi8qIEhlcmUgZm9yIElFOCBTdXBwb3J0ICovXG5pZiAoIVN0cmluZy5wcm90b3R5cGUudHJpbSkge1xuICBTdHJpbmcucHJvdG90eXBlLnRyaW0gPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgJycpO1xuICB9O1xufVxuXG4vKiBIZXJlIGZvciBub2RlIDEwLnggc3VwcG9ydCAqL1xuaWYgKCFTdHJpbmcucHJvdG90eXBlLmVuZHNXaXRoKSB7XG4gIFN0cmluZy5wcm90b3R5cGUuZW5kc1dpdGggPSBmdW5jdGlvbihzdWZmaXgpIHtcbiAgICByZXR1cm4gdGhpcy5pbmRleE9mKHN1ZmZpeCwgdGhpcy5sZW5ndGggLSBzdWZmaXgubGVuZ3RoKSAhPT0gLTE7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gU3dhZ2dlckNsaWVudDtcblxuU3dhZ2dlckNsaWVudC5BcGlLZXlBdXRob3JpemF0aW9uID0gYXV0aC5BcGlLZXlBdXRob3JpemF0aW9uO1xuU3dhZ2dlckNsaWVudC5QYXNzd29yZEF1dGhvcml6YXRpb24gPSBhdXRoLlBhc3N3b3JkQXV0aG9yaXphdGlvbjtcblN3YWdnZXJDbGllbnQuQ29va2llQXV0aG9yaXphdGlvbiA9IGF1dGguQ29va2llQXV0aG9yaXphdGlvbjtcblN3YWdnZXJDbGllbnQuU3dhZ2dlckFwaSA9IGRlcHJlY2F0aW9uV3JhcHBlcjtcblN3YWdnZXJDbGllbnQuU3dhZ2dlckNsaWVudCA9IGRlcHJlY2F0aW9uV3JhcHBlcjtcblN3YWdnZXJDbGllbnQuU2NoZW1hTWFya3VwID0gcmVxdWlyZSgnLi9saWIvc2NoZW1hLW1hcmt1cCcpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4vaGVscGVycycpO1xudmFyIGJ0b2EgPSByZXF1aXJlKCdidG9hJyk7IC8vIGpzaGludCBpZ25vcmU6bGluZVxudmFyIENvb2tpZUphciA9IHJlcXVpcmUoJ2Nvb2tpZWphcicpLkNvb2tpZUphcjtcbnZhciBfID0ge1xuICBlYWNoOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2NvbGxlY3Rpb24vZWFjaCcpLFxuICBpbmNsdWRlczogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9jb2xsZWN0aW9uL2luY2x1ZGVzJyksXG4gIGlzT2JqZWN0OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNPYmplY3QnKSxcbiAgaXNBcnJheTogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzQXJyYXknKVxufTtcblxuLyoqXG4gKiBTd2FnZ2VyQXV0aG9yaXphdGlvbnMgYXBwbGllcyB0aGUgY29ycmVjdCBhdXRob3JpemF0aW9uIHRvIGFuIG9wZXJhdGlvbiBiZWluZyBleGVjdXRlZFxuICovXG52YXIgU3dhZ2dlckF1dGhvcml6YXRpb25zID0gbW9kdWxlLmV4cG9ydHMuU3dhZ2dlckF1dGhvcml6YXRpb25zID0gZnVuY3Rpb24gKGF1dGh6KSB7XG4gIHRoaXMuYXV0aHogPSBhdXRoeiB8fCB7fTtcbn07XG5cbi8qKlxuICogQWRkIGF1dGhzIHRvIHRoZSBoYXNoXG4gKiBXaWxsIG92ZXJ3cml0ZSBhbnkgZXhpc3RpbmdcbiAqXG4gKi9cblN3YWdnZXJBdXRob3JpemF0aW9ucy5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gKG5hbWUsIGF1dGgpIHtcbiAgaWYoXy5pc09iamVjdChuYW1lKSkge1xuICAgIGZvciAodmFyIGtleSBpbiBuYW1lKSB7XG4gICAgICB0aGlzLmF1dGh6W2tleV0gPSBuYW1lW2tleV07XG4gICAgfVxuICB9IGVsc2UgaWYodHlwZW9mIG5hbWUgPT09ICdzdHJpbmcnICl7XG4gICAgdGhpcy5hdXRoeltuYW1lXSA9IGF1dGg7XG4gIH1cblxuICByZXR1cm4gYXV0aDtcbn07XG5cblN3YWdnZXJBdXRob3JpemF0aW9ucy5wcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgcmV0dXJuIGRlbGV0ZSB0aGlzLmF1dGh6W25hbWVdO1xufTtcblxuU3dhZ2dlckF1dGhvcml6YXRpb25zLnByb3RvdHlwZS5hcHBseSA9IGZ1bmN0aW9uIChvYmosIHNlY3VyaXRpZXMpIHtcbiAgdmFyIHN0YXR1cyA9IHRydWU7XG4gIHZhciBhcHBseUFsbCA9ICFzZWN1cml0aWVzO1xuICB2YXIgZmxhdHRlbmVkU2VjdXJpdGllcyA9IFtdO1xuXG4gIC8vIGZhdm9yIHRoZSBvYmplY3QtbGV2ZWwgYXV0aG9yaXphdGlvbnMgb3ZlciBnbG9iYWxcbiAgdmFyIGF1dGh6ID0gb2JqLmNsaWVudEF1dGhvcml6YXRpb25zIHx8IHRoaXMuYXV0aHo7XG5cbiAgLy8gU2VjdXJpdGllcyBjb3VsZCBiZSBbIHt9IF1cbiAgXy5lYWNoKHNlY3VyaXRpZXMsIGZ1bmN0aW9uIChvYmosIGtleSkge1xuXG4gICAgLy8gTWFrZSBzdXJlIHdlIGFjY291bnQgZm9yIHNlY3VyaXRpZXMgYmVpbmcgWyBzdHIgXVxuICAgIGlmKHR5cGVvZiBrZXkgPT09ICdzdHJpbmcnKSB7XG4gICAgICBmbGF0dGVuZWRTZWN1cml0aWVzLnB1c2goa2V5KTtcbiAgICB9XG5cbiAgICAvLyBGbGF0dGVuIGtleXMgaW4gdG8gb3VyIGFycmF5XG4gICAgXy5lYWNoKG9iaiwgZnVuY3Rpb24gKHZhbCwga2V5KSB7XG4gICAgICBmbGF0dGVuZWRTZWN1cml0aWVzLnB1c2goa2V5KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgXy5lYWNoKGF1dGh6LCBmdW5jdGlvbiAoYXV0aCwgYXV0aE5hbWUpIHtcbiAgICBpZihhcHBseUFsbCB8fCBfLmluY2x1ZGVzKGZsYXR0ZW5lZFNlY3VyaXRpZXMsIGF1dGhOYW1lKSkge1xuICAgICAgdmFyIG5ld1N0YXR1cyA9IGF1dGguYXBwbHkob2JqKTtcbiAgICAgIHN0YXR1cyA9IHN0YXR1cyAmJiAhIW5ld1N0YXR1czsgLy8gbG9naWNhbCBPUnMgcmVnYXJkaW5nIHN0YXR1c1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHN0YXR1cztcbn07XG5cbi8qKlxuICogQXBpS2V5QXV0aG9yaXphdGlvbiBhbGxvd3MgYSBxdWVyeSBwYXJhbSBvciBoZWFkZXIgdG8gYmUgaW5qZWN0ZWRcbiAqL1xudmFyIEFwaUtleUF1dGhvcml6YXRpb24gPSBtb2R1bGUuZXhwb3J0cy5BcGlLZXlBdXRob3JpemF0aW9uID0gZnVuY3Rpb24gKG5hbWUsIHZhbHVlLCB0eXBlKSB7XG4gIHRoaXMubmFtZSA9IG5hbWU7XG4gIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgdGhpcy50eXBlID0gdHlwZTtcbn07XG5cbkFwaUtleUF1dGhvcml6YXRpb24ucHJvdG90eXBlLmFwcGx5ID0gZnVuY3Rpb24gKG9iaikge1xuICBpZiAodGhpcy50eXBlID09PSAncXVlcnknKSB7XG4gICAgLy8gc2VlIGlmIGFscmVhZHkgYXBwbGllZC4gIElmIHNvLCBkb24ndCBkbyBpdCBhZ2FpblxuXG4gICAgdmFyIHFwO1xuICAgIGlmIChvYmoudXJsLmluZGV4T2YoJz8nKSA+IDApIHtcbiAgICAgIHFwID0gb2JqLnVybC5zdWJzdHJpbmcob2JqLnVybC5pbmRleE9mKCc/JykgKyAxKTtcbiAgICAgIHZhciBwYXJ0cyA9IHFwLnNwbGl0KCcmJyk7XG4gICAgICBpZihwYXJ0cyAmJiBwYXJ0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBwYXJ0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIHZhciBrdiA9IHBhcnRzW2ldLnNwbGl0KCc9Jyk7XG4gICAgICAgICAgaWYoa3YgJiYga3YubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgaWYgKGt2WzBdID09PSB0aGlzLm5hbWUpIHtcbiAgICAgICAgICAgICAgLy8gc2tpcCBpdFxuICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG9iai51cmwuaW5kZXhPZignPycpID4gMCkge1xuICAgICAgb2JqLnVybCA9IG9iai51cmwgKyAnJicgKyB0aGlzLm5hbWUgKyAnPScgKyB0aGlzLnZhbHVlO1xuICAgIH0gZWxzZSB7XG4gICAgICBvYmoudXJsID0gb2JqLnVybCArICc/JyArIHRoaXMubmFtZSArICc9JyArIHRoaXMudmFsdWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH0gZWxzZSBpZiAodGhpcy50eXBlID09PSAnaGVhZGVyJykge1xuICAgIGlmKHR5cGVvZiBvYmouaGVhZGVyc1t0aGlzLm5hbWVdID09PSAndW5kZWZpbmVkJykge1xuICAgICAgb2JqLmhlYWRlcnNbdGhpcy5uYW1lXSA9IHRoaXMudmFsdWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbn07XG5cbnZhciBDb29raWVBdXRob3JpemF0aW9uID0gbW9kdWxlLmV4cG9ydHMuQ29va2llQXV0aG9yaXphdGlvbiA9IGZ1bmN0aW9uIChjb29raWUpIHtcbiAgdGhpcy5jb29raWUgPSBjb29raWU7XG59O1xuXG5Db29raWVBdXRob3JpemF0aW9uLnByb3RvdHlwZS5hcHBseSA9IGZ1bmN0aW9uIChvYmopIHtcbiAgb2JqLmNvb2tpZUphciA9IG9iai5jb29raWVKYXIgfHwgbmV3IENvb2tpZUphcigpO1xuICBvYmouY29va2llSmFyLnNldENvb2tpZSh0aGlzLmNvb2tpZSk7XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG4vKipcbiAqIFBhc3N3b3JkIEF1dGhvcml6YXRpb24gaXMgYSBiYXNpYyBhdXRoIGltcGxlbWVudGF0aW9uXG4gKi9cbnZhciBQYXNzd29yZEF1dGhvcml6YXRpb24gPSBtb2R1bGUuZXhwb3J0cy5QYXNzd29yZEF1dGhvcml6YXRpb24gPSBmdW5jdGlvbiAodXNlcm5hbWUsIHBhc3N3b3JkKSB7XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAzKSB7XG4gICAgaGVscGVycy5sb2coJ1Bhc3N3b3JkQXV0aG9yaXphdGlvbjogdGhlIFxcJ25hbWVcXCcgYXJndW1lbnQgaGFzIGJlZW4gcmVtb3ZlZCwgcGFzcyBvbmx5IHVzZXJuYW1lIGFuZCBwYXNzd29yZCcpO1xuICAgIHVzZXJuYW1lID0gYXJndW1lbnRzWzFdO1xuICAgIHBhc3N3b3JkID0gYXJndW1lbnRzWzJdO1xuICB9XG4gIHRoaXMudXNlcm5hbWUgPSB1c2VybmFtZTtcbiAgdGhpcy5wYXNzd29yZCA9IHBhc3N3b3JkO1xufTtcblxuUGFzc3dvcmRBdXRob3JpemF0aW9uLnByb3RvdHlwZS5hcHBseSA9IGZ1bmN0aW9uIChvYmopIHtcbiAgaWYodHlwZW9mIG9iai5oZWFkZXJzLkF1dGhvcml6YXRpb24gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgb2JqLmhlYWRlcnMuQXV0aG9yaXphdGlvbiA9ICdCYXNpYyAnICsgYnRvYSh0aGlzLnVzZXJuYW1lICsgJzonICsgdGhpcy5wYXNzd29yZCk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBfID0ge1xuICBiaW5kOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2Z1bmN0aW9uL2JpbmQnKSxcbiAgY2xvbmVEZWVwOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvY2xvbmVEZWVwJyksXG4gIGZpbmQ6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvY29sbGVjdGlvbi9maW5kJyksXG4gIGZvckVhY2g6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvY29sbGVjdGlvbi9mb3JFYWNoJyksXG4gIGluZGV4T2Y6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvYXJyYXkvaW5kZXhPZicpLFxuICBpc0FycmF5OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNBcnJheScpLFxuICBpc09iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzT2JqZWN0JyksXG4gIGlzRnVuY3Rpb246IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc0Z1bmN0aW9uJyksXG4gIGlzUGxhaW5PYmplY3Q6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc1BsYWluT2JqZWN0JyksXG4gIGlzVW5kZWZpbmVkOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNVbmRlZmluZWQnKVxufTtcbnZhciBhdXRoID0gcmVxdWlyZSgnLi9hdXRoJyk7XG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4vaGVscGVycycpO1xudmFyIE1vZGVsID0gcmVxdWlyZSgnLi90eXBlcy9tb2RlbCcpO1xudmFyIE9wZXJhdGlvbiA9IHJlcXVpcmUoJy4vdHlwZXMvb3BlcmF0aW9uJyk7XG52YXIgT3BlcmF0aW9uR3JvdXAgPSByZXF1aXJlKCcuL3R5cGVzL29wZXJhdGlvbkdyb3VwJyk7XG52YXIgUmVzb2x2ZXIgPSByZXF1aXJlKCcuL3Jlc29sdmVyJyk7XG52YXIgU3dhZ2dlckh0dHAgPSByZXF1aXJlKCcuL2h0dHAnKTtcbnZhciBTd2FnZ2VyU3BlY0NvbnZlcnRlciA9IHJlcXVpcmUoJy4vc3BlYy1jb252ZXJ0ZXInKTtcbnZhciBRID0gcmVxdWlyZSgncScpO1xuXG4vLyBXZSBoYXZlIHRvIGtlZXAgdHJhY2sgb2YgdGhlIGZ1bmN0aW9uL3Byb3BlcnR5IG5hbWVzIHRvIGF2b2lkIGNvbGxpc2lvbnMgZm9yIHRhZyBuYW1lcyB3aGljaCBhcmUgdXNlZCB0byBhbGxvdyB0aGVcbi8vIGZvbGxvd2luZyB1c2FnZTogJ2NsaWVudC57dGFnTmFtZX0nXG52YXIgcmVzZXJ2ZWRDbGllbnRUYWdzID0gW1xuICAnYXBpcycsXG4gICdhdXRob3JpemF0aW9uU2NoZW1lJyxcbiAgJ2F1dGhvcml6YXRpb25zJyxcbiAgJ2Jhc2VQYXRoJyxcbiAgJ2J1aWxkJyxcbiAgJ2J1aWxkRnJvbTFfMVNwZWMnLFxuICAnYnVpbGRGcm9tMV8yU3BlYycsXG4gICdidWlsZEZyb21TcGVjJyxcbiAgJ2NsaWVudEF1dGhvcml6YXRpb25zJyxcbiAgJ2NvbnZlcnRJbmZvJyxcbiAgJ2RlYnVnJyxcbiAgJ2RlZmF1bHRFcnJvckNhbGxiYWNrJyxcbiAgJ2RlZmF1bHRTdWNjZXNzQ2FsbGJhY2snLFxuICAnZW5hYmxlQ29va2llcycsXG4gICdmYWlsJyxcbiAgJ2ZhaWx1cmUnLFxuICAnZmluaXNoJyxcbiAgJ2hlbHAnLFxuICAnaG9zdCcsXG4gICdpZEZyb21PcCcsXG4gICdpbmZvJyxcbiAgJ2luaXRpYWxpemUnLFxuICAnaXNCdWlsdCcsXG4gICdpc1ZhbGlkJyxcbiAgJ21vZGVsUHJvcGVydHlNYWNybycsXG4gICdtb2RlbHMnLFxuICAnbW9kZWxzQXJyYXknLFxuICAnb3B0aW9ucycsXG4gICdwYXJhbWV0ZXJNYWNybycsXG4gICdwYXJzZVVyaScsXG4gICdwcm9ncmVzcycsXG4gICdyZXNvdXJjZUNvdW50JyxcbiAgJ3NhbXBsZU1vZGVscycsXG4gICdzZWxmUmVmbGVjdCcsXG4gICdzZXRDb25zb2xpZGF0ZWRNb2RlbHMnLFxuICAnc3BlYycsXG4gICdzdXBwb3J0ZWRTdWJtaXRNZXRob2RzJyxcbiAgJ3N3YWdnZXJSZXF1ZXN0SGVhZGVycycsXG4gICd0YWdGcm9tTGFiZWwnLFxuICAndGl0bGUnLFxuICAndXJsJyxcbiAgJ3VzZUpRdWVyeScsXG4gICdqcXVlcnlBamF4Q2FjaGUnXG5dO1xuLy8gV2UgaGF2ZSB0byBrZWVwIHRyYWNrIG9mIHRoZSBmdW5jdGlvbi9wcm9wZXJ0eSBuYW1lcyB0byBhdm9pZCBjb2xsaXNpb25zIGZvciB0YWcgbmFtZXMgd2hpY2ggYXJlIHVzZWQgdG8gYWxsb3cgdGhlXG4vLyBmb2xsb3dpbmcgdXNhZ2U6ICdjbGllbnQuYXBpcy57dGFnTmFtZX0nXG52YXIgcmVzZXJ2ZWRBcGlUYWdzID0gW1xuICAnYXBpcycsXG4gICdhc0N1cmwnLFxuICAnZGVzY3JpcHRpb24nLFxuICAnZXh0ZXJuYWxEb2NzJyxcbiAgJ2hlbHAnLFxuICAnbGFiZWwnLFxuICAnbmFtZScsXG4gICdvcGVyYXRpb24nLFxuICAnb3BlcmF0aW9ucycsXG4gICdvcGVyYXRpb25zQXJyYXknLFxuICAncGF0aCcsXG4gICd0YWcnXG5dO1xudmFyIHN1cHBvcnRlZE9wZXJhdGlvbk1ldGhvZHMgPSBbJ2RlbGV0ZScsICdnZXQnLCAnaGVhZCcsICdvcHRpb25zJywgJ3BhdGNoJywgJ3Bvc3QnLCAncHV0J107XG52YXIgU3dhZ2dlckNsaWVudCA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHVybCwgb3B0aW9ucykge1xuICB0aGlzLmF1dGhvcml6YXRpb25zID0gbnVsbDtcbiAgdGhpcy5hdXRob3JpemF0aW9uU2NoZW1lID0gbnVsbDtcbiAgdGhpcy5iYXNlUGF0aCA9IG51bGw7XG4gIHRoaXMuZGVidWcgPSBmYWxzZTtcbiAgdGhpcy5lbmFibGVDb29raWVzID0gZmFsc2U7XG4gIHRoaXMuaW5mbyA9IG51bGw7XG4gIHRoaXMuaXNCdWlsdCA9IGZhbHNlO1xuICB0aGlzLmlzVmFsaWQgPSBmYWxzZTtcbiAgdGhpcy5tb2RlbHNBcnJheSA9IFtdO1xuICB0aGlzLnJlc291cmNlQ291bnQgPSAwO1xuICB0aGlzLnVybCA9IG51bGw7XG4gIHRoaXMudXNlSlF1ZXJ5ID0gZmFsc2U7XG4gIHRoaXMuanF1ZXJ5QWpheENhY2hlID0gZmFsc2U7XG4gIHRoaXMuc3dhZ2dlck9iamVjdCA9IHt9O1xuICB0aGlzLmRlZmVycmVkQ2xpZW50ID0gdW5kZWZpbmVkO1xuXG4gIHRoaXMuY2xpZW50QXV0aG9yaXphdGlvbnMgPSBuZXcgYXV0aC5Td2FnZ2VyQXV0aG9yaXphdGlvbnMoKTtcblxuICBpZiAodHlwZW9mIHVybCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXR1cm4gdGhpcy5pbml0aWFsaXplKHVybCwgb3B0aW9ucyk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbn07XG5cblN3YWdnZXJDbGllbnQucHJvdG90eXBlLmluaXRpYWxpemUgPSBmdW5jdGlvbiAodXJsLCBvcHRpb25zKSB7XG4gIHRoaXMubW9kZWxzID0ge307XG4gIHRoaXMuc2FtcGxlTW9kZWxzID0ge307XG5cbiAgaWYgKHR5cGVvZiB1cmwgPT09ICdzdHJpbmcnKSB7XG4gICAgdGhpcy51cmwgPSB1cmw7XG4gIH0gZWxzZSBpZiAoXy5pc09iamVjdCh1cmwpKSB7XG4gICAgb3B0aW9ucyA9IHVybDtcbiAgICB0aGlzLnVybCA9IG9wdGlvbnMudXJsO1xuICB9XG5cbiAgaWYodGhpcy51cmwgJiYgdGhpcy51cmwuaW5kZXhPZignaHR0cDonKSA9PT0gLTEgJiYgdGhpcy51cmwuaW5kZXhPZignaHR0cHM6JykgPT09IC0xKSB7XG4gICAgLy8gbm8gcHJvdG9jb2wsIHNvIHdlIGNhbiBvbmx5IHVzZSB3aW5kb3cgaWYgaXQgZXhpc3RzXG4gICAgaWYodHlwZW9mKHdpbmRvdykgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZih3aW5kb3cubG9jYXRpb24pICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhpcy51cmwgPSB3aW5kb3cubG9jYXRpb24ub3JpZ2luICsgdGhpcy51cmw7XG4gICAgfVxuICB9XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIHRoaXMuY2xpZW50QXV0aG9yaXphdGlvbnMuYWRkKG9wdGlvbnMuYXV0aG9yaXphdGlvbnMpO1xuICB0aGlzLnN3YWdnZXJSZXF1ZXN0SGVhZGVycyA9IG9wdGlvbnMuc3dhZ2dlclJlcXVlc3RIZWFkZXJzIHx8ICdhcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTgsKi8qJztcbiAgdGhpcy5kZWZhdWx0U3VjY2Vzc0NhbGxiYWNrID0gb3B0aW9ucy5kZWZhdWx0U3VjY2Vzc0NhbGxiYWNrIHx8IG51bGw7XG4gIHRoaXMuZGVmYXVsdEVycm9yQ2FsbGJhY2sgPSBvcHRpb25zLmRlZmF1bHRFcnJvckNhbGxiYWNrIHx8IG51bGw7XG4gIHRoaXMubW9kZWxQcm9wZXJ0eU1hY3JvID0gb3B0aW9ucy5tb2RlbFByb3BlcnR5TWFjcm8gfHwgbnVsbDtcbiAgdGhpcy5jb25uZWN0aW9uQWdlbnQgPSBvcHRpb25zLmNvbm5lY3Rpb25BZ2VudCB8fCBudWxsO1xuICB0aGlzLnBhcmFtZXRlck1hY3JvID0gb3B0aW9ucy5wYXJhbWV0ZXJNYWNybyB8fCBudWxsO1xuICB0aGlzLnVzZVByb21pc2UgPSBvcHRpb25zLnVzZVByb21pc2UgfHwgbnVsbDtcblxuICAvLyBvcGVyYXRpb24gcmVxdWVzdCB0aW1lb3V0IGRlZmF1bHRcbiAgdGhpcy50aW1lb3V0ID0gb3B0aW9ucy50aW1lb3V0IHx8IG51bGw7XG4gIC8vIGRlZmF1bHQgdG8gcmVxdWVzdCB0aW1lb3V0IHdoZW4gbm90IHNwZWNpZmllZFxuICB0aGlzLmZldGNoU3BlY1RpbWVvdXQgPSB0eXBlb2Ygb3B0aW9ucy5mZXRjaFNwZWNUaW1lb3V0ICE9PSAndW5kZWZpbmVkJyA/XG4gICAgICBvcHRpb25zLmZldGNoU3BlY1RpbWVvdXQgOiBvcHRpb25zLnRpbWVvdXQgfHwgbnVsbDtcblxuICBpZih0aGlzLnVzZVByb21pc2UpIHtcbiAgICB0aGlzLmRlZmVycmVkQ2xpZW50ID0gUS5kZWZlcigpO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBvcHRpb25zLnN1Y2Nlc3MgPT09ICdmdW5jdGlvbicpIHtcbiAgICB0aGlzLnN1Y2Nlc3MgPSBvcHRpb25zLnN1Y2Nlc3M7XG4gIH1cbiAgaWYgKG9wdGlvbnMudXNlSlF1ZXJ5KSB7XG4gICAgdGhpcy51c2VKUXVlcnkgPSBvcHRpb25zLnVzZUpRdWVyeTtcbiAgfVxuXG4gIGlmIChvcHRpb25zLmpxdWVyeUFqYXhDYWNoZSkge1xuICAgIHRoaXMuanF1ZXJ5QWpheENhY2hlID0gb3B0aW9ucy5qcXVlcnlBamF4Q2FjaGU7XG4gIH1cblxuICBpZiAob3B0aW9ucy5lbmFibGVDb29raWVzKSB7XG4gICAgdGhpcy5lbmFibGVDb29raWVzID0gb3B0aW9ucy5lbmFibGVDb29raWVzO1xuICB9XG5cbiAgdGhpcy5vcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICAvLyBtYXliZSBkb24ndCBuZWVkIHRoaXM/XG4gIHRoaXMub3B0aW9ucy50aW1lb3V0ID0gdGhpcy50aW1lb3V0O1xuICB0aGlzLm9wdGlvbnMuZmV0Y2hTcGVjVGltZW91dCA9IHRoaXMuZmV0Y2hTcGVjVGltZW91dDtcblxuICB0aGlzLnN1cHBvcnRlZFN1Ym1pdE1ldGhvZHMgPSBvcHRpb25zLnN1cHBvcnRlZFN1Ym1pdE1ldGhvZHMgfHwgW107XG4gIHRoaXMuZmFpbHVyZSA9IG9wdGlvbnMuZmFpbHVyZSB8fCBmdW5jdGlvbiAoZXJyKSB7IHRocm93IGVycjsgfTtcbiAgdGhpcy5wcm9ncmVzcyA9IG9wdGlvbnMucHJvZ3Jlc3MgfHwgZnVuY3Rpb24gKCkge307XG4gIHRoaXMuc3BlYyA9IF8uY2xvbmVEZWVwKG9wdGlvbnMuc3BlYyk7IC8vIENsb25lIHNvIHdlIGRvIG5vdCBhbHRlciB0aGUgcHJvdmlkZWQgZG9jdW1lbnRcblxuICBpZiAob3B0aW9ucy5zY2hlbWUpIHtcbiAgICB0aGlzLnNjaGVtZSA9IG9wdGlvbnMuc2NoZW1lO1xuICB9XG5cbiAgaWYgKHRoaXMudXNlUHJvbWlzZSB8fCB0eXBlb2Ygb3B0aW9ucy5zdWNjZXNzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhpcy5yZWFkeSA9IHRydWU7XG4gICAgcmV0dXJuIHRoaXMuYnVpbGQoKTtcbiAgfVxufTtcblxuU3dhZ2dlckNsaWVudC5wcm90b3R5cGUuYnVpbGQgPSBmdW5jdGlvbiAobW9jaykge1xuICBpZiAodGhpcy5pc0J1aWx0KSB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgaWYgKHRoaXMuc3BlYykge1xuICAgIHRoaXMucHJvZ3Jlc3MoJ2ZldGNoaW5nIHJlc291cmNlIGxpc3Q7IFBsZWFzZSB3YWl0LicpO1xuICB9IGVsc2Uge1xuICAgIHRoaXMucHJvZ3Jlc3MoJ2ZldGNoaW5nIHJlc291cmNlIGxpc3Q6ICcgKyB0aGlzLnVybCArICc7IFBsZWFzZSB3YWl0LicpO1xuICB9XG5cbiAgdmFyIG9iaiA9IHtcbiAgICB1c2VKUXVlcnk6IHRoaXMudXNlSlF1ZXJ5LFxuICAgIGpxdWVyeUFqYXhDYWNoZTogdGhpcy5qcXVlcnlBamF4Q2FjaGUsXG4gICAgY29ubmVjdGlvbkFnZW50OiB0aGlzLmNvbm5lY3Rpb25BZ2VudCxcbiAgICBlbmFibGVDb29raWVzOiB0aGlzLmVuYWJsZUNvb2tpZXMsXG4gICAgdXJsOiB0aGlzLnVybCxcbiAgICBtZXRob2Q6ICdnZXQnLFxuICAgIGhlYWRlcnM6IHtcbiAgICAgIGFjY2VwdDogdGhpcy5zd2FnZ2VyUmVxdWVzdEhlYWRlcnNcbiAgICB9LFxuICAgIG9uOiB7XG4gICAgICBlcnJvcjogZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICAgIGlmIChzZWxmICYmIHNlbGYudXJsICYmIHNlbGYudXJsLnN1YnN0cmluZygwLCA0KSAhPT0gJ2h0dHAnKSB7XG4gICAgICAgICAgcmV0dXJuIHNlbGYuZmFpbCgnUGxlYXNlIHNwZWNpZnkgdGhlIHByb3RvY29sIGZvciAnICsgc2VsZi51cmwpO1xuICAgICAgICB9IGVsc2UgaWYgKHJlc3BvbnNlLmVyck9iaiAmJiAocmVzcG9uc2UuZXJyT2JqLmNvZGUgPT09ICdFQ09OTkFCT1JURUQnIHx8IHJlc3BvbnNlLmVyck9iai5tZXNzYWdlLmluZGV4T2YoJ3RpbWVvdXQnKSAhPT0gLTEpKSB7XG4gICAgICAgICAgcmV0dXJuIHNlbGYuZmFpbCgnUmVxdWVzdCB0aW1lZCBvdXQgYWZ0ZXIgJyArIHNlbGYuZmV0Y2hTcGVjVGltZW91dCArICdtcycpO1xuICAgICAgICB9IGVsc2UgaWYgKHJlc3BvbnNlLnN0YXR1cyA9PT0gMCkge1xuICAgICAgICAgIHJldHVybiBzZWxmLmZhaWwoJ0NhblxcJ3QgcmVhZCBmcm9tIHNlcnZlci4gIEl0IG1heSBub3QgaGF2ZSB0aGUgYXBwcm9wcmlhdGUgYWNjZXNzLWNvbnRyb2wtb3JpZ2luIHNldHRpbmdzLicpO1xuICAgICAgICB9IGVsc2UgaWYgKHJlc3BvbnNlLnN0YXR1cyA9PT0gNDA0KSB7XG4gICAgICAgICAgcmV0dXJuIHNlbGYuZmFpbCgnQ2FuXFwndCByZWFkIHN3YWdnZXIgSlNPTiBmcm9tICcgKyBzZWxmLnVybCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHNlbGYuZmFpbChyZXNwb25zZS5zdGF0dXMgKyAnIDogJyArIHJlc3BvbnNlLnN0YXR1c1RleHQgKyAnICcgKyBzZWxmLnVybCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICByZXNwb25zZTogZnVuY3Rpb24gKHJlc3ApIHtcblxuICAgICAgICB2YXIgcmVzcG9uc2VPYmogPSByZXNwLm9iajtcbiAgICAgICAgaWYoIXJlc3BvbnNlT2JqKSB7XG4gICAgICAgICAgcmV0dXJuIHNlbGYuZmFpbCgnZmFpbGVkIHRvIHBhcnNlIEpTT04vWUFNTCByZXNwb25zZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgc2VsZi5zd2FnZ2VyVmVyc2lvbiA9IHJlc3BvbnNlT2JqLnN3YWdnZXJWZXJzaW9uO1xuICAgICAgICBzZWxmLnN3YWdnZXJPYmplY3QgPSByZXNwb25zZU9iajtcblxuICAgICAgICBpZiAocmVzcG9uc2VPYmouc3dhZ2dlciAmJiBwYXJzZUludChyZXNwb25zZU9iai5zd2FnZ2VyKSA9PT0gMikge1xuICAgICAgICAgIHNlbGYuc3dhZ2dlclZlcnNpb24gPSByZXNwb25zZU9iai5zd2FnZ2VyO1xuXG4gICAgICAgICAgbmV3IFJlc29sdmVyKCkucmVzb2x2ZShyZXNwb25zZU9iaiwgc2VsZi51cmwsIHNlbGYuYnVpbGRGcm9tU3BlYywgc2VsZik7XG5cbiAgICAgICAgICBzZWxmLmlzVmFsaWQgPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciBjb252ZXJ0ZXIgPSBuZXcgU3dhZ2dlclNwZWNDb252ZXJ0ZXIoKTtcbiAgICAgICAgICBzZWxmLm9sZFN3YWdnZXJPYmplY3QgPSBzZWxmLnN3YWdnZXJPYmplY3Q7XG5cbiAgICAgICAgICBjb252ZXJ0ZXIuc2V0RG9jdW1lbnRhdGlvbkxvY2F0aW9uKHNlbGYudXJsKTtcbiAgICAgICAgICBjb252ZXJ0ZXIuY29udmVydChyZXNwb25zZU9iaiwgc2VsZi5jbGllbnRBdXRob3JpemF0aW9ucywgc2VsZi5vcHRpb25zLCBmdW5jdGlvbihzcGVjKSB7XG4gICAgICAgICAgICBzZWxmLnN3YWdnZXJPYmplY3QgPSBzcGVjO1xuICAgICAgICAgICAgbmV3IFJlc29sdmVyKCkucmVzb2x2ZShzcGVjLCBzZWxmLnVybCwgc2VsZi5idWlsZEZyb21TcGVjLCBzZWxmKTtcbiAgICAgICAgICAgIHNlbGYuaXNWYWxpZCA9IHRydWU7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgLy8gb25seSBzZXQgdGltZW91dCB3aGVuIHNwZWNpZmllZFxuICBpZiAodGhpcy5mZXRjaFNwZWNUaW1lb3V0KSB7XG4gICAgb2JqLnRpbWVvdXQgPSB0aGlzLmZldGNoU3BlY1RpbWVvdXQ7XG4gIH1cblxuICBpZiAodGhpcy5zcGVjICYmIHR5cGVvZiB0aGlzLnNwZWMgPT09ICdvYmplY3QnKSB7XG4gICAgc2VsZi5zd2FnZ2VyT2JqZWN0ID0gdGhpcy5zcGVjO1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgbmV3IFJlc29sdmVyKCkucmVzb2x2ZShzZWxmLnNwZWMsIHNlbGYudXJsLCBzZWxmLmJ1aWxkRnJvbVNwZWMsIHNlbGYpO1xuICAgIH0sIDEwKTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmNsaWVudEF1dGhvcml6YXRpb25zLmFwcGx5KG9iaik7XG5cbiAgICBpZiAobW9jaykge1xuICAgICAgcmV0dXJuIG9iajtcbiAgICB9XG5cbiAgICBuZXcgU3dhZ2dlckh0dHAoKS5leGVjdXRlKG9iaiwgdGhpcy5vcHRpb25zKTtcbiAgfVxuXG4gIHJldHVybiAodGhpcy51c2VQcm9taXNlKSA/IHRoaXMuZGVmZXJyZWRDbGllbnQucHJvbWlzZSA6IHRoaXM7XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS5idWlsZEZyb21TcGVjID0gZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gIGlmICh0aGlzLmlzQnVpbHQpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHRoaXMuYXBpcyA9IHt9O1xuICB0aGlzLmFwaXNBcnJheSA9IFtdO1xuICB0aGlzLmJhc2VQYXRoID0gcmVzcG9uc2UuYmFzZVBhdGggfHwgJyc7XG4gIHRoaXMuY29uc3VtZXMgPSByZXNwb25zZS5jb25zdW1lcztcbiAgdGhpcy5ob3N0ID0gcmVzcG9uc2UuaG9zdCB8fCAnJztcbiAgdGhpcy5pbmZvID0gcmVzcG9uc2UuaW5mbyB8fCB7fTtcbiAgdGhpcy5wcm9kdWNlcyA9IHJlc3BvbnNlLnByb2R1Y2VzO1xuICB0aGlzLnNjaGVtZXMgPSByZXNwb25zZS5zY2hlbWVzIHx8IFtdO1xuICB0aGlzLnNlY3VyaXR5RGVmaW5pdGlvbnMgPSBfLmNsb25lRGVlcChyZXNwb25zZS5zZWN1cml0eURlZmluaXRpb25zKTtcbiAgdGhpcy5zZWN1cml0eSA9IHJlc3BvbnNlLnNlY3VyaXR5O1xuICB0aGlzLnRpdGxlID0gcmVzcG9uc2UudGl0bGUgfHwgJyc7XG5cbiAgdmFyIGtleSwgZGVmaW5lZFRhZ3MgPSB7fSwgaywgbG9jYXRpb24sIHNlbGYgPSB0aGlzLCBpO1xuXG4gIGlmIChyZXNwb25zZS5leHRlcm5hbERvY3MpIHtcbiAgICB0aGlzLmV4dGVybmFsRG9jcyA9IHJlc3BvbnNlLmV4dGVybmFsRG9jcztcbiAgfVxuXG4gIC8vIGxlZ2FjeSBzdXBwb3J0XG4gIHRoaXMuYXV0aFNjaGVtZXMgPSB0aGlzLnNlY3VyaXR5RGVmaW5pdGlvbnM7XG5cbiAgaWYodGhpcy5zZWN1cml0eURlZmluaXRpb25zKSB7XG4gICAgZm9yKGtleSBpbiB0aGlzLnNlY3VyaXR5RGVmaW5pdGlvbnMpIHtcbiAgICAgIHZhciBzZWN1cml0eURlZmluaXRpb24gPSB0aGlzLnNlY3VyaXR5RGVmaW5pdGlvbnNba2V5XTtcbiAgICAgIHNlY3VyaXR5RGVmaW5pdGlvbi52ZW5kb3JFeHRlbnNpb25zID0ge307XG4gICAgICBmb3IodmFyIGV4dCBpbiBzZWN1cml0eURlZmluaXRpb24pIHtcbiAgICAgICAgaGVscGVycy5leHRyYWN0RXh0ZW5zaW9ucyhleHQsIHNlY3VyaXR5RGVmaW5pdGlvbik7XG4gICAgICAgIGlmIChleHQgPT09ICdzY29wZXMnKSB7XG4gICAgICAgICAgdmFyIHNjb3BlcyA9IHNlY3VyaXR5RGVmaW5pdGlvbltleHRdO1xuICAgICAgICAgIGlmKHR5cGVvZiBzY29wZXMgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICBzY29wZXMudmVuZG9yRXh0ZW5zaW9ucyA9IHt9O1xuICAgICAgICAgICAgZm9yICh2YXIgcyBpbiBzY29wZXMpIHtcbiAgICAgICAgICAgICAgaGVscGVycy5leHRyYWN0RXh0ZW5zaW9ucyhzLCBzY29wZXMpO1xuICAgICAgICAgICAgICBpZihzLmluZGV4T2YoJ3gtJykgPT09IDApIHtcbiAgICAgICAgICAgICAgICBkZWxldGUgc2NvcGVzW3NdO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKEFycmF5LmlzQXJyYXkocmVzcG9uc2UudGFncykpIHtcbiAgICBkZWZpbmVkVGFncyA9IHt9O1xuXG4gICAgZm9yIChrID0gMDsgayA8IHJlc3BvbnNlLnRhZ3MubGVuZ3RoOyBrKyspIHtcbiAgICAgIHZhciB0ID0gXy5jbG9uZURlZXAocmVzcG9uc2UudGFnc1trXSk7XG4gICAgICBkZWZpbmVkVGFnc1t0Lm5hbWVdID0gdDtcbiAgICAgIGZvcihpIGluIHQpIHtcbiAgICAgICAgaWYoaSA9PT0gJ2V4dGVybmFsRG9jcycgJiYgdHlwZW9mIHRbaV0gPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgZm9yKHZhciBqIGluIHRbaV0pIHtcbiAgICAgICAgICAgIGhlbHBlcnMuZXh0cmFjdEV4dGVuc2lvbnMoaiwgdFtpXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGhlbHBlcnMuZXh0cmFjdEV4dGVuc2lvbnMoaSwgdCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cblxuICBpZiAodHlwZW9mIHRoaXMudXJsID09PSAnc3RyaW5nJykge1xuICAgIGxvY2F0aW9uID0gdGhpcy5wYXJzZVVyaSh0aGlzLnVybCk7XG4gICAgaWYgKHR5cGVvZiB0aGlzLnNjaGVtZSA9PT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIHRoaXMuc2NoZW1lcyA9PT0gJ3VuZGVmaW5lZCcgfHwgdGhpcy5zY2hlbWVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgaWYgKHR5cGVvZiBsb2NhdGlvbiAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mKGxvY2F0aW9uLnNjaGVtZSkgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHRoaXMuc2NoZW1lID0gbG9jYXRpb24uc2NoZW1lO1xuICAgICAgfVxuICAgICAgaWYodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mKHdpbmRvdy5sb2NhdGlvbikgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIC8vIHVzZSB0aGUgd2luZG93IHNjaGVtZVxuICAgICAgICB0aGlzLnNjaGVtZSA9IHdpbmRvdy5sb2NhdGlvbi5wcm90b2NvbC5yZXBsYWNlKCc6JywnJyk7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgdGhpcy5zY2hlbWUgPSBsb2NhdGlvbi5zY2hlbWUgfHwgJ2h0dHAnO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mKHdpbmRvdy5sb2NhdGlvbikgIT09ICd1bmRlZmluZWQnICYmIHdpbmRvdy5sb2NhdGlvbi5wcm90b2NvbC5pbmRleE9mKCdjaHJvbWUtZXh0ZW5zaW9uJykgPT09IDApIHtcblx0XHQvLyBpZiBpdCBpcyBjaHJvbWUgc3dhZ2dlciB1aSBleHRlbnNpb24gc2NoZW1lIHRoZW4gbGV0IHN3YWdnZXIgZG9jIHVybCBzY2hlbWUgZGVjaWRlIHRoZSBwcm90b2NvbFxuXHRcdHRoaXMuc2NoZW1lID0gbG9jYXRpb24uc2NoZW1lO1xuXHR9IGVsc2UgaWYgKHR5cGVvZiB0aGlzLnNjaGVtZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGlmKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZih3aW5kb3cubG9jYXRpb24pICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICB2YXIgc2NoZW1lID0gd2luZG93LmxvY2F0aW9uLnByb3RvY29sLnJlcGxhY2UoJzonLCcnKTtcbiAgICAgICAgaWYoc2NoZW1lID09PSAnaHR0cHMnICYmIHRoaXMuc2NoZW1lcy5pbmRleE9mKHNjaGVtZSkgPT09IC0xKSB7XG4gICAgICAgICAgLy8gY2FuJ3QgY2FsbCBodHRwIGZyb20gaHR0cHMgc2VydmVkIHBhZ2UgaW4gYSBicm93c2VyIVxuICAgICAgICAgIGhlbHBlcnMubG9nKCdDYW5ub3QgY2FsbCBhIGh0dHAgc2VydmVyIGZyb20gaHR0cHMgaW5zaWRlIGEgYnJvd3NlciEnKTtcbiAgICAgICAgICB0aGlzLnNjaGVtZSA9ICdodHRwJztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmKHRoaXMuc2NoZW1lcy5pbmRleE9mKHNjaGVtZSkgIT09IC0xKSB7XG4gICAgICAgICAgdGhpcy5zY2hlbWUgPSBzY2hlbWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgaWYodGhpcy5zY2hlbWVzLmluZGV4T2YoJ2h0dHBzJykgIT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLnNjaGVtZSA9ICdodHRwcyc7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zY2hlbWUgPSAnaHR0cCc7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgdGhpcy5zY2hlbWUgPSB0aGlzLnNjaGVtZXNbMF0gfHwgbG9jYXRpb24uc2NoZW1lO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdGhpcy5ob3N0ID09PSAndW5kZWZpbmVkJyB8fCB0aGlzLmhvc3QgPT09ICcnKSB7XG4gICAgICB0aGlzLmhvc3QgPSBsb2NhdGlvbi5ob3N0O1xuXG4gICAgICBpZiAobG9jYXRpb24ucG9ydCkge1xuICAgICAgICB0aGlzLmhvc3QgPSB0aGlzLmhvc3QgKyAnOicgKyBsb2NhdGlvbi5wb3J0O1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBlbHNlIHtcbiAgICBpZiAodHlwZW9mIHRoaXMuc2NoZW1lcyA9PT0gJ3VuZGVmaW5lZCcgfHwgdGhpcy5zY2hlbWVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5zY2hlbWUgPSAnaHR0cCc7XG4gICAgfVxuICAgIGVsc2UgaWYgKHR5cGVvZiB0aGlzLnNjaGVtZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHRoaXMuc2NoZW1lID0gdGhpcy5zY2hlbWVzWzBdO1xuICAgIH1cbiAgfVxuXG4gIHRoaXMuZGVmaW5pdGlvbnMgPSByZXNwb25zZS5kZWZpbml0aW9ucztcblxuICBmb3IgKGtleSBpbiB0aGlzLmRlZmluaXRpb25zKSB7XG4gICAgdmFyIG1vZGVsID0gbmV3IE1vZGVsKGtleSwgdGhpcy5kZWZpbml0aW9uc1trZXldLCB0aGlzLm1vZGVscywgdGhpcy5tb2RlbFByb3BlcnR5TWFjcm8pO1xuXG4gICAgaWYgKG1vZGVsKSB7XG4gICAgICB0aGlzLm1vZGVsc1trZXldID0gbW9kZWw7XG4gICAgfVxuICB9XG5cbiAgLy8gZ2V0IHBhdGhzLCBjcmVhdGUgZnVuY3Rpb25zIGZvciBlYWNoIG9wZXJhdGlvbklkXG5cbiAgLy8gQmluZCBoZWxwIHRvICdjbGllbnQuYXBpcydcbiAgc2VsZi5hcGlzLmhlbHAgPSBfLmJpbmQoc2VsZi5oZWxwLCBzZWxmKTtcblxuICBfLmZvckVhY2gocmVzcG9uc2UucGF0aHMsIGZ1bmN0aW9uIChwYXRoT2JqLCBwYXRoKSB7XG4gICAgLy8gT25seSBwcm9jZXNzIGEgcGF0aCBpZiBpdCdzIGFuIG9iamVjdFxuICAgIGlmICghXy5pc1BsYWluT2JqZWN0KHBhdGhPYmopKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgXy5mb3JFYWNoKHN1cHBvcnRlZE9wZXJhdGlvbk1ldGhvZHMsIGZ1bmN0aW9uIChtZXRob2QpIHtcbiAgICAgIHZhciBvcGVyYXRpb24gPSBwYXRoT2JqW21ldGhvZF07XG5cbiAgICAgIGlmIChfLmlzVW5kZWZpbmVkKG9wZXJhdGlvbikpIHtcbiAgICAgICAgLy8gT3BlcmF0aW9uIGRvZXMgbm90IGV4aXN0XG4gICAgICAgIHJldHVybjtcbiAgICAgIH0gZWxzZSBpZiAoIV8uaXNQbGFpbk9iamVjdChvcGVyYXRpb24pKSB7XG4gICAgICAgIC8vIE9wZXJhdGlvbiBleGlzdHMgYnV0IGl0IGlzIG5vdCBhbiBPcGVyYXRpb24gT2JqZWN0LiAgU2luY2UgdGhpcyBpcyBpbnZhbGlkLCBsb2cgaXQuXG4gICAgICAgIGhlbHBlcnMubG9nKCdUaGUgXFwnJyArIG1ldGhvZCArICdcXCcgb3BlcmF0aW9uIGZvciBcXCcnICsgcGF0aCArICdcXCcgcGF0aCBpcyBub3QgYW4gT3BlcmF0aW9uIE9iamVjdCcpO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIHRhZ3MgPSBvcGVyYXRpb24udGFncztcblxuICAgICAgaWYgKF8uaXNVbmRlZmluZWQodGFncykgfHwgIV8uaXNBcnJheSh0YWdzKSB8fCB0YWdzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0YWdzID0gb3BlcmF0aW9uLnRhZ3MgPSBbICdkZWZhdWx0JyBdO1xuICAgICAgfVxuXG4gICAgICB2YXIgb3BlcmF0aW9uSWQgPSBzZWxmLmlkRnJvbU9wKHBhdGgsIG1ldGhvZCwgb3BlcmF0aW9uKTtcblxuICAgICAgdmFyIG9wZXJhdGlvbk9iamVjdCA9IG5ldyBPcGVyYXRpb24oc2VsZixcbiAgICAgICAgb3BlcmF0aW9uLnNjaGVtZSxcbiAgICAgICAgb3BlcmF0aW9uSWQsXG4gICAgICAgIG1ldGhvZCxcbiAgICAgICAgcGF0aCxcbiAgICAgICAgb3BlcmF0aW9uLFxuICAgICAgICBzZWxmLmRlZmluaXRpb25zLFxuICAgICAgICBzZWxmLm1vZGVscyxcbiAgICAgICAgc2VsZi5jbGllbnRBdXRob3JpemF0aW9ucyk7XG5cbiAgICAgIG9wZXJhdGlvbk9iamVjdC5jb25uZWN0aW9uQWdlbnQgPSBzZWxmLmNvbm5lY3Rpb25BZ2VudDtcbiAgICAgIG9wZXJhdGlvbk9iamVjdC52ZW5kb3JFeHRlbnNpb25zID0ge307XG4gICAgICBmb3IoaSBpbiBvcGVyYXRpb24pIHtcbiAgICAgICAgaGVscGVycy5leHRyYWN0RXh0ZW5zaW9ucyhpLCBvcGVyYXRpb25PYmplY3QsIG9wZXJhdGlvbltpXSk7XG4gICAgICB9XG4gICAgICBvcGVyYXRpb25PYmplY3QuZXh0ZXJuYWxEb2NzID0gb3BlcmF0aW9uLmV4dGVybmFsRG9jcztcbiAgICAgIGlmKG9wZXJhdGlvbk9iamVjdC5leHRlcm5hbERvY3MpIHtcbiAgICAgICAgb3BlcmF0aW9uT2JqZWN0LmV4dGVybmFsRG9jcyA9IF8uY2xvbmVEZWVwKG9wZXJhdGlvbk9iamVjdC5leHRlcm5hbERvY3MpO1xuICAgICAgICBvcGVyYXRpb25PYmplY3QuZXh0ZXJuYWxEb2NzLnZlbmRvckV4dGVuc2lvbnMgPSB7fTtcbiAgICAgICAgZm9yKGkgaW4gb3BlcmF0aW9uT2JqZWN0LmV4dGVybmFsRG9jcykge1xuICAgICAgICAgIGhlbHBlcnMuZXh0cmFjdEV4dGVuc2lvbnMoaSwgb3BlcmF0aW9uT2JqZWN0LmV4dGVybmFsRG9jcyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gYmluZCBzZWxmIG9wZXJhdGlvbidzIGV4ZWN1dGUgY29tbWFuZCB0byB0aGUgYXBpXG4gICAgICBfLmZvckVhY2godGFncywgZnVuY3Rpb24gKHRhZykge1xuICAgICAgICB2YXIgY2xpZW50UHJvcGVydHkgPSBfLmluZGV4T2YocmVzZXJ2ZWRDbGllbnRUYWdzLCB0YWcpID4gLTEgPyAnXycgKyB0YWcgOiB0YWc7XG4gICAgICAgIHZhciBhcGlQcm9wZXJ0eSA9IF8uaW5kZXhPZihyZXNlcnZlZEFwaVRhZ3MsIHRhZykgPiAtMSA/ICdfJyArIHRhZyA6IHRhZztcbiAgICAgICAgdmFyIG9wZXJhdGlvbkdyb3VwID0gc2VsZltjbGllbnRQcm9wZXJ0eV07XG5cbiAgICAgICAgaWYgKGNsaWVudFByb3BlcnR5ICE9PSB0YWcpIHtcbiAgICAgICAgICBoZWxwZXJzLmxvZygnVGhlIFxcJycgKyB0YWcgKyAnXFwnIHRhZyBjb25mbGljdHMgd2l0aCBhIFN3YWdnZXJDbGllbnQgZnVuY3Rpb24vcHJvcGVydHkgbmFtZS4gIFVzZSBcXCdjbGllbnQuJyArXG4gICAgICAgICAgICAgICAgICAgICAgY2xpZW50UHJvcGVydHkgKyAnXFwnIG9yIFxcJ2NsaWVudC5hcGlzLicgKyB0YWcgKyAnXFwnIGluc3RlYWQgb2YgXFwnY2xpZW50LicgKyB0YWcgKyAnXFwnLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGFwaVByb3BlcnR5ICE9PSB0YWcpIHtcbiAgICAgICAgICBoZWxwZXJzLmxvZygnVGhlIFxcJycgKyB0YWcgKyAnXFwnIHRhZyBjb25mbGljdHMgd2l0aCBhIFN3YWdnZXJDbGllbnQgb3BlcmF0aW9uIGZ1bmN0aW9uL3Byb3BlcnR5IG5hbWUuICBVc2UgJyArXG4gICAgICAgICAgICAgICAgICAgICAgJ1xcJ2NsaWVudC5hcGlzLicgKyBhcGlQcm9wZXJ0eSArICdcXCcgaW5zdGVhZCBvZiBcXCdjbGllbnQuYXBpcy4nICsgdGFnICsgJ1xcJy4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChfLmluZGV4T2YocmVzZXJ2ZWRBcGlUYWdzLCBvcGVyYXRpb25JZCkgPiAtMSkge1xuICAgICAgICAgIGhlbHBlcnMubG9nKCdUaGUgXFwnJyArIG9wZXJhdGlvbklkICsgJ1xcJyBvcGVyYXRpb25JZCBjb25mbGljdHMgd2l0aCBhIFN3YWdnZXJDbGllbnQgb3BlcmF0aW9uICcgK1xuICAgICAgICAgICAgICAgICAgICAgICdmdW5jdGlvbi9wcm9wZXJ0eSBuYW1lLiAgVXNlIFxcJ2NsaWVudC5hcGlzLicgKyBhcGlQcm9wZXJ0eSArICcuXycgKyBvcGVyYXRpb25JZCArXG4gICAgICAgICAgICAgICAgICAgICAgJ1xcJyBpbnN0ZWFkIG9mIFxcJ2NsaWVudC5hcGlzLicgKyBhcGlQcm9wZXJ0eSArICcuJyArIG9wZXJhdGlvbklkICsgJ1xcJy4nKTtcblxuICAgICAgICAgIG9wZXJhdGlvbklkID0gJ18nICsgb3BlcmF0aW9uSWQ7XG4gICAgICAgICAgb3BlcmF0aW9uT2JqZWN0Lm5pY2tuYW1lID0gb3BlcmF0aW9uSWQ7IC8vIFNvICdjbGllbnQuYXBpcy5bdGFnXS5vcGVyYXRpb25JZC5oZWxwKCkgd29ya3MgcHJvcGVybHlcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChfLmlzVW5kZWZpbmVkKG9wZXJhdGlvbkdyb3VwKSkge1xuICAgICAgICAgIG9wZXJhdGlvbkdyb3VwID0gc2VsZltjbGllbnRQcm9wZXJ0eV0gPSBzZWxmLmFwaXNbYXBpUHJvcGVydHldID0ge307XG5cbiAgICAgICAgICBvcGVyYXRpb25Hcm91cC5vcGVyYXRpb25zID0ge307XG4gICAgICAgICAgb3BlcmF0aW9uR3JvdXAubGFiZWwgPSBhcGlQcm9wZXJ0eTtcbiAgICAgICAgICBvcGVyYXRpb25Hcm91cC5hcGlzID0ge307XG5cbiAgICAgICAgICB2YXIgdGFnRGVmID0gZGVmaW5lZFRhZ3NbdGFnXTtcblxuICAgICAgICAgIGlmICghXy5pc1VuZGVmaW5lZCh0YWdEZWYpKSB7XG4gICAgICAgICAgICBvcGVyYXRpb25Hcm91cC5kZXNjcmlwdGlvbiA9IHRhZ0RlZi5kZXNjcmlwdGlvbjtcbiAgICAgICAgICAgIG9wZXJhdGlvbkdyb3VwLmV4dGVybmFsRG9jcyA9IHRhZ0RlZi5leHRlcm5hbERvY3M7XG4gICAgICAgICAgICBvcGVyYXRpb25Hcm91cC52ZW5kb3JFeHRlbnNpb25zID0gdGFnRGVmLnZlbmRvckV4dGVuc2lvbnM7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgc2VsZltjbGllbnRQcm9wZXJ0eV0uaGVscCA9IF8uYmluZChzZWxmLmhlbHAsIG9wZXJhdGlvbkdyb3VwKTtcbiAgICAgICAgICBzZWxmLmFwaXNBcnJheS5wdXNoKG5ldyBPcGVyYXRpb25Hcm91cCh0YWcsIG9wZXJhdGlvbkdyb3VwLmRlc2NyaXB0aW9uLCBvcGVyYXRpb25Hcm91cC5leHRlcm5hbERvY3MsIG9wZXJhdGlvbk9iamVjdCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgb3BlcmF0aW9uSWQgPSBzZWxmLm1ha2VVbmlxdWVPcGVyYXRpb25JZChvcGVyYXRpb25JZCwgc2VsZi5hcGlzW2FwaVByb3BlcnR5XSk7XG5cbiAgICAgICAgLy8gQmluZCB0YWcgaGVscFxuICAgICAgICBpZiAoIV8uaXNGdW5jdGlvbihvcGVyYXRpb25Hcm91cC5oZWxwKSkge1xuICAgICAgICAgIG9wZXJhdGlvbkdyb3VwLmhlbHAgPSBfLmJpbmQoc2VsZi5oZWxwLCBvcGVyYXRpb25Hcm91cCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBiaW5kIHRvIHRoZSBhcGlzIG9iamVjdFxuICAgICAgICBzZWxmLmFwaXNbYXBpUHJvcGVydHldW29wZXJhdGlvbklkXSA9IG9wZXJhdGlvbkdyb3VwW29wZXJhdGlvbklkXSA9IF8uYmluZChvcGVyYXRpb25PYmplY3QuZXhlY3V0ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRpb25PYmplY3QpO1xuICAgICAgICBzZWxmLmFwaXNbYXBpUHJvcGVydHldW29wZXJhdGlvbklkXS5oZWxwID0gb3BlcmF0aW9uR3JvdXBbb3BlcmF0aW9uSWRdLmhlbHAgPSBfLmJpbmQob3BlcmF0aW9uT2JqZWN0LmhlbHAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRpb25PYmplY3QpO1xuICAgICAgICBzZWxmLmFwaXNbYXBpUHJvcGVydHldW29wZXJhdGlvbklkXS5hc0N1cmwgPSBvcGVyYXRpb25Hcm91cFtvcGVyYXRpb25JZF0uYXNDdXJsID0gXy5iaW5kKG9wZXJhdGlvbk9iamVjdC5hc0N1cmwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uT2JqZWN0KTtcblxuICAgICAgICBvcGVyYXRpb25Hcm91cC5hcGlzW29wZXJhdGlvbklkXSA9IG9wZXJhdGlvbkdyb3VwLm9wZXJhdGlvbnNbb3BlcmF0aW9uSWRdID0gb3BlcmF0aW9uT2JqZWN0O1xuXG4gICAgICAgIC8vIGxlZ2FjeSBVSSBmZWF0dXJlXG4gICAgICAgIHZhciBhcGkgPSBfLmZpbmQoc2VsZi5hcGlzQXJyYXksIGZ1bmN0aW9uIChhcGkpIHtcbiAgICAgICAgICByZXR1cm4gYXBpLnRhZyA9PT0gdGFnO1xuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoYXBpKSB7XG4gICAgICAgICAgYXBpLm9wZXJhdGlvbnNBcnJheS5wdXNoKG9wZXJhdGlvbk9iamVjdCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICAvLyBzb3J0IHRoZSBhcGlzQXJyYXkgYWNjb3JkaW5nIHRvIHRoZSB0YWdzXG4gIHZhciBzb3J0ZWRBcGlzID0gW107XG4gIF8uZm9yRWFjaChPYmplY3Qua2V5cyhkZWZpbmVkVGFncyksIGZ1bmN0aW9uICh0YWcpIHtcbiAgICB2YXIgcG9zO1xuICAgIGZvcihwb3MgaW4gc2VsZi5hcGlzQXJyYXkpIHtcbiAgICAgIHZhciBfYXBpID0gc2VsZi5hcGlzQXJyYXlbcG9zXTtcbiAgICAgIGlmKF9hcGkgJiYgdGFnID09PSBfYXBpLm5hbWUpIHtcbiAgICAgICAgc29ydGVkQXBpcy5wdXNoKF9hcGkpO1xuICAgICAgICBzZWxmLmFwaXNBcnJheVtwb3NdID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuICAvLyBhZGQgYW55dGhpbmcgbGVmdFxuICBfLmZvckVhY2goc2VsZi5hcGlzQXJyYXksIGZ1bmN0aW9uIChhcGkpIHtcbiAgICBpZihhcGkpIHtcbiAgICAgIHNvcnRlZEFwaXMucHVzaChhcGkpO1xuICAgIH1cbiAgfSk7XG4gIHNlbGYuYXBpc0FycmF5ID0gc29ydGVkQXBpcztcblxuICBfLmZvckVhY2gocmVzcG9uc2UuZGVmaW5pdGlvbnMsIGZ1bmN0aW9uIChkZWZpbml0aW9uT2JqLCBkZWZpbml0aW9uKSB7XG4gICAgZGVmaW5pdGlvbk9iai5pZCA9IGRlZmluaXRpb24udG9Mb3dlckNhc2UoKTtcbiAgICBkZWZpbml0aW9uT2JqLm5hbWUgPSBkZWZpbml0aW9uO1xuICAgIHNlbGYubW9kZWxzQXJyYXkucHVzaChkZWZpbml0aW9uT2JqKTtcbiAgfSk7XG5cbiAgdGhpcy5pc0J1aWx0ID0gdHJ1ZTtcblxuICBpZiAodGhpcy51c2VQcm9taXNlKSB7XG4gICAgdGhpcy5pc1ZhbGlkID0gdHJ1ZTtcbiAgICB0aGlzLmlzQnVpbHQgPSB0cnVlO1xuICAgIHRoaXMuZGVmZXJyZWRDbGllbnQucmVzb2x2ZSh0aGlzKTtcblxuICAgIHJldHVybiB0aGlzLmRlZmVycmVkQ2xpZW50LnByb21pc2U7XG4gIH1cblxuICBpZiAodGhpcy5zdWNjZXNzKSB7XG4gICAgdGhpcy5zdWNjZXNzKCk7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cblN3YWdnZXJDbGllbnQucHJvdG90eXBlLm1ha2VVbmlxdWVPcGVyYXRpb25JZCA9IGZ1bmN0aW9uKG9wZXJhdGlvbklkLCBhcGkpIHtcbiAgdmFyIGNvdW50ID0gMDtcbiAgdmFyIG5hbWUgPSBvcGVyYXRpb25JZDtcblxuICAvLyBtYWtlIHVuaXF1ZSBhY3Jvc3MgdGhpcyBvcGVyYXRpb24gZ3JvdXBcbiAgd2hpbGUodHJ1ZSkge1xuICAgIHZhciBtYXRjaGVkID0gZmFsc2U7XG4gICAgXy5mb3JFYWNoKGFwaS5vcGVyYXRpb25zLCBmdW5jdGlvbiAob3BlcmF0aW9uKSB7XG4gICAgICBpZihvcGVyYXRpb24ubmlja25hbWUgPT09IG5hbWUpIHtcbiAgICAgICAgbWF0Y2hlZCA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG4gICAgaWYoIW1hdGNoZWQpIHtcbiAgICAgIHJldHVybiBuYW1lO1xuICAgIH1cbiAgICBuYW1lID0gb3BlcmF0aW9uSWQgKyAnXycgKyBjb3VudDtcbiAgICBjb3VudCArKztcbiAgfVxuXG4gIHJldHVybiBvcGVyYXRpb25JZDtcbn07XG5cblN3YWdnZXJDbGllbnQucHJvdG90eXBlLnBhcnNlVXJpID0gZnVuY3Rpb24gKHVyaSkge1xuICB2YXIgdXJsUGFyc2VSRSA9IC9eKCgoKFteOlxcLyNcXD9dKzopPyg/OihcXC9cXC8pKCg/OigoW146QFxcLyNcXD9dKykoPzpcXDooW146QFxcLyNcXD9dKykpPylAKT8oKFteOlxcLyNcXD9cXF1cXFtdK3xcXFtbXlxcL1xcXUAjP10rXFxdKSg/OlxcOihbMC05XSspKT8pKT8pPyk/KChcXC8/KD86W15cXC9cXD8jXStcXC8rKSopKFteXFw/I10qKSkpPyhcXD9bXiNdKyk/KSgjLiopPy87XG4gIHZhciBwYXJ0cyA9IHVybFBhcnNlUkUuZXhlYyh1cmkpO1xuXG4gIHJldHVybiB7XG4gICAgc2NoZW1lOiBwYXJ0c1s0XSA/IHBhcnRzWzRdLnJlcGxhY2UoJzonLCcnKSA6IHVuZGVmaW5lZCxcbiAgICBob3N0OiBwYXJ0c1sxMV0sXG4gICAgcG9ydDogcGFydHNbMTJdLFxuICAgIHBhdGg6IHBhcnRzWzE1XVxuICB9O1xufTtcblxuU3dhZ2dlckNsaWVudC5wcm90b3R5cGUuaGVscCA9IGZ1bmN0aW9uIChkb250UHJpbnQpIHtcbiAgdmFyIG91dHB1dCA9ICcnO1xuXG4gIGlmICh0aGlzIGluc3RhbmNlb2YgU3dhZ2dlckNsaWVudCkge1xuICAgIF8uZm9yRWFjaCh0aGlzLmFwaXMsIGZ1bmN0aW9uIChhcGksIG5hbWUpIHtcbiAgICAgIGlmIChfLmlzUGxhaW5PYmplY3QoYXBpKSkge1xuICAgICAgICBvdXRwdXQgKz0gJ29wZXJhdGlvbnMgZm9yIHRoZSBcXCcnICsgbmFtZSArICdcXCcgdGFnXFxuJztcblxuICAgICAgICBfLmZvckVhY2goYXBpLm9wZXJhdGlvbnMsIGZ1bmN0aW9uIChvcGVyYXRpb24sIG5hbWUpIHtcbiAgICAgICAgICBvdXRwdXQgKz0gJyAgKiAnICsgbmFtZSArICc6ICcgKyBvcGVyYXRpb24uc3VtbWFyeSArICdcXG4nO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSBlbHNlIGlmICh0aGlzIGluc3RhbmNlb2YgT3BlcmF0aW9uR3JvdXAgfHwgXy5pc1BsYWluT2JqZWN0KHRoaXMpKSB7XG4gICAgb3V0cHV0ICs9ICdvcGVyYXRpb25zIGZvciB0aGUgXFwnJyArIHRoaXMubGFiZWwgKyAnXFwnIHRhZ1xcbic7XG5cbiAgICBfLmZvckVhY2godGhpcy5hcGlzLCBmdW5jdGlvbiAob3BlcmF0aW9uLCBuYW1lKSB7XG4gICAgICBvdXRwdXQgKz0gJyAgKiAnICsgbmFtZSArICc6ICcgKyBvcGVyYXRpb24uc3VtbWFyeSArICdcXG4nO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKGRvbnRQcmludCkge1xuICAgIHJldHVybiBvdXRwdXQ7XG4gIH0gZWxzZSB7XG4gICAgaGVscGVycy5sb2cob3V0cHV0KTtcblxuICAgIHJldHVybiBvdXRwdXQ7XG4gIH1cbn07XG5cblN3YWdnZXJDbGllbnQucHJvdG90eXBlLnRhZ0Zyb21MYWJlbCA9IGZ1bmN0aW9uIChsYWJlbCkge1xuICByZXR1cm4gbGFiZWw7XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS5pZEZyb21PcCA9IGZ1bmN0aW9uIChwYXRoLCBodHRwTWV0aG9kLCBvcCkge1xuICBpZighb3AgfHwgIW9wLm9wZXJhdGlvbklkKSB7XG4gICAgb3AgPSBvcCB8fCB7fTtcbiAgICBvcC5vcGVyYXRpb25JZCA9IGh0dHBNZXRob2QgKyAnXycgKyBwYXRoO1xuICB9XG4gIHZhciBvcElkID0gb3Aub3BlcmF0aW9uSWQucmVwbGFjZSgvW1xccyFAIyQlXiYqKClfKz1cXFt7XFxdfTs6PD58LlxcLz8sXFxcXCdcIlwiLV0vZywgJ18nKSB8fCAocGF0aC5zdWJzdHJpbmcoMSkgKyAnXycgKyBodHRwTWV0aG9kKTtcblxuICBvcElkID0gb3BJZC5yZXBsYWNlKC8oKF8pezIsfSkvZywgJ18nKTtcbiAgb3BJZCA9IG9wSWQucmVwbGFjZSgvXihfKSovZywgJycpO1xuICBvcElkID0gb3BJZC5yZXBsYWNlKC8oW19dKSokL2csICcnKTtcblxuICByZXR1cm4gb3BJZDtcbn07XG5cblN3YWdnZXJDbGllbnQucHJvdG90eXBlLnNldEhvc3QgPSBmdW5jdGlvbiAoaG9zdCkge1xuICB0aGlzLmhvc3QgPSBob3N0O1xuXG4gIGlmKHRoaXMuYXBpcykge1xuICAgIF8uZm9yRWFjaCh0aGlzLmFwaXMsIGZ1bmN0aW9uKGFwaSkge1xuICAgICAgaWYoYXBpLm9wZXJhdGlvbnMpIHtcbiAgICAgICAgXy5mb3JFYWNoKGFwaS5vcGVyYXRpb25zLCBmdW5jdGlvbihvcGVyYXRpb24pIHtcbiAgICAgICAgICBvcGVyYXRpb24uaG9zdCA9IGhvc3Q7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS5zZXRCYXNlUGF0aCA9IGZ1bmN0aW9uIChiYXNlUGF0aCkge1xuICB0aGlzLmJhc2VQYXRoID0gYmFzZVBhdGg7XG5cbiAgaWYodGhpcy5hcGlzKSB7XG4gICAgXy5mb3JFYWNoKHRoaXMuYXBpcywgZnVuY3Rpb24oYXBpKSB7XG4gICAgICBpZihhcGkub3BlcmF0aW9ucykge1xuICAgICAgICBfLmZvckVhY2goYXBpLm9wZXJhdGlvbnMsIGZ1bmN0aW9uKG9wZXJhdGlvbikge1xuICAgICAgICAgIG9wZXJhdGlvbi5iYXNlUGF0aCA9IGJhc2VQYXRoO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufTtcblxuU3dhZ2dlckNsaWVudC5wcm90b3R5cGUuc2V0U2NoZW1lcyA9IGZ1bmN0aW9uIChzY2hlbWVzKSB7XG4gIHRoaXMuc2NoZW1lcyA9IHNjaGVtZXM7XG5cbiAgaWYoc2NoZW1lcyAmJiBzY2hlbWVzLmxlbmd0aCA+IDApIHtcbiAgICBpZih0aGlzLmFwaXMpIHtcbiAgICAgIF8uZm9yRWFjaCh0aGlzLmFwaXMsIGZ1bmN0aW9uIChhcGkpIHtcbiAgICAgICAgaWYgKGFwaS5vcGVyYXRpb25zKSB7XG4gICAgICAgICAgXy5mb3JFYWNoKGFwaS5vcGVyYXRpb25zLCBmdW5jdGlvbiAob3BlcmF0aW9uKSB7XG4gICAgICAgICAgICBvcGVyYXRpb24uc2NoZW1lID0gc2NoZW1lc1swXTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG59O1xuXG5Td2FnZ2VyQ2xpZW50LnByb3RvdHlwZS5mYWlsID0gZnVuY3Rpb24gKG1lc3NhZ2UpIHtcbiAgaWYgKHRoaXMudXNlUHJvbWlzZSkge1xuICAgIHRoaXMuZGVmZXJyZWRDbGllbnQucmVqZWN0KG1lc3NhZ2UpO1xuICAgIHJldHVybiB0aGlzLmRlZmVycmVkQ2xpZW50LnByb21pc2U7XG4gIH0gZWxzZSB7XG4gICAgaWYgKHRoaXMuZmFpbHVyZSkge1xuICAgICAgdGhpcy5mYWlsdXJlKG1lc3NhZ2UpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHRoaXMuZmFpbHVyZShtZXNzYWdlKTtcbiAgICB9XG4gIH1cbn07XG4iLCIoZnVuY3Rpb24gKHByb2Nlc3Mpe1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgXyA9IHtcbiAgaXNQbGFpbk9iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzUGxhaW5PYmplY3QnKSxcbiAgaW5kZXhPZjogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9hcnJheS9pbmRleE9mJylcbn07XG5cbm1vZHVsZS5leHBvcnRzLl9fYmluZCA9IGZ1bmN0aW9uIChmbiwgbWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCl7XG4gICAgcmV0dXJuIGZuLmFwcGx5KG1lLCBhcmd1bWVudHMpO1xuICB9O1xufTtcblxudmFyIGxvZyA9IG1vZHVsZS5leHBvcnRzLmxvZyA9IGZ1bmN0aW9uKCkge1xuICAvLyBPbmx5IGxvZyBpZiBhdmFpbGFibGUgYW5kIHdlJ3JlIG5vdCB0ZXN0aW5nXG4gIGlmIChjb25zb2xlICYmIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAndGVzdCcpIHtcbiAgICBjb25zb2xlLmxvZyhBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpWzBdKTtcbiAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMuZmFpbCA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7XG4gIGxvZyhtZXNzYWdlKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzLm9wdGlvbkh0bWwgPSBmdW5jdGlvbiAobGFiZWwsIHZhbHVlKSB7XG4gIHJldHVybiAnPHRyPjx0ZCBjbGFzcz1cIm9wdGlvbk5hbWVcIj4nICsgbGFiZWwgKyAnOjwvdGQ+PHRkPicgKyB2YWx1ZSArICc8L3RkPjwvdHI+Jztcbn07XG5cbnZhciByZXNvbHZlU2NoZW1hID0gbW9kdWxlLmV4cG9ydHMucmVzb2x2ZVNjaGVtYSA9IGZ1bmN0aW9uIChzY2hlbWEpIHtcbiAgaWYgKF8uaXNQbGFpbk9iamVjdChzY2hlbWEuc2NoZW1hKSkge1xuICAgIHNjaGVtYSA9IHJlc29sdmVTY2hlbWEoc2NoZW1hLnNjaGVtYSk7XG4gIH1cblxuICByZXR1cm4gc2NoZW1hO1xufTtcblxubW9kdWxlLmV4cG9ydHMuc2ltcGxlUmVmID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgaWYgKHR5cGVvZiBuYW1lID09PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgaWYgKG5hbWUuaW5kZXhPZignIy9kZWZpbml0aW9ucy8nKSA9PT0gMCkge1xuICAgIHJldHVybiBuYW1lLnN1YnN0cmluZygnIy9kZWZpbml0aW9ucy8nLmxlbmd0aCk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG5hbWU7XG4gIH1cbn07XG5cbi8qKlxuICogaGVscGVyIHRvIHJlbW92ZSBleHRlbnNpb25zIGFuZCBhZGQgdGhlbSB0byBhbiBvYmplY3RcbiAqXG4gKiBAcGFyYW0ga2V5bmFtZVxuICogQHBhcmFtIG9ialxuICovXG5tb2R1bGUuZXhwb3J0cy5leHRyYWN0RXh0ZW5zaW9ucyA9IGZ1bmN0aW9uIChrZXluYW1lLCBvYmosIHZhbHVlKSB7XG4gIGlmKCFrZXluYW1lIHx8ICFvYmopIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAodHlwZW9mIGtleW5hbWUgPT09ICdzdHJpbmcnICYmIGtleW5hbWUuaW5kZXhPZigneC0nKSA9PT0gMCkge1xuICAgIG9iai52ZW5kb3JFeHRlbnNpb25zID0gb2JqLnZlbmRvckV4dGVuc2lvbnMgfHwge307XG4gICAgaWYodmFsdWUpIHtcbiAgICAgIG9iai52ZW5kb3JFeHRlbnNpb25zW2tleW5hbWVdID0gdmFsdWU7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgb2JqLnZlbmRvckV4dGVuc2lvbnNba2V5bmFtZV0gPSBvYmpba2V5bmFtZV07XG4gICAgfVxuICB9XG59O1xufSkuY2FsbCh0aGlzLHJlcXVpcmUoJ19wcm9jZXNzJykpXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldDp1dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbXhwWWk5b1pXeHdaWEp6TG1weklsMHNJbTVoYldWeklqcGJYU3dpYldGd2NHbHVaM01pT2lJN1FVRkJRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRWlMQ0ptYVd4bElqb2laMlZ1WlhKaGRHVmtMbXB6SWl3aWMyOTFjbU5sVW05dmRDSTZJaUlzSW5OdmRYSmpaWE5EYjI1MFpXNTBJanBiSWlkMWMyVWdjM1J5YVdOMEp6dGNibHh1ZG1GeUlGOGdQU0I3WEc0Z0lHbHpVR3hoYVc1UFltcGxZM1E2SUhKbGNYVnBjbVVvSjJ4dlpHRnphQzFqYjIxd1lYUXZiR0Z1Wnk5cGMxQnNZV2x1VDJKcVpXTjBKeWtzWEc0Z0lHbHVaR1Y0VDJZNklISmxjWFZwY21Vb0oyeHZaR0Z6YUMxamIyMXdZWFF2WVhKeVlYa3ZhVzVrWlhoUFppY3BYRzU5TzF4dVhHNXRiMlIxYkdVdVpYaHdiM0owY3k1ZlgySnBibVFnUFNCbWRXNWpkR2x2YmlBb1ptNHNJRzFsS1NCN1hHNGdJSEpsZEhWeWJpQm1kVzVqZEdsdmJpZ3BlMXh1SUNBZ0lISmxkSFZ5YmlCbWJpNWhjSEJzZVNodFpTd2dZWEpuZFcxbGJuUnpLVHRjYmlBZ2ZUdGNibjA3WEc1Y2JuWmhjaUJzYjJjZ1BTQnRiMlIxYkdVdVpYaHdiM0owY3k1c2IyY2dQU0JtZFc1amRHbHZiaWdwSUh0Y2JpQWdMeThnVDI1c2VTQnNiMmNnYVdZZ1lYWmhhV3hoWW14bElHRnVaQ0IzWlNkeVpTQnViM1FnZEdWemRHbHVaMXh1SUNCcFppQW9ZMjl1YzI5c1pTQW1KaUJ3Y205alpYTnpMbVZ1ZGk1T1QwUkZYMFZPVmlBaFBUMGdKM1JsYzNRbktTQjdYRzRnSUNBZ1kyOXVjMjlzWlM1c2IyY29RWEp5WVhrdWNISnZkRzkwZVhCbExuTnNhV05sTG1OaGJHd29ZWEpuZFcxbGJuUnpLVnN3WFNrN1hHNGdJSDFjYm4wN1hHNWNibTF2WkhWc1pTNWxlSEJ2Y25SekxtWmhhV3dnUFNCbWRXNWpkR2x2YmlBb2JXVnpjMkZuWlNrZ2UxeHVJQ0JzYjJjb2JXVnpjMkZuWlNrN1hHNTlPMXh1WEc1dGIyUjFiR1V1Wlhod2IzSjBjeTV2Y0hScGIyNUlkRzFzSUQwZ1puVnVZM1JwYjI0Z0tHeGhZbVZzTENCMllXeDFaU2tnZTF4dUlDQnlaWFIxY200Z0p6eDBjajQ4ZEdRZ1kyeGhjM005WENKdmNIUnBiMjVPWVcxbFhDSStKeUFySUd4aFltVnNJQ3NnSnpvOEwzUmtQangwWkQ0bklDc2dkbUZzZFdVZ0t5QW5QQzkwWkQ0OEwzUnlQaWM3WEc1OU8xeHVYRzUyWVhJZ2NtVnpiMngyWlZOamFHVnRZU0E5SUcxdlpIVnNaUzVsZUhCdmNuUnpMbkpsYzI5c2RtVlRZMmhsYldFZ1BTQm1kVzVqZEdsdmJpQW9jMk5vWlcxaEtTQjdYRzRnSUdsbUlDaGZMbWx6VUd4aGFXNVBZbXBsWTNRb2MyTm9aVzFoTG5OamFHVnRZU2twSUh0Y2JpQWdJQ0J6WTJobGJXRWdQU0J5WlhOdmJIWmxVMk5vWlcxaEtITmphR1Z0WVM1elkyaGxiV0VwTzF4dUlDQjlYRzVjYmlBZ2NtVjBkWEp1SUhOamFHVnRZVHRjYm4wN1hHNWNibTF2WkhWc1pTNWxlSEJ2Y25SekxuTnBiWEJzWlZKbFppQTlJR1oxYm1OMGFXOXVJQ2h1WVcxbEtTQjdYRzRnSUdsbUlDaDBlWEJsYjJZZ2JtRnRaU0E5UFQwZ0ozVnVaR1ZtYVc1bFpDY3BJSHRjYmlBZ0lDQnlaWFIxY200Z2JuVnNiRHRjYmlBZ2ZWeHVYRzRnSUdsbUlDaHVZVzFsTG1sdVpHVjRUMllvSnlNdlpHVm1hVzVwZEdsdmJuTXZKeWtnUFQwOUlEQXBJSHRjYmlBZ0lDQnlaWFIxY200Z2JtRnRaUzV6ZFdKemRISnBibWNvSnlNdlpHVm1hVzVwZEdsdmJuTXZKeTVzWlc1bmRHZ3BPMXh1SUNCOUlHVnNjMlVnZTF4dUlDQWdJSEpsZEhWeWJpQnVZVzFsTzF4dUlDQjlYRzU5TzF4dVhHNHZLaXBjYmlBcUlHaGxiSEJsY2lCMGJ5QnlaVzF2ZG1VZ1pYaDBaVzV6YVc5dWN5QmhibVFnWVdSa0lIUm9aVzBnZEc4Z1lXNGdiMkpxWldOMFhHNGdLbHh1SUNvZ1FIQmhjbUZ0SUd0bGVXNWhiV1ZjYmlBcUlFQndZWEpoYlNCdlltcGNiaUFxTDF4dWJXOWtkV3hsTG1WNGNHOXlkSE11WlhoMGNtRmpkRVY0ZEdWdWMybHZibk1nUFNCbWRXNWpkR2x2YmlBb2EyVjVibUZ0WlN3Z2IySnFMQ0IyWVd4MVpTa2dlMXh1SUNCcFppZ2hhMlY1Ym1GdFpTQjhmQ0FoYjJKcUtTQjdYRzRnSUNBZ2NtVjBkWEp1TzF4dUlDQjlYRzVjYmlBZ2FXWWdLSFI1Y0dWdlppQnJaWGx1WVcxbElEMDlQU0FuYzNSeWFXNW5KeUFtSmlCclpYbHVZVzFsTG1sdVpHVjRUMllvSjNndEp5a2dQVDA5SURBcElIdGNiaUFnSUNCdlltb3VkbVZ1Wkc5eVJYaDBaVzV6YVc5dWN5QTlJRzlpYWk1MlpXNWtiM0pGZUhSbGJuTnBiMjV6SUh4OElIdDlPMXh1SUNBZ0lHbG1LSFpoYkhWbEtTQjdYRzRnSUNBZ0lDQnZZbW91ZG1WdVpHOXlSWGgwWlc1emFXOXVjMXRyWlhsdVlXMWxYU0E5SUhaaGJIVmxPMXh1SUNBZ0lIMWNiaUFnSUNCbGJITmxJSHRjYmlBZ0lDQWdJRzlpYWk1MlpXNWtiM0pGZUhSbGJuTnBiMjV6VzJ0bGVXNWhiV1ZkSUQwZ2IySnFXMnRsZVc1aGJXVmRPMXh1SUNBZ0lIMWNiaUFnZlZ4dWZUc2lYWDA9IiwiKGZ1bmN0aW9uIChCdWZmZXIpe1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4vaGVscGVycycpO1xudmFyIHJlcXVlc3QgPSByZXF1aXJlKCdzdXBlcmFnZW50Jyk7XG52YXIganN5YW1sID0gcmVxdWlyZSgnanMteWFtbCcpO1xudmFyIF8gPSB7XG4gIGlzT2JqZWN0OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNPYmplY3QnKSxcbiAga2V5czogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9vYmplY3Qva2V5cycpXG59O1xuXG4vKlxuICogSlF1ZXJ5SHR0cENsaWVudCBpcyBhIGxpZ2h0LXdlaWdodCwgbm9kZSBvciBicm93c2VyIEhUVFAgY2xpZW50XG4gKi9cbnZhciBKUXVlcnlIdHRwQ2xpZW50ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLnR5cGUgPSAnSlF1ZXJ5SHR0cENsaWVudCc7XG59O1xuXG4vKlxuICogU3VwZXJhZ2VudEh0dHBDbGllbnQgaXMgYSBsaWdodC13ZWlnaHQsIG5vZGUgb3IgYnJvd3NlciBIVFRQIGNsaWVudFxuICovXG52YXIgU3VwZXJhZ2VudEh0dHBDbGllbnQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMudHlwZSA9ICdTdXBlcmFnZW50SHR0cENsaWVudCc7XG59O1xuXG4vKipcbiAqIFN3YWdnZXJIdHRwIGlzIGEgd3JhcHBlciBmb3IgZXhlY3V0aW5nIHJlcXVlc3RzXG4gKi9cbnZhciBTd2FnZ2VySHR0cCA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge307XG5cblN3YWdnZXJIdHRwLnByb3RvdHlwZS5leGVjdXRlID0gZnVuY3Rpb24gKG9iaiwgb3B0cykge1xuICB2YXIgY2xpZW50O1xuXG4gIGlmKG9wdHMgJiYgb3B0cy5jbGllbnQpIHtcbiAgICBjbGllbnQgPSBvcHRzLmNsaWVudDtcbiAgfVxuICBlbHNlIHtcbiAgICBjbGllbnQgPSBuZXcgU3VwZXJhZ2VudEh0dHBDbGllbnQob3B0cyk7XG4gIH1cbiAgY2xpZW50Lm9wdHMgPSBvcHRzIHx8IHt9O1xuXG4gIGlmIChvcHRzICYmIG9wdHMucmVxdWVzdEFnZW50KSB7XG4gICAgcmVxdWVzdCA9IG9wdHMucmVxdWVzdEFnZW50O1xuICB9XG5cbiAgLy8gbGVnYWN5IHN1cHBvcnRcbiAgdmFyIGhhc0pRdWVyeSA9IGZhbHNlO1xuICBpZih0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xuICAgIGlmKHR5cGVvZiB3aW5kb3cualF1ZXJ5ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgaGFzSlF1ZXJ5ID0gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgLy8gT1BUSU9OUyBzdXBwb3J0XG4gIGlmKG9iai5tZXRob2QudG9Mb3dlckNhc2UoKSA9PT0gJ29wdGlvbnMnICYmIGNsaWVudC50eXBlID09PSAnU3VwZXJhZ2VudEh0dHBDbGllbnQnKSB7XG4gICAgbG9nKCdmb3JjaW5nIGpRdWVyeSBhcyBPUFRJT05TIGFyZSBub3Qgc3VwcG9ydGVkIGJ5IFN1cGVyQWdlbnQnKTtcbiAgICBvYmoudXNlSlF1ZXJ5ID0gdHJ1ZTtcbiAgfVxuICBpZih0aGlzLmlzSW50ZXJuZXRFeHBsb3JlcigpICYmIChvYmoudXNlSlF1ZXJ5ID09PSBmYWxzZSB8fCAhaGFzSlF1ZXJ5ICkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIGNvbmZpZ3VyYXRpb24hIEpRdWVyeSBpcyByZXF1aXJlZCBidXQgbm90IGF2YWlsYWJsZScpO1xuICB9XG4gIGlmICgob2JqICYmIG9iai51c2VKUXVlcnkgPT09IHRydWUpIHx8IHRoaXMuaXNJbnRlcm5ldEV4cGxvcmVyKCkgJiYgaGFzSlF1ZXJ5KSB7XG4gICAgY2xpZW50ID0gbmV3IEpRdWVyeUh0dHBDbGllbnQob3B0cyk7XG4gIH1cblxuICB2YXIgc3VjY2VzcyA9IG9iai5vbi5yZXNwb25zZTtcbiAgdmFyIGVycm9yID0gb2JqLm9uLmVycm9yO1xuXG4gIHZhciByZXF1ZXN0SW50ZXJjZXB0b3IgPSBmdW5jdGlvbihkYXRhKSB7XG4gICAgaWYob3B0cyAmJiBvcHRzLnJlcXVlc3RJbnRlcmNlcHRvcikge1xuICAgICAgZGF0YSA9IG9wdHMucmVxdWVzdEludGVyY2VwdG9yLmFwcGx5KGRhdGEpO1xuICAgIH1cbiAgICByZXR1cm4gZGF0YTtcbiAgfTtcblxuICB2YXIgcmVzcG9uc2VJbnRlcmNlcHRvciA9IGZ1bmN0aW9uKGRhdGEpIHtcbiAgICBpZihvcHRzICYmIG9wdHMucmVzcG9uc2VJbnRlcmNlcHRvcikge1xuICAgICAgZGF0YSA9IG9wdHMucmVzcG9uc2VJbnRlcmNlcHRvci5hcHBseShkYXRhLCBbb2JqXSk7XG4gICAgfVxuICAgIHJldHVybiBzdWNjZXNzKGRhdGEpO1xuICB9O1xuXG4gIHZhciBlcnJvckludGVyY2VwdG9yID0gZnVuY3Rpb24oZGF0YSkge1xuICAgIGlmKG9wdHMgJiYgb3B0cy5yZXNwb25zZUludGVyY2VwdG9yKSB7XG4gICAgICBkYXRhID0gb3B0cy5yZXNwb25zZUludGVyY2VwdG9yLmFwcGx5KGRhdGEsIFtvYmpdKTtcbiAgICB9XG4gICAgZXJyb3IoZGF0YSk7XG4gIH07XG5cbiAgb2JqLm9uLmVycm9yID0gZnVuY3Rpb24oZGF0YSkge1xuICAgIGVycm9ySW50ZXJjZXB0b3IoZGF0YSk7XG4gIH07XG5cbiAgb2JqLm9uLnJlc3BvbnNlID0gZnVuY3Rpb24oZGF0YSkge1xuICAgIGlmKGRhdGEgJiYgZGF0YS5zdGF0dXMgPj0gNDAwKSB7XG4gICAgICBlcnJvckludGVyY2VwdG9yKGRhdGEpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHJlc3BvbnNlSW50ZXJjZXB0b3IoZGF0YSk7XG4gICAgfVxuICB9O1xuXG4gIGlmIChfLmlzT2JqZWN0KG9iaikgJiYgXy5pc09iamVjdChvYmouYm9keSkpIHtcbiAgICAvLyBzcGVjaWFsIHByb2Nlc3NpbmcgZm9yIGZpbGUgdXBsb2FkcyB2aWEganF1ZXJ5XG4gICAgaWYgKG9iai5ib2R5LnR5cGUgJiYgb2JqLmJvZHkudHlwZSA9PT0gJ2Zvcm1EYXRhJyl7XG4gICAgICBpZihvcHRzLnVzZUpRdWVyeSkge1xuICAgICAgICBvYmouY29udGVudFR5cGUgPSBmYWxzZTtcbiAgICAgICAgb2JqLnByb2Nlc3NEYXRhID0gZmFsc2U7XG4gICAgICAgIGRlbGV0ZSBvYmouaGVhZGVyc1snQ29udGVudC1UeXBlJ107XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgb2JqID0gcmVxdWVzdEludGVyY2VwdG9yKG9iaikgfHwgb2JqO1xuICBpZiAob2JqLmJlZm9yZVNlbmQpIHtcbiAgICBvYmouYmVmb3JlU2VuZChmdW5jdGlvbihfb2JqKSB7XG4gICAgICBjbGllbnQuZXhlY3V0ZShfb2JqIHx8IG9iaik7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgY2xpZW50LmV4ZWN1dGUob2JqKTtcbiAgfVxuXG4gIHJldHVybiAob2JqLmRlZmVycmVkKSA/IG9iai5kZWZlcnJlZC5wcm9taXNlIDogb2JqO1xufTtcblxuU3dhZ2dlckh0dHAucHJvdG90eXBlLmlzSW50ZXJuZXRFeHBsb3JlciA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGRldGVjdGVkSUUgPSBmYWxzZTtcblxuICBpZiAodHlwZW9mIG5hdmlnYXRvciAhPT0gJ3VuZGVmaW5lZCcgJiYgbmF2aWdhdG9yLnVzZXJBZ2VudCkge1xuICAgIHZhciBuYXYgPSBuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCk7XG5cbiAgICBpZiAobmF2LmluZGV4T2YoJ21zaWUnKSAhPT0gLTEpIHtcbiAgICAgIHZhciB2ZXJzaW9uID0gcGFyc2VJbnQobmF2LnNwbGl0KCdtc2llJylbMV0pO1xuXG4gICAgICBpZiAodmVyc2lvbiA8PSA4KSB7XG4gICAgICAgIGRldGVjdGVkSUUgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBkZXRlY3RlZElFO1xufTtcblxuSlF1ZXJ5SHR0cENsaWVudC5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uIChvYmopIHtcbiAgdmFyIGpxID0gdGhpcy5qUXVlcnkgfHwgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHdpbmRvdy5qUXVlcnkpO1xuICB2YXIgY2IgPSBvYmoub247XG4gIHZhciByZXF1ZXN0ID0gb2JqO1xuXG4gIGlmKHR5cGVvZiBqcSA9PT0gJ3VuZGVmaW5lZCcgfHwganEgPT09IGZhbHNlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBjb25maWd1cmF0aW9uISBKUXVlcnkgaXMgcmVxdWlyZWQgYnV0IG5vdCBhdmFpbGFibGUnKTtcbiAgfVxuXG4gIG9iai50eXBlID0gb2JqLm1ldGhvZDtcbiAgb2JqLmNhY2hlID0gb2JqLmpxdWVyeUFqYXhDYWNoZTtcbiAgb2JqLmRhdGEgPSBvYmouYm9keTtcbiAgZGVsZXRlIG9iai5qcXVlcnlBamF4Q2FjaGU7XG4gIGRlbGV0ZSBvYmoudXNlSlF1ZXJ5O1xuICBkZWxldGUgb2JqLmJvZHk7XG5cbiAgb2JqLmNvbXBsZXRlID0gZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgdmFyIGhlYWRlcnMgPSB7fTtcbiAgICB2YXIgaGVhZGVyQXJyYXkgPSByZXNwb25zZS5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKS5zcGxpdCgnXFxuJyk7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGhlYWRlckFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgdG9TcGxpdCA9IGhlYWRlckFycmF5W2ldLnRyaW0oKTtcblxuICAgICAgaWYgKHRvU3BsaXQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICB2YXIgc2VwYXJhdG9yID0gdG9TcGxpdC5pbmRleE9mKCc6Jyk7XG5cbiAgICAgIGlmIChzZXBhcmF0b3IgPT09IC0xKSB7XG4gICAgICAgIC8vIE5hbWUgYnV0IG5vIHZhbHVlIGluIHRoZSBoZWFkZXJcbiAgICAgICAgaGVhZGVyc1t0b1NwbGl0XSA9IG51bGw7XG5cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIHZhciBuYW1lID0gdG9TcGxpdC5zdWJzdHJpbmcoMCwgc2VwYXJhdG9yKS50cmltKCk7XG4gICAgICB2YXIgdmFsdWUgPSB0b1NwbGl0LnN1YnN0cmluZyhzZXBhcmF0b3IgKyAxKS50cmltKCk7XG5cbiAgICAgIGhlYWRlcnNbbmFtZV0gPSB2YWx1ZTtcbiAgICB9XG5cbiAgICB2YXIgb3V0ID0ge1xuICAgICAgdXJsOiByZXF1ZXN0LnVybCxcbiAgICAgIG1ldGhvZDogcmVxdWVzdC5tZXRob2QsXG4gICAgICBzdGF0dXM6IHJlc3BvbnNlLnN0YXR1cyxcbiAgICAgIHN0YXR1c1RleHQ6IHJlc3BvbnNlLnN0YXR1c1RleHQsXG4gICAgICBkYXRhOiByZXNwb25zZS5yZXNwb25zZVRleHQsXG4gICAgICBoZWFkZXJzOiBoZWFkZXJzXG4gICAgfTtcblxuICAgIHRyeSB7XG4gICAgICB2YXIgcG9zc2libGVPYmogPSAgcmVzcG9uc2UucmVzcG9uc2VKU09OIHx8IGpzeWFtbC5zYWZlTG9hZChyZXNwb25zZS5yZXNwb25zZVRleHQpO1xuICAgICAgb3V0Lm9iaiA9ICh0eXBlb2YgcG9zc2libGVPYmogPT09ICdzdHJpbmcnKSA/IHt9IDogcG9zc2libGVPYmo7XG4gICAgfSBjYXRjaCAoZXgpIHtcbiAgICAgIC8vIGRvIG5vdCBzZXQgb3V0Lm9ialxuICAgICAgaGVscGVycy5sb2coJ3VuYWJsZSB0byBwYXJzZSBKU09OL1lBTUwgY29udGVudCcpO1xuICAgIH1cblxuICAgIC8vIEkgY2FuIHRocm93LCBvciBwYXJzZSBudWxsP1xuICAgIG91dC5vYmogPSBvdXQub2JqIHx8IG51bGw7XG5cbiAgICBpZiAocmVzcG9uc2Uuc3RhdHVzID49IDIwMCAmJiByZXNwb25zZS5zdGF0dXMgPCAzMDApIHtcbiAgICAgIGNiLnJlc3BvbnNlKG91dCk7XG4gICAgfSBlbHNlIGlmIChyZXNwb25zZS5zdGF0dXMgPT09IDAgfHwgKHJlc3BvbnNlLnN0YXR1cyA+PSA0MDAgJiYgcmVzcG9uc2Uuc3RhdHVzIDwgNTk5KSkge1xuICAgICAgY2IuZXJyb3Iob3V0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGNiLnJlc3BvbnNlKG91dCk7XG4gICAgfVxuICB9O1xuXG4gIGpxLnN1cHBvcnQuY29ycyA9IHRydWU7XG5cbiAgcmV0dXJuIGpxLmFqYXgob2JqKTtcbn07XG5cblN1cGVyYWdlbnRIdHRwQ2xpZW50LnByb3RvdHlwZS5leGVjdXRlID0gZnVuY3Rpb24gKG9iaikge1xuICB2YXIgbWV0aG9kID0gb2JqLm1ldGhvZC50b0xvd2VyQ2FzZSgpO1xuICB2YXIgdGltZW91dCA9IG9iai50aW1lb3V0O1xuXG4gIGlmIChtZXRob2QgPT09ICdkZWxldGUnKSB7XG4gICAgbWV0aG9kID0gJ2RlbCc7XG4gIH1cbiAgdmFyIGhlYWRlcnMgPSBvYmouaGVhZGVycyB8fCB7fTtcblxuICB2YXIgciA9IHJlcXVlc3RbbWV0aG9kXShvYmoudXJsKTtcblxuICBpZiAob2JqLmNvbm5lY3Rpb25BZ2VudCkge1xuICAgIHIuYWdlbnQob2JqLmNvbm5lY3Rpb25BZ2VudCk7XG4gIH1cblxuICBpZiAodGltZW91dCkge1xuICAgIHIudGltZW91dCh0aW1lb3V0KTtcbiAgfVxuXG4gIGlmIChvYmouZW5hYmxlQ29va2llcykge1xuICAgIHIud2l0aENyZWRlbnRpYWxzKCk7XG4gIH1cblxuICB2YXIgYWNjZXB0ID0gb2JqLmhlYWRlcnMuQWNjZXB0O1xuXG4gIGlmKHRoaXMuYmluYXJ5UmVxdWVzdChhY2NlcHQpKSB7XG4gICAgci5vbigncmVxdWVzdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmKHRoaXMueGhyKSB7XG4gICAgICAgIHRoaXMueGhyLnJlc3BvbnNlVHlwZSA9ICdibG9iJztcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGlmKG9iai5ib2R5KSB7XG4gICAgaWYoXy5pc09iamVjdChvYmouYm9keSkpIHtcbiAgICAgIHZhciBjb250ZW50VHlwZSA9IG9iai5oZWFkZXJzWydDb250ZW50LVR5cGUnXSB8fCAnJztcbiAgICAgIGlmIChjb250ZW50VHlwZS5pbmRleE9mKCdtdWx0aXBhcnQvZm9ybS1kYXRhJykgPT09IDApIHtcbiAgICAgICAgZGVsZXRlIGhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddO1xuICAgICAgICBpZih7fS50b1N0cmluZy5hcHBseShvYmouYm9keSkgPT09ICdbb2JqZWN0IEZvcm1EYXRhXScpIHtcbiAgICAgICAgICByLnNlbmQob2JqLmJvZHkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHZhciBrZXluYW1lLCB2YWx1ZSwgdjtcbiAgICAgICAgICBmb3IgKGtleW5hbWUgaW4gb2JqLmJvZHkpIHtcbiAgICAgICAgICAgIHZhbHVlID0gb2JqLmJvZHlba2V5bmFtZV07XG4gICAgICAgICAgICBpZihBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgICAgICBmb3IodiBpbiB2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHIuZmllbGQoa2V5bmFtZSwgdik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICByLmZpZWxkKGtleW5hbWUsIHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKF8uaXNPYmplY3Qob2JqLmJvZHkpKSB7XG4gICAgICAgIC8vIG5vbiBtdWx0aXBhcnQvZm9ybS1kYXRhXG4gICAgICAgIG9iai5ib2R5ID0gSlNPTi5zdHJpbmdpZnkob2JqLmJvZHkpO1xuICAgICAgICByLnNlbmQob2JqLmJvZHkpO1xuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHIuc2VuZChvYmouYm9keSk7XG4gICAgfVxuICB9XG5cbiAgdmFyIG5hbWU7XG4gIGZvciAobmFtZSBpbiBoZWFkZXJzKSB7XG4gICAgci5zZXQobmFtZSwgaGVhZGVyc1tuYW1lXSk7XG4gIH1cblxuICBpZih0eXBlb2Ygci5idWZmZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICByLmJ1ZmZlcigpOyAvLyBmb3JjZSBzdXBlcmFnZW50IHRvIHBvcHVsYXRlIHJlcy50ZXh0IHdpdGggdGhlIHJhdyByZXNwb25zZSBkYXRhXG4gIH1cblxuICByLmVuZChmdW5jdGlvbiAoZXJyLCByZXMpIHtcbiAgICByZXMgPSByZXMgfHwge1xuICAgICAgc3RhdHVzOiAwLFxuICAgICAgaGVhZGVyczoge2Vycm9yOiAnbm8gcmVzcG9uc2UgZnJvbSBzZXJ2ZXInfVxuICAgIH07XG4gICAgdmFyIHJlc3BvbnNlID0ge1xuICAgICAgdXJsOiBvYmoudXJsLFxuICAgICAgbWV0aG9kOiBvYmoubWV0aG9kLFxuICAgICAgaGVhZGVyczogcmVzLmhlYWRlcnNcbiAgICB9O1xuICAgIHZhciBjYjtcblxuICAgIGlmICghZXJyICYmIHJlcy5lcnJvcikge1xuICAgICAgZXJyID0gcmVzLmVycm9yO1xuICAgIH1cblxuICAgIGlmIChlcnIgJiYgb2JqLm9uICYmIG9iai5vbi5lcnJvcikge1xuICAgICAgcmVzcG9uc2UuZXJyT2JqID0gZXJyO1xuICAgICAgcmVzcG9uc2Uuc3RhdHVzID0gcmVzID8gcmVzLnN0YXR1cyA6IDUwMDtcbiAgICAgIHJlc3BvbnNlLnN0YXR1c1RleHQgPSByZXMgPyByZXMudGV4dCA6IGVyci5tZXNzYWdlO1xuICAgICAgaWYgKHJlcy5oZWFkZXJzICYmIHJlcy5oZWFkZXJzWydjb250ZW50LXR5cGUnXSkge1xuICAgICAgICBpZiAocmVzLmhlYWRlcnNbJ2NvbnRlbnQtdHlwZSddLmluZGV4T2YoJ2FwcGxpY2F0aW9uL2pzb24nKSA+PSAwKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJlc3BvbnNlLm9iaiA9IEpTT04ucGFyc2UocmVzcG9uc2Uuc3RhdHVzVGV4dCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICByZXNwb25zZS5vYmogPSBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY2IgPSBvYmoub24uZXJyb3I7XG4gICAgfSBlbHNlIGlmIChyZXMgJiYgb2JqLm9uICYmIG9iai5vbi5yZXNwb25zZSkge1xuICAgICAgdmFyIHBvc3NpYmxlT2JqO1xuXG4gICAgICAvLyBBbHJlYWR5IHBhcnNlZCBieSBieSBzdXBlcmFnZW50P1xuICAgICAgaWYgKHJlcy5ib2R5ICYmIF8ua2V5cyhyZXMuYm9keSkubGVuZ3RoID4gMCkge1xuICAgICAgICBwb3NzaWJsZU9iaiA9IHJlcy5ib2R5O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBwb3NzaWJsZU9iaiA9IGpzeWFtbC5zYWZlTG9hZChyZXMudGV4dCk7XG4gICAgICAgICAgLy8gY2FuIHBhcnNlIGludG8gYSBzdHJpbmcuLi4gd2hpY2ggd2UgZG9uJ3QgbmVlZCBydW5uaW5nIGFyb3VuZCBpbiB0aGUgc3lzdGVtXG4gICAgICAgICAgcG9zc2libGVPYmogPSAodHlwZW9mIHBvc3NpYmxlT2JqID09PSAnc3RyaW5nJykgPyBudWxsIDogcG9zc2libGVPYmo7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBoZWxwZXJzLmxvZygnY2Fubm90IHBhcnNlIEpTT04vWUFNTCBjb250ZW50Jyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gbnVsbCBtZWFucyB3ZSBjYW4ndCBwYXJzZSBpbnRvIG9iamVjdFxuICAgICAgaWYodHlwZW9mIEJ1ZmZlciA9PT0gJ2Z1bmN0aW9uJyAmJiBCdWZmZXIuaXNCdWZmZXIocG9zc2libGVPYmopKSB7XG4gICAgICAgIHJlc3BvbnNlLmRhdGEgPSBwb3NzaWJsZU9iajtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICByZXNwb25zZS5vYmogPSAodHlwZW9mIHBvc3NpYmxlT2JqID09PSAnb2JqZWN0JykgPyBwb3NzaWJsZU9iaiA6IG51bGw7XG4gICAgICB9XG5cbiAgICAgIHJlc3BvbnNlLnN0YXR1cyA9IHJlcy5zdGF0dXM7XG4gICAgICByZXNwb25zZS5zdGF0dXNUZXh0ID0gcmVzLnRleHQ7XG4gICAgICBjYiA9IG9iai5vbi5yZXNwb25zZTtcbiAgICB9XG4gICAgaWYgKHJlcy54aHIgJiYgcmVzLnhoci5yZXNwb25zZSkge1xuICAgICAgcmVzcG9uc2UuZGF0YSA9IHJlcy54aHIucmVzcG9uc2U7XG4gICAgfVxuICAgIGVsc2UgaWYoIXJlc3BvbnNlLmRhdGEpIHtcbiAgICAgIHJlc3BvbnNlLmRhdGEgPSByZXNwb25zZS5zdGF0dXNUZXh0O1xuICAgIH1cblxuICAgIGlmIChjYikge1xuICAgICAgY2IocmVzcG9uc2UpO1xuICAgIH1cbiAgfSk7XG59O1xuXG5TdXBlcmFnZW50SHR0cENsaWVudC5wcm90b3R5cGUuIGJpbmFyeVJlcXVlc3QgPSBmdW5jdGlvbiAoYWNjZXB0KSB7XG4gIGlmKCFhY2NlcHQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuICgvXmltYWdlL2kpLnRlc3QoYWNjZXB0KVxuICAgIHx8ICgvXmFwcGxpY2F0aW9uXFwvcGRmLykudGVzdChhY2NlcHQpXG4gICAgfHwgKC9eYXBwbGljYXRpb25cXC9vY3RldC1zdHJlYW0vKS50ZXN0KGFjY2VwdCk7XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIpXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldDp1dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbXhwWWk5b2RIUndMbXB6SWwwc0ltNWhiV1Z6SWpwYlhTd2liV0Z3Y0dsdVozTWlPaUk3UVVGQlFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJJaXdpWm1sc1pTSTZJbWRsYm1WeVlYUmxaQzVxY3lJc0luTnZkWEpqWlZKdmIzUWlPaUlpTENKemIzVnlZMlZ6UTI5dWRHVnVkQ0k2V3lJbmRYTmxJSE4wY21samRDYzdYRzVjYm5aaGNpQm9aV3h3WlhKeklEMGdjbVZ4ZFdseVpTZ25MaTlvWld4d1pYSnpKeWs3WEc1MllYSWdjbVZ4ZFdWemRDQTlJSEpsY1hWcGNtVW9KM04xY0dWeVlXZGxiblFuS1R0Y2JuWmhjaUJxYzNsaGJXd2dQU0J5WlhGMWFYSmxLQ2RxY3kxNVlXMXNKeWs3WEc1MllYSWdYeUE5SUh0Y2JpQWdhWE5QWW1wbFkzUTZJSEpsY1hWcGNtVW9KMnh2WkdGemFDMWpiMjF3WVhRdmJHRnVaeTlwYzA5aWFtVmpkQ2NwTEZ4dUlDQnJaWGx6T2lCeVpYRjFhWEpsS0Nkc2IyUmhjMmd0WTI5dGNHRjBMMjlpYW1WamRDOXJaWGx6SnlsY2JuMDdYRzVjYmk4cVhHNGdLaUJLVVhWbGNubElkSFJ3UTJ4cFpXNTBJR2x6SUdFZ2JHbG5hSFF0ZDJWcFoyaDBMQ0J1YjJSbElHOXlJR0p5YjNkelpYSWdTRlJVVUNCamJHbGxiblJjYmlBcUwxeHVkbUZ5SUVwUmRXVnllVWgwZEhCRGJHbGxiblFnUFNCbWRXNWpkR2x2YmlBb0tTQjdYRzRnSUhSb2FYTXVkSGx3WlNBOUlDZEtVWFZsY25sSWRIUndRMnhwWlc1MEp6dGNibjA3WEc1Y2JpOHFYRzRnS2lCVGRYQmxjbUZuWlc1MFNIUjBjRU5zYVdWdWRDQnBjeUJoSUd4cFoyaDBMWGRsYVdkb2RDd2dibTlrWlNCdmNpQmljbTkzYzJWeUlFaFVWRkFnWTJ4cFpXNTBYRzRnS2k5Y2JuWmhjaUJUZFhCbGNtRm5aVzUwU0hSMGNFTnNhV1Z1ZENBOUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ2RHaHBjeTUwZVhCbElEMGdKMU4xY0dWeVlXZGxiblJJZEhSd1EyeHBaVzUwSnp0Y2JuMDdYRzVjYmk4cUtseHVJQ29nVTNkaFoyZGxja2gwZEhBZ2FYTWdZU0IzY21Gd2NHVnlJR1p2Y2lCbGVHVmpkWFJwYm1jZ2NtVnhkV1Z6ZEhOY2JpQXFMMXh1ZG1GeUlGTjNZV2RuWlhKSWRIUndJRDBnYlc5a2RXeGxMbVY0Y0c5eWRITWdQU0JtZFc1amRHbHZiaUFvS1NCN2ZUdGNibHh1VTNkaFoyZGxja2gwZEhBdWNISnZkRzkwZVhCbExtVjRaV04xZEdVZ1BTQm1kVzVqZEdsdmJpQW9iMkpxTENCdmNIUnpLU0I3WEc0Z0lIWmhjaUJqYkdsbGJuUTdYRzVjYmlBZ2FXWW9iM0IwY3lBbUppQnZjSFJ6TG1Oc2FXVnVkQ2tnZTF4dUlDQWdJR05zYVdWdWRDQTlJRzl3ZEhNdVkyeHBaVzUwTzF4dUlDQjlYRzRnSUdWc2MyVWdlMXh1SUNBZ0lHTnNhV1Z1ZENBOUlHNWxkeUJUZFhCbGNtRm5aVzUwU0hSMGNFTnNhV1Z1ZENodmNIUnpLVHRjYmlBZ2ZWeHVJQ0JqYkdsbGJuUXViM0IwY3lBOUlHOXdkSE1nZkh3Z2UzMDdYRzVjYmlBZ2FXWWdLRzl3ZEhNZ0ppWWdiM0IwY3k1eVpYRjFaWE4wUVdkbGJuUXBJSHRjYmlBZ0lDQnlaWEYxWlhOMElEMGdiM0IwY3k1eVpYRjFaWE4wUVdkbGJuUTdYRzRnSUgxY2JseHVJQ0F2THlCc1pXZGhZM2tnYzNWd2NHOXlkRnh1SUNCMllYSWdhR0Z6U2xGMVpYSjVJRDBnWm1Gc2MyVTdYRzRnSUdsbUtIUjVjR1Z2WmlCM2FXNWtiM2NnSVQwOUlDZDFibVJsWm1sdVpXUW5LU0I3WEc0Z0lDQWdhV1lvZEhsd1pXOW1JSGRwYm1SdmR5NXFVWFZsY25rZ0lUMDlJQ2QxYm1SbFptbHVaV1FuS1NCN1hHNGdJQ0FnSUNCb1lYTktVWFZsY25rZ1BTQjBjblZsTzF4dUlDQWdJSDFjYmlBZ2ZWeHVJQ0F2THlCUFVGUkpUMDVUSUhOMWNIQnZjblJjYmlBZ2FXWW9iMkpxTG0xbGRHaHZaQzUwYjB4dmQyVnlRMkZ6WlNncElEMDlQU0FuYjNCMGFXOXVjeWNnSmlZZ1kyeHBaVzUwTG5SNWNHVWdQVDA5SUNkVGRYQmxjbUZuWlc1MFNIUjBjRU5zYVdWdWRDY3BJSHRjYmlBZ0lDQnNiMmNvSjJadmNtTnBibWNnYWxGMVpYSjVJR0Z6SUU5UVZFbFBUbE1nWVhKbElHNXZkQ0J6ZFhCd2IzSjBaV1FnWW5rZ1UzVndaWEpCWjJWdWRDY3BPMXh1SUNBZ0lHOWlhaTUxYzJWS1VYVmxjbmtnUFNCMGNuVmxPMXh1SUNCOVhHNGdJR2xtS0hSb2FYTXVhWE5KYm5SbGNtNWxkRVY0Y0d4dmNtVnlLQ2tnSmlZZ0tHOWlhaTUxYzJWS1VYVmxjbmtnUFQwOUlHWmhiSE5sSUh4OElDRm9ZWE5LVVhWbGNua2dLU2tnZTF4dUlDQWdJSFJvY205M0lHNWxkeUJGY25KdmNpZ25WVzV6ZFhCd2IzSjBaV1FnWTI5dVptbG5kWEpoZEdsdmJpRWdTbEYxWlhKNUlHbHpJSEpsY1hWcGNtVmtJR0oxZENCdWIzUWdZWFpoYVd4aFlteGxKeWs3WEc0Z0lIMWNiaUFnYVdZZ0tDaHZZbW9nSmlZZ2IySnFMblZ6WlVwUmRXVnllU0E5UFQwZ2RISjFaU2tnZkh3Z2RHaHBjeTVwYzBsdWRHVnlibVYwUlhod2JHOXlaWElvS1NBbUppQm9ZWE5LVVhWbGNua3BJSHRjYmlBZ0lDQmpiR2xsYm5RZ1BTQnVaWGNnU2xGMVpYSjVTSFIwY0VOc2FXVnVkQ2h2Y0hSektUdGNiaUFnZlZ4dVhHNGdJSFpoY2lCemRXTmpaWE56SUQwZ2IySnFMbTl1TG5KbGMzQnZibk5sTzF4dUlDQjJZWElnWlhKeWIzSWdQU0J2WW1vdWIyNHVaWEp5YjNJN1hHNWNiaUFnZG1GeUlISmxjWFZsYzNSSmJuUmxjbU5sY0hSdmNpQTlJR1oxYm1OMGFXOXVLR1JoZEdFcElIdGNiaUFnSUNCcFppaHZjSFJ6SUNZbUlHOXdkSE11Y21WeGRXVnpkRWx1ZEdWeVkyVndkRzl5S1NCN1hHNGdJQ0FnSUNCa1lYUmhJRDBnYjNCMGN5NXlaWEYxWlhOMFNXNTBaWEpqWlhCMGIzSXVZWEJ3Ykhrb1pHRjBZU2s3WEc0Z0lDQWdmVnh1SUNBZ0lISmxkSFZ5YmlCa1lYUmhPMXh1SUNCOU8xeHVYRzRnSUhaaGNpQnlaWE53YjI1elpVbHVkR1Z5WTJWd2RHOXlJRDBnWm5WdVkzUnBiMjRvWkdGMFlTa2dlMXh1SUNBZ0lHbG1LRzl3ZEhNZ0ppWWdiM0IwY3k1eVpYTndiMjV6WlVsdWRHVnlZMlZ3ZEc5eUtTQjdYRzRnSUNBZ0lDQmtZWFJoSUQwZ2IzQjBjeTV5WlhOd2IyNXpaVWx1ZEdWeVkyVndkRzl5TG1Gd2NHeDVLR1JoZEdFc0lGdHZZbXBkS1R0Y2JpQWdJQ0I5WEc0Z0lDQWdjbVYwZFhKdUlITjFZMk5sYzNNb1pHRjBZU2s3WEc0Z0lIMDdYRzVjYmlBZ2RtRnlJR1Z5Y205eVNXNTBaWEpqWlhCMGIzSWdQU0JtZFc1amRHbHZiaWhrWVhSaEtTQjdYRzRnSUNBZ2FXWW9iM0IwY3lBbUppQnZjSFJ6TG5KbGMzQnZibk5sU1c1MFpYSmpaWEIwYjNJcElIdGNiaUFnSUNBZ0lHUmhkR0VnUFNCdmNIUnpMbkpsYzNCdmJuTmxTVzUwWlhKalpYQjBiM0l1WVhCd2JIa29aR0YwWVN3Z1cyOWlhbDBwTzF4dUlDQWdJSDFjYmlBZ0lDQmxjbkp2Y2loa1lYUmhLVHRjYmlBZ2ZUdGNibHh1SUNCdlltb3ViMjR1WlhKeWIzSWdQU0JtZFc1amRHbHZiaWhrWVhSaEtTQjdYRzRnSUNBZ1pYSnliM0pKYm5SbGNtTmxjSFJ2Y2loa1lYUmhLVHRjYmlBZ2ZUdGNibHh1SUNCdlltb3ViMjR1Y21WemNHOXVjMlVnUFNCbWRXNWpkR2x2Ymloa1lYUmhLU0I3WEc0Z0lDQWdhV1lvWkdGMFlTQW1KaUJrWVhSaExuTjBZWFIxY3lBK1BTQTBNREFwSUh0Y2JpQWdJQ0FnSUdWeWNtOXlTVzUwWlhKalpYQjBiM0lvWkdGMFlTazdYRzRnSUNBZ2ZWeHVJQ0FnSUdWc2MyVWdlMXh1SUNBZ0lDQWdjbVZ6Y0c5dWMyVkpiblJsY21ObGNIUnZjaWhrWVhSaEtUdGNiaUFnSUNCOVhHNGdJSDA3WEc1Y2JpQWdhV1lnS0Y4dWFYTlBZbXBsWTNRb2IySnFLU0FtSmlCZkxtbHpUMkpxWldOMEtHOWlhaTVpYjJSNUtTa2dlMXh1SUNBZ0lDOHZJSE53WldOcFlXd2djSEp2WTJWemMybHVaeUJtYjNJZ1ptbHNaU0IxY0d4dllXUnpJSFpwWVNCcWNYVmxjbmxjYmlBZ0lDQnBaaUFvYjJKcUxtSnZaSGt1ZEhsd1pTQW1KaUJ2WW1vdVltOWtlUzUwZVhCbElEMDlQU0FuWm05eWJVUmhkR0VuS1h0Y2JpQWdJQ0FnSUdsbUtHOXdkSE11ZFhObFNsRjFaWEo1S1NCN1hHNGdJQ0FnSUNBZ0lHOWlhaTVqYjI1MFpXNTBWSGx3WlNBOUlHWmhiSE5sTzF4dUlDQWdJQ0FnSUNCdlltb3VjSEp2WTJWemMwUmhkR0VnUFNCbVlXeHpaVHRjYmlBZ0lDQWdJQ0FnWkdWc1pYUmxJRzlpYWk1b1pXRmtaWEp6V3lkRGIyNTBaVzUwTFZSNWNHVW5YVHRjYmlBZ0lDQWdJSDFjYmlBZ0lDQjlYRzRnSUgxY2JseHVJQ0J2WW1vZ1BTQnlaWEYxWlhOMFNXNTBaWEpqWlhCMGIzSW9iMkpxS1NCOGZDQnZZbW83WEc0Z0lHbG1JQ2h2WW1vdVltVm1iM0psVTJWdVpDa2dlMXh1SUNBZ0lHOWlhaTVpWldadmNtVlRaVzVrS0daMWJtTjBhVzl1S0Y5dlltb3BJSHRjYmlBZ0lDQWdJR05zYVdWdWRDNWxlR1ZqZFhSbEtGOXZZbW9nZkh3Z2IySnFLVHRjYmlBZ0lDQjlLVHRjYmlBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0JqYkdsbGJuUXVaWGhsWTNWMFpTaHZZbW9wTzF4dUlDQjlYRzVjYmlBZ2NtVjBkWEp1SUNodlltb3VaR1ZtWlhKeVpXUXBJRDhnYjJKcUxtUmxabVZ5Y21Wa0xuQnliMjFwYzJVZ09pQnZZbW83WEc1OU8xeHVYRzVUZDJGbloyVnlTSFIwY0M1d2NtOTBiM1I1Y0dVdWFYTkpiblJsY201bGRFVjRjR3h2Y21WeUlEMGdablZ1WTNScGIyNGdLQ2tnZTF4dUlDQjJZWElnWkdWMFpXTjBaV1JKUlNBOUlHWmhiSE5sTzF4dVhHNGdJR2xtSUNoMGVYQmxiMllnYm1GMmFXZGhkRzl5SUNFOVBTQW5kVzVrWldacGJtVmtKeUFtSmlCdVlYWnBaMkYwYjNJdWRYTmxja0ZuWlc1MEtTQjdYRzRnSUNBZ2RtRnlJRzVoZGlBOUlHNWhkbWxuWVhSdmNpNTFjMlZ5UVdkbGJuUXVkRzlNYjNkbGNrTmhjMlVvS1R0Y2JseHVJQ0FnSUdsbUlDaHVZWFl1YVc1a1pYaFBaaWduYlhOcFpTY3BJQ0U5UFNBdE1Ta2dlMXh1SUNBZ0lDQWdkbUZ5SUhabGNuTnBiMjRnUFNCd1lYSnpaVWx1ZENodVlYWXVjM0JzYVhRb0oyMXphV1VuS1ZzeFhTazdYRzVjYmlBZ0lDQWdJR2xtSUNoMlpYSnphVzl1SUR3OUlEZ3BJSHRjYmlBZ0lDQWdJQ0FnWkdWMFpXTjBaV1JKUlNBOUlIUnlkV1U3WEc0Z0lDQWdJQ0I5WEc0Z0lDQWdmVnh1SUNCOVhHNWNiaUFnY21WMGRYSnVJR1JsZEdWamRHVmtTVVU3WEc1OU8xeHVYRzVLVVhWbGNubElkSFJ3UTJ4cFpXNTBMbkJ5YjNSdmRIbHdaUzVsZUdWamRYUmxJRDBnWm5WdVkzUnBiMjRnS0c5aWFpa2dlMXh1SUNCMllYSWdhbkVnUFNCMGFHbHpMbXBSZFdWeWVTQjhmQ0FvZEhsd1pXOW1JSGRwYm1SdmR5QWhQVDBnSjNWdVpHVm1hVzVsWkNjZ0ppWWdkMmx1Wkc5M0xtcFJkV1Z5ZVNrN1hHNGdJSFpoY2lCallpQTlJRzlpYWk1dmJqdGNiaUFnZG1GeUlISmxjWFZsYzNRZ1BTQnZZbW83WEc1Y2JpQWdhV1lvZEhsd1pXOW1JR3B4SUQwOVBTQW5kVzVrWldacGJtVmtKeUI4ZkNCcWNTQTlQVDBnWm1Gc2MyVXBJSHRjYmlBZ0lDQjBhSEp2ZHlCdVpYY2dSWEp5YjNJb0oxVnVjM1Z3Y0c5eWRHVmtJR052Ym1acFozVnlZWFJwYjI0aElFcFJkV1Z5ZVNCcGN5QnlaWEYxYVhKbFpDQmlkWFFnYm05MElHRjJZV2xzWVdKc1pTY3BPMXh1SUNCOVhHNWNiaUFnYjJKcUxuUjVjR1VnUFNCdlltb3ViV1YwYUc5a08xeHVJQ0J2WW1vdVkyRmphR1VnUFNCdlltb3VhbkYxWlhKNVFXcGhlRU5oWTJobE8xeHVJQ0J2WW1vdVpHRjBZU0E5SUc5aWFpNWliMlI1TzF4dUlDQmtaV3hsZEdVZ2IySnFMbXB4ZFdWeWVVRnFZWGhEWVdOb1pUdGNiaUFnWkdWc1pYUmxJRzlpYWk1MWMyVktVWFZsY25rN1hHNGdJR1JsYkdWMFpTQnZZbW91WW05a2VUdGNibHh1SUNCdlltb3VZMjl0Y0d4bGRHVWdQU0JtZFc1amRHbHZiaUFvY21WemNHOXVjMlVwSUh0Y2JpQWdJQ0IyWVhJZ2FHVmhaR1Z5Y3lBOUlIdDlPMXh1SUNBZ0lIWmhjaUJvWldGa1pYSkJjbkpoZVNBOUlISmxjM0J2Ym5ObExtZGxkRUZzYkZKbGMzQnZibk5sU0dWaFpHVnljeWdwTG5Od2JHbDBLQ2RjWEc0bktUdGNibHh1SUNBZ0lHWnZjaUFvZG1GeUlHa2dQU0F3T3lCcElEd2dhR1ZoWkdWeVFYSnlZWGt1YkdWdVozUm9PeUJwS3lzcElIdGNiaUFnSUNBZ0lIWmhjaUIwYjFOd2JHbDBJRDBnYUdWaFpHVnlRWEp5WVhsYmFWMHVkSEpwYlNncE8xeHVYRzRnSUNBZ0lDQnBaaUFvZEc5VGNHeHBkQzVzWlc1bmRHZ2dQVDA5SURBcElIdGNiaUFnSUNBZ0lDQWdZMjl1ZEdsdWRXVTdYRzRnSUNBZ0lDQjlYRzVjYmlBZ0lDQWdJSFpoY2lCelpYQmhjbUYwYjNJZ1BTQjBiMU53YkdsMExtbHVaR1Y0VDJZb0p6b25LVHRjYmx4dUlDQWdJQ0FnYVdZZ0tITmxjR0Z5WVhSdmNpQTlQVDBnTFRFcElIdGNiaUFnSUNBZ0lDQWdMeThnVG1GdFpTQmlkWFFnYm04Z2RtRnNkV1VnYVc0Z2RHaGxJR2hsWVdSbGNseHVJQ0FnSUNBZ0lDQm9aV0ZrWlhKelczUnZVM0JzYVhSZElEMGdiblZzYkR0Y2JseHVJQ0FnSUNBZ0lDQmpiMjUwYVc1MVpUdGNiaUFnSUNBZ0lIMWNibHh1SUNBZ0lDQWdkbUZ5SUc1aGJXVWdQU0IwYjFOd2JHbDBMbk4xWW5OMGNtbHVaeWd3TENCelpYQmhjbUYwYjNJcExuUnlhVzBvS1R0Y2JpQWdJQ0FnSUhaaGNpQjJZV3gxWlNBOUlIUnZVM0JzYVhRdWMzVmljM1J5YVc1bktITmxjR0Z5WVhSdmNpQXJJREVwTG5SeWFXMG9LVHRjYmx4dUlDQWdJQ0FnYUdWaFpHVnljMXR1WVcxbFhTQTlJSFpoYkhWbE8xeHVJQ0FnSUgxY2JseHVJQ0FnSUhaaGNpQnZkWFFnUFNCN1hHNGdJQ0FnSUNCMWNtdzZJSEpsY1hWbGMzUXVkWEpzTEZ4dUlDQWdJQ0FnYldWMGFHOWtPaUJ5WlhGMVpYTjBMbTFsZEdodlpDeGNiaUFnSUNBZ0lITjBZWFIxY3pvZ2NtVnpjRzl1YzJVdWMzUmhkSFZ6TEZ4dUlDQWdJQ0FnYzNSaGRIVnpWR1Y0ZERvZ2NtVnpjRzl1YzJVdWMzUmhkSFZ6VkdWNGRDeGNiaUFnSUNBZ0lHUmhkR0U2SUhKbGMzQnZibk5sTG5KbGMzQnZibk5sVkdWNGRDeGNiaUFnSUNBZ0lHaGxZV1JsY25NNklHaGxZV1JsY25OY2JpQWdJQ0I5TzF4dVhHNGdJQ0FnZEhKNUlIdGNiaUFnSUNBZ0lIWmhjaUJ3YjNOemFXSnNaVTlpYWlBOUlDQnlaWE53YjI1elpTNXlaWE53YjI1elpVcFRUMDRnZkh3Z2FuTjVZVzFzTG5OaFptVk1iMkZrS0hKbGMzQnZibk5sTG5KbGMzQnZibk5sVkdWNGRDazdYRzRnSUNBZ0lDQnZkWFF1YjJKcUlEMGdLSFI1Y0dWdlppQndiM056YVdKc1pVOWlhaUE5UFQwZ0ozTjBjbWx1WnljcElEOGdlMzBnT2lCd2IzTnphV0pzWlU5aWFqdGNiaUFnSUNCOUlHTmhkR05vSUNobGVDa2dlMXh1SUNBZ0lDQWdMeThnWkc4Z2JtOTBJSE5sZENCdmRYUXViMkpxWEc0Z0lDQWdJQ0JvWld4d1pYSnpMbXh2WnlnbmRXNWhZbXhsSUhSdklIQmhjbk5sSUVwVFQwNHZXVUZOVENCamIyNTBaVzUwSnlrN1hHNGdJQ0FnZlZ4dVhHNGdJQ0FnTHk4Z1NTQmpZVzRnZEdoeWIzY3NJRzl5SUhCaGNuTmxJRzUxYkd3L1hHNGdJQ0FnYjNWMExtOWlhaUE5SUc5MWRDNXZZbW9nZkh3Z2JuVnNiRHRjYmx4dUlDQWdJR2xtSUNoeVpYTndiMjV6WlM1emRHRjBkWE1nUGowZ01qQXdJQ1ltSUhKbGMzQnZibk5sTG5OMFlYUjFjeUE4SURNd01Da2dlMXh1SUNBZ0lDQWdZMkl1Y21WemNHOXVjMlVvYjNWMEtUdGNiaUFnSUNCOUlHVnNjMlVnYVdZZ0tISmxjM0J2Ym5ObExuTjBZWFIxY3lBOVBUMGdNQ0I4ZkNBb2NtVnpjRzl1YzJVdWMzUmhkSFZ6SUQ0OUlEUXdNQ0FtSmlCeVpYTndiMjV6WlM1emRHRjBkWE1nUENBMU9Ua3BLU0I3WEc0Z0lDQWdJQ0JqWWk1bGNuSnZjaWh2ZFhRcE8xeHVJQ0FnSUgwZ1pXeHpaU0I3WEc0Z0lDQWdJQ0J5WlhSMWNtNGdZMkl1Y21WemNHOXVjMlVvYjNWMEtUdGNiaUFnSUNCOVhHNGdJSDA3WEc1Y2JpQWdhbkV1YzNWd2NHOXlkQzVqYjNKeklEMGdkSEoxWlR0Y2JseHVJQ0J5WlhSMWNtNGdhbkV1WVdwaGVDaHZZbW9wTzF4dWZUdGNibHh1VTNWd1pYSmhaMlZ1ZEVoMGRIQkRiR2xsYm5RdWNISnZkRzkwZVhCbExtVjRaV04xZEdVZ1BTQm1kVzVqZEdsdmJpQW9iMkpxS1NCN1hHNGdJSFpoY2lCdFpYUm9iMlFnUFNCdlltb3ViV1YwYUc5a0xuUnZURzkzWlhKRFlYTmxLQ2s3WEc0Z0lIWmhjaUIwYVcxbGIzVjBJRDBnYjJKcUxuUnBiV1Z2ZFhRN1hHNWNiaUFnYVdZZ0tHMWxkR2h2WkNBOVBUMGdKMlJsYkdWMFpTY3BJSHRjYmlBZ0lDQnRaWFJvYjJRZ1BTQW5aR1ZzSnp0Y2JpQWdmVnh1SUNCMllYSWdhR1ZoWkdWeWN5QTlJRzlpYWk1b1pXRmtaWEp6SUh4OElIdDlPMXh1WEc0Z0lIWmhjaUJ5SUQwZ2NtVnhkV1Z6ZEZ0dFpYUm9iMlJkS0c5aWFpNTFjbXdwTzF4dVhHNGdJR2xtSUNodlltb3VZMjl1Ym1WamRHbHZia0ZuWlc1MEtTQjdYRzRnSUNBZ2NpNWhaMlZ1ZENodlltb3VZMjl1Ym1WamRHbHZia0ZuWlc1MEtUdGNiaUFnZlZ4dVhHNGdJR2xtSUNoMGFXMWxiM1YwS1NCN1hHNGdJQ0FnY2k1MGFXMWxiM1YwS0hScGJXVnZkWFFwTzF4dUlDQjlYRzVjYmlBZ2FXWWdLRzlpYWk1bGJtRmliR1ZEYjI5cmFXVnpLU0I3WEc0Z0lDQWdjaTUzYVhSb1EzSmxaR1Z1ZEdsaGJITW9LVHRjYmlBZ2ZWeHVYRzRnSUhaaGNpQmhZMk5sY0hRZ1BTQnZZbW91YUdWaFpHVnljeTVCWTJObGNIUTdYRzVjYmlBZ2FXWW9kR2hwY3k1aWFXNWhjbmxTWlhGMVpYTjBLR0ZqWTJWd2RDa3BJSHRjYmlBZ0lDQnlMbTl1S0NkeVpYRjFaWE4wSnl3Z1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdhV1lvZEdocGN5NTRhSElwSUh0Y2JpQWdJQ0FnSUNBZ2RHaHBjeTU0YUhJdWNtVnpjRzl1YzJWVWVYQmxJRDBnSjJKc2IySW5PMXh1SUNBZ0lDQWdmVnh1SUNBZ0lIMHBPMXh1SUNCOVhHNWNiaUFnYVdZb2IySnFMbUp2WkhrcElIdGNiaUFnSUNCcFppaGZMbWx6VDJKcVpXTjBLRzlpYWk1aWIyUjVLU2tnZTF4dUlDQWdJQ0FnZG1GeUlHTnZiblJsYm5SVWVYQmxJRDBnYjJKcUxtaGxZV1JsY25OYkowTnZiblJsYm5RdFZIbHdaU2RkSUh4OElDY25PMXh1SUNBZ0lDQWdhV1lnS0dOdmJuUmxiblJVZVhCbExtbHVaR1Y0VDJZb0oyMTFiSFJwY0dGeWRDOW1iM0p0TFdSaGRHRW5LU0E5UFQwZ01Da2dlMXh1SUNBZ0lDQWdJQ0JrWld4bGRHVWdhR1ZoWkdWeWMxc25RMjl1ZEdWdWRDMVVlWEJsSjEwN1hHNGdJQ0FnSUNBZ0lHbG1LSHQ5TG5SdlUzUnlhVzVuTG1Gd2NHeDVLRzlpYWk1aWIyUjVLU0E5UFQwZ0oxdHZZbXBsWTNRZ1JtOXliVVJoZEdGZEp5a2dlMXh1SUNBZ0lDQWdJQ0FnSUhJdWMyVnVaQ2h2WW1vdVltOWtlU2s3WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ1pXeHpaU0I3WEc0Z0lDQWdJQ0FnSUNBZ2RtRnlJR3RsZVc1aGJXVXNJSFpoYkhWbExDQjJPMXh1SUNBZ0lDQWdJQ0FnSUdadmNpQW9hMlY1Ym1GdFpTQnBiaUJ2WW1vdVltOWtlU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdkbUZzZFdVZ1BTQnZZbW91WW05a2VWdHJaWGx1WVcxbFhUdGNiaUFnSUNBZ0lDQWdJQ0FnSUdsbUtFRnljbUY1TG1selFYSnlZWGtvZG1Gc2RXVXBLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJR1p2Y2loMklHbHVJSFpoYkhWbEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdjaTVtYVdWc1pDaHJaWGx1WVcxbExDQjJLVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQWdJQ0FnWld4elpTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lISXVabWxsYkdRb2EyVjVibUZ0WlN3Z2RtRnNkV1VwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ1pXeHpaU0JwWmlBb1h5NXBjMDlpYW1WamRDaHZZbW91WW05a2VTa3BJSHRjYmlBZ0lDQWdJQ0FnTHk4Z2JtOXVJRzExYkhScGNHRnlkQzltYjNKdExXUmhkR0ZjYmlBZ0lDQWdJQ0FnYjJKcUxtSnZaSGtnUFNCS1UwOU9Mbk4wY21sdVoybG1lU2h2WW1vdVltOWtlU2s3WEc0Z0lDQWdJQ0FnSUhJdWMyVnVaQ2h2WW1vdVltOWtlU2s3WEc0Z0lDQWdJQ0I5WEc0Z0lDQWdmVnh1SUNBZ0lHVnNjMlVnZTF4dUlDQWdJQ0FnY2k1elpXNWtLRzlpYWk1aWIyUjVLVHRjYmlBZ0lDQjlYRzRnSUgxY2JseHVJQ0IyWVhJZ2JtRnRaVHRjYmlBZ1ptOXlJQ2h1WVcxbElHbHVJR2hsWVdSbGNuTXBJSHRjYmlBZ0lDQnlMbk5sZENodVlXMWxMQ0JvWldGa1pYSnpXMjVoYldWZEtUdGNiaUFnZlZ4dVhHNGdJR2xtS0hSNWNHVnZaaUJ5TG1KMVptWmxjaUE5UFQwZ0oyWjFibU4wYVc5dUp5a2dlMXh1SUNBZ0lISXVZblZtWm1WeUtDazdJQzh2SUdadmNtTmxJSE4xY0dWeVlXZGxiblFnZEc4Z2NHOXdkV3hoZEdVZ2NtVnpMblJsZUhRZ2QybDBhQ0IwYUdVZ2NtRjNJSEpsYzNCdmJuTmxJR1JoZEdGY2JpQWdmVnh1WEc0Z0lISXVaVzVrS0daMWJtTjBhVzl1SUNobGNuSXNJSEpsY3lrZ2UxeHVJQ0FnSUhKbGN5QTlJSEpsY3lCOGZDQjdYRzRnSUNBZ0lDQnpkR0YwZFhNNklEQXNYRzRnSUNBZ0lDQm9aV0ZrWlhKek9pQjdaWEp5YjNJNklDZHVieUJ5WlhOd2IyNXpaU0JtY205dElITmxjblpsY2lkOVhHNGdJQ0FnZlR0Y2JpQWdJQ0IyWVhJZ2NtVnpjRzl1YzJVZ1BTQjdYRzRnSUNBZ0lDQjFjbXc2SUc5aWFpNTFjbXdzWEc0Z0lDQWdJQ0J0WlhSb2IyUTZJRzlpYWk1dFpYUm9iMlFzWEc0Z0lDQWdJQ0JvWldGa1pYSnpPaUJ5WlhNdWFHVmhaR1Z5YzF4dUlDQWdJSDA3WEc0Z0lDQWdkbUZ5SUdOaU8xeHVYRzRnSUNBZ2FXWWdLQ0ZsY25JZ0ppWWdjbVZ6TG1WeWNtOXlLU0I3WEc0Z0lDQWdJQ0JsY25JZ1BTQnlaWE11WlhKeWIzSTdYRzRnSUNBZ2ZWeHVYRzRnSUNBZ2FXWWdLR1Z5Y2lBbUppQnZZbW91YjI0Z0ppWWdiMkpxTG05dUxtVnljbTl5S1NCN1hHNGdJQ0FnSUNCeVpYTndiMjV6WlM1bGNuSlBZbW9nUFNCbGNuSTdYRzRnSUNBZ0lDQnlaWE53YjI1elpTNXpkR0YwZFhNZ1BTQnlaWE1nUHlCeVpYTXVjM1JoZEhWeklEb2dOVEF3TzF4dUlDQWdJQ0FnY21WemNHOXVjMlV1YzNSaGRIVnpWR1Y0ZENBOUlISmxjeUEvSUhKbGN5NTBaWGgwSURvZ1pYSnlMbTFsYzNOaFoyVTdYRzRnSUNBZ0lDQnBaaUFvY21WekxtaGxZV1JsY25NZ0ppWWdjbVZ6TG1obFlXUmxjbk5iSjJOdmJuUmxiblF0ZEhsd1pTZGRLU0I3WEc0Z0lDQWdJQ0FnSUdsbUlDaHlaWE11YUdWaFpHVnljMXNuWTI5dWRHVnVkQzEwZVhCbEoxMHVhVzVrWlhoUFppZ25ZWEJ3YkdsallYUnBiMjR2YW5OdmJpY3BJRDQ5SURBcElIdGNiaUFnSUNBZ0lDQWdJQ0IwY25rZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WemNHOXVjMlV1YjJKcUlEMGdTbE5QVGk1d1lYSnpaU2h5WlhOd2IyNXpaUzV6ZEdGMGRYTlVaWGgwS1R0Y2JpQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJQ0FnWTJGMFkyZ2dLR1VwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEpsYzNCdmJuTmxMbTlpYWlBOUlHNTFiR3c3WEc0Z0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQjlYRzRnSUNBZ0lDQmpZaUE5SUc5aWFpNXZiaTVsY25KdmNqdGNiaUFnSUNCOUlHVnNjMlVnYVdZZ0tISmxjeUFtSmlCdlltb3ViMjRnSmlZZ2IySnFMbTl1TG5KbGMzQnZibk5sS1NCN1hHNGdJQ0FnSUNCMllYSWdjRzl6YzJsaWJHVlBZbW83WEc1Y2JpQWdJQ0FnSUM4dklFRnNjbVZoWkhrZ2NHRnljMlZrSUdKNUlHSjVJSE4xY0dWeVlXZGxiblEvWEc0Z0lDQWdJQ0JwWmlBb2NtVnpMbUp2WkhrZ0ppWWdYeTVyWlhsektISmxjeTVpYjJSNUtTNXNaVzVuZEdnZ1BpQXdLU0I3WEc0Z0lDQWdJQ0FnSUhCdmMzTnBZbXhsVDJKcUlEMGdjbVZ6TG1KdlpIazdYRzRnSUNBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQjBjbmtnZTF4dUlDQWdJQ0FnSUNBZ0lIQnZjM05wWW14bFQySnFJRDBnYW5ONVlXMXNMbk5oWm1WTWIyRmtLSEpsY3k1MFpYaDBLVHRjYmlBZ0lDQWdJQ0FnSUNBdkx5QmpZVzRnY0dGeWMyVWdhVzUwYnlCaElITjBjbWx1Wnk0dUxpQjNhR2xqYUNCM1pTQmtiMjRuZENCdVpXVmtJSEoxYm01cGJtY2dZWEp2ZFc1a0lHbHVJSFJvWlNCemVYTjBaVzFjYmlBZ0lDQWdJQ0FnSUNCd2IzTnphV0pzWlU5aWFpQTlJQ2gwZVhCbGIyWWdjRzl6YzJsaWJHVlBZbW9nUFQwOUlDZHpkSEpwYm1jbktTQS9JRzUxYkd3Z09pQndiM056YVdKc1pVOWlhanRjYmlBZ0lDQWdJQ0FnZlNCallYUmphQ0FvWlNrZ2UxeHVJQ0FnSUNBZ0lDQWdJR2hsYkhCbGNuTXViRzluS0NkallXNXViM1FnY0dGeWMyVWdTbE5QVGk5WlFVMU1JR052Ym5SbGJuUW5LVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnZlZ4dVhHNGdJQ0FnSUNBdkx5QnVkV3hzSUcxbFlXNXpJSGRsSUdOaGJpZDBJSEJoY25ObElHbHVkRzhnYjJKcVpXTjBYRzRnSUNBZ0lDQnBaaWgwZVhCbGIyWWdRblZtWm1WeUlEMDlQU0FuWm5WdVkzUnBiMjRuSUNZbUlFSjFabVpsY2k1cGMwSjFabVpsY2lod2IzTnphV0pzWlU5aWFpa3BJSHRjYmlBZ0lDQWdJQ0FnY21WemNHOXVjMlV1WkdGMFlTQTlJSEJ2YzNOcFlteGxUMkpxTzF4dUlDQWdJQ0FnZlZ4dUlDQWdJQ0FnWld4elpTQjdYRzRnSUNBZ0lDQWdJSEpsYzNCdmJuTmxMbTlpYWlBOUlDaDBlWEJsYjJZZ2NHOXpjMmxpYkdWUFltb2dQVDA5SUNkdlltcGxZM1FuS1NBL0lIQnZjM05wWW14bFQySnFJRG9nYm5Wc2JEdGNiaUFnSUNBZ0lIMWNibHh1SUNBZ0lDQWdjbVZ6Y0c5dWMyVXVjM1JoZEhWeklEMGdjbVZ6TG5OMFlYUjFjenRjYmlBZ0lDQWdJSEpsYzNCdmJuTmxMbk4wWVhSMWMxUmxlSFFnUFNCeVpYTXVkR1Y0ZER0Y2JpQWdJQ0FnSUdOaUlEMGdiMkpxTG05dUxuSmxjM0J2Ym5ObE8xeHVJQ0FnSUgxY2JpQWdJQ0JwWmlBb2NtVnpMbmhvY2lBbUppQnlaWE11ZUdoeUxuSmxjM0J2Ym5ObEtTQjdYRzRnSUNBZ0lDQnlaWE53YjI1elpTNWtZWFJoSUQwZ2NtVnpMbmhvY2k1eVpYTndiMjV6WlR0Y2JpQWdJQ0I5WEc0Z0lDQWdaV3h6WlNCcFppZ2hjbVZ6Y0c5dWMyVXVaR0YwWVNrZ2UxeHVJQ0FnSUNBZ2NtVnpjRzl1YzJVdVpHRjBZU0E5SUhKbGMzQnZibk5sTG5OMFlYUjFjMVJsZUhRN1hHNGdJQ0FnZlZ4dVhHNGdJQ0FnYVdZZ0tHTmlLU0I3WEc0Z0lDQWdJQ0JqWWloeVpYTndiMjV6WlNrN1hHNGdJQ0FnZlZ4dUlDQjlLVHRjYm4wN1hHNWNibE4xY0dWeVlXZGxiblJJZEhSd1EyeHBaVzUwTG5CeWIzUnZkSGx3WlM0Z1ltbHVZWEo1VW1WeGRXVnpkQ0E5SUdaMWJtTjBhVzl1SUNoaFkyTmxjSFFwSUh0Y2JpQWdhV1lvSVdGalkyVndkQ2tnZTF4dUlDQWdJSEpsZEhWeWJpQm1ZV3h6WlR0Y2JpQWdmVnh1SUNCeVpYUjFjbTRnS0M5ZWFXMWhaMlV2YVNrdWRHVnpkQ2hoWTJObGNIUXBYRzRnSUNBZ2ZId2dLQzllWVhCd2JHbGpZWFJwYjI1Y1hDOXdaR1l2S1M1MFpYTjBLR0ZqWTJWd2RDbGNiaUFnSUNCOGZDQW9MMTVoY0hCc2FXTmhkR2x2Ymx4Y0wyOWpkR1YwTFhOMGNtVmhiUzhwTG5SbGMzUW9ZV05qWlhCMEtUdGNibjA3WEc0aVhYMD0iLCIndXNlIHN0cmljdCc7XG5cbnZhciBTd2FnZ2VySHR0cCA9IHJlcXVpcmUoJy4vaHR0cCcpO1xudmFyIF8gPSB7XG4gIGlzT2JqZWN0OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNPYmplY3QnKSxcbiAgY2xvbmVEZWVwOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvY2xvbmVEZWVwJyksXG4gIGlzQXJyYXk6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc0FycmF5JyksXG4gIGlzU3RyaW5nOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNTdHJpbmcnKVxufTtcblxuXG4vKipcbiAqIFJlc29sdmVzIGEgc3BlYydzIHJlbW90ZSByZWZlcmVuY2VzXG4gKi9cbnZhciBSZXNvbHZlciA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmZhaWxlZFVybHMgPSBbXTtcbiAgdGhpcy5yZXNvbHZlckNhY2hlID0ge307XG4gIHRoaXMucGVuZGluZ1VybHMgPSB7fTtcbn07XG5cblJlc29sdmVyLnByb3RvdHlwZS5wcm9jZXNzQWxsT2YgPSBmdW5jdGlvbihyb290LCBuYW1lLCBkZWZpbml0aW9uLCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBzcGVjKSB7XG4gIHZhciBpLCBsb2NhdGlvbiwgcHJvcGVydHk7XG5cbiAgZGVmaW5pdGlvblsneC1yZXNvbHZlZC1mcm9tJ10gPSBbICcjL2RlZmluaXRpb25zLycgKyBuYW1lIF07XG4gIHZhciBhbGxPZiA9IGRlZmluaXRpb24uYWxsT2Y7XG4gIC8vIHRoZSByZWZzIGdvIGZpcnN0XG4gIGFsbE9mLnNvcnQoZnVuY3Rpb24oYSwgYikge1xuICAgIGlmKGEuJHJlZiAmJiBiLiRyZWYpIHsgcmV0dXJuIDA7IH1cbiAgICBlbHNlIGlmKGEuJHJlZikgeyByZXR1cm4gLTE7IH1cbiAgICBlbHNlIHsgcmV0dXJuIDE7IH1cbiAgfSk7XG4gIGZvciAoaSA9IDA7IGkgPCBhbGxPZi5sZW5ndGg7IGkrKykge1xuICAgIHByb3BlcnR5ID0gYWxsT2ZbaV07XG4gICAgbG9jYXRpb24gPSAnL2RlZmluaXRpb25zLycgKyBuYW1lICsgJy9hbGxPZic7XG4gICAgdGhpcy5yZXNvbHZlSW5saW5lKHJvb3QsIHNwZWMsIHByb3BlcnR5LCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBsb2NhdGlvbik7XG4gIH1cbn07XG5cblJlc29sdmVyLnByb3RvdHlwZS5yZXNvbHZlID0gZnVuY3Rpb24gKHNwZWMsIGFyZzEsIGFyZzIsIGFyZzMpIHtcbiAgdGhpcy5zcGVjID0gc3BlYztcbiAgdmFyIHJvb3QgPSBhcmcxLCBjYWxsYmFjayA9IGFyZzIsIHNjb3BlID0gYXJnMywgb3B0cyA9IHt9LCBsb2NhdGlvbiwgaTtcbiAgaWYodHlwZW9mIGFyZzEgPT09ICdmdW5jdGlvbicpIHtcbiAgICByb290ID0gbnVsbDtcbiAgICBjYWxsYmFjayA9IGFyZzE7XG4gICAgc2NvcGUgPSBhcmcyO1xuICB9XG4gIHZhciBfcm9vdCA9IHJvb3QsIG1vZGVsTmFtZTtcbiAgdGhpcy5zY29wZSA9IChzY29wZSB8fCB0aGlzKTtcbiAgdGhpcy5pdGVyYXRpb24gPSB0aGlzLml0ZXJhdGlvbiB8fCAwO1xuXG4gIGlmKHRoaXMuc2NvcGUub3B0aW9ucyAmJiB0aGlzLnNjb3BlLm9wdGlvbnMucmVxdWVzdEludGVyY2VwdG9yKXtcbiAgICBvcHRzLnJlcXVlc3RJbnRlcmNlcHRvciA9IHRoaXMuc2NvcGUub3B0aW9ucy5yZXF1ZXN0SW50ZXJjZXB0b3I7XG4gIH1cblxuICBpZih0aGlzLnNjb3BlLm9wdGlvbnMgJiYgdGhpcy5zY29wZS5vcHRpb25zLnJlc3BvbnNlSW50ZXJjZXB0b3Ipe1xuICAgIG9wdHMucmVzcG9uc2VJbnRlcmNlcHRvciA9IHRoaXMuc2NvcGUub3B0aW9ucy5yZXNwb25zZUludGVyY2VwdG9yO1xuICB9XG5cbiAgdmFyIG5hbWUsIHBhdGgsIHByb3BlcnR5LCBwcm9wZXJ0eU5hbWUsIHBhcmFtZXRlciwgZG9uZSwgY291bnRlcjtcbiAgdmFyIHByb2Nlc3NlZENhbGxzID0gMCwgcmVzb2x2ZWRSZWZzID0ge30sIHVucmVzb2x2ZWRSZWZzID0ge307XG4gIHZhciByZXNvbHV0aW9uVGFibGUgPSBbXTsgLy8gc3RvcmUgb2JqZWN0cyBmb3IgZGVyZWZlcmVuY2luZ1xuXG4gIHNwZWMuZGVmaW5pdGlvbnMgPSBzcGVjLmRlZmluaXRpb25zIHx8IHt9O1xuICAvLyBkZWZpbml0aW9uc1xuICBmb3IgKG5hbWUgaW4gc3BlYy5kZWZpbml0aW9ucykge1xuICAgIHZhciBkZWZpbml0aW9uID0gc3BlYy5kZWZpbml0aW9uc1tuYW1lXTtcbiAgICBpZihkZWZpbml0aW9uLiRyZWYpIHtcbiAgICAgIHRoaXMucmVzb2x2ZUlubGluZShyb290LCBzcGVjLCBkZWZpbml0aW9uLCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBkZWZpbml0aW9uKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBmb3IgKHByb3BlcnR5TmFtZSBpbiBkZWZpbml0aW9uLnByb3BlcnRpZXMpIHtcbiAgICAgICAgcHJvcGVydHkgPSBkZWZpbml0aW9uLnByb3BlcnRpZXNbcHJvcGVydHlOYW1lXTtcbiAgICAgICAgaWYgKF8uaXNBcnJheShwcm9wZXJ0eS5hbGxPZikpIHtcbiAgICAgICAgICB0aGlzLnByb2Nlc3NBbGxPZihyb290LCBuYW1lLCBwcm9wZXJ0eSwgcmVzb2x1dGlvblRhYmxlLCB1bnJlc29sdmVkUmVmcywgc3BlYyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgdGhpcy5yZXNvbHZlVG8ocm9vdCwgcHJvcGVydHksIHJlc29sdXRpb25UYWJsZSwgJy9kZWZpbml0aW9ucycpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChkZWZpbml0aW9uLmFsbE9mKSB7XG4gICAgICAgIHRoaXMucHJvY2Vzc0FsbE9mKHJvb3QsIG5hbWUsIGRlZmluaXRpb24sIHJlc29sdXRpb25UYWJsZSwgdW5yZXNvbHZlZFJlZnMsIHNwZWMpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIHNoYXJlZCBwYXJhbWV0ZXJzXG4gIHNwZWMucGFyYW1ldGVycyA9IHNwZWMucGFyYW1ldGVycyB8fCB7fTtcbiAgZm9yKG5hbWUgaW4gc3BlYy5wYXJhbWV0ZXJzKSB7XG4gICAgcGFyYW1ldGVyID0gc3BlYy5wYXJhbWV0ZXJzW25hbWVdO1xuICAgIGlmIChwYXJhbWV0ZXIuaW4gPT09ICdib2R5JyAmJiBwYXJhbWV0ZXIuc2NoZW1hKSB7XG4gICAgICBpZihfLmlzQXJyYXkocGFyYW1ldGVyLnNjaGVtYS5hbGxPZikpIHtcbiAgICAgICAgLy8gbW92ZSB0byBhIGRlZmluaXRpb25cbiAgICAgICAgbW9kZWxOYW1lID0gJ2lubGluZV9tb2RlbCc7XG4gICAgICAgIHZhciBfbmFtZSA9IG1vZGVsTmFtZTtcbiAgICAgICAgZG9uZSA9IGZhbHNlOyBjb3VudGVyID0gMDtcbiAgICAgICAgd2hpbGUoIWRvbmUpIHtcbiAgICAgICAgICBpZih0eXBlb2Ygc3BlYy5kZWZpbml0aW9uc1tfbmFtZV0gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBkb25lID0gdHJ1ZTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBfbmFtZSA9IG1vZGVsTmFtZSArICdfJyArIGNvdW50ZXI7XG4gICAgICAgICAgY291bnRlciArKztcbiAgICAgICAgfVxuICAgICAgICBzcGVjLmRlZmluaXRpb25zW19uYW1lXSA9IHsgYWxsT2Y6IHBhcmFtZXRlci5zY2hlbWEuYWxsT2YgfTtcbiAgICAgICAgZGVsZXRlIHBhcmFtZXRlci5zY2hlbWEuYWxsT2Y7XG4gICAgICAgIHBhcmFtZXRlci5zY2hlbWEuJHJlZiA9ICcjL2RlZmluaXRpb25zLycgKyBfbmFtZTtcbiAgICAgICAgdGhpcy5wcm9jZXNzQWxsT2Yocm9vdCwgX25hbWUsIHNwZWMuZGVmaW5pdGlvbnNbX25hbWVdLCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBzcGVjKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICB0aGlzLnJlc29sdmVUbyhyb290LCBwYXJhbWV0ZXIuc2NoZW1hLCByZXNvbHV0aW9uVGFibGUsIGxvY2F0aW9uKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocGFyYW1ldGVyLiRyZWYpIHtcbiAgICAgIC8vIHBhcmFtZXRlciByZWZlcmVuY2VcbiAgICAgIHRoaXMucmVzb2x2ZUlubGluZShyb290LCBzcGVjLCBwYXJhbWV0ZXIsIHJlc29sdXRpb25UYWJsZSwgdW5yZXNvbHZlZFJlZnMsIHBhcmFtZXRlci4kcmVmKTtcbiAgICB9XG4gIH1cblxuICAvLyBvcGVyYXRpb25zXG4gIGZvciAobmFtZSBpbiBzcGVjLnBhdGhzKSB7XG4gICAgdmFyIG1ldGhvZCwgb3BlcmF0aW9uLCByZXNwb25zZUNvZGU7XG4gICAgcGF0aCA9IHNwZWMucGF0aHNbbmFtZV07XG5cbiAgICBpZih0eXBlb2YgcGF0aCA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGZvciAobWV0aG9kIGluIHBhdGgpIHtcbiAgICAgICAgLy8gb3BlcmF0aW9uIHJlZmVyZW5jZVxuICAgICAgICBpZiAobWV0aG9kID09PSAnJHJlZicpIHtcbiAgICAgICAgICAvLyBsb2NhdGlvbiA9IHBhdGhbbWV0aG9kXTtcbiAgICAgICAgICBsb2NhdGlvbiA9ICcvcGF0aHMnICsgbmFtZTtcbiAgICAgICAgICB0aGlzLnJlc29sdmVJbmxpbmUocm9vdCwgc3BlYywgcGF0aCwgcmVzb2x1dGlvblRhYmxlLCB1bnJlc29sdmVkUmVmcywgbG9jYXRpb24pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIG9wZXJhdGlvbiA9IHBhdGhbbWV0aG9kXTtcbiAgICAgICAgICB2YXIgc2hhcmVkUGFyYW1ldGVycyA9IHBhdGgucGFyYW1ldGVycyB8fCBbXTtcbiAgICAgICAgICB2YXIgcGFyYW1ldGVycyA9IG9wZXJhdGlvbi5wYXJhbWV0ZXJzIHx8IFtdO1xuXG4gICAgICAgICAgc2hhcmVkUGFyYW1ldGVycy5mb3JFYWNoKGZ1bmN0aW9uKHBhcmFtZXRlcikge1xuICAgICAgICAgICAgcGFyYW1ldGVycy51bnNoaWZ0KHBhcmFtZXRlcik7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpZiAobWV0aG9kICE9PSAncGFyYW1ldGVycycgJiYgXy5pc09iamVjdChvcGVyYXRpb24pKSB7XG4gICAgICAgICAgICBvcGVyYXRpb24ucGFyYW1ldGVycyA9IG9wZXJhdGlvbi5wYXJhbWV0ZXJzIHx8IHBhcmFtZXRlcnM7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZm9yIChpIGluIHBhcmFtZXRlcnMpIHtcbiAgICAgICAgICAgIHBhcmFtZXRlciA9IHBhcmFtZXRlcnNbaV07XG4gICAgICAgICAgICBsb2NhdGlvbiA9ICcvcGF0aHMnICsgbmFtZSArICcvJyArIG1ldGhvZCArICcvcGFyYW1ldGVycyc7XG5cbiAgICAgICAgICAgIGlmIChwYXJhbWV0ZXIuaW4gPT09ICdib2R5JyAmJiBwYXJhbWV0ZXIuc2NoZW1hKSB7XG4gICAgICAgICAgICAgIGlmIChfLmlzQXJyYXkocGFyYW1ldGVyLnNjaGVtYS5hbGxPZikpIHtcbiAgICAgICAgICAgICAgICAvLyBtb3ZlIHRvIGEgZGVmaW5pdGlvblxuICAgICAgICAgICAgICAgIG1vZGVsTmFtZSA9ICdpbmxpbmVfbW9kZWwnO1xuICAgICAgICAgICAgICAgIG5hbWUgPSBtb2RlbE5hbWU7XG4gICAgICAgICAgICAgICAgZG9uZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGNvdW50ZXIgPSAwO1xuICAgICAgICAgICAgICAgIHdoaWxlICghZG9uZSkge1xuICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBzcGVjLmRlZmluaXRpb25zW25hbWVdID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBuYW1lID0gbW9kZWxOYW1lICsgJ18nICsgY291bnRlcjtcbiAgICAgICAgICAgICAgICAgIGNvdW50ZXIrKztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgc3BlYy5kZWZpbml0aW9uc1tuYW1lXSA9IHthbGxPZjogcGFyYW1ldGVyLnNjaGVtYS5hbGxPZn07XG4gICAgICAgICAgICAgICAgZGVsZXRlIHBhcmFtZXRlci5zY2hlbWEuYWxsT2Y7XG4gICAgICAgICAgICAgICAgcGFyYW1ldGVyLnNjaGVtYS4kcmVmID0gJyMvZGVmaW5pdGlvbnMvJyArIG5hbWU7XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzQWxsT2Yocm9vdCwgbmFtZSwgc3BlYy5kZWZpbml0aW9uc1tuYW1lXSwgcmVzb2x1dGlvblRhYmxlLCB1bnJlc29sdmVkUmVmcywgc3BlYyk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZXNvbHZlVG8ocm9vdCwgcGFyYW1ldGVyLnNjaGVtYSwgcmVzb2x1dGlvblRhYmxlLCBsb2NhdGlvbik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHBhcmFtZXRlci4kcmVmKSB7XG4gICAgICAgICAgICAgIC8vIHBhcmFtZXRlciByZWZlcmVuY2VcbiAgICAgICAgICAgICAgdGhpcy5yZXNvbHZlSW5saW5lKHJvb3QsIHNwZWMsIHBhcmFtZXRlciwgcmVzb2x1dGlvblRhYmxlLCB1bnJlc29sdmVkUmVmcywgcGFyYW1ldGVyLiRyZWYpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGZvciAocmVzcG9uc2VDb2RlIGluIG9wZXJhdGlvbi5yZXNwb25zZXMpIHtcbiAgICAgICAgICAgIHZhciByZXNwb25zZSA9IG9wZXJhdGlvbi5yZXNwb25zZXNbcmVzcG9uc2VDb2RlXTtcbiAgICAgICAgICAgIGxvY2F0aW9uID0gJy9wYXRocycgKyBuYW1lICsgJy8nICsgbWV0aG9kICsgJy9yZXNwb25zZXMvJyArIHJlc3BvbnNlQ29kZTtcblxuICAgICAgICAgICAgaWYgKF8uaXNPYmplY3QocmVzcG9uc2UpKSB7XG4gICAgICAgICAgICAgIGlmIChyZXNwb25zZS4kcmVmKSB7XG4gICAgICAgICAgICAgICAgLy8gcmVzcG9uc2UgcmVmZXJlbmNlXG4gICAgICAgICAgICAgICAgdGhpcy5yZXNvbHZlSW5saW5lKHJvb3QsIHNwZWMsIHJlc3BvbnNlLCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBsb2NhdGlvbik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlLnNjaGVtYSkge1xuICAgICAgICAgICAgICAgIHZhciByZXNwb25zZU9iaiA9IHJlc3BvbnNlO1xuICAgICAgICAgICAgICAgIGlmIChfLmlzQXJyYXkocmVzcG9uc2VPYmouc2NoZW1hLmFsbE9mKSkge1xuICAgICAgICAgICAgICAgICAgLy8gbW92ZSB0byBhIGRlZmluaXRpb25cbiAgICAgICAgICAgICAgICAgIG1vZGVsTmFtZSA9ICdpbmxpbmVfbW9kZWwnO1xuICAgICAgICAgICAgICAgICAgbmFtZSA9IG1vZGVsTmFtZTtcbiAgICAgICAgICAgICAgICAgIGRvbmUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgIGNvdW50ZXIgPSAwO1xuICAgICAgICAgICAgICAgICAgd2hpbGUgKCFkb25lKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygc3BlYy5kZWZpbml0aW9uc1tuYW1lXSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBuYW1lID0gbW9kZWxOYW1lICsgJ18nICsgY291bnRlcjtcbiAgICAgICAgICAgICAgICAgICAgY291bnRlcisrO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgc3BlYy5kZWZpbml0aW9uc1tuYW1lXSA9IHthbGxPZjogcmVzcG9uc2VPYmouc2NoZW1hLmFsbE9mfTtcbiAgICAgICAgICAgICAgICAgIGRlbGV0ZSByZXNwb25zZU9iai5zY2hlbWEuYWxsT2Y7XG4gICAgICAgICAgICAgICAgICBkZWxldGUgcmVzcG9uc2VPYmouc2NoZW1hLnR5cGU7XG4gICAgICAgICAgICAgICAgICByZXNwb25zZU9iai5zY2hlbWEuJHJlZiA9ICcjL2RlZmluaXRpb25zLycgKyBuYW1lO1xuICAgICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzQWxsT2Yocm9vdCwgbmFtZSwgc3BlYy5kZWZpbml0aW9uc1tuYW1lXSwgcmVzb2x1dGlvblRhYmxlLCB1bnJlc29sdmVkUmVmcywgc3BlYyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKCdhcnJheScgPT09IHJlc3BvbnNlT2JqLnNjaGVtYS50eXBlKSB7XG4gICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2VPYmouc2NoZW1hLml0ZW1zICYmIHJlc3BvbnNlT2JqLnNjaGVtYS5pdGVtcy4kcmVmKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHJlc3BvbnNlIHJlZmVyZW5jZVxuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc29sdmVJbmxpbmUocm9vdCwgc3BlYywgcmVzcG9uc2VPYmouc2NoZW1hLml0ZW1zLCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBsb2NhdGlvbik7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgdGhpcy5yZXNvbHZlVG8ocm9vdCwgcmVzcG9uc2Uuc2NoZW1hLCByZXNvbHV0aW9uVGFibGUsIGxvY2F0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIGNsZWFyIHRoZW0gb3V0IHRvIGF2b2lkIG11bHRpcGxlIHJlc29sdXRpb25zXG4gICAgICBwYXRoLnBhcmFtZXRlcnMgPSBbXTtcbiAgICB9XG4gIH1cblxuICB2YXIgZXhwZWN0ZWRDYWxscyA9IDAsIHRvUmVzb2x2ZSA9IFtdO1xuICAvLyBpZiB0aGUgcm9vdCBpcyBzYW1lIGFzIG9ialtpXS5yb290IHdlIGNhbiByZXNvbHZlIGxvY2FsbHlcbiAgdmFyIGFsbCA9IHJlc29sdXRpb25UYWJsZTtcblxuICB2YXIgcGFydHM7XG4gIGZvcihpID0gMDsgaSA8IGFsbC5sZW5ndGg7IGkrKykge1xuICAgIHZhciBhID0gYWxsW2ldO1xuICAgIGlmKHJvb3QgPT09IGEucm9vdCkge1xuICAgICAgaWYoYS5yZXNvbHZlQXMgPT09ICdyZWYnKSB7XG4gICAgICAgIC8vIHJlc29sdmUgYW55IHBhdGggd2Fsa2luZ1xuICAgICAgICB2YXIgam9pbmVkID0gKChhLnJvb3QgfHwgJycpICsgJy8nICsgYS5rZXkpLnNwbGl0KCcvJyk7XG4gICAgICAgIHZhciBub3JtYWxpemVkID0gW107XG4gICAgICAgIHZhciB1cmwgPSAnJztcbiAgICAgICAgdmFyIGs7XG5cbiAgICAgICAgaWYoYS5rZXkuaW5kZXhPZignLi4vJykgPj0gMCkge1xuICAgICAgICAgIGZvcih2YXIgaiA9IDA7IGogPCBqb2luZWQubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgIGlmKGpvaW5lZFtqXSA9PT0gJy4uJykge1xuICAgICAgICAgICAgICBub3JtYWxpemVkID0gbm9ybWFsaXplZC5zbGljZSgwLCBub3JtYWxpemVkLmxlbmd0aC0xKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICBub3JtYWxpemVkLnB1c2goam9pbmVkW2pdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgZm9yKGsgPSAwOyBrIDwgbm9ybWFsaXplZC5sZW5ndGg7IGsgKyspIHtcbiAgICAgICAgICAgIGlmKGsgPiAwKSB7XG4gICAgICAgICAgICAgIHVybCArPSAnLyc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB1cmwgKz0gbm9ybWFsaXplZFtrXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gd2Ugbm93IGhhdmUgdG8gcmVtb3RlIHJlc29sdmUgdGhpcyBiZWNhdXNlIHRoZSBwYXRoIGhhcyBjaGFuZ2VkXG4gICAgICAgICAgYS5yb290ID0gdXJsO1xuICAgICAgICAgIHRvUmVzb2x2ZS5wdXNoKGEpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHBhcnRzID0gYS5rZXkuc3BsaXQoJyMnKTtcbiAgICAgICAgICBpZihwYXJ0cy5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgICAgIGlmKHBhcnRzWzBdLmluZGV4T2YoJ2h0dHA6JykgPT09IDAgfHwgcGFydHNbMF0uaW5kZXhPZignaHR0cHM6JykgPT09IDApIHtcbiAgICAgICAgICAgICAgYS5yb290ID0gcGFydHNbMF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsb2NhdGlvbiA9IHBhcnRzWzFdLnNwbGl0KCcvJyk7XG4gICAgICAgICAgICB2YXIgcjtcbiAgICAgICAgICAgIHZhciBzID0gc3BlYztcbiAgICAgICAgICAgIGZvcihrID0gMDsgayA8IGxvY2F0aW9uLmxlbmd0aDsgaysrKSB7XG4gICAgICAgICAgICAgIHZhciBwYXJ0ID0gbG9jYXRpb25ba107XG4gICAgICAgICAgICAgIGlmKHBhcnQgIT09ICcnKSB7XG4gICAgICAgICAgICAgICAgcyA9IHNbcGFydF07XG4gICAgICAgICAgICAgICAgaWYodHlwZW9mIHMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICByID0gcztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICByID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYociA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAvLyBtdXN0IHJlc29sdmUgdGhpcyB0b29cbiAgICAgICAgICAgICAgdG9SZXNvbHZlLnB1c2goYSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgaWYgKGEucmVzb2x2ZUFzID09PSAnaW5saW5lJykge1xuICAgICAgICAgIGlmKGEua2V5ICYmIGEua2V5LmluZGV4T2YoJyMnKSA9PT0gLTEgJiYgYS5rZXkuY2hhckF0KDApICE9PSAnLycpIHtcbiAgICAgICAgICAgIC8vIGhhbmRsZSByZWxhdGl2ZSBzY2hlbWFcbiAgICAgICAgICAgIHBhcnRzID0gYS5yb290LnNwbGl0KCcvJyk7XG4gICAgICAgICAgICBsb2NhdGlvbiA9ICcnO1xuICAgICAgICAgICAgZm9yKGkgPSAwOyBpIDwgcGFydHMubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgICAgICAgIGxvY2F0aW9uICs9IHBhcnRzW2ldICsgJy8nO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbG9jYXRpb24gKz0gYS5rZXk7XG4gICAgICAgICAgICBhLnJvb3QgPSBsb2NhdGlvbjtcbiAgICAgICAgICAgIGEubG9jYXRpb24gPSAnJztcbiAgICAgICAgICB9XG4gICAgICAgICAgdG9SZXNvbHZlLnB1c2goYSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICB0b1Jlc29sdmUucHVzaChhKTtcbiAgICB9XG4gIH1cbiAgZXhwZWN0ZWRDYWxscyA9IHRvUmVzb2x2ZS5sZW5ndGg7XG5cbiAgLy8gcmVzb2x2ZSBhbnl0aGluZyB0aGF0IGlzIGxvY2FsXG5cbiAgdmFyIGxvY2sgPSB7fTtcbiAgZm9yKHZhciBpaSA9IDA7IGlpIDwgdG9SZXNvbHZlLmxlbmd0aDsgaWkrKykge1xuICAgIChmdW5jdGlvbihpdGVtLCBzcGVjLCBzZWxmLCBsb2NrLCBpaSkge1xuICAgICAgaWYoIWl0ZW0ucm9vdCB8fCBpdGVtLnJvb3QgPT09IHJvb3QpIHtcbiAgICAgICAgLy8gbG9jYWwgcmVzb2x2ZVxuICAgICAgICBzZWxmLnJlc29sdmVJdGVtKHNwZWMsIF9yb290LCByZXNvbHV0aW9uVGFibGUsIHJlc29sdmVkUmVmcywgdW5yZXNvbHZlZFJlZnMsIGl0ZW0pO1xuICAgICAgICBwcm9jZXNzZWRDYWxscyArPSAxO1xuXG4gICAgICAgIGlmKHByb2Nlc3NlZENhbGxzID09PSBleHBlY3RlZENhbGxzKSB7XG4gICAgICAgICAgc2VsZi5maW5pc2goc3BlYywgcm9vdCwgcmVzb2x1dGlvblRhYmxlLCByZXNvbHZlZFJlZnMsIHVucmVzb2x2ZWRSZWZzLCBjYWxsYmFjaywgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGVsc2UgaWYoc2VsZi5mYWlsZWRVcmxzLmluZGV4T2YoaXRlbS5yb290KSA9PT0gLTEpIHtcbiAgICAgICAgdmFyIG9iaiA9IHtcbiAgICAgICAgICB1c2VKUXVlcnk6IGZhbHNlLCAgLy8gVE9ET1xuICAgICAgICAgIHVybDogaXRlbS5yb290LFxuICAgICAgICAgIG1ldGhvZDogJ2dldCcsXG4gICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgYWNjZXB0OiBzZWxmLnNjb3BlLnN3YWdnZXJSZXF1ZXN0SGVhZGVycyB8fCAnYXBwbGljYXRpb24vanNvbidcbiAgICAgICAgICB9LFxuICAgICAgICAgIG9uOiB7XG4gICAgICAgICAgICBlcnJvcjogZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgICAgICAgIHByb2Nlc3NlZENhbGxzICs9IDE7XG4gICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdmYWlsZWQgdXJsOiAnICsgb2JqLnVybCk7XG4gICAgICAgICAgICAgIHNlbGYuZmFpbGVkVXJscy5wdXNoKG9iai51cmwpO1xuICAgICAgICAgICAgICBpZiAobG9jaykge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBsb2NrW2l0ZW0ucm9vdF07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdW5yZXNvbHZlZFJlZnNbaXRlbS5rZXldID0ge1xuICAgICAgICAgICAgICAgIHJvb3Q6IGl0ZW0ucm9vdCxcbiAgICAgICAgICAgICAgICBsb2NhdGlvbjogaXRlbS5sb2NhdGlvblxuICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgIGlmIChwcm9jZXNzZWRDYWxscyA9PT0gZXhwZWN0ZWRDYWxscykge1xuICAgICAgICAgICAgICAgIHNlbGYuZmluaXNoKHNwZWMsIF9yb290LCByZXNvbHV0aW9uVGFibGUsIHJlc29sdmVkUmVmcywgdW5yZXNvbHZlZFJlZnMsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSwgIC8vIGpzaGludCBpZ25vcmU6bGluZVxuICAgICAgICAgICAgcmVzcG9uc2U6IGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgICAgICAgICAgICB2YXIgc3dhZ2dlciA9IHJlc3BvbnNlLm9iajtcbiAgICAgICAgICAgICAgaWYgKGxvY2spIHtcbiAgICAgICAgICAgICAgICBkZWxldGUgbG9ja1tpdGVtLnJvb3RdO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChzZWxmLnJlc29sdmVyQ2FjaGUpIHtcbiAgICAgICAgICAgICAgICBzZWxmLnJlc29sdmVyQ2FjaGVbaXRlbS5yb290XSA9IHN3YWdnZXI7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgc2VsZi5yZXNvbHZlSXRlbShzd2FnZ2VyLCBpdGVtLnJvb3QsIHJlc29sdXRpb25UYWJsZSwgcmVzb2x2ZWRSZWZzLCB1bnJlc29sdmVkUmVmcywgaXRlbSk7XG4gICAgICAgICAgICAgIHByb2Nlc3NlZENhbGxzICs9IDE7XG5cbiAgICAgICAgICAgICAgaWYgKHByb2Nlc3NlZENhbGxzID09PSBleHBlY3RlZENhbGxzKSB7XG4gICAgICAgICAgICAgICAgc2VsZi5maW5pc2goc3BlYywgX3Jvb3QsIHJlc29sdXRpb25UYWJsZSwgcmVzb2x2ZWRSZWZzLCB1bnJlc29sdmVkUmVmcywgY2FsbGJhY2spO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSAvLyBqc2hpbnQgaWdub3JlOmxpbmVcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBhcHBseSB0aW1lb3V0IG9ubHkgd2hlbiBzcGVjaWZpZWRcbiAgICAgICAgaWYgKHNjb3BlICYmIHNjb3BlLmZldGNoU3BlY1RpbWVvdXQpIHtcbiAgICAgICAgICBvYmoudGltZW91dCA9IHNjb3BlLmZldGNoU3BlY1RpbWVvdXQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc2NvcGUgJiYgc2NvcGUuY2xpZW50QXV0aG9yaXphdGlvbnMpIHtcbiAgICAgICAgICBzY29wZS5jbGllbnRBdXRob3JpemF0aW9ucy5hcHBseShvYmopO1xuICAgICAgICB9XG5cbiAgICAgICAgKGZ1bmN0aW9uIHdhaXRGb3JVbmxvY2soKSB7XG4gICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGlmIChsb2NrW29iai51cmxdKSB7XG4gICAgICAgICAgICAgIHdhaXRGb3JVbmxvY2soKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICB2YXIgY2FjaGVkID0gc2VsZi5yZXNvbHZlckNhY2hlW29iai51cmxdO1xuICAgICAgICAgICAgICBpZiAoXy5pc09iamVjdChjYWNoZWQpKSB7XG4gICAgICAgICAgICAgICAgb2JqLm9uLnJlc3BvbnNlKHtvYmo6IGNhY2hlZH0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGxvY2tbb2JqLnVybF0gPSB0cnVlO1xuICAgICAgICAgICAgICAgIG5ldyBTd2FnZ2VySHR0cCgpLmV4ZWN1dGUob2JqLCBvcHRzKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sIDApO1xuICAgICAgICB9KSgpO1xuICAgICAgfVxuXG4gICAgICBlbHNlIHtcbiAgICAgICAgcHJvY2Vzc2VkQ2FsbHMgKz0gMTtcbiAgICAgICAgdW5yZXNvbHZlZFJlZnNbaXRlbS5rZXldID0ge1xuICAgICAgICAgIHJvb3Q6IGl0ZW0ucm9vdCxcbiAgICAgICAgICBsb2NhdGlvbjogaXRlbS5sb2NhdGlvblxuICAgICAgICB9O1xuICAgICAgICBpZiAocHJvY2Vzc2VkQ2FsbHMgPT09IGV4cGVjdGVkQ2FsbHMpIHtcbiAgICAgICAgICBzZWxmLmZpbmlzaChzcGVjLCBfcm9vdCwgcmVzb2x1dGlvblRhYmxlLCByZXNvbHZlZFJlZnMsIHVucmVzb2x2ZWRSZWZzLCBjYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KHRvUmVzb2x2ZVtpaV0sIHNwZWMsIHRoaXMsIGxvY2ssIGlpKSk7XG4gIH1cblxuICBpZiAoT2JqZWN0LmtleXModG9SZXNvbHZlKS5sZW5ndGggPT09IDApIHtcbiAgICB0aGlzLmZpbmlzaChzcGVjLCBfcm9vdCwgcmVzb2x1dGlvblRhYmxlLCByZXNvbHZlZFJlZnMsIHVucmVzb2x2ZWRSZWZzLCBjYWxsYmFjayk7XG4gIH1cbn07XG5cblJlc29sdmVyLnByb3RvdHlwZS5yZXNvbHZlSXRlbSA9IGZ1bmN0aW9uKHNwZWMsIHJvb3QsIHJlc29sdXRpb25UYWJsZSwgcmVzb2x2ZWRSZWZzLCB1bnJlc29sdmVkUmVmcywgaXRlbSkge1xuICB2YXIgcGF0aCA9IGl0ZW0ubG9jYXRpb247XG4gIHZhciBsb2NhdGlvbiA9IHNwZWMsIHBhcnRzID0gcGF0aC5zcGxpdCgnLycpO1xuICBpZihwYXRoICE9PSAnJykge1xuICAgIGZvciAodmFyIGogPSAwOyBqIDwgcGFydHMubGVuZ3RoOyBqKyspIHtcbiAgICAgIHZhciBzZWdtZW50ID0gcGFydHNbal07XG4gICAgICBpZiAoc2VnbWVudC5pbmRleE9mKCd+MScpICE9PSAtMSkge1xuICAgICAgICBzZWdtZW50ID0gcGFydHNbal0ucmVwbGFjZSgvfjAvZywgJ34nKS5yZXBsYWNlKC9+MS9nLCAnLycpO1xuICAgICAgICBpZiAoc2VnbWVudC5jaGFyQXQoMCkgIT09ICcvJykge1xuICAgICAgICAgIHNlZ21lbnQgPSAnLycgKyBzZWdtZW50O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIGxvY2F0aW9uID09PSAndW5kZWZpbmVkJyB8fCBsb2NhdGlvbiA9PT0gbnVsbCkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGlmIChzZWdtZW50ID09PSAnJyAmJiBqID09PSAocGFydHMubGVuZ3RoIC0gMSkgJiYgcGFydHMubGVuZ3RoID4gMSkge1xuICAgICAgICBsb2NhdGlvbiA9IG51bGw7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgaWYgKHNlZ21lbnQubGVuZ3RoID4gMCkge1xuICAgICAgICBsb2NhdGlvbiA9IGxvY2F0aW9uW3NlZ21lbnRdO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICB2YXIgcmVzb2x2ZWQgPSBpdGVtLmtleTtcbiAgcGFydHMgPSBpdGVtLmtleS5zcGxpdCgnLycpO1xuICB2YXIgcmVzb2x2ZWROYW1lID0gcGFydHNbcGFydHMubGVuZ3RoLTFdO1xuXG4gIGlmKHJlc29sdmVkTmFtZS5pbmRleE9mKCcjJykgPj0gMCkge1xuICAgIHJlc29sdmVkTmFtZSA9IHJlc29sdmVkTmFtZS5zcGxpdCgnIycpWzFdO1xuICB9XG5cbiAgaWYgKGxvY2F0aW9uICE9PSBudWxsICYmIHR5cGVvZiBsb2NhdGlvbiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXNvbHZlZFJlZnNbcmVzb2x2ZWRdID0ge1xuICAgICAgbmFtZTogcmVzb2x2ZWROYW1lLFxuICAgICAgb2JqOiBsb2NhdGlvbixcbiAgICAgIGtleTogaXRlbS5rZXksXG4gICAgICByb290OiBpdGVtLnJvb3RcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIHVucmVzb2x2ZWRSZWZzW3Jlc29sdmVkXSA9IHtcbiAgICAgIHJvb3Q6IGl0ZW0ucm9vdCxcbiAgICAgIGxvY2F0aW9uOiBpdGVtLmxvY2F0aW9uXG4gICAgfTtcbiAgfVxufTtcblxuUmVzb2x2ZXIucHJvdG90eXBlLmZpbmlzaCA9IGZ1bmN0aW9uIChzcGVjLCByb290LCByZXNvbHV0aW9uVGFibGUsIHJlc29sdmVkUmVmcywgdW5yZXNvbHZlZFJlZnMsIGNhbGxiYWNrLCBsb2NhbFJlc29sdmUpIHtcbiAgLy8gd2FsayByZXNvbHV0aW9uIHRhYmxlIGFuZCByZXBsYWNlIHdpdGggcmVzb2x2ZWQgcmVmc1xuICB2YXIgcmVmLCBhYnM7XG4gIGZvciAocmVmIGluIHJlc29sdXRpb25UYWJsZSkge1xuICAgIHZhciBpdGVtID0gcmVzb2x1dGlvblRhYmxlW3JlZl07XG5cbiAgICB2YXIga2V5ID0gaXRlbS5rZXk7XG4gICAgdmFyIHJlc29sdmVkVG8gPSByZXNvbHZlZFJlZnNba2V5XTtcbiAgICBpZiAocmVzb2x2ZWRUbykge1xuICAgICAgc3BlYy5kZWZpbml0aW9ucyA9IHNwZWMuZGVmaW5pdGlvbnMgfHwge307XG4gICAgICBpZiAoaXRlbS5yZXNvbHZlQXMgPT09ICdyZWYnKSB7XG4gICAgICAgIGlmIChsb2NhbFJlc29sdmUgIT09IHRydWUpIHtcbiAgICAgICAgICAvLyBkb24ndCByZXRhaW4gcm9vdCBmb3IgbG9jYWwgZGVmaW5pdGlvbnNcbiAgICAgICAgICBmb3IgKGtleSBpbiByZXNvbHZlZFRvLm9iaikge1xuICAgICAgICAgICAgYWJzID0gdGhpcy5yZXRhaW5Sb290KGtleSwgcmVzb2x2ZWRUby5vYmpba2V5XSwgaXRlbS5yb290KTtcbiAgICAgICAgICAgIHJlc29sdmVkVG8ub2JqW2tleV0gPSBhYnM7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHNwZWMuZGVmaW5pdGlvbnNbcmVzb2x2ZWRUby5uYW1lXSA9IHJlc29sdmVkVG8ub2JqO1xuICAgICAgICBpdGVtLm9iai4kcmVmID0gJyMvZGVmaW5pdGlvbnMvJyArIHJlc29sdmVkVG8ubmFtZTtcbiAgICAgIH0gZWxzZSBpZiAoaXRlbS5yZXNvbHZlQXMgPT09ICdpbmxpbmUnKSB7XG4gICAgICAgIHZhciB0YXJnZXRPYmogPSBpdGVtLm9iajtcbiAgICAgICAgdGFyZ2V0T2JqWyd4LXJlc29sdmVkLWZyb20nXSA9IFsgaXRlbS5rZXkgXTtcbiAgICAgICAgZGVsZXRlIHRhcmdldE9iai4kcmVmO1xuXG4gICAgICAgIGZvciAoa2V5IGluIHJlc29sdmVkVG8ub2JqKSB7XG4gICAgICAgICAgYWJzID0gcmVzb2x2ZWRUby5vYmpba2V5XTtcblxuICAgICAgICAgIGlmIChsb2NhbFJlc29sdmUgIT09IHRydWUpIHtcbiAgICAgICAgICAgIC8vIGRvbid0IHJldGFpbiByb290IGZvciBsb2NhbCBkZWZpbml0aW9uc1xuICAgICAgICAgICAgYWJzID0gdGhpcy5yZXRhaW5Sb290KGtleSwgcmVzb2x2ZWRUby5vYmpba2V5XSwgaXRlbS5yb290KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGFyZ2V0T2JqW2tleV0gPSBhYnM7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgdmFyIGV4aXN0aW5nVW5yZXNvbHZlZCA9IHRoaXMuY291bnRVbnJlc29sdmVkUmVmcyhzcGVjKTtcblxuICBpZihleGlzdGluZ1VucmVzb2x2ZWQgPT09IDAgfHwgdGhpcy5pdGVyYXRpb24gPiA1KSB7XG4gICAgdGhpcy5yZXNvbHZlQWxsT2Yoc3BlYy5kZWZpbml0aW9ucyk7XG4gICAgdGhpcy5yZXNvbHZlckNhY2hlID0gbnVsbDtcbiAgICBjYWxsYmFjay5jYWxsKHRoaXMuc2NvcGUsIHNwZWMsIHVucmVzb2x2ZWRSZWZzKTtcbiAgfVxuICBlbHNlIHtcbiAgICB0aGlzLml0ZXJhdGlvbiArPSAxO1xuICAgIHRoaXMucmVzb2x2ZShzcGVjLCByb290LCBjYWxsYmFjaywgdGhpcy5zY29wZSk7XG4gIH1cbn07XG5cblJlc29sdmVyLnByb3RvdHlwZS5jb3VudFVucmVzb2x2ZWRSZWZzID0gZnVuY3Rpb24oc3BlYykge1xuICB2YXIgaTtcbiAgdmFyIHJlZnMgPSB0aGlzLmdldFJlZnMoc3BlYyk7XG4gIHZhciBrZXlzID0gW107XG4gIHZhciB1bnJlc29sdmVkS2V5cyA9IFtdO1xuICBmb3IoaSBpbiByZWZzKSB7XG4gICAgaWYoaS5pbmRleE9mKCcjJykgPT09IDApIHtcbiAgICAgIGtleXMucHVzaChpLnN1YnN0cmluZygxKSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgdW5yZXNvbHZlZEtleXMucHVzaChpKTtcbiAgICB9XG4gIH1cblxuICAvLyB2ZXJpZnkgcG9zc2libGUga2V5c1xuICBmb3IgKGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwYXJ0ID0ga2V5c1tpXTtcbiAgICB2YXIgcGFydHMgPSBwYXJ0LnNwbGl0KCcvJyk7XG4gICAgdmFyIG9iaiA9IHNwZWM7XG5cbiAgICBmb3IgKHZhciBrID0gMDsgayA8IHBhcnRzLmxlbmd0aDsgaysrKSB7XG4gICAgICB2YXIga2V5ID0gcGFydHNba107XG4gICAgICBpZihrZXkgIT09ICcnKSB7XG4gICAgICAgIG9iaiA9IG9ialtrZXldO1xuICAgICAgICBpZih0eXBlb2Ygb2JqID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIHVucmVzb2x2ZWRLZXlzLnB1c2gocGFydCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHVucmVzb2x2ZWRLZXlzLmxlbmd0aDtcbn07XG5cblJlc29sdmVyLnByb3RvdHlwZS5nZXRSZWZzID0gZnVuY3Rpb24oc3BlYywgb2JqKSB7XG4gIG9iaiA9IG9iaiB8fCBzcGVjO1xuICB2YXIgb3V0cHV0ID0ge307XG4gIGZvcih2YXIga2V5IGluIG9iaikge1xuICAgIGlmICghb2JqLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICB2YXIgaXRlbSA9IG9ialtrZXldO1xuICAgIGlmKGtleSA9PT0gJyRyZWYnICYmIHR5cGVvZiBpdGVtID09PSAnc3RyaW5nJykge1xuICAgICAgb3V0cHV0W2l0ZW1dID0gbnVsbDtcbiAgICB9XG4gICAgZWxzZSBpZihfLmlzT2JqZWN0KGl0ZW0pKSB7XG4gICAgICB2YXIgbyA9IHRoaXMuZ2V0UmVmcyhpdGVtKTtcbiAgICAgIGZvcih2YXIgayBpbiBvKSB7XG4gICAgICAgIG91dHB1dFtrXSA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBvdXRwdXQ7XG59O1xuXG5mdW5jdGlvbiBzcGxpdFVybCh1cmwpIHtcbiAgdmFyIHJlc3VsdCA9IHt9O1xuICB2YXIgcHJvdG8gPSAvW2Etel0rOlxcL1xcLy9pLmV4ZWModXJsKTtcbiAgaWYgKHByb3RvKSB7XG4gICAgcmVzdWx0LnByb3RvID0gcHJvdG9bMF0uc2xpY2UoMCwgLTMpO1xuICAgIHVybCA9IHVybC5zbGljZShyZXN1bHQucHJvdG8ubGVuZ3RoICsgMSk7XG4gIH1cbiAgaWYgKHVybC5zbGljZSgwLCAyKSA9PT0gJy8vJykge1xuICAgIHJlc3VsdC5kb21haW4gPSB1cmwuc2xpY2UoMikuc3BsaXQoJy8nKVswXTtcbiAgICB1cmwgPSB1cmwuc2xpY2UoMiArIHJlc3VsdC5kb21haW4ubGVuZ3RoKTtcbiAgfVxuICB2YXIgcCA9IHVybC5zcGxpdCgnIycpO1xuICBpZiAocFswXS5sZW5ndGgpIHtcbiAgICByZXN1bHQucGF0aCA9IHBbMF07XG4gIH1cbiAgaWYgKHAubGVuZ3RoID4gMSkge1xuICAgIHJlc3VsdC5mcmFnbWVudCA9IHAuc2xpY2UoMSkuam9pbignIycpO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIHVuc3BsaXRVcmwodXJsKSB7XG4gIHZhciByZXN1bHQgPSB1cmwucGF0aDtcbiAgaWYgKHJlc3VsdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmVzdWx0ID0gJyc7XG4gIH1cbiAgaWYgKHVybC5mcmFnbWVudCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmVzdWx0ICs9ICcjJyArIHVybC5mcmFnbWVudDtcbiAgfVxuICBpZiAodXJsLmRvbWFpbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKHJlc3VsdC5zbGljZSgwLCAxKSA9PT0gJy8nKSB7XG4gICAgICByZXN1bHQgPSByZXN1bHQuc2xpY2UoMSk7XG4gICAgfVxuICAgIHJlc3VsdCA9ICcvLycgKyB1cmwuZG9tYWluICsgJy8nICsgcmVzdWx0O1xuICAgIGlmICh1cmwucHJvdG8gIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmVzdWx0ID0gdXJsLnByb3RvICsgJzonICsgcmVzdWx0O1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBqb2luVXJsKGJhc2UsIHJlbCkge1xuICB2YXIgcmVsc3AgPSBzcGxpdFVybChyZWwpO1xuICBpZiAocmVsc3AuZG9tYWluICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gcmVsO1xuICB9XG4gIHZhciByZXN1bHQgPSBzcGxpdFVybChiYXNlKTtcbiAgaWYgKHJlbHNwLnBhdGggPT09IHVuZGVmaW5lZCkge1xuICAgIC8vIGNoYW5nZSBvbmx5IGZyYWdtZW50IHBhcnRcbiAgICByZXN1bHQuZnJhZ21lbnQgPSByZWxzcC5mcmFnbWVudDtcbiAgfSBlbHNlIGlmIChyZWxzcC5wYXRoLnNsaWNlKDAsIDEpID09PSAnLycpIHtcbiAgICAvLyByZWxhdGl2ZSB0byBkb21haW5cbiAgICByZXN1bHQucGF0aCA9IHJlbHNwLnBhdGg7XG4gICAgcmVzdWx0LmZyYWdtZW50ID0gcmVsc3AuZnJhZ21lbnQ7XG4gIH0gZWxzZSB7XG4gICAgLy8gcmVsYXRpdmUgdG8gcGF0aFxuICAgIHZhciBwYXRoID0gcmVzdWx0LnBhdGggPT09IHVuZGVmaW5lZCA/IFtdIDogcmVzdWx0LnBhdGguc3BsaXQoJy8nKTtcbiAgICB2YXIgcmVscGF0aCA9IHJlbHNwLnBhdGguc3BsaXQoJy8nKTtcbiAgICBpZiAocGF0aC5sZW5ndGgpIHtcbiAgICAgIHBhdGgucG9wKCk7XG4gICAgfVxuICAgIHdoaWxlIChyZWxwYXRoWzBdID09PSAnLi4nIHx8IHJlbHBhdGhbMF0gPT09ICcuJykge1xuICAgICAgaWYgKHJlbHBhdGhbMF0gPT09ICcuLicpIHtcbiAgICAgICAgcGF0aC5wb3AoKTtcbiAgICAgIH1cbiAgICAgIHJlbHBhdGguc2hpZnQoKTtcbiAgICB9XG4gICAgcmVzdWx0LnBhdGggPSBwYXRoLmNvbmNhdChyZWxwYXRoKS5qb2luKCcvJyk7XG4gICAgcmVzdWx0LmZyYWdtZW50ID0gcmVsc3AuZnJhZ21lbnQ7XG4gIH1cbiAgcmV0dXJuIHVuc3BsaXRVcmwocmVzdWx0KTtcbn1cblxuUmVzb2x2ZXIucHJvdG90eXBlLnJldGFpblJvb3QgPSBmdW5jdGlvbihvcmlnS2V5LCBvYmosIHJvb3QpIHtcbiAgLy8gd2FsayBvYmplY3QgYW5kIGxvb2sgZm9yIHJlbGF0aXZlICRyZWZzXG4gIGlmKF8uaXNPYmplY3Qob2JqKSkge1xuICAgIGZvcih2YXIga2V5IGluIG9iaikge1xuICAgICAgdmFyIGl0ZW0gPSBvYmpba2V5XTtcbiAgICAgIGlmIChrZXkgPT09ICckcmVmJyAmJiB0eXBlb2YgaXRlbSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgb2JqW2tleV0gPSBqb2luVXJsKHJvb3QsIGl0ZW0pO1xuICAgICAgfVxuICAgICAgZWxzZSBpZiAoXy5pc09iamVjdChpdGVtKSkge1xuICAgICAgICB0aGlzLnJldGFpblJvb3Qoa2V5LCBpdGVtLCByb290KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgZWxzZSBpZihfLmlzU3RyaW5nKG9iaikgJiYgb3JpZ0tleSA9PT0gJyRyZWYnKSB7XG4gICAgb2JqID0gam9pblVybChyb290LCBvYmopO1xuICB9XG4gIHJldHVybiBvYmo7XG59O1xuXG4vKipcbiAqIGltbWVkaWF0ZWx5IGluLWxpbmVzIGxvY2FsIHJlZnMsIHF1ZXVlcyByZW1vdGUgcmVmc1xuICogZm9yIGlubGluZSByZXNvbHV0aW9uXG4gKi9cblJlc29sdmVyLnByb3RvdHlwZS5yZXNvbHZlSW5saW5lID0gZnVuY3Rpb24gKHJvb3QsIHNwZWMsIHByb3BlcnR5LCByZXNvbHV0aW9uVGFibGUsIHVucmVzb2x2ZWRSZWZzLCBsb2NhdGlvbikge1xuICB2YXIga2V5ID0gcHJvcGVydHkuJHJlZiwgcmVmID0gcHJvcGVydHkuJHJlZiwgaSwgcCwgcDIsIHJzO1xuICB2YXIgcm9vdFRyaW1tZWQgPSBmYWxzZTtcblxuICByb290ID0gcm9vdCB8fCAnJzsgLy8gR3VhcmQgYWdhaW5zdCAuc3BsaXQuIEBmZWhndXksIHlvdSdsbCBuZWVkIHRvIGNoZWNrIGlmIHRoaXMgbG9naWMgZml0c1xuICAvLyBNb3JlIGltcG9yYW50bHkgaXMgaG93IGRvIHdlIGdyYWNlZnVsbHkgaGFuZGxlIHJlbGF0aXZlIHVybHMsIHdoZW4gcHJvdmlkZWQganVzdCBhICdzcGVjJywgbm90IGEgJ3VybCcgP1xuXG4gIGlmIChyZWYpIHtcbiAgICBpZihyZWYuaW5kZXhPZignLi4vJykgPT09IDApIHtcbiAgICAgIC8vIHJlc2V0IHJvb3RcbiAgICAgIHAgPSByZWYuc3BsaXQoJy4uLycpO1xuICAgICAgcDIgPSByb290LnNwbGl0KCcvJyk7XG4gICAgICByZWYgPSAnJztcbiAgICAgIGZvcihpID0gMDsgaSA8IHAubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYocFtpXSA9PT0gJycpIHtcbiAgICAgICAgICBwMiA9IHAyLnNsaWNlKDAsIHAyLmxlbmd0aC0xKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICByZWYgKz0gcFtpXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcm9vdCA9ICcnO1xuICAgICAgZm9yKGkgPSAwOyBpIDwgcDIubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgIGlmKGkgPiAwKSB7IHJvb3QgKz0gJy8nOyB9XG4gICAgICAgIHJvb3QgKz0gcDJbaV07XG4gICAgICB9XG4gICAgICByb290VHJpbW1lZCA9IHRydWU7XG4gICAgfVxuICAgIGlmKHJlZi5pbmRleE9mKCcjJykgPj0gMCkge1xuICAgICAgaWYocmVmLmluZGV4T2YoJy8nKSA9PT0gMCkge1xuICAgICAgICBycyA9IHJlZi5zcGxpdCgnIycpO1xuICAgICAgICBwICA9IHJvb3Quc3BsaXQoJy8vJyk7XG4gICAgICAgIHAyID0gcFsxXS5zcGxpdCgnLycpO1xuICAgICAgICByb290ID0gcFswXSArICcvLycgKyBwMlswXSArIHJzWzBdO1xuICAgICAgICBsb2NhdGlvbiA9IHJzWzFdO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHJzID0gcmVmLnNwbGl0KCcjJyk7XG4gICAgICAgIGlmKHJzWzBdICE9PSAnJykge1xuICAgICAgICAgIHAyID0gcm9vdC5zcGxpdCgnLycpO1xuICAgICAgICAgIHAyID0gcDIuc2xpY2UoMCwgcDIubGVuZ3RoIC0gMSk7XG4gICAgICAgICAgaWYoIXJvb3RUcmltbWVkKSB7XG4gICAgICAgICAgICByb290ID0gJyc7XG4gICAgICAgICAgICBmb3IgKHZhciBrID0gMDsgayA8IHAyLmxlbmd0aDsgaysrKSB7XG4gICAgICAgICAgICAgIGlmKGsgPiAwKSB7IHJvb3QgKz0gJy8nOyB9XG4gICAgICAgICAgICAgIHJvb3QgKz0gcDJba107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHJvb3QgKz0gJy8nICsgcmVmLnNwbGl0KCcjJylbMF07XG4gICAgICAgIH1cbiAgICAgICAgbG9jYXRpb24gPSByc1sxXTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHJlZi5pbmRleE9mKCdodHRwOicpID09PSAwIHx8IHJlZi5pbmRleE9mKCdodHRwczonKSA9PT0gMCkge1xuICAgICAgaWYocmVmLmluZGV4T2YoJyMnKSA+PSAwKSB7XG4gICAgICAgIHJvb3QgPSByZWYuc3BsaXQoJyMnKVswXTtcbiAgICAgICAgbG9jYXRpb24gPSByZWYuc3BsaXQoJyMnKVsxXTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICByb290ID0gcmVmO1xuICAgICAgICBsb2NhdGlvbiA9ICcnO1xuICAgICAgfVxuICAgICAgcmVzb2x1dGlvblRhYmxlLnB1c2goe29iajogcHJvcGVydHksIHJlc29sdmVBczogJ2lubGluZScsIHJvb3Q6IHJvb3QsIGtleToga2V5LCBsb2NhdGlvbjogbG9jYXRpb259KTtcbiAgICB9IGVsc2UgaWYgKHJlZi5pbmRleE9mKCcjJykgPT09IDApIHtcbiAgICAgIGxvY2F0aW9uID0gcmVmLnNwbGl0KCcjJylbMV07XG4gICAgICByZXNvbHV0aW9uVGFibGUucHVzaCh7b2JqOiBwcm9wZXJ0eSwgcmVzb2x2ZUFzOiAnaW5saW5lJywgcm9vdDogcm9vdCwga2V5OiBrZXksIGxvY2F0aW9uOiBsb2NhdGlvbn0pO1xuICAgIH0gZWxzZSBpZiAocmVmLmluZGV4T2YoJy8nKSA9PT0gMCAmJiByZWYuaW5kZXhPZignIycpID09PSAtMSkge1xuICAgICAgbG9jYXRpb24gPSByZWY7XG4gICAgICB2YXIgbWF0Y2hlcyA9IHJvb3QubWF0Y2goL15odHRwcz9cXDpcXC9cXC8oW15cXC8/I10rKSg/OltcXC8/I118JCkvaSk7XG4gICAgICBpZihtYXRjaGVzKSB7XG4gICAgICAgIHJvb3QgPSBtYXRjaGVzWzBdICsgcmVmLnN1YnN0cmluZygxKTtcbiAgICAgICAgbG9jYXRpb24gPSAnJztcbiAgICAgIH1cbiAgICAgIHJlc29sdXRpb25UYWJsZS5wdXNoKHtvYmo6IHByb3BlcnR5LCByZXNvbHZlQXM6ICdpbmxpbmUnLCByb290OiByb290LCBrZXk6IGtleSwgbG9jYXRpb246IGxvY2F0aW9ufSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgcmVzb2x1dGlvblRhYmxlLnB1c2goe29iajogcHJvcGVydHksIHJlc29sdmVBczogJ2lubGluZScsIHJvb3Q6IHJvb3QsIGtleToga2V5LCBsb2NhdGlvbjogbG9jYXRpb259KTtcbiAgICB9XG4gIH1cbiAgZWxzZSBpZiAocHJvcGVydHkudHlwZSA9PT0gJ2FycmF5Jykge1xuICAgIHRoaXMucmVzb2x2ZVRvKHJvb3QsIHByb3BlcnR5Lml0ZW1zLCByZXNvbHV0aW9uVGFibGUsIGxvY2F0aW9uKTtcbiAgfVxufTtcblxuUmVzb2x2ZXIucHJvdG90eXBlLnJlc29sdmVUbyA9IGZ1bmN0aW9uIChyb290LCBwcm9wZXJ0eSwgcmVzb2x1dGlvblRhYmxlLCBsb2NhdGlvbikge1xuICB2YXIgc3AsIGk7XG4gIHZhciByZWYgPSBwcm9wZXJ0eS4kcmVmO1xuICB2YXIgbHJvb3QgPSByb290O1xuICBpZiAoKHR5cGVvZiByZWYgIT09ICd1bmRlZmluZWQnKSAmJiAocmVmICE9PSBudWxsKSkge1xuICAgIGlmKHJlZi5pbmRleE9mKCcjJykgPj0gMCkge1xuICAgICAgdmFyIHBhcnRzID0gcmVmLnNwbGl0KCcjJyk7XG5cbiAgICAgIC8vICMvZGVmaW5pdGlvbnMvZm9vXG4gICAgICAvLyBmb28uanNvbiMvYmFyXG4gICAgICBpZihwYXJ0c1swXSAmJiByZWYuaW5kZXhPZignLycpID09PSAwKSB7XG5cbiAgICAgIH1cbiAgICAgIGVsc2UgaWYocGFydHNbMF0gJiYgKHBhcnRzWzBdLmluZGV4T2YoJ2h0dHA6JykgPT09IDAgfHwgcGFydHNbMF0uaW5kZXhPZignaHR0cHM6JykgPT09IDApKSB7XG4gICAgICAgIGxyb290ID0gcGFydHNbMF07XG4gICAgICAgIHJlZiA9IHBhcnRzWzFdO1xuICAgICAgfVxuICAgICAgZWxzZSBpZihwYXJ0c1swXSAmJiBwYXJ0c1swXS5sZW5ndGggPiAwKSB7XG4gICAgICAgIC8vIHJlbGF0aXZlIGZpbGVcbiAgICAgICAgc3AgPSByb290LnNwbGl0KCcvJyk7XG4gICAgICAgIGxyb290ID0gJyc7XG4gICAgICAgIGZvcihpID0gMDsgaSA8IHNwLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgICAgIGxyb290ICs9IHNwW2ldICsgJy8nO1xuICAgICAgICB9XG4gICAgICAgIGxyb290ICs9IHBhcnRzWzBdO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG5cbiAgICAgIH1cblxuICAgICAgbG9jYXRpb24gPSBwYXJ0c1sxXTtcbiAgICB9XG4gICAgZWxzZSBpZiAocmVmLmluZGV4T2YoJ2h0dHA6JykgPT09IDAgfHwgcmVmLmluZGV4T2YoJ2h0dHBzOicpID09PSAwKSB7XG4gICAgICBscm9vdCA9IHJlZjtcbiAgICAgIGxvY2F0aW9uID0gJyc7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgLy8gcmVsYXRpdmUgZmlsZVxuICAgICAgc3AgPSByb290LnNwbGl0KCcvJyk7XG4gICAgICBscm9vdCA9ICcnO1xuICAgICAgZm9yKGkgPSAwOyBpIDwgc3AubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgIGxyb290ICs9IHNwW2ldICsgJy8nO1xuICAgICAgfVxuICAgICAgbHJvb3QgKz0gcmVmO1xuICAgICAgbG9jYXRpb24gPSAnJztcbiAgICB9XG4gICAgcmVzb2x1dGlvblRhYmxlLnB1c2goe1xuICAgICAgb2JqOiBwcm9wZXJ0eSwgcmVzb2x2ZUFzOiAncmVmJywgcm9vdDogbHJvb3QsIGtleTogcmVmLCBsb2NhdGlvbjogbG9jYXRpb25cbiAgICB9KTtcbiAgfSBlbHNlIGlmIChwcm9wZXJ0eS50eXBlID09PSAnYXJyYXknKSB7XG4gICAgdmFyIGl0ZW1zID0gcHJvcGVydHkuaXRlbXM7XG4gICAgdGhpcy5yZXNvbHZlVG8ocm9vdCwgaXRlbXMsIHJlc29sdXRpb25UYWJsZSwgbG9jYXRpb24pO1xuICB9IGVsc2Uge1xuICAgIGlmKHByb3BlcnR5ICYmIChwcm9wZXJ0eS5wcm9wZXJ0aWVzIHx8IHByb3BlcnR5LmFkZGl0aW9uYWxQcm9wZXJ0aWVzKSkge1xuICAgICAgdmFyIG5hbWUgPSB0aGlzLnVuaXF1ZU5hbWUoJ2lubGluZV9tb2RlbCcpO1xuICAgICAgaWYgKHByb3BlcnR5LnRpdGxlKSB7XG4gICAgICAgIG5hbWUgPSB0aGlzLnVuaXF1ZU5hbWUocHJvcGVydHkudGl0bGUpO1xuICAgICAgfVxuICAgICAgZGVsZXRlIHByb3BlcnR5LnRpdGxlO1xuICAgICAgdGhpcy5zcGVjLmRlZmluaXRpb25zW25hbWVdID0gXy5jbG9uZURlZXAocHJvcGVydHkpO1xuICAgICAgcHJvcGVydHkuJHJlZiA9ICcjL2RlZmluaXRpb25zLycgKyBuYW1lO1xuICAgICAgZGVsZXRlIHByb3BlcnR5LnR5cGU7XG4gICAgICBkZWxldGUgcHJvcGVydHkucHJvcGVydGllcztcbiAgICB9XG4gIH1cbn07XG5cblJlc29sdmVyLnByb3RvdHlwZS51bmlxdWVOYW1lID0gZnVuY3Rpb24oYmFzZSkge1xuICB2YXIgbmFtZSA9IGJhc2U7XG4gIHZhciBjb3VudCA9IDA7XG4gIHdoaWxlKHRydWUpIHtcbiAgICBpZighXy5pc09iamVjdCh0aGlzLnNwZWMuZGVmaW5pdGlvbnNbbmFtZV0pKSB7XG4gICAgICByZXR1cm4gbmFtZTtcbiAgICB9XG4gICAgbmFtZSA9IGJhc2UgKyAnXycgKyBjb3VudDtcbiAgICBjb3VudCsrO1xuICB9XG59O1xuXG5SZXNvbHZlci5wcm90b3R5cGUucmVzb2x2ZUFsbE9mID0gZnVuY3Rpb24oc3BlYywgb2JqLCBkZXB0aCkge1xuICBkZXB0aCA9IGRlcHRoIHx8IDA7XG4gIG9iaiA9IG9iaiB8fCBzcGVjO1xuICB2YXIgbmFtZTtcbiAgZm9yKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgaWYgKCFvYmouaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIHZhciBpdGVtID0gb2JqW2tleV07XG4gICAgaWYoaXRlbSA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignU3dhZ2dlciAyLjAgZG9lcyBub3Qgc3VwcG9ydCBudWxsIHR5cGVzICgnICsgb2JqICsgJykuICBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3N3YWdnZXItYXBpL3N3YWdnZXItc3BlYy9pc3N1ZXMvMjI5LicpO1xuICAgIH1cbiAgICBpZih0eXBlb2YgaXRlbSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIHRoaXMucmVzb2x2ZUFsbE9mKHNwZWMsIGl0ZW0sIGRlcHRoICsgMSk7XG4gICAgfVxuICAgIGlmKGl0ZW0gJiYgdHlwZW9mIGl0ZW0uYWxsT2YgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB2YXIgYWxsT2YgPSBpdGVtLmFsbE9mO1xuICAgICAgaWYoXy5pc0FycmF5KGFsbE9mKSkge1xuICAgICAgICB2YXIgb3V0cHV0ID0gXy5jbG9uZURlZXAoaXRlbSk7XG4gICAgICAgIGRlbGV0ZSBvdXRwdXQuYWxsT2Y7XG5cbiAgICAgICAgb3V0cHV0Wyd4LWNvbXBvc2VkJ10gPSB0cnVlO1xuICAgICAgICBpZiAodHlwZW9mIGl0ZW1bJ3gtcmVzb2x2ZWQtZnJvbSddICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIG91dHB1dFsneC1yZXNvbHZlZC1mcm9tJ10gPSBpdGVtWyd4LXJlc29sdmVkLWZyb20nXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBhbGxPZi5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIHZhciBjb21wb25lbnQgPSBhbGxPZltpXTtcbiAgICAgICAgICB2YXIgc291cmNlID0gJ3NlbGYnO1xuICAgICAgICAgIGlmKHR5cGVvZiBjb21wb25lbnRbJ3gtcmVzb2x2ZWQtZnJvbSddICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgc291cmNlID0gY29tcG9uZW50Wyd4LXJlc29sdmVkLWZyb20nXVswXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBmb3IodmFyIHBhcnQgaW4gY29tcG9uZW50KSB7XG4gICAgICAgICAgICBpZighb3V0cHV0Lmhhc093blByb3BlcnR5KHBhcnQpKSB7XG4gICAgICAgICAgICAgIG91dHB1dFtwYXJ0XSA9IF8uY2xvbmVEZWVwKGNvbXBvbmVudFtwYXJ0XSk7XG4gICAgICAgICAgICAgIGlmKHBhcnQgPT09ICdwcm9wZXJ0aWVzJykge1xuICAgICAgICAgICAgICAgIGZvcihuYW1lIGluIG91dHB1dFtwYXJ0XSkge1xuICAgICAgICAgICAgICAgICAgb3V0cHV0W3BhcnRdW25hbWVdWyd4LXJlc29sdmVkLWZyb20nXSA9IHNvdXJjZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICBpZihwYXJ0ID09PSAncHJvcGVydGllcycpIHtcbiAgICAgICAgICAgICAgICB2YXIgcHJvcGVydGllcyA9IGNvbXBvbmVudFtwYXJ0XTtcbiAgICAgICAgICAgICAgICBmb3IobmFtZSBpbiBwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICAgICAgICBvdXRwdXQucHJvcGVydGllc1tuYW1lXSA9IF8uY2xvbmVEZWVwKHByb3BlcnRpZXNbbmFtZV0pO1xuICAgICAgICAgICAgICAgICAgdmFyIHJlc29sdmVkRnJvbSA9IHByb3BlcnRpZXNbbmFtZV1bJ3gtcmVzb2x2ZWQtZnJvbSddO1xuICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiByZXNvbHZlZEZyb20gPT09ICd1bmRlZmluZWQnIHx8IHJlc29sdmVkRnJvbSA9PT0gJ3NlbGYnKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmVkRnJvbSA9IHNvdXJjZTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIG91dHB1dC5wcm9wZXJ0aWVzW25hbWVdWyd4LXJlc29sdmVkLWZyb20nXSA9IHJlc29sdmVkRnJvbTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZWxzZSBpZihwYXJ0ID09PSAncmVxdWlyZWQnKSB7XG4gICAgICAgICAgICAgICAgLy8gbWVyZ2UgJiBkZWR1cCB0aGUgcmVxdWlyZWQgYXJyYXlcbiAgICAgICAgICAgICAgICB2YXIgYSA9IG91dHB1dC5yZXF1aXJlZC5jb25jYXQoY29tcG9uZW50W3BhcnRdKTtcbiAgICAgICAgICAgICAgICBmb3IodmFyIGsgPSAwOyBrIDwgYS5sZW5ndGg7ICsraykge1xuICAgICAgICAgICAgICAgICAgZm9yKHZhciBqID0gayArIDE7IGogPCBhLmxlbmd0aDsgKytqKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmKGFba10gPT09IGFbal0pIHsgYS5zcGxpY2Uoai0tLCAxKTsgfVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBvdXRwdXQucmVxdWlyZWQgPSBhO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGVsc2UgaWYocGFydCA9PT0gJ3gtcmVzb2x2ZWQtZnJvbScpIHtcbiAgICAgICAgICAgICAgICBvdXRwdXRbJ3gtcmVzb2x2ZWQtZnJvbSddLnB1c2goc291cmNlKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBUT0RPOiBuZWVkIHRvIG1lcmdlIHRoaXMgcHJvcGVydHlcbiAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZygnd2hhdCB0byBkbyB3aXRoICcgKyBwYXJ0KVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIG9ialtrZXldID0gb3V0cHV0O1xuICAgICAgfVxuICAgIH1cbiAgfVxufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIEhlbHBlcnMgPSByZXF1aXJlKCcuL2hlbHBlcnMnKTtcblxudmFyIF8gPSB7XG4gIGlzUGxhaW5PYmplY3Q6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc1BsYWluT2JqZWN0JyksXG4gIGlzVW5kZWZpbmVkOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNVbmRlZmluZWQnKSxcbiAgaXNBcnJheTogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzQXJyYXknKSxcbiAgaXNPYmplY3Q6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc09iamVjdCcpLFxuICBpc0VtcHR5OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNFbXB0eScpLFxuICBtYXA6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvY29sbGVjdGlvbi9tYXAnKSxcbiAgaW5kZXhPZjogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9hcnJheS9pbmRleE9mJyksXG4gIGNsb25lRGVlcDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2Nsb25lRGVlcCcpLFxuICBrZXlzOiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L29iamVjdC9rZXlzJyksXG4gIGZvckVhY2g6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvY29sbGVjdGlvbi9mb3JFYWNoJylcbn07XG5cbnZhciBvcHRpb25IdG1sID0gbW9kdWxlLmV4cG9ydHMub3B0aW9uSHRtbCA9IGZ1bmN0aW9uICAobGFiZWwsIHZhbHVlKSB7XG4gIHJldHVybiAnPHRyPjx0ZCBjbGFzcz1cIm9wdGlvbk5hbWVcIj4nICsgbGFiZWwgKyAnOjwvdGQ+PHRkPicgKyB2YWx1ZSArICc8L3RkPjwvdHI+Jztcbn07XG5cbm1vZHVsZS5leHBvcnRzLnR5cGVGcm9tSnNvblNjaGVtYSA9IGZ1bmN0aW9uICh0eXBlLCBmb3JtYXQpIHtcbiAgdmFyIHN0cjtcblxuICBpZiAodHlwZSA9PT0gJ2ludGVnZXInICYmIGZvcm1hdCA9PT0gJ2ludDMyJykge1xuICAgIHN0ciA9ICdpbnRlZ2VyJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnaW50ZWdlcicgJiYgZm9ybWF0ID09PSAnaW50NjQnKSB7XG4gICAgc3RyID0gJ2xvbmcnO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdpbnRlZ2VyJyAmJiB0eXBlb2YgZm9ybWF0ID09PSAndW5kZWZpbmVkJykge1xuICAgIHN0ciA9ICdsb25nJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnc3RyaW5nJyAmJiBmb3JtYXQgPT09ICdkYXRlLXRpbWUnKSB7XG4gICAgc3RyID0gJ2RhdGUtdGltZSc7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3N0cmluZycgJiYgZm9ybWF0ID09PSAnZGF0ZScpIHtcbiAgICBzdHIgPSAnZGF0ZSc7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ251bWJlcicgJiYgZm9ybWF0ID09PSAnZmxvYXQnKSB7XG4gICAgc3RyID0gJ2Zsb2F0JztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJyAmJiBmb3JtYXQgPT09ICdkb3VibGUnKSB7XG4gICAgc3RyID0gJ2RvdWJsZSc7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ251bWJlcicgJiYgdHlwZW9mIGZvcm1hdCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBzdHIgPSAnZG91YmxlJztcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnYm9vbGVhbicpIHtcbiAgICBzdHIgPSAnYm9vbGVhbic7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICBzdHIgPSAnc3RyaW5nJztcbiAgfVxuXG4gIHJldHVybiBzdHI7XG59O1xuXG52YXIgZ2V0U3RyaW5nU2lnbmF0dXJlID0gbW9kdWxlLmV4cG9ydHMuZ2V0U3RyaW5nU2lnbmF0dXJlID0gZnVuY3Rpb24gKG9iaiwgYmFzZUNvbXBvbmVudCkge1xuICB2YXIgc3RyID0gJyc7XG5cbiAgaWYgKHR5cGVvZiBvYmouJHJlZiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBzdHIgKz0gSGVscGVycy5zaW1wbGVSZWYob2JqLiRyZWYpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBvYmoudHlwZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBzdHIgKz0gJ29iamVjdCc7XG4gIH0gZWxzZSBpZiAob2JqLnR5cGUgPT09ICdhcnJheScpIHtcbiAgICBpZiAoYmFzZUNvbXBvbmVudCkge1xuICAgICAgc3RyICs9IGdldFN0cmluZ1NpZ25hdHVyZSgob2JqLml0ZW1zIHx8IG9iai4kcmVmIHx8IHt9KSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0ciArPSAnQXJyYXlbJztcbiAgICAgIHN0ciArPSBnZXRTdHJpbmdTaWduYXR1cmUoKG9iai5pdGVtcyB8fCBvYmouJHJlZiB8fCB7fSkpO1xuICAgICAgc3RyICs9ICddJztcbiAgICB9XG4gIH0gZWxzZSBpZiAob2JqLnR5cGUgPT09ICdpbnRlZ2VyJyAmJiBvYmouZm9ybWF0ID09PSAnaW50MzInKSB7XG4gICAgc3RyICs9ICdpbnRlZ2VyJztcbiAgfSBlbHNlIGlmIChvYmoudHlwZSA9PT0gJ2ludGVnZXInICYmIG9iai5mb3JtYXQgPT09ICdpbnQ2NCcpIHtcbiAgICBzdHIgKz0gJ2xvbmcnO1xuICB9IGVsc2UgaWYgKG9iai50eXBlID09PSAnaW50ZWdlcicgJiYgdHlwZW9mIG9iai5mb3JtYXQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgc3RyICs9ICdsb25nJztcbiAgfSBlbHNlIGlmIChvYmoudHlwZSA9PT0gJ3N0cmluZycgJiYgb2JqLmZvcm1hdCA9PT0gJ2RhdGUtdGltZScpIHtcbiAgICBzdHIgKz0gJ2RhdGUtdGltZSc7XG4gIH0gZWxzZSBpZiAob2JqLnR5cGUgPT09ICdzdHJpbmcnICYmIG9iai5mb3JtYXQgPT09ICdkYXRlJykge1xuICAgIHN0ciArPSAnZGF0ZSc7XG4gIH0gZWxzZSBpZiAob2JqLnR5cGUgPT09ICdzdHJpbmcnICYmIHR5cGVvZiBvYmouZm9ybWF0ID09PSAndW5kZWZpbmVkJykge1xuICAgIHN0ciArPSAnc3RyaW5nJztcbiAgfSBlbHNlIGlmIChvYmoudHlwZSA9PT0gJ251bWJlcicgJiYgb2JqLmZvcm1hdCA9PT0gJ2Zsb2F0Jykge1xuICAgIHN0ciArPSAnZmxvYXQnO1xuICB9IGVsc2UgaWYgKG9iai50eXBlID09PSAnbnVtYmVyJyAmJiBvYmouZm9ybWF0ID09PSAnZG91YmxlJykge1xuICAgIHN0ciArPSAnZG91YmxlJztcbiAgfSBlbHNlIGlmIChvYmoudHlwZSA9PT0gJ251bWJlcicgJiYgdHlwZW9mIG9iai5mb3JtYXQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgc3RyICs9ICdkb3VibGUnO1xuICB9IGVsc2UgaWYgKG9iai50eXBlID09PSAnYm9vbGVhbicpIHtcbiAgICBzdHIgKz0gJ2Jvb2xlYW4nO1xuICB9IGVsc2UgaWYgKG9iai4kcmVmKSB7XG4gICAgc3RyICs9IEhlbHBlcnMuc2ltcGxlUmVmKG9iai4kcmVmKTtcbiAgfSBlbHNlIHtcbiAgICBzdHIgKz0gb2JqLnR5cGU7XG4gIH1cblxuICByZXR1cm4gc3RyO1xufTtcblxudmFyIHNjaGVtYVRvSlNPTiA9IG1vZHVsZS5leHBvcnRzLnNjaGVtYVRvSlNPTiA9IGZ1bmN0aW9uIChzY2hlbWEsIG1vZGVscywgbW9kZWxzVG9JZ25vcmUsIG1vZGVsUHJvcGVydHlNYWNybykge1xuICAvLyBSZXNvbHZlIHRoZSBzY2hlbWEgKEhhbmRsZSBuZXN0ZWQgc2NoZW1hcylcbiAgc2NoZW1hID0gSGVscGVycy5yZXNvbHZlU2NoZW1hKHNjaGVtYSk7XG5cbiAgaWYodHlwZW9mIG1vZGVsUHJvcGVydHlNYWNybyAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIG1vZGVsUHJvcGVydHlNYWNybyA9IGZ1bmN0aW9uKHByb3Ape1xuICAgICAgcmV0dXJuIChwcm9wIHx8IHt9KS5kZWZhdWx0O1xuICAgIH07XG4gIH1cblxuICBtb2RlbHNUb0lnbm9yZT0gbW9kZWxzVG9JZ25vcmUgfHwge307XG5cbiAgdmFyIHR5cGUgPSBzY2hlbWEudHlwZSB8fCAnb2JqZWN0JztcbiAgdmFyIGZvcm1hdCA9IHNjaGVtYS5mb3JtYXQ7XG4gIHZhciBtb2RlbDtcbiAgdmFyIG91dHB1dDtcblxuICBpZiAoIV8uaXNVbmRlZmluZWQoc2NoZW1hLmV4YW1wbGUpKSB7XG4gICAgb3V0cHV0ID0gc2NoZW1hLmV4YW1wbGU7XG4gIH0gZWxzZSBpZiAoXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMpICYmIF8uaXNBcnJheShzY2hlbWEuZW51bSkpIHtcbiAgICBvdXRwdXQgPSBzY2hlbWEuZW51bVswXTtcbiAgfVxuXG4gIGlmIChfLmlzVW5kZWZpbmVkKG91dHB1dCkpIHtcbiAgICBpZiAoc2NoZW1hLiRyZWYpIHtcbiAgICAgIG1vZGVsID0gbW9kZWxzW0hlbHBlcnMuc2ltcGxlUmVmKHNjaGVtYS4kcmVmKV07XG5cbiAgICAgIGlmICghXy5pc1VuZGVmaW5lZChtb2RlbCkpIHtcbiAgICAgICAgaWYgKF8uaXNVbmRlZmluZWQobW9kZWxzVG9JZ25vcmVbbW9kZWwubmFtZV0pKSB7XG4gICAgICAgICAgbW9kZWxzVG9JZ25vcmVbbW9kZWwubmFtZV0gPSBtb2RlbDtcbiAgICAgICAgICBvdXRwdXQgPSBzY2hlbWFUb0pTT04obW9kZWwuZGVmaW5pdGlvbiwgbW9kZWxzLCBtb2RlbHNUb0lnbm9yZSwgbW9kZWxQcm9wZXJ0eU1hY3JvKTtcbiAgICAgICAgICBkZWxldGUgbW9kZWxzVG9JZ25vcmVbbW9kZWwubmFtZV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKG1vZGVsLnR5cGUgPT09ICdhcnJheScpIHtcbiAgICAgICAgICAgIG91dHB1dCA9IFtdO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBvdXRwdXQgPSB7fTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKCFfLmlzVW5kZWZpbmVkKHNjaGVtYS5kZWZhdWx0KSkge1xuICAgICAgb3V0cHV0ID0gc2NoZW1hLmRlZmF1bHQ7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgaWYgKGZvcm1hdCA9PT0gJ2RhdGUtdGltZScpIHtcbiAgICAgICAgb3V0cHV0ID0gbmV3IERhdGUoKS50b0lTT1N0cmluZygpO1xuICAgICAgfSBlbHNlIGlmIChmb3JtYXQgPT09ICdkYXRlJykge1xuICAgICAgICBvdXRwdXQgPSBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCkuc3BsaXQoJ1QnKVswXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG91dHB1dCA9ICdzdHJpbmcnO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2ludGVnZXInKSB7XG4gICAgICBvdXRwdXQgPSAwO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ251bWJlcicpIHtcbiAgICAgIG91dHB1dCA9IDAuMDtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdib29sZWFuJykge1xuICAgICAgb3V0cHV0ID0gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgICBvdXRwdXQgPSB7fTtcblxuICAgICAgXy5mb3JFYWNoKHNjaGVtYS5wcm9wZXJ0aWVzLCBmdW5jdGlvbiAocHJvcGVydHksIG5hbWUpIHtcbiAgICAgICAgdmFyIGNQcm9wZXJ0eSA9IF8uY2xvbmVEZWVwKHByb3BlcnR5KTtcblxuICAgICAgICAvLyBBbGxvdyBtYWNybyB0byBzZXQgdGhlIGRlZmF1bHQgdmFsdWVcbiAgICAgICAgY1Byb3BlcnR5LmRlZmF1bHQgPSBtb2RlbFByb3BlcnR5TWFjcm8ocHJvcGVydHkpO1xuXG4gICAgICAgIG91dHB1dFtuYW1lXSA9IHNjaGVtYVRvSlNPTihjUHJvcGVydHksIG1vZGVscywgbW9kZWxzVG9JZ25vcmUsIG1vZGVsUHJvcGVydHlNYWNybyk7XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdhcnJheScpIHtcbiAgICAgIG91dHB1dCA9IFtdO1xuXG4gICAgICBpZiAoXy5pc0FycmF5KHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgXy5mb3JFYWNoKHNjaGVtYS5pdGVtcywgZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgICBvdXRwdXQucHVzaChzY2hlbWFUb0pTT04oaXRlbSwgbW9kZWxzLCBtb2RlbHNUb0lnbm9yZSwgbW9kZWxQcm9wZXJ0eU1hY3JvKSk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmIChfLmlzUGxhaW5PYmplY3Qoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICBvdXRwdXQucHVzaChzY2hlbWFUb0pTT04oc2NoZW1hLml0ZW1zLCBtb2RlbHMsIG1vZGVsc1RvSWdub3JlLCBtb2RlbFByb3BlcnR5TWFjcm8pKTtcbiAgICAgIH0gZWxzZSBpZiAoXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMpKSB7XG4gICAgICAgIG91dHB1dC5wdXNoKHt9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIEhlbHBlcnMubG9nKCdBcnJheSB0eXBlXFwncyBcXCdpdGVtc1xcJyBwcm9wZXJ0eSBpcyBub3QgYW4gYXJyYXkgb3IgYW4gb2JqZWN0LCBjYW5ub3QgcHJvY2VzcycpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvdXRwdXQ7XG59O1xuXG5tb2R1bGUuZXhwb3J0cy5zY2hlbWFUb0hUTUwgPWZ1bmN0aW9uIChuYW1lLCBzY2hlbWEsIG1vZGVscywgbW9kZWxQcm9wZXJ0eU1hY3JvKSB7XG4gIHZhciBzdHJvbmdPcGVuID0gJzxzcGFuIGNsYXNzPVwic3Ryb25nXCI+JztcbiAgdmFyIHN0cm9uZ0Nsb3NlID0gJzwvc3Bhbj4nO1xuXG4gIC8vIEFsbG93IGZvciBpZ25vcmluZyB0aGUgJ25hbWUnIGFyZ3VtZW50Li4uLiBzaGlmdGluZyB0aGUgcmVzdFxuICBpZihfLmlzT2JqZWN0KGFyZ3VtZW50c1swXSkpIHtcbiAgICBuYW1lID0gdm9pZCAwO1xuICAgIHNjaGVtYSA9IGFyZ3VtZW50c1swXTtcbiAgICBtb2RlbHMgPSBhcmd1bWVudHNbMV07XG4gICAgbW9kZWxQcm9wZXJ0eU1hY3JvID0gYXJndW1lbnRzWzJdO1xuICB9XG5cbiAgbW9kZWxzID0gbW9kZWxzIHx8IHt9O1xuXG4gIC8vIFJlc29sdmUgdGhlIHNjaGVtYSAoSGFuZGxlIG5lc3RlZCBzY2hlbWFzKVxuICBzY2hlbWEgPSBIZWxwZXJzLnJlc29sdmVTY2hlbWEoc2NoZW1hKTtcblxuICAvLyBSZXR1cm4gZm9yIGVtcHR5IG9iamVjdFxuICBpZihfLmlzRW1wdHkoc2NoZW1hKSkge1xuICAgIHJldHVybiBzdHJvbmdPcGVuICsgJ0VtcHR5JyArIHN0cm9uZ0Nsb3NlO1xuICB9XG5cbiAgLy8gRGVyZWZlcmVuY2UgJHJlZiBmcm9tICdtb2RlbHMnXG4gIGlmKHR5cGVvZiBzY2hlbWEuJHJlZiA9PT0gJ3N0cmluZycpIHtcbiAgICBuYW1lID0gSGVscGVycy5zaW1wbGVSZWYoc2NoZW1hLiRyZWYpO1xuICAgIHNjaGVtYSA9IG1vZGVsc1tuYW1lXTtcbiAgICBpZih0eXBlb2Ygc2NoZW1hID09PSAndW5kZWZpbmVkJylcbiAgICB7XG4gICAgICByZXR1cm4gc3Ryb25nT3BlbiArIG5hbWUgKyAnIGlzIG5vdCBkZWZpbmVkIScgKyBzdHJvbmdDbG9zZTtcbiAgICB9XG4gIH1cblxuICBpZih0eXBlb2YgbmFtZSAhPT0gJ3N0cmluZycpIHtcbiAgICBuYW1lID0gc2NoZW1hLnRpdGxlIHx8ICdJbmxpbmUgTW9kZWwnO1xuICB9XG5cbiAgLy8gSWYgd2UgYXJlIGEgTW9kZWwgb2JqZWN0Li4uIGFkanVzdCBhY2NvcmRpbmdseVxuICBpZihzY2hlbWEuZGVmaW5pdGlvbikge1xuICAgIHNjaGVtYSA9IHNjaGVtYS5kZWZpbml0aW9uO1xuICB9XG5cbiAgaWYodHlwZW9mIG1vZGVsUHJvcGVydHlNYWNybyAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIG1vZGVsUHJvcGVydHlNYWNybyA9IGZ1bmN0aW9uKHByb3Ape1xuICAgICAgcmV0dXJuIChwcm9wIHx8IHt9KS5kZWZhdWx0O1xuICAgIH07XG4gIH1cblxuICB2YXIgcmVmZXJlbmNlcyA9IHt9O1xuICB2YXIgc2Vlbk1vZGVscyA9IFtdO1xuICB2YXIgaW5saW5lTW9kZWxzID0gMDtcblxuXG5cbiAgLy8gR2VuZXJhdGUgY3VycmVudCBIVE1MXG4gIHZhciBodG1sID0gcHJvY2Vzc01vZGVsKHNjaGVtYSwgbmFtZSk7XG5cbiAgLy8gR2VuZXJhdGUgcmVmZXJlbmNlcyBIVE1MXG4gIHdoaWxlIChfLmtleXMocmVmZXJlbmNlcykubGVuZ3RoID4gMCkge1xuICAgIC8qIGpzaGludCBpZ25vcmU6c3RhcnQgKi9cbiAgICBfLmZvckVhY2gocmVmZXJlbmNlcywgZnVuY3Rpb24gKHNjaGVtYSwgbmFtZSkge1xuICAgICAgdmFyIHNlZW5Nb2RlbCA9IF8uaW5kZXhPZihzZWVuTW9kZWxzLCBuYW1lKSA+IC0xO1xuXG4gICAgICBkZWxldGUgcmVmZXJlbmNlc1tuYW1lXTtcblxuICAgICAgaWYgKCFzZWVuTW9kZWwpIHtcbiAgICAgICAgc2Vlbk1vZGVscy5wdXNoKG5hbWUpO1xuXG4gICAgICAgIGh0bWwgKz0gJzxiciAvPicgKyBwcm9jZXNzTW9kZWwoc2NoZW1hLCBuYW1lKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICAvKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuICB9XG5cbiAgcmV0dXJuIGh0bWw7XG5cbiAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbiAgZnVuY3Rpb24gYWRkUmVmZXJlbmNlKHNjaGVtYSwgbmFtZSwgc2tpcFJlZikge1xuICAgIHZhciBtb2RlbE5hbWUgPSBuYW1lO1xuICAgIHZhciBtb2RlbDtcblxuICAgIGlmIChzY2hlbWEuJHJlZikge1xuICAgICAgbW9kZWxOYW1lID0gc2NoZW1hLnRpdGxlIHx8IEhlbHBlcnMuc2ltcGxlUmVmKHNjaGVtYS4kcmVmKTtcbiAgICAgIG1vZGVsID0gbW9kZWxzW21vZGVsTmFtZV07XG4gICAgfSBlbHNlIGlmIChfLmlzVW5kZWZpbmVkKG5hbWUpKSB7XG4gICAgICBtb2RlbE5hbWUgPSBzY2hlbWEudGl0bGUgfHwgJ0lubGluZSBNb2RlbCAnICsgKCsraW5saW5lTW9kZWxzKTtcbiAgICAgIG1vZGVsID0ge2RlZmluaXRpb246IHNjaGVtYX07XG4gICAgfVxuXG4gICAgaWYgKHNraXBSZWYgIT09IHRydWUpIHtcbiAgICAgIHJlZmVyZW5jZXNbbW9kZWxOYW1lXSA9IF8uaXNVbmRlZmluZWQobW9kZWwpID8ge30gOiBtb2RlbC5kZWZpbml0aW9uO1xuICAgIH1cblxuICAgIHJldHVybiBtb2RlbE5hbWU7XG4gIH1cblxuICBmdW5jdGlvbiBwcmltaXRpdmVUb0hUTUwoc2NoZW1hKSB7XG4gICAgdmFyIGh0bWwgPSAnPHNwYW4gY2xhc3M9XCJwcm9wVHlwZVwiPic7XG4gICAgdmFyIHR5cGUgPSBzY2hlbWEudHlwZSB8fCAnb2JqZWN0JztcblxuICAgIGlmIChzY2hlbWEuJHJlZikge1xuICAgICAgaHRtbCArPSBhZGRSZWZlcmVuY2Uoc2NoZW1hLCBIZWxwZXJzLnNpbXBsZVJlZihzY2hlbWEuJHJlZikpO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGlmICghXy5pc1VuZGVmaW5lZChzY2hlbWEucHJvcGVydGllcykpIHtcbiAgICAgICAgaHRtbCArPSBhZGRSZWZlcmVuY2Uoc2NoZW1hKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGh0bWwgKz0gJ29iamVjdCc7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnYXJyYXknKSB7XG4gICAgICBodG1sICs9ICdBcnJheVsnO1xuXG4gICAgICBpZiAoXy5pc0FycmF5KHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgaHRtbCArPSBfLm1hcChzY2hlbWEuaXRlbXMsIGFkZFJlZmVyZW5jZSkuam9pbignLCcpO1xuICAgICAgfSBlbHNlIGlmIChfLmlzUGxhaW5PYmplY3Qoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICBpZiAoXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMuJHJlZikpIHtcbiAgICAgICAgICBpZiAoIV8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zLnR5cGUpICYmIF8uaW5kZXhPZihbJ2FycmF5JywgJ29iamVjdCddLCBzY2hlbWEuaXRlbXMudHlwZSkgPT09IC0xKSB7XG4gICAgICAgICAgICBodG1sICs9IHNjaGVtYS5pdGVtcy50eXBlO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBodG1sICs9IGFkZFJlZmVyZW5jZShzY2hlbWEuaXRlbXMpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBodG1sICs9IGFkZFJlZmVyZW5jZShzY2hlbWEuaXRlbXMsIEhlbHBlcnMuc2ltcGxlUmVmKHNjaGVtYS5pdGVtcy4kcmVmKSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIEhlbHBlcnMubG9nKCdBcnJheSB0eXBlXFwncyBcXCdpdGVtc1xcJyBzY2hlbWEgaXMgbm90IGFuIGFycmF5IG9yIGFuIG9iamVjdCwgY2Fubm90IHByb2Nlc3MnKTtcbiAgICAgICAgaHRtbCArPSAnb2JqZWN0JztcbiAgICAgIH1cblxuICAgICAgaHRtbCArPSAnXSc7XG4gICAgfSBlbHNlIHtcbiAgICAgIGh0bWwgKz0gc2NoZW1hLnR5cGU7XG4gICAgfVxuXG4gICAgaHRtbCArPSAnPC9zcGFuPic7XG5cbiAgICByZXR1cm4gaHRtbDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHByaW1pdGl2ZVRvT3B0aW9uc0hUTUwoc2NoZW1hLCBodG1sKSB7XG4gICAgdmFyIG9wdGlvbnMgPSAnJztcbiAgICB2YXIgdHlwZSA9IHNjaGVtYS50eXBlIHx8ICdvYmplY3QnO1xuICAgIHZhciBpc0FycmF5ID0gdHlwZSA9PT0gJ2FycmF5JztcblxuICAgIGlmIChpc0FycmF5KSB7XG4gICAgICBpZiAoXy5pc1BsYWluT2JqZWN0KHNjaGVtYS5pdGVtcykgJiYgIV8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zLnR5cGUpKSB7XG4gICAgICAgIHR5cGUgPSBzY2hlbWEuaXRlbXMudHlwZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHR5cGUgPSAnb2JqZWN0JztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIV8uaXNVbmRlZmluZWQoc2NoZW1hLmRlZmF1bHQpKSB7XG4gICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ0RlZmF1bHQnLCBzY2hlbWEuZGVmYXVsdCk7XG4gICAgfVxuXG4gICAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSAnc3RyaW5nJzpcbiAgICAgIGlmIChzY2hlbWEubWluTGVuZ3RoKSB7XG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnTWluLiBMZW5ndGgnLCBzY2hlbWEubWluTGVuZ3RoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNjaGVtYS5tYXhMZW5ndGgpIHtcbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdNYXguIExlbmd0aCcsIHNjaGVtYS5tYXhMZW5ndGgpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NoZW1hLnBhdHRlcm4pIHtcbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdSZWcuIEV4cC4nLCBzY2hlbWEucGF0dGVybik7XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICBjYXNlICdpbnRlZ2VyJzpcbiAgICBjYXNlICdudW1iZXInOlxuICAgICAgaWYgKHNjaGVtYS5taW5pbXVtKSB7XG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnTWluLiBWYWx1ZScsIHNjaGVtYS5taW5pbXVtKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHNjaGVtYS5leGNsdXNpdmVNaW5pbXVtKSB7XG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnRXhjbHVzaXZlIE1pbi4nLCAndHJ1ZScpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NoZW1hLm1heGltdW0pIHtcbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdNYXguIFZhbHVlJywgc2NoZW1hLm1heGltdW0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NoZW1hLmV4Y2x1c2l2ZU1heGltdW0pIHtcbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdFeGNsdXNpdmUgTWF4LicsICd0cnVlJyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2hlbWEubXVsdGlwbGVPZikge1xuICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ011bHRpcGxlIE9mJywgc2NoZW1hLm11bHRpcGxlT2YpO1xuICAgICAgfVxuXG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICBpZiAoaXNBcnJheSkge1xuICAgICAgaWYgKHNjaGVtYS5taW5JdGVtcykge1xuICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ01pbi4gSXRlbXMnLCBzY2hlbWEubWluSXRlbXMpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NoZW1hLm1heEl0ZW1zKSB7XG4gICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnTWF4LiBJdGVtcycsIHNjaGVtYS5tYXhJdGVtcyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2hlbWEudW5pcXVlSXRlbXMpIHtcbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdVbmlxdWUgSXRlbXMnLCAndHJ1ZScpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2NoZW1hLmNvbGxlY3Rpb25Gb3JtYXQpIHtcbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdDb2xsLiBGb3JtYXQnLCBzY2hlbWEuY29sbGVjdGlvbkZvcm1hdCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKF8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgaWYgKF8uaXNBcnJheShzY2hlbWEuZW51bSkpIHtcbiAgICAgICAgdmFyIGVudW1TdHJpbmc7XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdudW1iZXInIHx8IHR5cGUgPT09ICdpbnRlZ2VyJykge1xuICAgICAgICAgIGVudW1TdHJpbmcgPSBzY2hlbWEuZW51bS5qb2luKCcsICcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVudW1TdHJpbmcgPSAnXCInICsgc2NoZW1hLmVudW0uam9pbignXCIsIFwiJykgKyAnXCInO1xuICAgICAgICB9XG5cbiAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdFbnVtJywgZW51bVN0cmluZyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMubGVuZ3RoID4gMCkge1xuICAgICAgaHRtbCA9ICc8c3BhbiBjbGFzcz1cInByb3BXcmFwXCI+JyArIGh0bWwgKyAnPHRhYmxlIGNsYXNzPVwib3B0aW9uc1dyYXBwZXJcIj48dHI+PHRoIGNvbHNwYW49XCIyXCI+JyArIHR5cGUgKyAnPC90aD48L3RyPicgKyBvcHRpb25zICsgJzwvdGFibGU+PC9zcGFuPic7XG4gICAgfVxuXG4gICAgcmV0dXJuIGh0bWw7XG4gIH1cblxuICBmdW5jdGlvbiBwcm9jZXNzTW9kZWwoc2NoZW1hLCBuYW1lKSB7XG4gICAgdmFyIHR5cGUgPSBzY2hlbWEudHlwZSB8fCAnb2JqZWN0JztcbiAgICB2YXIgaXNBcnJheSA9IHNjaGVtYS50eXBlID09PSAnYXJyYXknO1xuICAgIHZhciBodG1sID0gc3Ryb25nT3BlbiArIG5hbWUgKyAnICcgKyAoaXNBcnJheSA/ICdbJyA6ICd7JykgKyBzdHJvbmdDbG9zZTtcblxuICAgIGlmIChuYW1lKSB7XG4gICAgICBzZWVuTW9kZWxzLnB1c2gobmFtZSk7XG4gICAgfVxuXG4gICAgaWYgKGlzQXJyYXkpIHtcbiAgICAgIGlmIChfLmlzQXJyYXkoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICBodG1sICs9ICc8ZGl2PicgKyBfLm1hcChzY2hlbWEuaXRlbXMsIGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgdmFyIHR5cGUgPSBpdGVtLnR5cGUgfHwgJ29iamVjdCc7XG5cbiAgICAgICAgICBpZiAoXy5pc1VuZGVmaW5lZChpdGVtLiRyZWYpKSB7XG4gICAgICAgICAgICBpZiAoXy5pbmRleE9mKFsnYXJyYXknLCAnb2JqZWN0J10sIHR5cGUpID4gLTEpIHtcbiAgICAgICAgICAgICAgaWYgKHR5cGUgPT09ICdvYmplY3QnICYmIF8uaXNVbmRlZmluZWQoaXRlbS5wcm9wZXJ0aWVzKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiAnb2JqZWN0JztcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYWRkUmVmZXJlbmNlKGl0ZW0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXR1cm4gcHJpbWl0aXZlVG9PcHRpb25zSFRNTChpdGVtLCB0eXBlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGFkZFJlZmVyZW5jZShpdGVtLCBIZWxwZXJzLnNpbXBsZVJlZihpdGVtLiRyZWYpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pLmpvaW4oJyw8L2Rpdj48ZGl2PicpO1xuICAgICAgfSBlbHNlIGlmIChfLmlzUGxhaW5PYmplY3Qoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICBpZiAoXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMuJHJlZikpIHtcbiAgICAgICAgICBpZiAoXy5pbmRleE9mKFsnYXJyYXknLCAnb2JqZWN0J10sIHNjaGVtYS5pdGVtcy50eXBlIHx8ICdvYmplY3QnKSA+IC0xKSB7XG4gICAgICAgICAgICBpZiAoKF8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zLnR5cGUpIHx8IHNjaGVtYS5pdGVtcy50eXBlID09PSAnb2JqZWN0JykgJiYgXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMucHJvcGVydGllcykpIHtcbiAgICAgICAgICAgICAgaHRtbCArPSAnPGRpdj5vYmplY3Q8L2Rpdj4nO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgaHRtbCArPSAnPGRpdj4nICsgYWRkUmVmZXJlbmNlKHNjaGVtYS5pdGVtcykgKyAnPC9kaXY+JztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaHRtbCArPSAnPGRpdj4nICsgcHJpbWl0aXZlVG9PcHRpb25zSFRNTChzY2hlbWEuaXRlbXMsIHNjaGVtYS5pdGVtcy50eXBlKSArICc8L2Rpdj4nO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBodG1sICs9ICc8ZGl2PicgKyBhZGRSZWZlcmVuY2Uoc2NoZW1hLml0ZW1zLCBIZWxwZXJzLnNpbXBsZVJlZihzY2hlbWEuaXRlbXMuJHJlZikpICsgJzwvZGl2Pic7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIEhlbHBlcnMubG9nKCdBcnJheSB0eXBlXFwncyBcXCdpdGVtc1xcJyBwcm9wZXJ0eSBpcyBub3QgYW4gYXJyYXkgb3IgYW4gb2JqZWN0LCBjYW5ub3QgcHJvY2VzcycpO1xuICAgICAgICBodG1sICs9ICc8ZGl2Pm9iamVjdDwvZGl2Pic7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChzY2hlbWEuJHJlZikge1xuICAgICAgICBodG1sICs9ICc8ZGl2PicgKyBhZGRSZWZlcmVuY2Uoc2NoZW1hLCBuYW1lKSArICc8L2Rpdj4nO1xuICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnb2JqZWN0Jykge1xuICAgICAgICBpZiAoXy5pc1BsYWluT2JqZWN0KHNjaGVtYS5wcm9wZXJ0aWVzKSkge1xuICAgICAgICAgIHZhciBjb250ZW50cyA9IF8ubWFwKHNjaGVtYS5wcm9wZXJ0aWVzLCBmdW5jdGlvbiAocHJvcGVydHksIG5hbWUpIHtcbiAgICAgICAgICAgIHZhciBwcm9wZXJ0eUlzUmVxdWlyZWQgPSAoXy5pbmRleE9mKHNjaGVtYS5yZXF1aXJlZCwgbmFtZSkgPj0gMCk7XG4gICAgICAgICAgICB2YXIgY1Byb3BlcnR5ID0gXy5jbG9uZURlZXAocHJvcGVydHkpO1xuXG4gICAgICAgICAgICB2YXIgcmVxdWlyZWRDbGFzcyA9IHByb3BlcnR5SXNSZXF1aXJlZCA/ICdyZXF1aXJlZCcgOiAnJztcbiAgICAgICAgICAgIHZhciBodG1sID0gJzxzcGFuIGNsYXNzPVwicHJvcE5hbWUgJyArIHJlcXVpcmVkQ2xhc3MgKyAnXCI+JyArIG5hbWUgKyAnPC9zcGFuPiAoJztcbiAgICAgICAgICAgIHZhciBtb2RlbDtcbiAgICAgICAgICAgIHZhciBwcm9wRGVzY3JpcHRpb247XG5cbiAgICAgICAgICAgIC8vIEFsbG93IG1hY3JvIHRvIHNldCB0aGUgZGVmYXVsdCB2YWx1ZVxuICAgICAgICAgICAgY1Byb3BlcnR5LmRlZmF1bHQgPSBtb2RlbFByb3BlcnR5TWFjcm8oY1Byb3BlcnR5KTtcblxuICAgICAgICAgICAgLy8gUmVzb2x2ZSB0aGUgc2NoZW1hIChIYW5kbGUgbmVzdGVkIHNjaGVtYXMpXG4gICAgICAgICAgICBjUHJvcGVydHkgPSBIZWxwZXJzLnJlc29sdmVTY2hlbWEoY1Byb3BlcnR5KTtcblxuICAgICAgICAgICAgcHJvcERlc2NyaXB0aW9uID0gcHJvcGVydHkuZGVzY3JpcHRpb24gfHwgY1Byb3BlcnR5LmRlc2NyaXB0aW9uO1xuXG4gICAgICAgICAgICAvLyBXZSBuZWVkIHRvIGhhbmRsZSBwcm9wZXJ0eSByZWZlcmVuY2VzIHRvIHByaW1pdGl2ZXMgKElzc3VlIDMzOSlcbiAgICAgICAgICAgIGlmICghXy5pc1VuZGVmaW5lZChjUHJvcGVydHkuJHJlZikpIHtcbiAgICAgICAgICAgICAgbW9kZWwgPSBtb2RlbHNbSGVscGVycy5zaW1wbGVSZWYoY1Byb3BlcnR5LiRyZWYpXTtcblxuICAgICAgICAgICAgICBpZiAoIV8uaXNVbmRlZmluZWQobW9kZWwpICYmIF8uaW5kZXhPZihbdW5kZWZpbmVkLCAnYXJyYXknLCAnb2JqZWN0J10sIG1vZGVsLmRlZmluaXRpb24udHlwZSkgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgLy8gVXNlIHJlZmVyZW5jZWQgc2NoZW1hXG4gICAgICAgICAgICAgICAgY1Byb3BlcnR5ID0gSGVscGVycy5yZXNvbHZlU2NoZW1hKG1vZGVsLmRlZmluaXRpb24pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGh0bWwgKz0gcHJpbWl0aXZlVG9IVE1MKGNQcm9wZXJ0eSk7XG5cbiAgICAgICAgICAgIGlmKCFwcm9wZXJ0eUlzUmVxdWlyZWQpIHtcbiAgICAgICAgICAgICAgaHRtbCArPSAnLCA8c3BhbiBjbGFzcz1cInByb3BPcHRLZXlcIj5vcHRpb25hbDwvc3Bhbj4nO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZihwcm9wZXJ0eS5yZWFkT25seSkge1xuICAgICAgICAgICAgICAgIGh0bWwgKz0gJywgPHNwYW4gY2xhc3M9XCJwcm9wUmVhZE9ubHlcIj5yZWFkIG9ubHk8L3NwYW4+JztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaHRtbCArPSAnKSc7XG5cbiAgICAgICAgICAgIGlmICghXy5pc1VuZGVmaW5lZChwcm9wRGVzY3JpcHRpb24pKSB7XG4gICAgICAgICAgICAgIGh0bWwgKz0gJzogJyArICc8c3BhbiBjbGFzcz1cInByb3BEZXNjXCI+JyArIHByb3BEZXNjcmlwdGlvbiArICc8L3NwYW4+JztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGNQcm9wZXJ0eS5lbnVtKSB7XG4gICAgICAgICAgICAgIGh0bWwgKz0gJyA9IDxzcGFuIGNsYXNzPVwicHJvcFZhbHNcIj5bXFwnJyArIGNQcm9wZXJ0eS5lbnVtLmpvaW4oJ1xcJywgXFwnJykgKyAnXFwnXTwvc3Bhbj4nO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gJzxkaXYnICsgKHByb3BlcnR5LnJlYWRPbmx5ID8gJyBjbGFzcz1cInJlYWRPbmx5XCInIDogJycpICsgJz4nICsgcHJpbWl0aXZlVG9PcHRpb25zSFRNTChjUHJvcGVydHksIGh0bWwpO1xuICAgICAgICAgIH0pLmpvaW4oJyw8L2Rpdj4nKTtcblxuICAgICAgICAgIGlmIChjb250ZW50cykge1xuICAgICAgICAgICAgaHRtbCArPSBjb250ZW50cyArICc8L2Rpdj4nO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaHRtbCArPSAnPGRpdj4nICsgcHJpbWl0aXZlVG9PcHRpb25zSFRNTChzY2hlbWEsIHR5cGUpICsgJzwvZGl2Pic7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGh0bWwgKyBzdHJvbmdPcGVuICsgKGlzQXJyYXkgPyAnXScgOiAnfScpICsgc3Ryb25nQ2xvc2U7XG4gIH1cbn07IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgU3dhZ2dlckh0dHAgPSByZXF1aXJlKCcuL2h0dHAnKTtcbnZhciBfID0ge1xuICBpc09iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzT2JqZWN0Jylcbn07XG5cbnZhciBTd2FnZ2VyU3BlY0NvbnZlcnRlciA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmVycm9ycyA9IFtdO1xuICB0aGlzLndhcm5pbmdzID0gW107XG4gIHRoaXMubW9kZWxNYXAgPSB7fTtcbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5zZXREb2N1bWVudGF0aW9uTG9jYXRpb24gPSBmdW5jdGlvbiAobG9jYXRpb24pIHtcbiAgdGhpcy5kb2NMb2NhdGlvbiA9IGxvY2F0aW9uO1xufTtcblxuLyoqXG4gKiBjb252ZXJ0cyBhIHJlc291cmNlIGxpc3RpbmcgT1IgYXBpIGRlY2xhcmF0aW9uXG4gKiovXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUuY29udmVydCA9IGZ1bmN0aW9uIChvYmosIGNsaWVudEF1dGhvcml6YXRpb25zLCBvcHRzLCBjYWxsYmFjaykge1xuICAvLyBub3QgYSB2YWxpZCBzcGVjXG4gIGlmKCFvYmogfHwgIUFycmF5LmlzQXJyYXkob2JqLmFwaXMpKSB7XG4gICAgcmV0dXJuIHRoaXMuZmluaXNoKGNhbGxiYWNrLCBudWxsKTtcbiAgfVxuICB0aGlzLmNsaWVudEF1dGhvcml6YXRpb25zID0gY2xpZW50QXV0aG9yaXphdGlvbnM7XG5cbiAgLy8gY3JlYXRlIGEgbmV3IHN3YWdnZXIgb2JqZWN0IHRvIHJldHVyblxuICB2YXIgc3dhZ2dlciA9IHsgc3dhZ2dlcjogJzIuMCcgfTtcblxuICBzd2FnZ2VyLm9yaWdpbmFsVmVyc2lvbiA9IG9iai5zd2FnZ2VyVmVyc2lvbjtcblxuICAvLyBhZGQgdGhlIGluZm9cbiAgdGhpcy5hcGlJbmZvKG9iaiwgc3dhZ2dlcik7XG5cbiAgLy8gYWRkIHNlY3VyaXR5IGRlZmluaXRpb25zXG4gIHRoaXMuc2VjdXJpdHlEZWZpbml0aW9ucyhvYmosIHN3YWdnZXIpO1xuXG4gIC8vIHRha2UgYmFzZVBhdGggaW50byBhY2NvdW50XG4gIGlmIChvYmouYmFzZVBhdGgpIHtcbiAgICB0aGlzLnNldERvY3VtZW50YXRpb25Mb2NhdGlvbihvYmouYmFzZVBhdGgpO1xuICB9XG5cbiAgLy8gc2VlIGlmIHRoaXMgaXMgYSBzaW5nbGUtZmlsZSBzd2FnZ2VyIGRlZmluaXRpb25cbiAgdmFyIGlzU2luZ2xlRmlsZVN3YWdnZXIgPSBmYWxzZTtcbiAgdmFyIGk7XG4gIGZvcihpID0gMDsgaSA8IG9iai5hcGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGFwaSA9IG9iai5hcGlzW2ldO1xuICAgIGlmKEFycmF5LmlzQXJyYXkoYXBpLm9wZXJhdGlvbnMpKSB7XG4gICAgICBpc1NpbmdsZUZpbGVTd2FnZ2VyID0gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgaWYoaXNTaW5nbGVGaWxlU3dhZ2dlcikge1xuICAgIHRoaXMuZGVjbGFyYXRpb24ob2JqLCBzd2FnZ2VyKTtcbiAgICB0aGlzLmZpbmlzaChjYWxsYmFjaywgc3dhZ2dlcik7XG4gIH1cbiAgZWxzZSB7XG4gICAgdGhpcy5yZXNvdXJjZUxpc3Rpbmcob2JqLCBzd2FnZ2VyLCBvcHRzLCBjYWxsYmFjayk7XG4gIH1cbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5kZWNsYXJhdGlvbiA9IGZ1bmN0aW9uKG9iaiwgc3dhZ2dlcikge1xuICB2YXIgbmFtZSwgaSwgcCwgcG9zO1xuICBpZighb2JqLmFwaXMpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAob2JqLmJhc2VQYXRoLmluZGV4T2YoJ2h0dHA6Ly8nKSA9PT0gMCkge1xuICAgIHAgPSBvYmouYmFzZVBhdGguc3Vic3RyaW5nKCdodHRwOi8vJy5sZW5ndGgpO1xuICAgIHBvcyA9IHAuaW5kZXhPZignLycpO1xuICAgIGlmIChwb3MgPiAwKSB7XG4gICAgICBzd2FnZ2VyLmhvc3QgPSBwLnN1YnN0cmluZygwLCBwb3MpO1xuICAgICAgc3dhZ2dlci5iYXNlUGF0aCA9IHAuc3Vic3RyaW5nKHBvcyk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgc3dhZ2dlci5ob3N0ID0gcDtcbiAgICAgIHN3YWdnZXIuYmFzZVBhdGggPSAnLyc7XG4gICAgfVxuICB9IGVsc2UgaWYgKG9iai5iYXNlUGF0aC5pbmRleE9mKCdodHRwczovLycpID09PSAwKSB7XG4gICAgcCA9IG9iai5iYXNlUGF0aC5zdWJzdHJpbmcoJ2h0dHBzOi8vJy5sZW5ndGgpO1xuICAgIHBvcyA9IHAuaW5kZXhPZignLycpO1xuICAgIGlmIChwb3MgPiAwKSB7XG4gICAgICBzd2FnZ2VyLmhvc3QgPSBwLnN1YnN0cmluZygwLCBwb3MpO1xuICAgICAgc3dhZ2dlci5iYXNlUGF0aCA9IHAuc3Vic3RyaW5nKHBvcyk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgc3dhZ2dlci5ob3N0ID0gcDtcbiAgICAgIHN3YWdnZXIuYmFzZVBhdGggPSAnLyc7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHN3YWdnZXIuYmFzZVBhdGggPSBvYmouYmFzZVBhdGg7XG4gIH1cblxuICB2YXIgcmVzb3VyY2VMZXZlbEF1dGg7XG4gIGlmKG9iai5hdXRob3JpemF0aW9ucykge1xuICAgIHJlc291cmNlTGV2ZWxBdXRoID0gb2JqLmF1dGhvcml6YXRpb25zO1xuICB9XG4gIGlmKG9iai5jb25zdW1lcykge1xuICAgIHN3YWdnZXIuY29uc3VtZXMgPSBvYmouY29uc3VtZXM7XG4gIH1cbiAgaWYob2JqLnByb2R1Y2VzKSB7XG4gICAgc3dhZ2dlci5wcm9kdWNlcyA9IG9iai5wcm9kdWNlcztcbiAgfVxuXG4gIC8vIGJ1aWxkIGEgbWFwcGluZyBvZiBpZCB0byBuYW1lIGZvciAxLjAgbW9kZWwgcmVzb2x1dGlvbnNcbiAgaWYoXy5pc09iamVjdChvYmopKSB7XG4gICAgZm9yKG5hbWUgaW4gb2JqLm1vZGVscykge1xuICAgICAgdmFyIGV4aXN0aW5nTW9kZWwgPSBvYmoubW9kZWxzW25hbWVdO1xuICAgICAgdmFyIGtleSA9IChleGlzdGluZ01vZGVsLmlkIHx8IG5hbWUpO1xuICAgICAgdGhpcy5tb2RlbE1hcFtrZXldID0gbmFtZTtcbiAgICB9XG4gIH1cblxuICBmb3IoaSA9IDA7IGkgPCBvYmouYXBpcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBhcGkgPSBvYmouYXBpc1tpXTtcbiAgICB2YXIgcGF0aCA9IGFwaS5wYXRoO1xuICAgIHZhciBvcGVyYXRpb25zID0gYXBpLm9wZXJhdGlvbnM7XG4gICAgdGhpcy5vcGVyYXRpb25zKHBhdGgsIG9iai5yZXNvdXJjZVBhdGgsIG9wZXJhdGlvbnMsIHJlc291cmNlTGV2ZWxBdXRoLCBzd2FnZ2VyKTtcbiAgfVxuXG4gIHZhciBtb2RlbHMgPSBvYmoubW9kZWxzIHx8IHt9O1xuICB0aGlzLm1vZGVscyhtb2RlbHMsIHN3YWdnZXIpO1xufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLm1vZGVscyA9IGZ1bmN0aW9uKG9iaiwgc3dhZ2dlcikge1xuICBpZighXy5pc09iamVjdChvYmopKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHZhciBuYW1lO1xuXG4gIHN3YWdnZXIuZGVmaW5pdGlvbnMgPSBzd2FnZ2VyLmRlZmluaXRpb25zIHx8IHt9O1xuICBmb3IobmFtZSBpbiBvYmopIHtcbiAgICB2YXIgZXhpc3RpbmdNb2RlbCA9IG9ialtuYW1lXTtcbiAgICB2YXIgX3JlcXVpcmVkID0gW107XG4gICAgdmFyIHNjaGVtYSA9IHsgcHJvcGVydGllczoge319O1xuICAgIHZhciBwcm9wZXJ0eU5hbWU7XG4gICAgZm9yKHByb3BlcnR5TmFtZSBpbiBleGlzdGluZ01vZGVsLnByb3BlcnRpZXMpIHtcbiAgICAgIHZhciBleGlzdGluZ1Byb3BlcnR5ID0gZXhpc3RpbmdNb2RlbC5wcm9wZXJ0aWVzW3Byb3BlcnR5TmFtZV07XG4gICAgICB2YXIgcHJvcGVydHkgPSB7fTtcbiAgICAgIHRoaXMuZGF0YVR5cGUoZXhpc3RpbmdQcm9wZXJ0eSwgcHJvcGVydHkpO1xuICAgICAgaWYoZXhpc3RpbmdQcm9wZXJ0eS5kZXNjcmlwdGlvbikge1xuICAgICAgICBwcm9wZXJ0eS5kZXNjcmlwdGlvbiA9IGV4aXN0aW5nUHJvcGVydHkuZGVzY3JpcHRpb247XG4gICAgICB9XG4gICAgICBpZihleGlzdGluZ1Byb3BlcnR5WydlbnVtJ10pIHtcbiAgICAgICAgcHJvcGVydHlbJ2VudW0nXSA9IGV4aXN0aW5nUHJvcGVydHlbJ2VudW0nXTtcbiAgICAgIH1cbiAgICAgIGlmKHR5cGVvZiBleGlzdGluZ1Byb3BlcnR5LnJlcXVpcmVkID09PSAnYm9vbGVhbicgJiYgZXhpc3RpbmdQcm9wZXJ0eS5yZXF1aXJlZCA9PT0gdHJ1ZSkge1xuICAgICAgICBfcmVxdWlyZWQucHVzaChwcm9wZXJ0eU5hbWUpO1xuICAgICAgfVxuICAgICAgaWYodHlwZW9mIGV4aXN0aW5nUHJvcGVydHkucmVxdWlyZWQgPT09ICdzdHJpbmcnICYmIGV4aXN0aW5nUHJvcGVydHkucmVxdWlyZWQgPT09ICd0cnVlJykge1xuICAgICAgICBfcmVxdWlyZWQucHVzaChwcm9wZXJ0eU5hbWUpO1xuICAgICAgfVxuICAgICAgc2NoZW1hLnByb3BlcnRpZXNbcHJvcGVydHlOYW1lXSA9IHByb3BlcnR5O1xuICAgIH1cbiAgICBpZihfcmVxdWlyZWQubGVuZ3RoID4gMCkge1xuICAgICAgc2NoZW1hLnJlcXVpcmVkID0gX3JlcXVpcmVkO1xuICAgIH0gZWxzZSB7XG4gICAgICBzY2hlbWEucmVxdWlyZWQgPSBleGlzdGluZ01vZGVsLnJlcXVpcmVkO1xuICAgIH1cbiAgICBzd2FnZ2VyLmRlZmluaXRpb25zW25hbWVdID0gc2NoZW1hO1xuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUuZXh0cmFjdFRhZyA9IGZ1bmN0aW9uKHJlc291cmNlUGF0aCkge1xuICB2YXIgcGF0aFN0cmluZyA9IHJlc291cmNlUGF0aCB8fCAnZGVmYXVsdCc7XG4gIGlmKHBhdGhTdHJpbmcuaW5kZXhPZignaHR0cDonKSA9PT0gMCB8fCBwYXRoU3RyaW5nLmluZGV4T2YoJ2h0dHBzOicpID09PSAwKSB7XG4gICAgcGF0aFN0cmluZyA9IHBhdGhTdHJpbmcuc3BsaXQoWycvJ10pO1xuICAgIHBhdGhTdHJpbmcgPSBwYXRoU3RyaW5nW3BhdGhTdHJpbmcubGVuZ3RoIC0xXS5zdWJzdHJpbmcoKTtcbiAgfVxuICBpZihwYXRoU3RyaW5nLmVuZHNXaXRoKCcuanNvbicpKSB7XG4gICAgcGF0aFN0cmluZyA9IHBhdGhTdHJpbmcuc3Vic3RyaW5nKDAsIHBhdGhTdHJpbmcubGVuZ3RoIC0gJy5qc29uJy5sZW5ndGgpO1xuICB9XG4gIHJldHVybiBwYXRoU3RyaW5nLnJlcGxhY2UoJy8nLCcnKTtcbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5vcGVyYXRpb25zID0gZnVuY3Rpb24ocGF0aCwgcmVzb3VyY2VQYXRoLCBvYmosIHJlc291cmNlTGV2ZWxBdXRoLCBzd2FnZ2VyKSB7XG4gIGlmKCFBcnJheS5pc0FycmF5KG9iaikpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgdmFyIGk7XG5cbiAgaWYoIXN3YWdnZXIucGF0aHMpIHtcbiAgICBzd2FnZ2VyLnBhdGhzID0ge307XG4gIH1cblxuICB2YXIgcGF0aE9iaiA9IHN3YWdnZXIucGF0aHNbcGF0aF0gfHwge307XG4gIHZhciB0YWcgPSB0aGlzLmV4dHJhY3RUYWcocmVzb3VyY2VQYXRoKTtcbiAgc3dhZ2dlci50YWdzID0gc3dhZ2dlci50YWdzIHx8IFtdO1xuICB2YXIgbWF0Y2hlZCA9IGZhbHNlO1xuICBmb3IoaSA9IDA7IGkgPCBzd2FnZ2VyLnRhZ3MubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgdGFnT2JqZWN0ID0gc3dhZ2dlci50YWdzW2ldO1xuICAgIGlmKHRhZ09iamVjdC5uYW1lID09PSB0YWcpIHtcbiAgICAgIG1hdGNoZWQgPSB0cnVlO1xuICAgIH1cbiAgfVxuICBpZighbWF0Y2hlZCkge1xuICAgIHN3YWdnZXIudGFncy5wdXNoKHtuYW1lOiB0YWd9KTtcbiAgfVxuXG4gIGZvcihpID0gMDsgaSA8IG9iai5sZW5ndGg7IGkrKykge1xuICAgIHZhciBleGlzdGluZ09wZXJhdGlvbiA9IG9ialtpXTtcbiAgICB2YXIgbWV0aG9kID0gKGV4aXN0aW5nT3BlcmF0aW9uLm1ldGhvZCB8fCBleGlzdGluZ09wZXJhdGlvbi5odHRwTWV0aG9kKS50b0xvd2VyQ2FzZSgpO1xuICAgIHZhciBvcGVyYXRpb24gPSB7dGFnczogW3RhZ119O1xuICAgIHZhciBleGlzdGluZ0F1dGhvcml6YXRpb25zID0gZXhpc3RpbmdPcGVyYXRpb24uYXV0aG9yaXphdGlvbnM7XG5cbiAgICBpZihleGlzdGluZ0F1dGhvcml6YXRpb25zICYmIE9iamVjdC5rZXlzKGV4aXN0aW5nQXV0aG9yaXphdGlvbnMpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgZXhpc3RpbmdBdXRob3JpemF0aW9ucyA9IHJlc291cmNlTGV2ZWxBdXRoO1xuICAgIH1cblxuICAgIGlmKHR5cGVvZiBleGlzdGluZ0F1dGhvcml6YXRpb25zICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdmFyIHNjb3Blc09iamVjdDtcbiAgICAgIGZvcih2YXIga2V5IGluIGV4aXN0aW5nQXV0aG9yaXphdGlvbnMpIHtcbiAgICAgICAgb3BlcmF0aW9uLnNlY3VyaXR5ID0gb3BlcmF0aW9uLnNlY3VyaXR5IHx8IFtdO1xuICAgICAgICB2YXIgc2NvcGVzID0gZXhpc3RpbmdBdXRob3JpemF0aW9uc1trZXldO1xuICAgICAgICBpZihzY29wZXMpIHtcbiAgICAgICAgICB2YXIgc2VjdXJpdHlTY29wZXMgPSBbXTtcbiAgICAgICAgICBmb3IodmFyIGogaW4gc2NvcGVzKSB7XG4gICAgICAgICAgICBzZWN1cml0eVNjb3Blcy5wdXNoKHNjb3Blc1tqXS5zY29wZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHNjb3Blc09iamVjdCA9IHt9O1xuICAgICAgICAgIHNjb3Blc09iamVjdFtrZXldID0gc2VjdXJpdHlTY29wZXM7XG4gICAgICAgICAgb3BlcmF0aW9uLnNlY3VyaXR5LnB1c2goc2NvcGVzT2JqZWN0KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBzY29wZXNPYmplY3QgPSB7fTtcbiAgICAgICAgICBzY29wZXNPYmplY3Rba2V5XSA9IFtdO1xuICAgICAgICAgIG9wZXJhdGlvbi5zZWN1cml0eS5wdXNoKHNjb3Blc09iamVjdCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZihleGlzdGluZ09wZXJhdGlvbi5jb25zdW1lcykge1xuICAgICAgb3BlcmF0aW9uLmNvbnN1bWVzID0gZXhpc3RpbmdPcGVyYXRpb24uY29uc3VtZXM7XG4gICAgfVxuICAgIGVsc2UgaWYoc3dhZ2dlci5jb25zdW1lcykge1xuICAgICAgb3BlcmF0aW9uLmNvbnN1bWVzID0gc3dhZ2dlci5jb25zdW1lcztcbiAgICB9XG4gICAgaWYoZXhpc3RpbmdPcGVyYXRpb24ucHJvZHVjZXMpIHtcbiAgICAgIG9wZXJhdGlvbi5wcm9kdWNlcyA9IGV4aXN0aW5nT3BlcmF0aW9uLnByb2R1Y2VzO1xuICAgIH1cbiAgICBlbHNlIGlmKHN3YWdnZXIucHJvZHVjZXMpIHtcbiAgICAgIG9wZXJhdGlvbi5wcm9kdWNlcyA9IHN3YWdnZXIucHJvZHVjZXM7XG4gICAgfVxuICAgIGlmKGV4aXN0aW5nT3BlcmF0aW9uLnN1bW1hcnkpIHtcbiAgICAgIG9wZXJhdGlvbi5zdW1tYXJ5ID0gZXhpc3RpbmdPcGVyYXRpb24uc3VtbWFyeTtcbiAgICB9XG4gICAgaWYoZXhpc3RpbmdPcGVyYXRpb24ubm90ZXMpIHtcbiAgICAgIG9wZXJhdGlvbi5kZXNjcmlwdGlvbiA9IGV4aXN0aW5nT3BlcmF0aW9uLm5vdGVzO1xuICAgIH1cbiAgICBpZihleGlzdGluZ09wZXJhdGlvbi5uaWNrbmFtZSkge1xuICAgICAgb3BlcmF0aW9uLm9wZXJhdGlvbklkID0gZXhpc3RpbmdPcGVyYXRpb24ubmlja25hbWU7XG4gICAgfVxuICAgIGlmKGV4aXN0aW5nT3BlcmF0aW9uLmRlcHJlY2F0ZWQpIHtcbiAgICAgIG9wZXJhdGlvbi5kZXByZWNhdGVkID0gZXhpc3RpbmdPcGVyYXRpb24uZGVwcmVjYXRlZDtcbiAgICB9XG5cbiAgICB0aGlzLmF1dGhvcml6YXRpb25zKGV4aXN0aW5nQXV0aG9yaXphdGlvbnMsIHN3YWdnZXIpO1xuICAgIHRoaXMucGFyYW1ldGVycyhvcGVyYXRpb24sIGV4aXN0aW5nT3BlcmF0aW9uLnBhcmFtZXRlcnMsIHN3YWdnZXIpO1xuICAgIHRoaXMucmVzcG9uc2VNZXNzYWdlcyhvcGVyYXRpb24sIGV4aXN0aW5nT3BlcmF0aW9uLCBzd2FnZ2VyKTtcblxuICAgIHBhdGhPYmpbbWV0aG9kXSA9IG9wZXJhdGlvbjtcbiAgfVxuXG4gIHN3YWdnZXIucGF0aHNbcGF0aF0gPSBwYXRoT2JqO1xufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLnJlc3BvbnNlTWVzc2FnZXMgPSBmdW5jdGlvbihvcGVyYXRpb24sIGV4aXN0aW5nT3BlcmF0aW9uKSB7XG4gIGlmKCFfLmlzT2JqZWN0KGV4aXN0aW5nT3BlcmF0aW9uKSkge1xuICAgIHJldHVybjtcbiAgfVxuICAvLyBidWlsZCBkZWZhdWx0IHJlc3BvbnNlIGZyb20gdGhlIG9wZXJhdGlvbiAoMS54KVxuICB2YXIgZGVmYXVsdFJlc3BvbnNlID0ge307XG4gIHRoaXMuZGF0YVR5cGUoZXhpc3RpbmdPcGVyYXRpb24sIGRlZmF1bHRSZXNwb25zZSk7XG4gIC8vIFRPRE86IGxvb2sgaW50byB0aGUgcmVhbCBwcm9ibGVtIG9mIHJlbmRlcmluZyByZXNwb25zZXMgaW4gc3dhZ2dlci11aVxuICAvLyAuLi4uc2hvdWxkIHJlcG9uc2VUeXBlIGhhdmUgYW4gaW1wbGljaXQgc2NoZW1hP1xuICBpZighZGVmYXVsdFJlc3BvbnNlLnNjaGVtYSAmJiBkZWZhdWx0UmVzcG9uc2UudHlwZSkge1xuICAgIGRlZmF1bHRSZXNwb25zZSA9IHtzY2hlbWE6IGRlZmF1bHRSZXNwb25zZX07XG4gIH1cblxuICBvcGVyYXRpb24ucmVzcG9uc2VzID0gb3BlcmF0aW9uLnJlc3BvbnNlcyB8fCB7fTtcblxuICAvLyBncmFiIGZyb20gcmVzcG9uc2VNZXNzYWdlcyAoMS4yKVxuICB2YXIgaGFzMjAwID0gZmFsc2U7XG4gIGlmKEFycmF5LmlzQXJyYXkoZXhpc3RpbmdPcGVyYXRpb24ucmVzcG9uc2VNZXNzYWdlcykpIHtcbiAgICB2YXIgaTtcbiAgICB2YXIgZXhpc3RpbmdSZXNwb25zZXMgPSBleGlzdGluZ09wZXJhdGlvbi5yZXNwb25zZU1lc3NhZ2VzO1xuICAgIGZvcihpID0gMDsgaSA8IGV4aXN0aW5nUmVzcG9uc2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgZXhpc3RpbmdSZXNwb25zZSA9IGV4aXN0aW5nUmVzcG9uc2VzW2ldO1xuICAgICAgdmFyIHJlc3BvbnNlID0geyBkZXNjcmlwdGlvbjogZXhpc3RpbmdSZXNwb25zZS5tZXNzYWdlIH07XG4gICAgICBpZihleGlzdGluZ1Jlc3BvbnNlLmNvZGUgPT09IDIwMCkge1xuICAgICAgICBoYXMyMDAgPSB0cnVlO1xuICAgICAgfVxuICAgICAgLy8gQ29udmVydCByZXNwb25zZU1vZGVsIC0+IHNjaGVtYXskcmVmOiByZXNwb25zZU1vZGVsfVxuICAgICAgaWYoZXhpc3RpbmdSZXNwb25zZS5yZXNwb25zZU1vZGVsKSB7XG4gICAgICAgIHJlc3BvbnNlLnNjaGVtYSA9IHsnJHJlZic6ICcjL2RlZmluaXRpb25zLycgKyBleGlzdGluZ1Jlc3BvbnNlLnJlc3BvbnNlTW9kZWx9O1xuICAgICAgfVxuICAgICAgb3BlcmF0aW9uLnJlc3BvbnNlc1snJyArIGV4aXN0aW5nUmVzcG9uc2UuY29kZV0gPSByZXNwb25zZTtcbiAgICB9XG4gIH1cblxuICBpZihoYXMyMDApIHtcbiAgICBvcGVyYXRpb24ucmVzcG9uc2VzWydkZWZhdWx0J10gPSBkZWZhdWx0UmVzcG9uc2U7XG4gIH1cbiAgZWxzZSB7XG4gICAgb3BlcmF0aW9uLnJlc3BvbnNlc1snMjAwJ10gPSBkZWZhdWx0UmVzcG9uc2U7XG4gIH1cbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5hdXRob3JpemF0aW9ucyA9IGZ1bmN0aW9uKG9iaikge1xuICAvLyBUT0RPXG4gIGlmKCFfLmlzT2JqZWN0KG9iaikpIHtcbiAgICByZXR1cm47XG4gIH1cbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5wYXJhbWV0ZXJzID0gZnVuY3Rpb24ob3BlcmF0aW9uLCBvYmopIHtcbiAgaWYoIUFycmF5LmlzQXJyYXkob2JqKSkge1xuICAgIHJldHVybjtcbiAgfVxuICB2YXIgaTtcbiAgZm9yKGkgPSAwOyBpIDwgb2JqLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGV4aXN0aW5nUGFyYW1ldGVyID0gb2JqW2ldO1xuICAgIHZhciBwYXJhbWV0ZXIgPSB7fTtcbiAgICBwYXJhbWV0ZXIubmFtZSA9IGV4aXN0aW5nUGFyYW1ldGVyLm5hbWU7XG4gICAgcGFyYW1ldGVyLmRlc2NyaXB0aW9uID0gZXhpc3RpbmdQYXJhbWV0ZXIuZGVzY3JpcHRpb247XG4gICAgcGFyYW1ldGVyLnJlcXVpcmVkID0gZXhpc3RpbmdQYXJhbWV0ZXIucmVxdWlyZWQ7XG4gICAgcGFyYW1ldGVyLmluID0gZXhpc3RpbmdQYXJhbWV0ZXIucGFyYW1UeXBlO1xuXG4gICAgLy8gcGVyICMxNjhcbiAgICBpZihwYXJhbWV0ZXIuaW4gPT09ICdib2R5Jykge1xuICAgICAgcGFyYW1ldGVyLm5hbWUgPSAnYm9keSc7XG4gICAgfVxuICAgIGlmKHBhcmFtZXRlci5pbiA9PT0gJ2Zvcm0nKSB7XG4gICAgICBwYXJhbWV0ZXIuaW4gPSAnZm9ybURhdGEnO1xuICAgIH1cblxuICAgIGlmKGV4aXN0aW5nUGFyYW1ldGVyLmVudW0pIHtcbiAgICAgIHBhcmFtZXRlci5lbnVtID0gZXhpc3RpbmdQYXJhbWV0ZXIuZW51bTtcbiAgICB9XG5cbiAgICBpZihleGlzdGluZ1BhcmFtZXRlci5hbGxvd011bHRpcGxlID09PSB0cnVlIHx8IGV4aXN0aW5nUGFyYW1ldGVyLmFsbG93TXVsdGlwbGUgPT09ICd0cnVlJykge1xuICAgICAgdmFyIGlubmVyVHlwZSA9IHt9O1xuICAgICAgdGhpcy5kYXRhVHlwZShleGlzdGluZ1BhcmFtZXRlciwgaW5uZXJUeXBlKTtcbiAgICAgIHBhcmFtZXRlci50eXBlID0gJ2FycmF5JztcbiAgICAgIHBhcmFtZXRlci5pdGVtcyA9IGlubmVyVHlwZTtcblxuICAgICAgaWYoZXhpc3RpbmdQYXJhbWV0ZXIuYWxsb3dhYmxlVmFsdWVzKSB7XG4gICAgICAgIHZhciBhdiA9IGV4aXN0aW5nUGFyYW1ldGVyLmFsbG93YWJsZVZhbHVlcztcbiAgICAgICAgaWYoYXYudmFsdWVUeXBlID09PSAnTElTVCcpIHtcbiAgICAgICAgICBwYXJhbWV0ZXJbJ2VudW0nXSA9IGF2LnZhbHVlcztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHRoaXMuZGF0YVR5cGUoZXhpc3RpbmdQYXJhbWV0ZXIsIHBhcmFtZXRlcik7XG4gICAgfVxuICAgIGlmKHR5cGVvZiBleGlzdGluZ1BhcmFtZXRlci5kZWZhdWx0VmFsdWUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBwYXJhbWV0ZXIuZGVmYXVsdCA9IGV4aXN0aW5nUGFyYW1ldGVyLmRlZmF1bHRWYWx1ZTtcbiAgICB9XG5cbiAgICBvcGVyYXRpb24ucGFyYW1ldGVycyA9IG9wZXJhdGlvbi5wYXJhbWV0ZXJzIHx8IFtdO1xuICAgIG9wZXJhdGlvbi5wYXJhbWV0ZXJzLnB1c2gocGFyYW1ldGVyKTtcbiAgfVxufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLmRhdGFUeXBlID0gZnVuY3Rpb24oc291cmNlLCB0YXJnZXQpIHtcbiAgaWYoIV8uaXNPYmplY3Qoc291cmNlKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmKHNvdXJjZS5taW5pbXVtKSB7XG4gICAgdGFyZ2V0Lm1pbmltdW0gPSBzb3VyY2UubWluaW11bTtcbiAgfVxuICBpZihzb3VyY2UubWF4aW11bSkge1xuICAgIHRhcmdldC5tYXhpbXVtID0gc291cmNlLm1heGltdW07XG4gIH1cbiAgaWYgKHNvdXJjZS5mb3JtYXQpIHtcbiAgICB0YXJnZXQuZm9ybWF0ID0gc291cmNlLmZvcm1hdDtcbiAgfVxuXG4gIC8vIGRlZmF1bHQgY2FuIGJlICdmYWxzZSdcbiAgaWYodHlwZW9mIHNvdXJjZS5kZWZhdWx0VmFsdWUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgdGFyZ2V0LmRlZmF1bHQgPSBzb3VyY2UuZGVmYXVsdFZhbHVlO1xuICB9XG5cbiAgdmFyIGpzb25TY2hlbWFUeXBlID0gdGhpcy50b0pzb25TY2hlbWEoc291cmNlKTtcbiAgaWYoanNvblNjaGVtYVR5cGUpIHtcbiAgICB0YXJnZXQgPSB0YXJnZXQgfHwge307XG4gICAgaWYoanNvblNjaGVtYVR5cGUudHlwZSkge1xuICAgICAgdGFyZ2V0LnR5cGUgPSBqc29uU2NoZW1hVHlwZS50eXBlO1xuICAgIH1cbiAgICBpZihqc29uU2NoZW1hVHlwZS5mb3JtYXQpIHtcbiAgICAgIHRhcmdldC5mb3JtYXQgPSBqc29uU2NoZW1hVHlwZS5mb3JtYXQ7XG4gICAgfVxuICAgIGlmKGpzb25TY2hlbWFUeXBlLiRyZWYpIHtcbiAgICAgIHRhcmdldC5zY2hlbWEgPSB7JHJlZjoganNvblNjaGVtYVR5cGUuJHJlZn07XG4gICAgfVxuICAgIGlmKGpzb25TY2hlbWFUeXBlLml0ZW1zKSB7XG4gICAgICB0YXJnZXQuaXRlbXMgPSBqc29uU2NoZW1hVHlwZS5pdGVtcztcbiAgICB9XG4gIH1cbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS50b0pzb25TY2hlbWEgPSBmdW5jdGlvbihzb3VyY2UpIHtcbiAgaWYoIXNvdXJjZSkge1xuICAgIHJldHVybiAnb2JqZWN0JztcbiAgfVxuICB2YXIgZGV0ZWN0ZWRUeXBlID0gKHNvdXJjZS50eXBlIHx8IHNvdXJjZS5kYXRhVHlwZSB8fCBzb3VyY2UucmVzcG9uc2VDbGFzcyB8fCAnJyk7XG4gIHZhciBsY1R5cGUgPSBkZXRlY3RlZFR5cGUudG9Mb3dlckNhc2UoKTtcbiAgdmFyIGZvcm1hdCA9IChzb3VyY2UuZm9ybWF0IHx8ICcnKS50b0xvd2VyQ2FzZSgpO1xuXG4gIGlmKGxjVHlwZS5pbmRleE9mKCdsaXN0WycpID09PSAwKSB7XG4gICAgdmFyIGlubmVyVHlwZSA9IGRldGVjdGVkVHlwZS5zdWJzdHJpbmcoNSwgZGV0ZWN0ZWRUeXBlLmxlbmd0aCAtIDEpO1xuICAgIHZhciBqc29uVHlwZSA9IHRoaXMudG9Kc29uU2NoZW1hKHt0eXBlOiBpbm5lclR5cGV9KTtcbiAgICByZXR1cm4ge3R5cGU6ICdhcnJheScsIGl0ZW1zOiBqc29uVHlwZX07XG4gIH0gZWxzZSBpZihsY1R5cGUgPT09ICdpbnQnIHx8IChsY1R5cGUgPT09ICdpbnRlZ2VyJyAmJiBmb3JtYXQgPT09ICdpbnQzMicpKSB7XG4gICAge3JldHVybiB7dHlwZTogJ2ludGVnZXInLCBmb3JtYXQ6ICdpbnQzMid9O31cbiAgfSBlbHNlIGlmKGxjVHlwZSA9PT0gJ2xvbmcnIHx8IChsY1R5cGUgPT09ICdpbnRlZ2VyJyAmJiBmb3JtYXQgPT09ICdpbnQ2NCcpKSB7XG4gICAge3JldHVybiB7dHlwZTogJ2ludGVnZXInLCBmb3JtYXQ6ICdpbnQ2NCd9O31cbiAgfSBlbHNlIGlmKGxjVHlwZSA9PT0gJ2ludGVnZXInKSB7XG4gICAge3JldHVybiB7dHlwZTogJ2ludGVnZXInLCBmb3JtYXQ6ICdpbnQ2NCd9O31cbiAgfSBlbHNlIGlmKGxjVHlwZSA9PT0gJ2Zsb2F0JyB8fCAobGNUeXBlID09PSAnbnVtYmVyJyAmJiBmb3JtYXQgPT09ICdmbG9hdCcpKSB7XG4gICAge3JldHVybiB7dHlwZTogJ251bWJlcicsIGZvcm1hdDogJ2Zsb2F0J307fVxuICB9IGVsc2UgaWYobGNUeXBlID09PSAnZG91YmxlJyB8fCAobGNUeXBlID09PSAnbnVtYmVyJyAmJiBmb3JtYXQgPT09ICdkb3VibGUnKSkge1xuICAgIHtyZXR1cm4ge3R5cGU6ICdudW1iZXInLCBmb3JtYXQ6ICdkb3VibGUnfTt9XG4gIH0gZWxzZSBpZigobGNUeXBlID09PSAnc3RyaW5nJyAmJiBmb3JtYXQgPT09ICdkYXRlLXRpbWUnKSB8fCAobGNUeXBlID09PSAnZGF0ZScpKSB7XG4gICAge3JldHVybiB7dHlwZTogJ3N0cmluZycsIGZvcm1hdDogJ2RhdGUtdGltZSd9O31cbiAgfSBlbHNlIGlmKGxjVHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICB7cmV0dXJuIHt0eXBlOiAnc3RyaW5nJ307fVxuICB9IGVsc2UgaWYobGNUeXBlID09PSAnZmlsZScpIHtcbiAgICB7cmV0dXJuIHt0eXBlOiAnZmlsZSd9O31cbiAgfSBlbHNlIGlmKGxjVHlwZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAge3JldHVybiB7dHlwZTogJ2Jvb2xlYW4nfTt9XG4gIH0gZWxzZSBpZihsY1R5cGUgPT09ICdib29sZWFuJykge1xuICAgIHtyZXR1cm4ge3R5cGU6ICdib29sZWFuJ307fVxuICB9IGVsc2UgaWYobGNUeXBlID09PSAnYXJyYXknIHx8IGxjVHlwZSA9PT0gJ2xpc3QnKSB7XG4gICAgaWYoc291cmNlLml0ZW1zKSB7XG4gICAgICB2YXIgaXQgPSB0aGlzLnRvSnNvblNjaGVtYShzb3VyY2UuaXRlbXMpO1xuICAgICAgcmV0dXJuIHt0eXBlOiAnYXJyYXknLCBpdGVtczogaXR9O1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHJldHVybiB7dHlwZTogJ2FycmF5JywgaXRlbXM6IHt0eXBlOiAnb2JqZWN0J319O1xuICAgIH1cbiAgfSBlbHNlIGlmKHNvdXJjZS4kcmVmKSB7XG4gICAgcmV0dXJuIHskcmVmOiB0aGlzLm1vZGVsTWFwW3NvdXJjZS4kcmVmXSA/ICcjL2RlZmluaXRpb25zLycgKyB0aGlzLm1vZGVsTWFwW3NvdXJjZS4kcmVmXSA6IHNvdXJjZS4kcmVmfTtcbiAgfSBlbHNlIGlmKGxjVHlwZSA9PT0gJ3ZvaWQnIHx8IGxjVHlwZSA9PT0gJycpIHtcbiAgICB7cmV0dXJuIHt9O31cbiAgfSBlbHNlIGlmICh0aGlzLm1vZGVsTWFwW3NvdXJjZS50eXBlXSkge1xuICAgIC8vIElmIHRoaXMgYSBtb2RlbCB1c2luZyBgdHlwZWAgaW5zdGVhZCBvZiBgJHJlZmAsIHRoYXQncyBmaW5lLlxuICAgIHJldHVybiB7JHJlZjogJyMvZGVmaW5pdGlvbnMvJyArIHRoaXMubW9kZWxNYXBbc291cmNlLnR5cGVdfTtcbiAgfSBlbHNlIHtcbiAgICAvLyBVbmtub3duIG1vZGVsIHR5cGUgb3IgJ29iamVjdCcsIHBhc3MgaXQgYWxvbmcuXG4gICAgcmV0dXJuIHt0eXBlOiBzb3VyY2UudHlwZX07XG4gIH1cbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5yZXNvdXJjZUxpc3RpbmcgPSBmdW5jdGlvbihvYmosIHN3YWdnZXIsIG9wdHMsIGNhbGxiYWNrKSB7XG4gIHZhciBpO1xuICB2YXIgcHJvY2Vzc2VkQ291bnQgPSAwOyAgIC8vIGpzaGludCBpZ25vcmU6bGluZVxuICB2YXIgc2VsZiA9IHRoaXM7ICAgICAgICAgIC8vIGpzaGludCBpZ25vcmU6bGluZVxuICB2YXIgZXhwZWN0ZWRDb3VudCA9IG9iai5hcGlzLmxlbmd0aDtcbiAgdmFyIF9zd2FnZ2VyID0gc3dhZ2dlcjsgICAvLyBqc2hpbnQgaWdub3JlOmxpbmVcbiAgdmFyIF9vcHRzID0ge307XG5cbiAgaWYob3B0cyAmJiBvcHRzLnJlcXVlc3RJbnRlcmNlcHRvcil7XG4gICAgX29wdHMucmVxdWVzdEludGVyY2VwdG9yID0gb3B0cy5yZXF1ZXN0SW50ZXJjZXB0b3I7XG4gIH1cblxuICBpZihvcHRzICYmIG9wdHMucmVzcG9uc2VJbnRlcmNlcHRvcil7XG4gICAgX29wdHMucmVzcG9uc2VJbnRlcmNlcHRvciA9IG9wdHMucmVzcG9uc2VJbnRlcmNlcHRvcjtcbiAgfVxuXG4gIHZhciBzd2FnZ2VyUmVxdWVzdEhlYWRlcnMgPSAnYXBwbGljYXRpb24vanNvbic7XG5cbiAgaWYob3B0cyAmJiBvcHRzLnN3YWdnZXJSZXF1ZXN0SGVhZGVycykge1xuICAgIHN3YWdnZXJSZXF1ZXN0SGVhZGVycyA9IG9wdHMuc3dhZ2dlclJlcXVlc3RIZWFkZXJzO1xuICB9XG5cbiAgaWYoZXhwZWN0ZWRDb3VudCA9PT0gMCkge1xuICAgIHRoaXMuZmluaXNoKGNhbGxiYWNrLCBzd2FnZ2VyKTtcbiAgfVxuXG4gIGZvcihpID0gMDsgaSA8IGV4cGVjdGVkQ291bnQ7IGkrKykge1xuICAgIHZhciBhcGkgPSBvYmouYXBpc1tpXTtcbiAgICB2YXIgcGF0aCA9IGFwaS5wYXRoO1xuICAgIHZhciBhYnNvbHV0ZVBhdGggPSB0aGlzLmdldEFic29sdXRlUGF0aChvYmouc3dhZ2dlclZlcnNpb24sIHRoaXMuZG9jTG9jYXRpb24sIHBhdGgpO1xuXG4gICAgaWYoYXBpLmRlc2NyaXB0aW9uKSB7XG4gICAgICBzd2FnZ2VyLnRhZ3MgPSBzd2FnZ2VyLnRhZ3MgfHwgW107XG4gICAgICBzd2FnZ2VyLnRhZ3MucHVzaCh7XG4gICAgICAgIG5hbWUgOiB0aGlzLmV4dHJhY3RUYWcoYXBpLnBhdGgpLFxuICAgICAgICBkZXNjcmlwdGlvbiA6IGFwaS5kZXNjcmlwdGlvbiB8fCAnJ1xuICAgICAgfSk7XG4gICAgfVxuICAgIHZhciBodHRwID0ge1xuICAgICAgdXJsOiBhYnNvbHV0ZVBhdGgsXG4gICAgICBoZWFkZXJzOiB7IGFjY2VwdDogc3dhZ2dlclJlcXVlc3RIZWFkZXJzIH0sXG4gICAgICBvbjoge30sXG4gICAgICBtZXRob2Q6ICdnZXQnLFxuICAgICAgdGltZW91dDogb3B0cy50aW1lb3V0XG4gICAgfTtcbiAgICAvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXG4gICAgaHR0cC5vbi5yZXNwb25zZSA9IGZ1bmN0aW9uKGRhdGEpIHtcbiAgICAgIHByb2Nlc3NlZENvdW50ICs9IDE7XG4gICAgICB2YXIgb2JqID0gZGF0YS5vYmo7XG4gICAgICBpZihvYmopIHtcbiAgICAgICAgc2VsZi5kZWNsYXJhdGlvbihvYmosIF9zd2FnZ2VyKTtcbiAgICAgIH1cbiAgICAgIGlmKHByb2Nlc3NlZENvdW50ID09PSBleHBlY3RlZENvdW50KSB7XG4gICAgICAgIHNlbGYuZmluaXNoKGNhbGxiYWNrLCBfc3dhZ2dlcik7XG4gICAgICB9XG4gICAgfTtcbiAgICBodHRwLm9uLmVycm9yID0gZnVuY3Rpb24oZGF0YSkge1xuICAgICAgY29uc29sZS5lcnJvcihkYXRhKTtcbiAgICAgIHByb2Nlc3NlZENvdW50ICs9IDE7XG4gICAgICBpZihwcm9jZXNzZWRDb3VudCA9PT0gZXhwZWN0ZWRDb3VudCkge1xuICAgICAgICBzZWxmLmZpbmlzaChjYWxsYmFjaywgX3N3YWdnZXIpO1xuICAgICAgfVxuICAgIH07XG4gICAgLyoganNoaW50IGlnbm9yZTplbmQgKi9cblxuICAgIGlmKHRoaXMuY2xpZW50QXV0aG9yaXphdGlvbnMgJiYgdHlwZW9mIHRoaXMuY2xpZW50QXV0aG9yaXphdGlvbnMuYXBwbHkgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRoaXMuY2xpZW50QXV0aG9yaXphdGlvbnMuYXBwbHkoaHR0cCk7XG4gICAgfVxuXG4gICAgbmV3IFN3YWdnZXJIdHRwKCkuZXhlY3V0ZShodHRwLCBfb3B0cyk7XG4gIH1cbn07XG5cblN3YWdnZXJTcGVjQ29udmVydGVyLnByb3RvdHlwZS5nZXRBYnNvbHV0ZVBhdGggPSBmdW5jdGlvbih2ZXJzaW9uLCBkb2NMb2NhdGlvbiwgcGF0aCkgIHtcbiAgaWYodmVyc2lvbiA9PT0gJzEuMCcpIHtcbiAgICBpZihkb2NMb2NhdGlvbi5lbmRzV2l0aCgnLmpzb24nKSkge1xuICAgICAgLy8gZ2V0IHJvb3QgcGF0aFxuICAgICAgdmFyIHBvcyA9IGRvY0xvY2F0aW9uLmxhc3RJbmRleE9mKCcvJyk7XG4gICAgICBpZihwb3MgPiAwKSB7XG4gICAgICAgIGRvY0xvY2F0aW9uID0gZG9jTG9jYXRpb24uc3Vic3RyaW5nKDAsIHBvcyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIGxvY2F0aW9uID0gZG9jTG9jYXRpb247XG4gIGlmKHBhdGguaW5kZXhPZignaHR0cDonKSA9PT0gMCB8fCBwYXRoLmluZGV4T2YoJ2h0dHBzOicpID09PSAwKSB7XG4gICAgbG9jYXRpb24gPSBwYXRoO1xuICB9XG4gIGVsc2Uge1xuICAgIGlmKGRvY0xvY2F0aW9uLmVuZHNXaXRoKCcvJykpIHtcbiAgICAgIGxvY2F0aW9uID0gZG9jTG9jYXRpb24uc3Vic3RyaW5nKDAsIGRvY0xvY2F0aW9uLmxlbmd0aCAtIDEpO1xuICAgIH1cbiAgICBsb2NhdGlvbiArPSBwYXRoO1xuICB9XG4gIGxvY2F0aW9uID0gbG9jYXRpb24ucmVwbGFjZSgne2Zvcm1hdH0nLCAnanNvbicpO1xuICByZXR1cm4gbG9jYXRpb247XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUuc2VjdXJpdHlEZWZpbml0aW9ucyA9IGZ1bmN0aW9uKG9iaiwgc3dhZ2dlcikge1xuICBpZihvYmouYXV0aG9yaXphdGlvbnMpIHtcbiAgICB2YXIgbmFtZTtcbiAgICBmb3IobmFtZSBpbiBvYmouYXV0aG9yaXphdGlvbnMpIHtcbiAgICAgIHZhciBpc1ZhbGlkID0gZmFsc2U7XG4gICAgICB2YXIgc2VjdXJpdHlEZWZpbml0aW9uID0ge1xuICAgICAgICB2ZW5kb3JFeHRlbnNpb25zOiB7fVxuICAgICAgfTtcbiAgICAgIHZhciBkZWZpbml0aW9uID0gb2JqLmF1dGhvcml6YXRpb25zW25hbWVdO1xuICAgICAgaWYoZGVmaW5pdGlvbi50eXBlID09PSAnYXBpS2V5Jykge1xuICAgICAgICBzZWN1cml0eURlZmluaXRpb24udHlwZSA9ICdhcGlLZXknO1xuICAgICAgICBzZWN1cml0eURlZmluaXRpb24uaW4gPSBkZWZpbml0aW9uLnBhc3NBcztcbiAgICAgICAgc2VjdXJpdHlEZWZpbml0aW9uLm5hbWUgPSBkZWZpbml0aW9uLmtleW5hbWUgfHwgbmFtZTtcbiAgICAgICAgaXNWYWxpZCA9IHRydWU7XG4gICAgICB9XG4gICAgICBlbHNlIGlmKGRlZmluaXRpb24udHlwZSA9PT0gJ2Jhc2ljQXV0aCcpIHtcbiAgICAgICAgc2VjdXJpdHlEZWZpbml0aW9uLnR5cGUgPSAnYmFzaWNBdXRoJztcbiAgICAgICAgaXNWYWxpZCA9IHRydWU7XG4gICAgICB9XG4gICAgICBlbHNlIGlmKGRlZmluaXRpb24udHlwZSA9PT0gJ29hdXRoMicpIHtcbiAgICAgICAgdmFyIGV4aXN0aW5nU2NvcGVzID0gZGVmaW5pdGlvbi5zY29wZXMgfHwgW107XG4gICAgICAgIHZhciBzY29wZXMgPSB7fTtcbiAgICAgICAgdmFyIGk7XG4gICAgICAgIGZvcihpIGluIGV4aXN0aW5nU2NvcGVzKSB7XG4gICAgICAgICAgdmFyIHNjb3BlID0gZXhpc3RpbmdTY29wZXNbaV07XG4gICAgICAgICAgc2NvcGVzW3Njb3BlLnNjb3BlXSA9IHNjb3BlLmRlc2NyaXB0aW9uO1xuICAgICAgICB9XG4gICAgICAgIHNlY3VyaXR5RGVmaW5pdGlvbi50eXBlID0gJ29hdXRoMic7XG4gICAgICAgIGlmKGkgPiAwKSB7XG4gICAgICAgICAgc2VjdXJpdHlEZWZpbml0aW9uLnNjb3BlcyA9IHNjb3BlcztcbiAgICAgICAgfVxuICAgICAgICBpZihkZWZpbml0aW9uLmdyYW50VHlwZXMpIHtcbiAgICAgICAgICBpZihkZWZpbml0aW9uLmdyYW50VHlwZXMuaW1wbGljaXQpIHtcbiAgICAgICAgICAgIHZhciBpbXBsaWNpdCA9IGRlZmluaXRpb24uZ3JhbnRUeXBlcy5pbXBsaWNpdDtcbiAgICAgICAgICAgIHNlY3VyaXR5RGVmaW5pdGlvbi5mbG93ID0gJ2ltcGxpY2l0JztcbiAgICAgICAgICAgIHNlY3VyaXR5RGVmaW5pdGlvbi5hdXRob3JpemF0aW9uVXJsID0gaW1wbGljaXQubG9naW5FbmRwb2ludDtcbiAgICAgICAgICAgIGlzVmFsaWQgPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXG4gICAgICAgICAgaWYoZGVmaW5pdGlvbi5ncmFudFR5cGVzWydhdXRob3JpemF0aW9uX2NvZGUnXSkge1xuICAgICAgICAgICAgaWYoIXNlY3VyaXR5RGVmaW5pdGlvbi5mbG93KSB7XG4gICAgICAgICAgICAgIC8vIGNhbm5vdCBzZXQgaWYgZmxvdyBpcyBhbHJlYWR5IGRlZmluZWRcbiAgICAgICAgICAgICAgdmFyIGF1dGhDb2RlID0gZGVmaW5pdGlvbi5ncmFudFR5cGVzWydhdXRob3JpemF0aW9uX2NvZGUnXTtcbiAgICAgICAgICAgICAgc2VjdXJpdHlEZWZpbml0aW9uLmZsb3cgPSAnYWNjZXNzQ29kZSc7XG4gICAgICAgICAgICAgIHNlY3VyaXR5RGVmaW5pdGlvbi5hdXRob3JpemF0aW9uVXJsID0gYXV0aENvZGUudG9rZW5SZXF1ZXN0RW5kcG9pbnQudXJsO1xuICAgICAgICAgICAgICBzZWN1cml0eURlZmluaXRpb24udG9rZW5VcmwgPSBhdXRoQ29kZS50b2tlbkVuZHBvaW50LnVybDtcbiAgICAgICAgICAgICAgaXNWYWxpZCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIC8qIGpzaGludCBpZ25vcmU6ZW5kICovXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmKGlzVmFsaWQpIHtcbiAgICAgICAgc3dhZ2dlci5zZWN1cml0eURlZmluaXRpb25zID0gc3dhZ2dlci5zZWN1cml0eURlZmluaXRpb25zIHx8IHt9O1xuICAgICAgICBzd2FnZ2VyLnNlY3VyaXR5RGVmaW5pdGlvbnNbbmFtZV0gPSBzZWN1cml0eURlZmluaXRpb247XG4gICAgICB9XG4gICAgfVxuICB9XG59O1xuXG5Td2FnZ2VyU3BlY0NvbnZlcnRlci5wcm90b3R5cGUuYXBpSW5mbyA9IGZ1bmN0aW9uKG9iaiwgc3dhZ2dlcikge1xuICAvLyBpbmZvIHNlY3Rpb25cbiAgaWYob2JqLmluZm8pIHtcbiAgICB2YXIgaW5mbyA9IG9iai5pbmZvO1xuICAgIHN3YWdnZXIuaW5mbyA9IHt9O1xuXG4gICAgaWYoaW5mby5jb250YWN0KSB7XG4gICAgICBzd2FnZ2VyLmluZm8uY29udGFjdCA9IHt9O1xuICAgICAgc3dhZ2dlci5pbmZvLmNvbnRhY3QuZW1haWwgPSBpbmZvLmNvbnRhY3Q7XG4gICAgfVxuICAgIGlmKGluZm8uZGVzY3JpcHRpb24pIHtcbiAgICAgIHN3YWdnZXIuaW5mby5kZXNjcmlwdGlvbiA9IGluZm8uZGVzY3JpcHRpb247XG4gICAgfVxuICAgIGlmKGluZm8udGl0bGUpIHtcbiAgICAgIHN3YWdnZXIuaW5mby50aXRsZSA9IGluZm8udGl0bGU7XG4gICAgfVxuICAgIGlmKGluZm8udGVybXNPZlNlcnZpY2VVcmwpIHtcbiAgICAgIHN3YWdnZXIuaW5mby50ZXJtc09mU2VydmljZSA9IGluZm8udGVybXNPZlNlcnZpY2VVcmw7XG4gICAgfVxuICAgIGlmKGluZm8ubGljZW5zZSB8fCBpbmZvLmxpY2Vuc2VVcmwpIHtcbiAgICAgIHN3YWdnZXIubGljZW5zZSA9IHt9O1xuICAgICAgaWYoaW5mby5saWNlbnNlKSB7XG4gICAgICAgIHN3YWdnZXIubGljZW5zZS5uYW1lID0gaW5mby5saWNlbnNlO1xuICAgICAgfVxuICAgICAgaWYoaW5mby5saWNlbnNlVXJsKSB7XG4gICAgICAgIHN3YWdnZXIubGljZW5zZS51cmwgPSBpbmZvLmxpY2Vuc2VVcmw7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGVsc2Uge1xuICAgIHRoaXMud2FybmluZ3MucHVzaCgnbWlzc2luZyBpbmZvIHNlY3Rpb24nKTtcbiAgfVxufTtcblxuU3dhZ2dlclNwZWNDb252ZXJ0ZXIucHJvdG90eXBlLmZpbmlzaCA9IGZ1bmN0aW9uIChjYWxsYmFjaywgb2JqKSB7XG4gIGNhbGxiYWNrKG9iaik7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgbG9nID0gcmVxdWlyZSgnLi4vaGVscGVycycpLmxvZztcbnZhciBfID0ge1xuICBpc1BsYWluT2JqZWN0OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNQbGFpbk9iamVjdCcpLFxuICBpc1N0cmluZzogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzU3RyaW5nJyksXG59O1xuXG52YXIgU2NoZW1hTWFya3VwID0gcmVxdWlyZSgnLi4vc2NoZW1hLW1hcmt1cC5qcycpO1xudmFyIGpzeWFtbCA9IHJlcXVpcmUoJ2pzLXlhbWwnKTtcblxudmFyIE1vZGVsID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAobmFtZSwgZGVmaW5pdGlvbiwgbW9kZWxzLCBtb2RlbFByb3BlcnR5TWFjcm8pIHtcbiAgdGhpcy5kZWZpbml0aW9uID0gZGVmaW5pdGlvbiB8fCB7fTtcbiAgdGhpcy5pc0FycmF5ID0gZGVmaW5pdGlvbi50eXBlID09PSAnYXJyYXknO1xuICB0aGlzLm1vZGVscyA9IG1vZGVscyB8fCB7fTtcbiAgdGhpcy5uYW1lID0gbmFtZSB8fCBkZWZpbml0aW9uLnRpdGxlIHx8ICdJbmxpbmUgTW9kZWwnO1xuICB0aGlzLm1vZGVsUHJvcGVydHlNYWNybyA9IG1vZGVsUHJvcGVydHlNYWNybyB8fCBmdW5jdGlvbiAocHJvcGVydHkpIHtcbiAgICByZXR1cm4gcHJvcGVydHkuZGVmYXVsdDtcbiAgfTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIE5vdGUhICBUaGlzIGZ1bmN0aW9uIHdpbGwgYmUgcmVtb3ZlZCBpbiAyLjIueCFcbk1vZGVsLnByb3RvdHlwZS5jcmVhdGVKU09OU2FtcGxlID0gTW9kZWwucHJvdG90eXBlLmdldFNhbXBsZVZhbHVlID0gZnVuY3Rpb24gKG1vZGVsc1RvSWdub3JlKSB7XG4gIG1vZGVsc1RvSWdub3JlID0gbW9kZWxzVG9JZ25vcmUgfHwge307XG5cbiAgbW9kZWxzVG9JZ25vcmVbdGhpcy5uYW1lXSA9IHRoaXM7XG5cbiAgLy8gUmVzcG9uc2Ugc3VwcG9ydFxuICBpZiAodGhpcy5leGFtcGxlcyAmJiBfLmlzUGxhaW5PYmplY3QodGhpcy5leGFtcGxlcykgJiYgdGhpcy5leGFtcGxlc1snYXBwbGljYXRpb24vanNvbiddKSB7XG4gICAgdGhpcy5kZWZpbml0aW9uLmV4YW1wbGUgPSB0aGlzLmV4YW1wbGVzWydhcHBsaWNhdGlvbi9qc29uJ107XG5cbiAgICBpZiAoXy5pc1N0cmluZyh0aGlzLmRlZmluaXRpb24uZXhhbXBsZSkpIHtcbiAgICAgIHRoaXMuZGVmaW5pdGlvbi5leGFtcGxlID0ganN5YW1sLnNhZmVMb2FkKHRoaXMuZGVmaW5pdGlvbi5leGFtcGxlKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoIXRoaXMuZGVmaW5pdGlvbi5leGFtcGxlKSB7XG4gICAgdGhpcy5kZWZpbml0aW9uLmV4YW1wbGUgPSB0aGlzLmV4YW1wbGVzO1xuICB9XG5cbiAgcmV0dXJuIFNjaGVtYU1hcmt1cC5zY2hlbWFUb0pTT04odGhpcy5kZWZpbml0aW9uLCB0aGlzLm1vZGVscywgbW9kZWxzVG9JZ25vcmUsIHRoaXMubW9kZWxQcm9wZXJ0eU1hY3JvKTtcbn07XG5cbk1vZGVsLnByb3RvdHlwZS5nZXRNb2NrU2lnbmF0dXJlID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gU2NoZW1hTWFya3VwLnNjaGVtYVRvSFRNTCh0aGlzLm5hbWUsIHRoaXMuZGVmaW5pdGlvbiwgdGhpcy5tb2RlbHMsIHRoaXMubW9kZWxQcm9wZXJ0eU1hY3JvKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBfID0ge1xuICBjbG9uZURlZXA6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9jbG9uZURlZXAnKSxcbiAgaXNVbmRlZmluZWQ6IHJlcXVpcmUoJ2xvZGFzaC1jb21wYXQvbGFuZy9pc1VuZGVmaW5lZCcpLFxuICBpc0VtcHR5OiByZXF1aXJlKCdsb2Rhc2gtY29tcGF0L2xhbmcvaXNFbXB0eScpLFxuICBpc09iamVjdDogcmVxdWlyZSgnbG9kYXNoLWNvbXBhdC9sYW5nL2lzT2JqZWN0Jylcbn07XG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4uL2hlbHBlcnMnKTtcbnZhciBNb2RlbCA9IHJlcXVpcmUoJy4vbW9kZWwnKTtcbnZhciBTd2FnZ2VySHR0cCA9IHJlcXVpcmUoJy4uL2h0dHAnKTtcbnZhciBRID0gcmVxdWlyZSgncScpO1xuXG52YXIgT3BlcmF0aW9uID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAocGFyZW50LCBzY2hlbWUsIG9wZXJhdGlvbklkLCBodHRwTWV0aG9kLCBwYXRoLCBhcmdzLCBkZWZpbml0aW9ucywgbW9kZWxzLCBjbGllbnRBdXRob3JpemF0aW9ucykge1xuICB2YXIgZXJyb3JzID0gW107XG5cbiAgcGFyZW50ID0gcGFyZW50IHx8IHt9O1xuICBhcmdzID0gYXJncyB8fCB7fTtcblxuICBpZihwYXJlbnQgJiYgcGFyZW50Lm9wdGlvbnMpIHtcbiAgICB0aGlzLmNsaWVudCA9IHBhcmVudC5vcHRpb25zLmNsaWVudCB8fCBudWxsO1xuICAgIHRoaXMucmVxdWVzdEludGVyY2VwdG9yID0gcGFyZW50Lm9wdGlvbnMucmVxdWVzdEludGVyY2VwdG9yIHx8IG51bGw7XG4gICAgdGhpcy5yZXNwb25zZUludGVyY2VwdG9yID0gcGFyZW50Lm9wdGlvbnMucmVzcG9uc2VJbnRlcmNlcHRvciB8fCBudWxsO1xuICAgIHRoaXMucmVxdWVzdEFnZW50ID0gcGFyZW50Lm9wdGlvbnMucmVxdWVzdEFnZW50O1xuICB9XG4gIHRoaXMuYXV0aG9yaXphdGlvbnMgPSBhcmdzLnNlY3VyaXR5O1xuICB0aGlzLmJhc2VQYXRoID0gcGFyZW50LmJhc2VQYXRoIHx8ICcvJztcbiAgdGhpcy5jbGllbnRBdXRob3JpemF0aW9ucyA9IGNsaWVudEF1dGhvcml6YXRpb25zO1xuICB0aGlzLmNvbnN1bWVzID0gYXJncy5jb25zdW1lcyB8fCBwYXJlbnQuY29uc3VtZXMgfHwgWydhcHBsaWNhdGlvbi9qc29uJ107XG4gIHRoaXMucHJvZHVjZXMgPSBhcmdzLnByb2R1Y2VzIHx8IHBhcmVudC5wcm9kdWNlcyB8fCBbJ2FwcGxpY2F0aW9uL2pzb24nXTtcbiAgdGhpcy5kZXByZWNhdGVkID0gYXJncy5kZXByZWNhdGVkO1xuICB0aGlzLmRlc2NyaXB0aW9uID0gYXJncy5kZXNjcmlwdGlvbjtcbiAgdGhpcy5ob3N0ID0gcGFyZW50Lmhvc3Q7XG4gIHRoaXMubWV0aG9kID0gKGh0dHBNZXRob2QgfHwgZXJyb3JzLnB1c2goJ09wZXJhdGlvbiAnICsgb3BlcmF0aW9uSWQgKyAnIGlzIG1pc3NpbmcgbWV0aG9kLicpKTtcbiAgdGhpcy5tb2RlbHMgPSBtb2RlbHMgfHwge307XG4gIHRoaXMubmlja25hbWUgPSAob3BlcmF0aW9uSWQgfHwgZXJyb3JzLnB1c2goJ09wZXJhdGlvbnMgbXVzdCBoYXZlIGEgbmlja25hbWUuJykpO1xuICB0aGlzLm9wZXJhdGlvbiA9IGFyZ3M7XG4gIHRoaXMub3BlcmF0aW9ucyA9IHt9O1xuICB0aGlzLnBhcmFtZXRlcnMgPSBhcmdzICE9PSBudWxsID8gKGFyZ3MucGFyYW1ldGVycyB8fCBbXSkgOiB7fTtcbiAgdGhpcy5wYXJlbnQgPSBwYXJlbnQ7XG4gIHRoaXMucGF0aCA9IChwYXRoIHx8IGVycm9ycy5wdXNoKCdPcGVyYXRpb24gJyArIHRoaXMubmlja25hbWUgKyAnIGlzIG1pc3NpbmcgcGF0aC4nKSk7XG4gIHRoaXMucmVzcG9uc2VzID0gKGFyZ3MucmVzcG9uc2VzIHx8IHt9KTtcbiAgdGhpcy5zY2hlbWUgPSBzY2hlbWUgfHwgcGFyZW50LnNjaGVtZSB8fCAnaHR0cCc7XG4gIHRoaXMuc2NoZW1lcyA9IGFyZ3Muc2NoZW1lcyB8fCBwYXJlbnQuc2NoZW1lcztcbiAgdGhpcy5zZWN1cml0eSA9IGFyZ3Muc2VjdXJpdHkgfHwgcGFyZW50LnNlY3VyaXR5O1xuICB0aGlzLnN1bW1hcnkgPSBhcmdzLnN1bW1hcnkgfHwgJyc7XG4gIHRoaXMudGltZW91dCA9IHBhcmVudC50aW1lb3V0O1xuICB0aGlzLnR5cGUgPSBudWxsO1xuICB0aGlzLnVzZUpRdWVyeSA9IHBhcmVudC51c2VKUXVlcnk7XG4gIHRoaXMuanF1ZXJ5QWpheENhY2hlID0gcGFyZW50LmpxdWVyeUFqYXhDYWNoZTtcbiAgdGhpcy5lbmFibGVDb29raWVzID0gcGFyZW50LmVuYWJsZUNvb2tpZXM7XG5cbiAgdmFyIGtleTtcblxuICBpZighdGhpcy5ob3N0KSB7XG4gICAgaWYodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHRoaXMuaG9zdCA9IHdpbmRvdy5sb2NhdGlvbi5ob3N0O1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHRoaXMuaG9zdCA9ICdsb2NhbGhvc3QnO1xuICAgIH1cbiAgfVxuICB0aGlzLnBhcmFtZXRlck1hY3JvID0gcGFyZW50LnBhcmFtZXRlck1hY3JvIHx8IGZ1bmN0aW9uIChvcGVyYXRpb24sIHBhcmFtZXRlcikge1xuICAgIHJldHVybiBwYXJhbWV0ZXIuZGVmYXVsdDtcbiAgfTtcblxuICB0aGlzLmlubGluZU1vZGVscyA9IFtdO1xuXG4gIGlmKHRoaXMuYmFzZVBhdGggIT09ICcvJyAmJiB0aGlzLmJhc2VQYXRoLnNsaWNlKC0xKSA9PT0gJy8nKSB7XG4gICAgdGhpcy5iYXNlUGF0aCA9IHRoaXMuYmFzZVBhdGguc2xpY2UoMCwgLTEpO1xuICB9XG5cbiAgaWYgKHR5cGVvZiB0aGlzLmRlcHJlY2F0ZWQgPT09ICdzdHJpbmcnKSB7XG4gICAgc3dpdGNoKHRoaXMuZGVwcmVjYXRlZC50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICBjYXNlICd0cnVlJzogY2FzZSAneWVzJzogY2FzZSAnMSc6IHtcbiAgICAgICAgdGhpcy5kZXByZWNhdGVkID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGNhc2UgJ2ZhbHNlJzogY2FzZSAnbm8nOiBjYXNlICcwJzogY2FzZSBudWxsOiB7XG4gICAgICAgIHRoaXMuZGVwcmVjYXRlZCA9IGZhbHNlO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgZGVmYXVsdDogdGhpcy5kZXByZWNhdGVkID0gQm9vbGVhbih0aGlzLmRlcHJlY2F0ZWQpO1xuICAgIH1cbiAgfVxuXG4gIHZhciBpLCBtb2RlbDtcblxuICBpZiAoZGVmaW5pdGlvbnMpIHtcbiAgICAvLyBhZGQgdG8gZ2xvYmFsIG1vZGVsc1xuICAgIGZvciAoa2V5IGluIGRlZmluaXRpb25zKSB7XG4gICAgICBtb2RlbCA9IG5ldyBNb2RlbChrZXksIGRlZmluaXRpb25zW2tleV0sIHRoaXMubW9kZWxzLCBwYXJlbnQubW9kZWxQcm9wZXJ0eU1hY3JvKTtcblxuICAgICAgaWYgKG1vZGVsKSB7XG4gICAgICAgIHRoaXMubW9kZWxzW2tleV0gPSBtb2RlbDtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgZWxzZSB7XG4gICAgZGVmaW5pdGlvbnMgPSB7fTtcbiAgfVxuXG4gIGZvciAoaSA9IDA7IGkgPCB0aGlzLnBhcmFtZXRlcnMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgZCwgcGFyYW0gPSB0aGlzLnBhcmFtZXRlcnNbaV07XG5cbiAgICAvLyBBbGxvdyBtYWNybyB0byBzZXQgdGhlIGRlZmF1bHQgdmFsdWVcbiAgICBwYXJhbS5kZWZhdWx0ID0gdGhpcy5wYXJhbWV0ZXJNYWNybyh0aGlzLCBwYXJhbSk7XG5cbiAgICBpZiAocGFyYW0udHlwZSA9PT0gJ2FycmF5Jykge1xuICAgICAgcGFyYW0uaXNMaXN0ID0gdHJ1ZTtcbiAgICAgIHBhcmFtLmFsbG93TXVsdGlwbGUgPSB0cnVlO1xuICAgIH1cblxuICAgIHZhciBpbm5lclR5cGUgPSB0aGlzLmdldFR5cGUocGFyYW0pO1xuXG4gICAgaWYgKGlubmVyVHlwZSAmJiBpbm5lclR5cGUudG9TdHJpbmcoKS50b0xvd2VyQ2FzZSgpID09PSAnYm9vbGVhbicpIHtcbiAgICAgIHBhcmFtLmFsbG93YWJsZVZhbHVlcyA9IHt9O1xuICAgICAgcGFyYW0uaXNMaXN0ID0gdHJ1ZTtcbiAgICAgIHBhcmFtWydlbnVtJ10gPSBbdHJ1ZSwgZmFsc2VdOyAvLyB1c2UgYWN0dWFsIHByaW1pdGl2ZXNcbiAgICB9XG5cbiAgICBmb3Ioa2V5IGluIHBhcmFtKSB7XG4gICAgICBoZWxwZXJzLmV4dHJhY3RFeHRlbnNpb25zKGtleSwgcGFyYW0pO1xuICAgIH1cbiAgICBpZih0eXBlb2YgcGFyYW1bJ3gtZXhhbXBsZSddICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgZCA9IHBhcmFtWyd4LWV4YW1wbGUnXTtcbiAgICAgIHBhcmFtLmRlZmF1bHQgPSBkO1xuICAgIH1cbiAgICBpZihwYXJhbVsneC1leGFtcGxlcyddKSB7XG4gICAgICBkID0gcGFyYW1bJ3gtZXhhbXBsZXMnXS5kZWZhdWx0O1xuICAgICAgaWYodHlwZW9mIGQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHBhcmFtLmRlZmF1bHQgPSBkO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBlbnVtVmFsdWVzID0gcGFyYW1bJ2VudW0nXSB8fCAocGFyYW0uaXRlbXMgJiYgcGFyYW0uaXRlbXNbJ2VudW0nXSk7XG5cbiAgICBpZiAodHlwZW9mIGVudW1WYWx1ZXMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB2YXIgaWQ7XG5cbiAgICAgIHBhcmFtLmFsbG93YWJsZVZhbHVlcyA9IHt9O1xuICAgICAgcGFyYW0uYWxsb3dhYmxlVmFsdWVzLnZhbHVlcyA9IFtdO1xuICAgICAgcGFyYW0uYWxsb3dhYmxlVmFsdWVzLmRlc2NyaXB0aXZlVmFsdWVzID0gW107XG5cbiAgICAgIGZvciAoaWQgPSAwOyBpZCA8IGVudW1WYWx1ZXMubGVuZ3RoOyBpZCsrKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IGVudW1WYWx1ZXNbaWRdO1xuICAgICAgICB2YXIgaXNEZWZhdWx0ID0gKHZhbHVlID09PSBwYXJhbS5kZWZhdWx0IHx8IHZhbHVlKycnID09PSBwYXJhbS5kZWZhdWx0KTtcblxuICAgICAgICBwYXJhbS5hbGxvd2FibGVWYWx1ZXMudmFsdWVzLnB1c2godmFsdWUpO1xuICAgICAgICAvLyBBbHdheXMgaGF2ZSBzdHJpbmcgZm9yIGRlc2NyaXB0aXZlIHZhbHVlcy4uLi5cbiAgICAgICAgcGFyYW0uYWxsb3dhYmxlVmFsdWVzLmRlc2NyaXB0aXZlVmFsdWVzLnB1c2goe3ZhbHVlIDogdmFsdWUrJycsIGlzRGVmYXVsdDogaXNEZWZhdWx0fSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHBhcmFtLnR5cGUgPT09ICdhcnJheScpIHtcbiAgICAgIGlubmVyVHlwZSA9IFtpbm5lclR5cGVdO1xuXG4gICAgICBpZiAodHlwZW9mIHBhcmFtLmFsbG93YWJsZVZhbHVlcyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgLy8gY2FuJ3Qgc2hvdyBhcyBhIGxpc3QgaWYgbm8gdmFsdWVzIHRvIHNlbGVjdCBmcm9tXG4gICAgICAgIGRlbGV0ZSBwYXJhbS5pc0xpc3Q7XG4gICAgICAgIGRlbGV0ZSBwYXJhbS5hbGxvd011bHRpcGxlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHBhcmFtLm1vZGVsU2lnbmF0dXJlID0ge3R5cGU6IGlubmVyVHlwZSwgZGVmaW5pdGlvbnM6IHRoaXMubW9kZWxzfTtcbiAgICBwYXJhbS5zaWduYXR1cmUgPSB0aGlzLmdldE1vZGVsU2lnbmF0dXJlKGlubmVyVHlwZSwgdGhpcy5tb2RlbHMpLnRvU3RyaW5nKCk7XG4gICAgcGFyYW0uc2FtcGxlSlNPTiA9IHRoaXMuZ2V0TW9kZWxTYW1wbGVKU09OKGlubmVyVHlwZSwgdGhpcy5tb2RlbHMpO1xuICAgIHBhcmFtLnJlc3BvbnNlQ2xhc3NTaWduYXR1cmUgPSBwYXJhbS5zaWduYXR1cmU7XG4gIH1cblxuICB2YXIga2V5bmFtZSwgZGVmYXVsdFJlc3BvbnNlQ29kZSwgcmVzcG9uc2UsIHJlc3BvbnNlcyA9IHRoaXMucmVzcG9uc2VzO1xuXG4gIGlmIChyZXNwb25zZXNbJzIwMCddKSB7XG4gICAgcmVzcG9uc2UgPSByZXNwb25zZXNbJzIwMCddO1xuICAgIGRlZmF1bHRSZXNwb25zZUNvZGUgPSAnMjAwJztcbiAgfSBlbHNlIGlmIChyZXNwb25zZXNbJzIwMSddKSB7XG4gICAgcmVzcG9uc2UgPSByZXNwb25zZXNbJzIwMSddO1xuICAgIGRlZmF1bHRSZXNwb25zZUNvZGUgPSAnMjAxJztcbiAgfSBlbHNlIGlmIChyZXNwb25zZXNbJzIwMiddKSB7XG4gICAgcmVzcG9uc2UgPSByZXNwb25zZXNbJzIwMiddO1xuICAgIGRlZmF1bHRSZXNwb25zZUNvZGUgPSAnMjAyJztcbiAgfSBlbHNlIGlmIChyZXNwb25zZXNbJzIwMyddKSB7XG4gICAgcmVzcG9uc2UgPSByZXNwb25zZXNbJzIwMyddO1xuICAgIGRlZmF1bHRSZXNwb25zZUNvZGUgPSAnMjAzJztcbiAgfSBlbHNlIGlmIChyZXNwb25zZXNbJzIwNCddKSB7XG4gICAgcmVzcG9uc2UgPSByZXNwb25zZXNbJzIwNCddO1xuICAgIGRlZmF1bHRSZXNwb25zZUNvZGUgPSAnMjA0JztcbiAgfSBlbHNlIGlmIChyZXNwb25zZXNbJzIwNSddKSB7XG4gICAgcmVzcG9uc2UgPSByZXNwb25zZXNbJzIwNSddO1xuICAgIGRlZmF1bHRSZXNwb25zZUNvZGUgPSAnMjA1JztcbiAgfSBlbHNlIGlmIChyZXNwb25zZXNbJzIwNiddKSB7XG4gICAgcmVzcG9uc2UgPSByZXNwb25zZXNbJzIwNiddO1xuICAgIGRlZmF1bHRSZXNwb25zZUNvZGUgPSAnMjA2JztcbiAgfSBlbHNlIGlmIChyZXNwb25zZXNbJ2RlZmF1bHQnXSkge1xuICAgIHJlc3BvbnNlID0gcmVzcG9uc2VzWydkZWZhdWx0J107XG4gICAgZGVmYXVsdFJlc3BvbnNlQ29kZSA9ICdkZWZhdWx0JztcbiAgfVxuXG4gIGZvcihrZXluYW1lIGluIHJlc3BvbnNlcykge1xuICAgIGhlbHBlcnMuZXh0cmFjdEV4dGVuc2lvbnMoa2V5bmFtZSwgcmVzcG9uc2VzKTtcbiAgICBpZih0eXBlb2Yga2V5bmFtZSA9PT0gJ3N0cmluZycgJiYga2V5bmFtZS5pbmRleE9mKCd4LScpID09PSAtMSkge1xuICAgICAgdmFyIHJlc3BvbnNlT2JqZWN0ID0gcmVzcG9uc2VzW2tleW5hbWVdO1xuICAgICAgaWYodHlwZW9mIHJlc3BvbnNlT2JqZWN0ID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgcmVzcG9uc2VPYmplY3QuaGVhZGVycyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgdmFyIGhlYWRlcnMgPSByZXNwb25zZU9iamVjdC5oZWFkZXJzO1xuICAgICAgICBmb3IodmFyIGhlYWRlck5hbWUgaW4gaGVhZGVycykge1xuICAgICAgICAgIHZhciBoZWFkZXIgPSBoZWFkZXJzW2hlYWRlck5hbWVdO1xuICAgICAgICAgIGlmKHR5cGVvZiBoZWFkZXIgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICBmb3IodmFyIGhlYWRlcktleSBpbiBoZWFkZXIpIHtcbiAgICAgICAgICAgICAgaGVscGVycy5leHRyYWN0RXh0ZW5zaW9ucyhoZWFkZXJLZXksIGhlYWRlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKHJlc3BvbnNlKSB7XG4gICAgZm9yKGtleW5hbWUgaW4gcmVzcG9uc2UpIHtcbiAgICAgIGhlbHBlcnMuZXh0cmFjdEV4dGVuc2lvbnMoa2V5bmFtZSwgcmVzcG9uc2UpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChyZXNwb25zZSAmJiByZXNwb25zZS5zY2hlbWEpIHtcbiAgICB2YXIgcmVzb2x2ZWRNb2RlbCA9IHRoaXMucmVzb2x2ZU1vZGVsKHJlc3BvbnNlLnNjaGVtYSwgZGVmaW5pdGlvbnMpO1xuICAgIHZhciBzdWNjZXNzUmVzcG9uc2U7XG5cbiAgICBkZWxldGUgcmVzcG9uc2VzW2RlZmF1bHRSZXNwb25zZUNvZGVdO1xuXG4gICAgaWYgKHJlc29sdmVkTW9kZWwpIHtcbiAgICAgIHRoaXMuc3VjY2Vzc1Jlc3BvbnNlID0ge307XG4gICAgICBzdWNjZXNzUmVzcG9uc2UgPSB0aGlzLnN1Y2Nlc3NSZXNwb25zZVtkZWZhdWx0UmVzcG9uc2VDb2RlXSA9IHJlc29sdmVkTW9kZWw7XG4gICAgfSBlbHNlIGlmICghcmVzcG9uc2Uuc2NoZW1hLnR5cGUgfHwgcmVzcG9uc2Uuc2NoZW1hLnR5cGUgPT09ICdvYmplY3QnIHx8IHJlc3BvbnNlLnNjaGVtYS50eXBlID09PSAnYXJyYXknKSB7XG4gICAgICAvLyBJbmxpbmUgbW9kZWxcbiAgICAgIHRoaXMuc3VjY2Vzc1Jlc3BvbnNlID0ge307XG4gICAgICBzdWNjZXNzUmVzcG9uc2UgPSB0aGlzLnN1Y2Nlc3NSZXNwb25zZVtkZWZhdWx0UmVzcG9uc2VDb2RlXSA9IG5ldyBNb2RlbCh1bmRlZmluZWQsIHJlc3BvbnNlLnNjaGVtYSB8fCB7fSwgdGhpcy5tb2RlbHMsIHBhcmVudC5tb2RlbFByb3BlcnR5TWFjcm8pO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBQcmltaXRpdmVcbiAgICAgIHRoaXMuc3VjY2Vzc1Jlc3BvbnNlID0ge307XG4gICAgICBzdWNjZXNzUmVzcG9uc2UgPSB0aGlzLnN1Y2Nlc3NSZXNwb25zZVtkZWZhdWx0UmVzcG9uc2VDb2RlXSA9IHJlc3BvbnNlLnNjaGVtYTtcbiAgICB9XG5cbiAgICBpZiAoc3VjY2Vzc1Jlc3BvbnNlKSB7XG4gICAgICBzdWNjZXNzUmVzcG9uc2UudmVuZG9yRXh0ZW5zaW9ucyA9IHJlc3BvbnNlLnZlbmRvckV4dGVuc2lvbnM7XG4gICAgICAvLyBBdHRhY2ggcmVzcG9uc2UgcHJvcGVydGllc1xuICAgICAgaWYgKHJlc3BvbnNlLmRlc2NyaXB0aW9uKSB7XG4gICAgICAgIHN1Y2Nlc3NSZXNwb25zZS5kZXNjcmlwdGlvbiA9IHJlc3BvbnNlLmRlc2NyaXB0aW9uO1xuICAgICAgfVxuXG4gICAgICBpZiAocmVzcG9uc2UuZXhhbXBsZXMpIHtcbiAgICAgICAgc3VjY2Vzc1Jlc3BvbnNlLmV4YW1wbGVzID0gcmVzcG9uc2UuZXhhbXBsZXM7XG4gICAgICB9XG5cbiAgICAgIGlmIChyZXNwb25zZS5oZWFkZXJzKSB7XG4gICAgICAgIHN1Y2Nlc3NSZXNwb25zZS5oZWFkZXJzID0gcmVzcG9uc2UuaGVhZGVycztcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLnR5cGUgPSByZXNwb25zZTtcbiAgfVxuXG4gIGlmIChlcnJvcnMubGVuZ3RoID4gMCkge1xuICAgIGlmICh0aGlzLnJlc291cmNlICYmIHRoaXMucmVzb3VyY2UuYXBpICYmIHRoaXMucmVzb3VyY2UuYXBpLmZhaWwpIHtcbiAgICAgIHRoaXMucmVzb3VyY2UuYXBpLmZhaWwoZXJyb3JzKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuaXNEZWZhdWx0QXJyYXlJdGVtVmFsdWUgPSBmdW5jdGlvbih2YWx1ZSwgcGFyYW0pIHtcbiAgaWYgKHBhcmFtLmRlZmF1bHQgJiYgQXJyYXkuaXNBcnJheShwYXJhbS5kZWZhdWx0KSkge1xuICAgIHJldHVybiBwYXJhbS5kZWZhdWx0LmluZGV4T2YodmFsdWUpICE9PSAtMTtcbiAgfVxuICByZXR1cm4gdmFsdWUgPT09IHBhcmFtLmRlZmF1bHQ7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmdldFR5cGUgPSBmdW5jdGlvbiAocGFyYW0pIHtcbiAgdmFyIHR5cGUgPSBwYXJhbS50eXBlO1xuICB2YXIgZm9ybWF0ID0gcGFyYW0uZm9ybWF0O1xuICB2YXIgaXNBcnJheSA9IGZhbHNlO1xuICB2YXIgc3RyO1xuXG4gIGlmICh0eXBlID09PSAnaW50ZWdlcicgJiYgZm9ybWF0ID09PSAnaW50MzInKSB7XG4gICAgc3RyID0gJ2ludGVnZXInO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdpbnRlZ2VyJyAmJiBmb3JtYXQgPT09ICdpbnQ2NCcpIHtcbiAgICBzdHIgPSAnbG9uZyc7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2ludGVnZXInKSB7XG4gICAgc3RyID0gJ2ludGVnZXInO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKGZvcm1hdCA9PT0gJ2RhdGUtdGltZScpIHtcbiAgICAgIHN0ciA9ICdkYXRlLXRpbWUnO1xuICAgIH0gZWxzZSBpZiAoZm9ybWF0ID09PSAnZGF0ZScpIHtcbiAgICAgIHN0ciA9ICdkYXRlJztcbiAgICB9IGVsc2Uge1xuICAgICAgc3RyID0gJ3N0cmluZyc7XG4gICAgfVxuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdudW1iZXInICYmIGZvcm1hdCA9PT0gJ2Zsb2F0Jykge1xuICAgIHN0ciA9ICdmbG9hdCc7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ251bWJlcicgJiYgZm9ybWF0ID09PSAnZG91YmxlJykge1xuICAgIHN0ciA9ICdkb3VibGUnO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdudW1iZXInKSB7XG4gICAgc3RyID0gJ2RvdWJsZSc7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgc3RyID0gJ2Jvb2xlYW4nO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdhcnJheScpIHtcbiAgICBpc0FycmF5ID0gdHJ1ZTtcblxuICAgIGlmIChwYXJhbS5pdGVtcykge1xuICAgICAgc3RyID0gdGhpcy5nZXRUeXBlKHBhcmFtLml0ZW1zKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2ZpbGUnKSB7XG4gICAgc3RyID0gJ2ZpbGUnO1xuICB9XG5cbiAgaWYgKHBhcmFtLiRyZWYpIHtcbiAgICBzdHIgPSBoZWxwZXJzLnNpbXBsZVJlZihwYXJhbS4kcmVmKTtcbiAgfVxuXG4gIHZhciBzY2hlbWEgPSBwYXJhbS5zY2hlbWE7XG5cbiAgaWYgKHNjaGVtYSkge1xuICAgIHZhciByZWYgPSBzY2hlbWEuJHJlZjtcblxuICAgIGlmIChyZWYpIHtcbiAgICAgIHJlZiA9IGhlbHBlcnMuc2ltcGxlUmVmKHJlZik7XG5cbiAgICAgIGlmIChpc0FycmF5KSB7XG4gICAgICAgIHJldHVybiBbIHJlZiBdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHJlZjtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSWYgaW5saW5lIHNjaGVtYSwgd2UgYWRkIGl0IG91ciBpbnRlcmFsIGhhc2ggLT4gd2hpY2ggZ2l2ZXMgdXMgaXQncyBJRCAoaW50KVxuICAgICAgaWYoc2NoZW1hLnR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFkZElubGluZU1vZGVsKHNjaGVtYSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5nZXRUeXBlKHNjaGVtYSk7XG4gICAgfVxuICB9XG4gIGlmIChpc0FycmF5KSB7XG4gICAgcmV0dXJuIFsgc3RyIF07XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHN0cjtcbiAgfVxufTtcblxuLyoqXG4gKiBhZGRzIGFuIGlubGluZSBzY2hlbWEgKG1vZGVsKSB0byBhIGhhc2gsIHdoZXJlIHdlIGNhbiByZWYgaXQgbGF0ZXJcbiAqIEBwYXJhbSB7b2JqZWN0fSBzY2hlbWEgYSBzY2hlbWFcbiAqIEByZXR1cm4ge251bWJlcn0gdGhlIElEIG9mIHRoZSBzY2hlbWEgYmVpbmcgYWRkZWQsIG9yIG51bGxcbiAqKi9cbk9wZXJhdGlvbi5wcm90b3R5cGUuYWRkSW5saW5lTW9kZWwgPSBmdW5jdGlvbiAoc2NoZW1hKSB7XG4gIHZhciBsZW4gPSB0aGlzLmlubGluZU1vZGVscy5sZW5ndGg7XG4gIHZhciBtb2RlbCA9IHRoaXMucmVzb2x2ZU1vZGVsKHNjaGVtYSwge30pO1xuICBpZihtb2RlbCkge1xuICAgIHRoaXMuaW5saW5lTW9kZWxzLnB1c2gobW9kZWwpO1xuICAgIHJldHVybiAnSW5saW5lIE1vZGVsICcrbGVuOyAvLyByZXR1cm4gc3RyaW5nIHJlZiBvZiB0aGUgaW5saW5lIG1vZGVsICh1c2VkIHdpdGggI2dldElubGluZU1vZGVsKVxuICB9XG4gIHJldHVybiBudWxsOyAvLyByZXBvcnQgZXJyb3JzP1xufTtcblxuLyoqXG4gKiBnZXRzIHRoZSBpbnRlcm5hbCByZWYgdG8gYW4gaW5saW5lIG1vZGVsXG4gKiBAcGFyYW0ge3N0cmluZ30gaW5saW5lX3N0ciBhIHN0cmluZyByZWZlcmVuY2UgdG8gYW4gaW5saW5lIG1vZGVsXG4gKiBAcmV0dXJuIHtNb2RlbH0gdGhlIG1vZGVsIGJlaW5nIHJlZmVyZW5jZWQuIE9yIG51bGxcbiAqKi9cbk9wZXJhdGlvbi5wcm90b3R5cGUuZ2V0SW5saW5lTW9kZWwgPSBmdW5jdGlvbihpbmxpbmVTdHIpIHtcbiAgaWYoL15JbmxpbmUgTW9kZWwgXFxkKyQvLnRlc3QoaW5saW5lU3RyKSkge1xuICAgIHZhciBpZCA9IHBhcnNlSW50KGlubGluZVN0ci5zdWJzdHIoJ0lubGluZSBNb2RlbCcubGVuZ3RoKS50cmltKCksMTApOyAvL1xuICAgIHZhciBtb2RlbCA9IHRoaXMuaW5saW5lTW9kZWxzW2lkXTtcbiAgICByZXR1cm4gbW9kZWw7XG4gIH1cbiAgLy8gSSdtIHJldHVybmluZyBudWxsIGhlcmUsIHNob3VsZCBJIHJhdGhlciB0aHJvdyBhbiBlcnJvcj9cbiAgcmV0dXJuIG51bGw7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLnJlc29sdmVNb2RlbCA9IGZ1bmN0aW9uIChzY2hlbWEsIGRlZmluaXRpb25zKSB7XG4gIGlmICh0eXBlb2Ygc2NoZW1hLiRyZWYgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgdmFyIHJlZiA9IHNjaGVtYS4kcmVmO1xuXG4gICAgaWYgKHJlZi5pbmRleE9mKCcjL2RlZmluaXRpb25zLycpID09PSAwKSB7XG4gICAgICByZWYgPSByZWYuc3Vic3RyaW5nKCcjL2RlZmluaXRpb25zLycubGVuZ3RoKTtcbiAgICB9XG5cbiAgICBpZiAoZGVmaW5pdGlvbnNbcmVmXSkge1xuICAgICAgcmV0dXJuIG5ldyBNb2RlbChyZWYsIGRlZmluaXRpb25zW3JlZl0sIHRoaXMubW9kZWxzLCB0aGlzLnBhcmVudC5tb2RlbFByb3BlcnR5TWFjcm8pO1xuICAgIH1cbiAgLy8gc2NoZW1hIG11c3QgYXQgbGVhc3QgYmUgYW4gb2JqZWN0IHRvIGdldCByZXNvbHZlZCB0byBhbiBpbmxpbmUgTW9kZWxcbiAgfSBlbHNlIGlmIChzY2hlbWEgJiYgdHlwZW9mIHNjaGVtYSA9PT0gJ29iamVjdCcgJiZcbiAgICAgICAgICAgIChzY2hlbWEudHlwZSA9PT0gJ29iamVjdCcgfHwgXy5pc1VuZGVmaW5lZChzY2hlbWEudHlwZSkpKSB7XG4gICAgcmV0dXJuIG5ldyBNb2RlbCh1bmRlZmluZWQsIHNjaGVtYSwgdGhpcy5tb2RlbHMsIHRoaXMucGFyZW50Lm1vZGVsUHJvcGVydHlNYWNybyk7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuaGVscCA9IGZ1bmN0aW9uIChkb250UHJpbnQpIHtcbiAgdmFyIG91dCA9IHRoaXMubmlja25hbWUgKyAnOiAnICsgdGhpcy5zdW1tYXJ5ICsgJ1xcbic7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnBhcmFtZXRlcnMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgcGFyYW0gPSB0aGlzLnBhcmFtZXRlcnNbaV07XG4gICAgdmFyIHR5cGVJbmZvID0gcGFyYW0uc2lnbmF0dXJlO1xuXG4gICAgb3V0ICs9ICdcXG4gICogJyArIHBhcmFtLm5hbWUgKyAnICgnICsgdHlwZUluZm8gKyAnKTogJyArIHBhcmFtLmRlc2NyaXB0aW9uO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBkb250UHJpbnQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgaGVscGVycy5sb2cob3V0KTtcbiAgfVxuXG4gIHJldHVybiBvdXQ7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmdldE1vZGVsU2lnbmF0dXJlID0gZnVuY3Rpb24gKHR5cGUsIGRlZmluaXRpb25zKSB7XG4gIHZhciBpc1ByaW1pdGl2ZSwgbGlzdFR5cGU7XG5cbiAgaWYgKHR5cGUgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgIGxpc3RUeXBlID0gdHJ1ZTtcbiAgICB0eXBlID0gdHlwZVswXTtcbiAgfVxuXG4gIC8vIENvbnZlcnQgdW5kZWZpbmVkIHRvIHN0cmluZyBvZiAndW5kZWZpbmVkJ1xuICBpZiAodHlwZW9mIHR5cGUgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgdHlwZSA9ICd1bmRlZmluZWQnO1xuICAgIGlzUHJpbWl0aXZlID0gdHJ1ZTtcblxuICB9IGVsc2UgaWYgKGRlZmluaXRpb25zW3R5cGVdKXtcbiAgICAvLyBhIG1vZGVsIGRlZiBleGlzdHM/XG4gICAgdHlwZSA9IGRlZmluaXRpb25zW3R5cGVdOyAvKiBNb2RlbCAqL1xuICAgIGlzUHJpbWl0aXZlID0gZmFsc2U7XG5cbiAgfSBlbHNlIGlmICh0aGlzLmdldElubGluZU1vZGVsKHR5cGUpKSB7XG4gICAgdHlwZSA9IHRoaXMuZ2V0SW5saW5lTW9kZWwodHlwZSk7IC8qIE1vZGVsICovXG4gICAgaXNQcmltaXRpdmUgPSBmYWxzZTtcblxuICB9IGVsc2Uge1xuICAgIC8vIFdlIGRlZmF1bHQgdG8gcHJpbWl0aXZlXG4gICAgaXNQcmltaXRpdmUgPSB0cnVlO1xuICB9XG5cbiAgaWYgKGlzUHJpbWl0aXZlKSB7XG4gICAgaWYgKGxpc3RUeXBlKSB7XG4gICAgICByZXR1cm4gJ0FycmF5WycgKyB0eXBlICsgJ10nO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdHlwZS50b1N0cmluZygpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAobGlzdFR5cGUpIHtcbiAgICAgIHJldHVybiAnQXJyYXlbJyArIHR5cGUuZ2V0TW9ja1NpZ25hdHVyZSgpICsgJ10nO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdHlwZS5nZXRNb2NrU2lnbmF0dXJlKCk7XG4gICAgfVxuICB9XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLnN1cHBvcnRIZWFkZXJQYXJhbXMgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiB0cnVlO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5zdXBwb3J0ZWRTdWJtaXRNZXRob2RzID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdGhpcy5wYXJlbnQuc3VwcG9ydGVkU3VibWl0TWV0aG9kcztcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuZ2V0SGVhZGVyUGFyYW1zID0gZnVuY3Rpb24gKGFyZ3MpIHtcbiAgdmFyIGhlYWRlcnMgPSB0aGlzLnNldENvbnRlbnRUeXBlcyhhcmdzLCB7fSk7XG4gIHZhciBoZWFkZXJQYXJhbXNCeUxvd2VyQ2FzZSA9IHt9O1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5wYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHBhcmFtID0gdGhpcy5wYXJhbWV0ZXJzW2ldO1xuXG4gICAgaWYgKHBhcmFtLmluID09PSAnaGVhZGVyJykge1xuICAgICAgaGVhZGVyUGFyYW1zQnlMb3dlckNhc2VbcGFyYW0ubmFtZS50b0xvd2VyQ2FzZSgpXSA9IHBhcmFtO1xuICAgIH1cbiAgfVxuXG4gIGZvciAodmFyIGFyZyBpbiBhcmdzKSB7XG4gICAgdmFyIGhlYWRlclBhcmFtID0gaGVhZGVyUGFyYW1zQnlMb3dlckNhc2VbYXJnLnRvTG93ZXJDYXNlKCldO1xuICAgIGlmICh0eXBlb2YgaGVhZGVyUGFyYW0gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB2YXIgdmFsdWUgPSBhcmdzW2FyZ107XG5cbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICB2YWx1ZSA9IHZhbHVlLnRvU3RyaW5nKCk7XG4gICAgICB9XG5cbiAgICAgIGhlYWRlcnNbaGVhZGVyUGFyYW0ubmFtZV0gPSB2YWx1ZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gaGVhZGVycztcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUudXJsaWZ5ID0gZnVuY3Rpb24gKGFyZ3MsIG1hc2tQYXNzd29yZHMpIHtcbiAgdmFyIGZvcm1QYXJhbXMgPSB7fTtcbiAgdmFyIHJlcXVlc3RVcmwgPSB0aGlzLnBhdGgucmVwbGFjZSgvIy4qLywgJycpOyAvLyByZW1vdmUgVVJMIGZyYWdtZW50XG4gIHZhciBxdWVyeXN0cmluZyA9ICcnOyAvLyBncmFiIHBhcmFtcyBmcm9tIHRoZSBhcmdzLCBidWlsZCB0aGUgcXVlcnlzdHJpbmcgYWxvbmcgdGhlIHdheVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5wYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHBhcmFtID0gdGhpcy5wYXJhbWV0ZXJzW2ldO1xuXG4gICAgaWYgKHR5cGVvZiBhcmdzW3BhcmFtLm5hbWVdICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdmFyIGlzUGFzc3dvcmQ7XG4gICAgICBpZihwYXJhbS50eXBlID09PSAnc3RyaW5nJyAmJiBwYXJhbS5mb3JtYXQgPT09ICdwYXNzd29yZCcgJiYgbWFza1Bhc3N3b3Jkcykge1xuICAgICAgICBpc1Bhc3N3b3JkID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKHBhcmFtLmluID09PSAncGF0aCcpIHtcbiAgICAgICAgdmFyIHJlZyA9IG5ldyBSZWdFeHAoJ1xceycgKyBwYXJhbS5uYW1lICsgJ1xcfScsICdnaScpO1xuICAgICAgICB2YXIgdmFsdWUgPSBhcmdzW3BhcmFtLm5hbWVdO1xuXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgIHZhbHVlID0gdGhpcy5lbmNvZGVQYXRoQ29sbGVjdGlvbihwYXJhbS5jb2xsZWN0aW9uRm9ybWF0LCBwYXJhbS5uYW1lLCB2YWx1ZSwgaXNQYXNzd29yZCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYoKHR5cGVvZihwYXJhbVsneC1lc2NhcGUnXSkgPT09ICd1bmRlZmluZWQnKSB8fCAocGFyYW1bJ3gtZXNjYXBlJ10gPT09IHRydWUpKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IHRoaXMuZW5jb2RlUGF0aFBhcmFtKHZhbHVlLCBpc1Bhc3N3b3JkKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXF1ZXN0VXJsID0gcmVxdWVzdFVybC5yZXBsYWNlKHJlZywgdmFsdWUpO1xuICAgICAgfSBlbHNlIGlmIChwYXJhbS5pbiA9PT0gJ3F1ZXJ5JyAmJiB0eXBlb2YgYXJnc1twYXJhbS5uYW1lXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgaWYgKHF1ZXJ5c3RyaW5nID09PSAnJyAmJiByZXF1ZXN0VXJsLmluZGV4T2YoJz8nKSA8IDApIHtcbiAgICAgICAgICBxdWVyeXN0cmluZyArPSAnPyc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcXVlcnlzdHJpbmcgKz0gJyYnO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiBwYXJhbS5jb2xsZWN0aW9uRm9ybWF0ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIHZhciBxcCA9IGFyZ3NbcGFyYW0ubmFtZV07XG5cbiAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShxcCkpIHtcbiAgICAgICAgICAgIHF1ZXJ5c3RyaW5nICs9IHRoaXMuZW5jb2RlUXVlcnlDb2xsZWN0aW9uKHBhcmFtLmNvbGxlY3Rpb25Gb3JtYXQsIHBhcmFtLm5hbWUsIHFwLCBpc1Bhc3N3b3JkKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcXVlcnlzdHJpbmcgKz0gdGhpcy5lbmNvZGVRdWVyeUtleShwYXJhbS5uYW1lKSArICc9JyArIHRoaXMuZW5jb2RlUXVlcnlQYXJhbShhcmdzW3BhcmFtLm5hbWVdLCBpc1Bhc3N3b3JkKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcXVlcnlzdHJpbmcgKz0gdGhpcy5lbmNvZGVRdWVyeUtleShwYXJhbS5uYW1lKSArICc9JyArIHRoaXMuZW5jb2RlUXVlcnlQYXJhbShhcmdzW3BhcmFtLm5hbWVdLCBpc1Bhc3N3b3JkKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChwYXJhbS5pbiA9PT0gJ2Zvcm1EYXRhJykge1xuICAgICAgICBmb3JtUGFyYW1zW3BhcmFtLm5hbWVdID0gYXJnc1twYXJhbS5uYW1lXTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYocGFyYW0uaW4gPT09ICdxdWVyeScgJiYgdHlwZW9mIGFyZ3NbcGFyYW0ubmFtZV0gPT09ICd1bmRlZmluZWQnICYmIHBhcmFtLmFsbG93RW1wdHlWYWx1ZSA9PT0gdHJ1ZSkge1xuICAgICAgaWYgKHF1ZXJ5c3RyaW5nID09PSAnJyAmJiByZXF1ZXN0VXJsLmluZGV4T2YoJz8nKSA8IDApIHtcbiAgICAgICAgcXVlcnlzdHJpbmcgKz0gJz8nO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcXVlcnlzdHJpbmcgKz0gJyYnO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIHBhcmFtLmNvbGxlY3Rpb25Gb3JtYXQgIT09ICd1bmRlZmluZWQnIHx8IHBhcmFtLnR5cGUgPT09ICdhcnJheScpIHtcbiAgICAgICAgdmFyIHFwO1xuICAgICAgICB2YXIgY29sbGVjdGlvbkZvcm1hdCA9IHBhcmFtLmNvbGxlY3Rpb25Gb3JtYXQgfHwgJ211bHRpJztcblxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShxcCkpIHtcbiAgICAgICAgICBxdWVyeXN0cmluZyArPSB0aGlzLmVuY29kZVF1ZXJ5Q29sbGVjdGlvbihjb2xsZWN0aW9uRm9ybWF0LCBwYXJhbS5uYW1lLCBxcCwgaXNQYXNzd29yZCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcXVlcnlzdHJpbmcgKz0gdGhpcy5lbmNvZGVRdWVyeUNvbGxlY3Rpb24oY29sbGVjdGlvbkZvcm1hdCwgcGFyYW0ubmFtZSwgW3FwXSwgaXNQYXNzd29yZCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHF1ZXJ5c3RyaW5nICs9IHRoaXMuZW5jb2RlUXVlcnlLZXkocGFyYW0ubmFtZSkgKyAnPScgKyB0aGlzLmVuY29kZVF1ZXJ5UGFyYW0oJycsIGlzUGFzc3dvcmQpO1xuICAgICAgfVxuXG4gICAgfVxuICB9XG4gIHZhciB1cmwgPSB0aGlzLnNjaGVtZSArICc6Ly8nICsgdGhpcy5ob3N0O1xuXG4gIGlmICh0aGlzLmJhc2VQYXRoICE9PSAnLycpIHtcbiAgICB1cmwgKz0gdGhpcy5iYXNlUGF0aDtcbiAgfVxuICByZXR1cm4gdXJsICsgcmVxdWVzdFVybCArIHF1ZXJ5c3RyaW5nO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5nZXRNaXNzaW5nUGFyYW1zID0gZnVuY3Rpb24gKGFyZ3MpIHtcbiAgdmFyIG1pc3NpbmdQYXJhbXMgPSBbXTsgLy8gY2hlY2sgcmVxdWlyZWQgcGFyYW1zLCB0cmFjayB0aGUgb25lcyB0aGF0IGFyZSBtaXNzaW5nXG4gIHZhciBpO1xuXG4gIGZvciAoaSA9IDA7IGkgPCB0aGlzLnBhcmFtZXRlcnMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgcGFyYW0gPSB0aGlzLnBhcmFtZXRlcnNbaV07XG5cbiAgICBpZiAocGFyYW0ucmVxdWlyZWQgPT09IHRydWUpIHtcbiAgICAgIGlmICh0eXBlb2YgYXJnc1twYXJhbS5uYW1lXSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgbWlzc2luZ1BhcmFtcyA9IHBhcmFtLm5hbWU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG1pc3NpbmdQYXJhbXM7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmdldEJvZHkgPSBmdW5jdGlvbiAoaGVhZGVycywgYXJncywgb3B0cykge1xuICB2YXIgZm9ybVBhcmFtcyA9IHt9LCBoYXNGb3JtUGFyYW1zLCBwYXJhbSwgYm9keSwga2V5LCB2YWx1ZSwgaGFzQm9keSA9IGZhbHNlO1xuXG4gIC8vIGxvb2sgYXQgZWFjaCBwYXJhbSBhbmQgcHV0IGZvcm0gcGFyYW1zIGluIGFuIG9iamVjdFxuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMucGFyYW1ldGVycy5sZW5ndGg7IGkrKykge1xuICAgIHBhcmFtID0gdGhpcy5wYXJhbWV0ZXJzW2ldO1xuICAgIGlmICh0eXBlb2YgYXJnc1twYXJhbS5uYW1lXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHZhciBpc1Bhc3N3b3JkO1xuICAgICAgaWYocGFyYW0udHlwZSA9PT0gJ3N0cmluZycgJiYgcGFyYW0uZm9ybWF0ID09PSAncGFzc3dvcmQnKSB7XG4gICAgICAgIGlzUGFzc3dvcmQgPSAncGFzc3dvcmQnO1xuICAgICAgfVxuICAgICAgaWYgKHBhcmFtLmluID09PSAnYm9keScpIHtcbiAgICAgICAgYm9keSA9IGFyZ3NbcGFyYW0ubmFtZV07XG4gICAgICB9IGVsc2UgaWYgKHBhcmFtLmluID09PSAnZm9ybURhdGEnKSB7XG4gICAgICAgIGZvcm1QYXJhbXNbcGFyYW0ubmFtZV0gPSB7XG4gICAgICAgICAgcGFyYW06IHBhcmFtLFxuICAgICAgICAgIHZhbHVlOiBhcmdzW3BhcmFtLm5hbWVdLFxuICAgICAgICAgIHBhc3N3b3JkOiBpc1Bhc3N3b3JkXG4gICAgICAgIH07XG4gICAgICAgIGhhc0Zvcm1QYXJhbXMgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGlmKHBhcmFtLmluID09PSAnYm9keScpIHtcbiAgICAgICAgaGFzQm9keSA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gaWYgYm9keSBpcyBudWxsIGFuZCBoYXNCb2R5IGlzIHRydWUsIEFORCBhIEpTT04gYm9keSBpcyByZXF1ZXN0ZWQsIHNlbmQgZW1wdHkge31cbiAgaWYoaGFzQm9keSAmJiB0eXBlb2YgYm9keSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICB2YXIgY29udGVudFR5cGUgPSBoZWFkZXJzWydDb250ZW50LVR5cGUnXTtcbiAgICBpZihjb250ZW50VHlwZSAmJiBjb250ZW50VHlwZS5pbmRleE9mKCdhcHBsaWNhdGlvbi9qc29uJykgPT09IDApIHtcbiAgICAgIGJvZHkgPSAne30nO1xuICAgIH1cbiAgfVxuXG4gIHZhciBpc011bHRpUGFydCA9IGZhbHNlO1xuICBpZihoZWFkZXJzWydDb250ZW50LVR5cGUnXSAmJiBoZWFkZXJzWydDb250ZW50LVR5cGUnXS5pbmRleE9mKCdtdWx0aXBhcnQvZm9ybS1kYXRhJykgPj0gMCkge1xuICAgIGlzTXVsdGlQYXJ0ID0gdHJ1ZTtcbiAgfVxuXG4gIC8vIGhhbmRsZSBmb3JtIHBhcmFtc1xuICBpZiAoaGFzRm9ybVBhcmFtcyAmJiAhaXNNdWx0aVBhcnQpIHtcbiAgICB2YXIgZW5jb2RlZCA9ICcnO1xuXG4gICAgZm9yIChrZXkgaW4gZm9ybVBhcmFtcykge1xuICAgICAgcGFyYW0gPSBmb3JtUGFyYW1zW2tleV0ucGFyYW07XG4gICAgICB2YWx1ZSA9IGZvcm1QYXJhbXNba2V5XS52YWx1ZTtcbiAgICAgIHZhciBwYXNzd29yZDtcblxuICAgICAgaWYob3B0cyAmJiBvcHRzLm1hc2tQYXNzd29yZHMpIHtcbiAgICAgICAgcGFzc3dvcmQgPSBmb3JtUGFyYW1zW2tleV0ucGFzc3dvcmQ7XG4gICAgICB9XG5cbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgIGlmIChlbmNvZGVkICE9PSAnJykge1xuICAgICAgICAgICAgZW5jb2RlZCArPSAnJic7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVuY29kZWQgKz0gdGhpcy5lbmNvZGVRdWVyeUNvbGxlY3Rpb24ocGFyYW0uY29sbGVjdGlvbkZvcm1hdCwga2V5LCB2YWx1ZSwgcGFzc3dvcmQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGlmIChlbmNvZGVkICE9PSAnJykge1xuICAgICAgICAgICAgZW5jb2RlZCArPSAnJic7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZW5jb2RlZCArPSBlbmNvZGVVUklDb21wb25lbnQoa2V5KSArICc9JyArIG1hc2soZW5jb2RlVVJJQ29tcG9uZW50KHZhbHVlKSwgcGFzc3dvcmQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgYm9keSA9IGVuY29kZWQ7XG4gIH0gZWxzZSBpZiAoaXNNdWx0aVBhcnQpIHtcbiAgICB2YXIgYm9keVBhcmFtO1xuICAgIGlmICh0eXBlb2YgRm9ybURhdGEgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGJvZHlQYXJhbSA9IG5ldyBGb3JtRGF0YSgpO1xuXG4gICAgICBib2R5UGFyYW0udHlwZSA9ICdmb3JtRGF0YSc7XG5cbiAgICAgIGZvciAoa2V5IGluIGZvcm1QYXJhbXMpIHtcbiAgICAgICAgcGFyYW0gPSBmb3JtUGFyYW1zW2tleV0ucGFyYW07XG4gICAgICAgIHZhbHVlID0gYXJnc1trZXldO1xuXG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgaWYoe30udG9TdHJpbmcuYXBwbHkodmFsdWUpID09PSAnW29iamVjdCBGaWxlXScpIHtcbiAgICAgICAgICAgIGJvZHlQYXJhbS5hcHBlbmQoa2V5LCB2YWx1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2UgaWYgKHZhbHVlLnR5cGUgPT09ICdmaWxlJyAmJiB2YWx1ZS52YWx1ZSkge1xuICAgICAgICAgICAgYm9keVBhcmFtLmFwcGVuZChrZXksIHZhbHVlLnZhbHVlKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICAgIGlmKHBhcmFtLmNvbGxlY3Rpb25Gb3JtYXQgPT09ICdtdWx0aScpIHtcbiAgICAgICAgICAgICAgICBib2R5UGFyYW0uZGVsZXRlKGtleSk7XG4gICAgICAgICAgICAgICAgZm9yKHZhciB2IGluIHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICBib2R5UGFyYW0uYXBwZW5kKGtleSwgdmFsdWVbdl0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBib2R5UGFyYW0uYXBwZW5kKGtleSwgdGhpcy5lbmNvZGVRdWVyeUNvbGxlY3Rpb24ocGFyYW0uY29sbGVjdGlvbkZvcm1hdCwga2V5LCB2YWx1ZSkuc3BsaXQoJz0nKS5zbGljZSgxKS5qb2luKCc9JykpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgYm9keVBhcmFtLmFwcGVuZChrZXksIHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGJvZHkgPSBib2R5UGFyYW07XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgYm9keVBhcmFtID0ge307XG4gICAgICBmb3IgKGtleSBpbiBmb3JtUGFyYW1zKSB7XG4gICAgICAgIHZhbHVlID0gYXJnc1trZXldO1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICB2YXIgZGVsaW1ldGVyO1xuICAgICAgICAgIHZhciBmb3JtYXQgPSBwYXJhbS5jb2xsZWN0aW9uRm9ybWF0IHx8ICdtdWx0aSc7XG4gICAgICAgICAgaWYoZm9ybWF0ID09PSAnc3N2Jykge1xuICAgICAgICAgICAgZGVsaW1ldGVyID0gJyAnO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIGlmKGZvcm1hdCA9PT0gJ3BpcGVzJykge1xuICAgICAgICAgICAgZGVsaW1ldGVyID0gJ3wnO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIGlmKGZvcm1hdCA9PT0gJ3RzdicpIHtcbiAgICAgICAgICAgIGRlbGltZXRlciA9ICdcXHQnO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIGlmKGZvcm1hdCA9PT0gJ211bHRpJykge1xuICAgICAgICAgICAgYm9keVBhcmFtW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGRlbGltZXRlciA9ICcsJztcbiAgICAgICAgICB9XG4gICAgICAgICAgdmFyIGRhdGE7XG4gICAgICAgICAgdmFsdWUuZm9yRWFjaChmdW5jdGlvbih2KSB7XG4gICAgICAgICAgICBpZihkYXRhKSB7XG4gICAgICAgICAgICAgIGRhdGEgKz0gZGVsaW1ldGVyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgIGRhdGEgPSAnJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRhdGEgKz0gdjtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBib2R5UGFyYW1ba2V5XSA9IGRhdGE7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgYm9keVBhcmFtW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgYm9keSA9IGJvZHlQYXJhbTtcbiAgICB9XG4gICAgaGVhZGVyc1snQ29udGVudC1UeXBlJ10gPSAnbXVsdGlwYXJ0L2Zvcm0tZGF0YSc7XG4gIH1cblxuICByZXR1cm4gYm9keTtcbn07XG5cbi8qKlxuICogZ2V0cyBzYW1wbGUgcmVzcG9uc2UgZm9yIGEgc2luZ2xlIG9wZXJhdGlvblxuICoqL1xuT3BlcmF0aW9uLnByb3RvdHlwZS5nZXRNb2RlbFNhbXBsZUpTT04gPSBmdW5jdGlvbiAodHlwZSwgbW9kZWxzKSB7XG4gIHZhciBsaXN0VHlwZSwgc2FtcGxlSnNvbiwgaW5uZXJUeXBlO1xuICBtb2RlbHMgPSBtb2RlbHMgfHwge307XG5cbiAgbGlzdFR5cGUgPSAodHlwZSBpbnN0YW5jZW9mIEFycmF5KTtcbiAgaW5uZXJUeXBlID0gbGlzdFR5cGUgPyB0eXBlWzBdIDogdHlwZTtcblxuICBpZihtb2RlbHNbaW5uZXJUeXBlXSkge1xuICAgIHNhbXBsZUpzb24gPSBtb2RlbHNbaW5uZXJUeXBlXS5jcmVhdGVKU09OU2FtcGxlKCk7XG4gIH0gZWxzZSBpZiAodGhpcy5nZXRJbmxpbmVNb2RlbChpbm5lclR5cGUpKXtcbiAgICBzYW1wbGVKc29uID0gdGhpcy5nZXRJbmxpbmVNb2RlbChpbm5lclR5cGUpLmNyZWF0ZUpTT05TYW1wbGUoKTsgLy8gbWF5IHJldHVybiBudWxsLCBpZiB0eXBlIGlzbid0IGNvcnJlY3RcbiAgfVxuXG5cbiAgaWYgKHNhbXBsZUpzb24pIHtcbiAgICBzYW1wbGVKc29uID0gbGlzdFR5cGUgPyBbc2FtcGxlSnNvbl0gOiBzYW1wbGVKc29uO1xuXG4gICAgaWYgKHR5cGVvZiBzYW1wbGVKc29uID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIHNhbXBsZUpzb247XG4gICAgfSBlbHNlIGlmIChfLmlzT2JqZWN0KHNhbXBsZUpzb24pKSB7XG4gICAgICB2YXIgdCA9IHNhbXBsZUpzb247XG5cbiAgICAgIGlmIChzYW1wbGVKc29uIGluc3RhbmNlb2YgQXJyYXkgJiYgc2FtcGxlSnNvbi5sZW5ndGggPiAwKSB7XG4gICAgICAgIHQgPSBzYW1wbGVKc29uWzBdO1xuICAgICAgfVxuXG4gICAgICBpZiAodC5ub2RlTmFtZSAmJiB0eXBlb2YgdCA9PT0gJ05vZGUnKSB7XG4gICAgICAgIHZhciB4bWxTdHJpbmcgPSBuZXcgWE1MU2VyaWFsaXplcigpLnNlcmlhbGl6ZVRvU3RyaW5nKHQpO1xuXG4gICAgICAgIHJldHVybiB0aGlzLmZvcm1hdFhtbCh4bWxTdHJpbmcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHNhbXBsZUpzb24sIG51bGwsIDIpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gc2FtcGxlSnNvbjtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogbGVnYWN5IGJpbmRpbmdcbiAqKi9cbk9wZXJhdGlvbi5wcm90b3R5cGUuZG8gPSBmdW5jdGlvbiAoYXJncywgb3B0cywgY2FsbGJhY2ssIGVycm9yLCBwYXJlbnQpIHtcbiAgcmV0dXJuIHRoaXMuZXhlY3V0ZShhcmdzLCBvcHRzLCBjYWxsYmFjaywgZXJyb3IsIHBhcmVudCk7XG59O1xuXG4vKipcbiAqIGV4ZWN1dGVzIGFuIG9wZXJhdGlvblxuICoqL1xuT3BlcmF0aW9uLnByb3RvdHlwZS5leGVjdXRlID0gZnVuY3Rpb24gKGFyZzEsIGFyZzIsIGFyZzMsIGFyZzQsIHBhcmVudCkge1xuICB2YXIgYXJncyA9IGFyZzEgfHwge307XG4gIHZhciBvcHRzID0ge30sIHN1Y2Nlc3MsIGVycm9yLCBkZWZlcnJlZCwgdGltZW91dDtcblxuICBpZiAoXy5pc09iamVjdChhcmcyKSkge1xuICAgIG9wdHMgPSBhcmcyO1xuICAgIHN1Y2Nlc3MgPSBhcmczO1xuICAgIGVycm9yID0gYXJnNDtcbiAgfVxuXG4gIHRpbWVvdXQgPSB0eXBlb2Ygb3B0cy50aW1lb3V0ICE9PSAndW5kZWZpbmVkJyA/IG9wdHMudGltZW91dCA6IHRoaXMudGltZW91dDtcblxuICBpZih0aGlzLmNsaWVudCkge1xuICAgIG9wdHMuY2xpZW50ID0gdGhpcy5jbGllbnQ7XG4gIH1cblxuICBpZih0aGlzLnJlcXVlc3RBZ2VudCkge1xuICAgIG9wdHMucmVxdWVzdEFnZW50ID0gdGhpcy5yZXF1ZXN0QWdlbnQ7XG4gIH1cblxuICAvLyBhZGQgdGhlIHJlcXVlc3QgaW50ZXJjZXB0b3IgZnJvbSBwYXJlbnQsIGlmIG5vbmUgc2VudCBmcm9tIGNsaWVudFxuICBpZighb3B0cy5yZXF1ZXN0SW50ZXJjZXB0b3IgJiYgdGhpcy5yZXF1ZXN0SW50ZXJjZXB0b3IgKSB7XG4gICAgb3B0cy5yZXF1ZXN0SW50ZXJjZXB0b3IgPSB0aGlzLnJlcXVlc3RJbnRlcmNlcHRvciA7XG4gIH1cblxuICBpZighb3B0cy5yZXNwb25zZUludGVyY2VwdG9yICYmIHRoaXMucmVzcG9uc2VJbnRlcmNlcHRvcikge1xuICAgIG9wdHMucmVzcG9uc2VJbnRlcmNlcHRvciA9IHRoaXMucmVzcG9uc2VJbnRlcmNlcHRvcjtcbiAgfVxuXG4gIGlmICh0eXBlb2YgYXJnMiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHN1Y2Nlc3MgPSBhcmcyO1xuICAgIGVycm9yID0gYXJnMztcbiAgfVxuXG4gIGlmICh0aGlzLnBhcmVudC51c2VQcm9taXNlKSB7XG4gICAgZGVmZXJyZWQgPSBRLmRlZmVyKCk7XG4gIH0gZWxzZSB7XG4gICAgc3VjY2VzcyA9IChzdWNjZXNzIHx8IHRoaXMucGFyZW50LmRlZmF1bHRTdWNjZXNzQ2FsbGJhY2sgfHwgaGVscGVycy5sb2cpO1xuICAgIGVycm9yID0gKGVycm9yIHx8IHRoaXMucGFyZW50LmRlZmF1bHRFcnJvckNhbGxiYWNrIHx8IGhlbHBlcnMubG9nKTtcbiAgfVxuXG4gIGlmICh0eXBlb2Ygb3B0cy51c2VKUXVlcnkgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgb3B0cy51c2VKUXVlcnkgPSB0aGlzLnVzZUpRdWVyeTtcbiAgfVxuXG4gIGlmICh0eXBlb2Ygb3B0cy5qcXVlcnlBamF4Q2FjaGUgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgb3B0cy5qcXVlcnlBamF4Q2FjaGUgPSB0aGlzLmpxdWVyeUFqYXhDYWNoZTtcbiAgfVxuXG4gIGlmICh0eXBlb2Ygb3B0cy5lbmFibGVDb29raWVzID09PSAndW5kZWZpbmVkJykge1xuICAgIG9wdHMuZW5hYmxlQ29va2llcyA9IHRoaXMuZW5hYmxlQ29va2llcztcbiAgfVxuXG4gIHZhciBtaXNzaW5nUGFyYW1zID0gdGhpcy5nZXRNaXNzaW5nUGFyYW1zKGFyZ3MpO1xuXG4gIGlmIChtaXNzaW5nUGFyYW1zLmxlbmd0aCA+IDApIHtcbiAgICB2YXIgbWVzc2FnZSA9ICdtaXNzaW5nIHJlcXVpcmVkIHBhcmFtczogJyArIG1pc3NpbmdQYXJhbXM7XG5cbiAgICBoZWxwZXJzLmZhaWwobWVzc2FnZSk7XG5cbiAgICBpZiAodGhpcy5wYXJlbnQudXNlUHJvbWlzZSkge1xuICAgICAgZGVmZXJyZWQucmVqZWN0KG1lc3NhZ2UpO1xuICAgICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVycm9yKG1lc3NhZ2UsIHBhcmVudCk7XG4gICAgICByZXR1cm4ge307XG4gICAgfVxuICB9XG5cbiAgdmFyIGFsbEhlYWRlcnMgPSB0aGlzLmdldEhlYWRlclBhcmFtcyhhcmdzKTtcbiAgdmFyIGNvbnRlbnRUeXBlSGVhZGVycyA9IHRoaXMuc2V0Q29udGVudFR5cGVzKGFyZ3MsIG9wdHMpO1xuICB2YXIgaGVhZGVycyA9IHt9LCBhdHRybmFtZTtcblxuICBmb3IgKGF0dHJuYW1lIGluIGFsbEhlYWRlcnMpIHsgaGVhZGVyc1thdHRybmFtZV0gPSBhbGxIZWFkZXJzW2F0dHJuYW1lXTsgfVxuICBmb3IgKGF0dHJuYW1lIGluIGNvbnRlbnRUeXBlSGVhZGVycykgeyBoZWFkZXJzW2F0dHJuYW1lXSA9IGNvbnRlbnRUeXBlSGVhZGVyc1thdHRybmFtZV07IH1cblxuICB2YXIgYm9keSA9IHRoaXMuZ2V0Qm9keShjb250ZW50VHlwZUhlYWRlcnMsIGFyZ3MsIG9wdHMpO1xuICB2YXIgdXJsID0gdGhpcy51cmxpZnkoYXJncywgb3B0cy5tYXNrUGFzc3dvcmRzKTtcblxuICBpZih1cmwuaW5kZXhPZignLntmb3JtYXR9JykgPiAwKSB7XG4gICAgaWYoaGVhZGVycykge1xuICAgICAgdmFyIGZvcm1hdCA9IGhlYWRlcnMuQWNjZXB0IHx8IGhlYWRlcnMuYWNjZXB0O1xuICAgICAgaWYoZm9ybWF0ICYmIGZvcm1hdC5pbmRleE9mKCdqc29uJykgPiAwKSB7XG4gICAgICAgIHVybCA9IHVybC5yZXBsYWNlKCcue2Zvcm1hdH0nLCAnLmpzb24nKTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYoZm9ybWF0ICYmIGZvcm1hdC5pbmRleE9mKCd4bWwnKSA+IDApIHtcbiAgICAgICAgdXJsID0gdXJsLnJlcGxhY2UoJy57Zm9ybWF0fScsICcueG1sJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIG9iaiA9IHtcbiAgICB1cmw6IHVybCxcbiAgICBtZXRob2Q6IHRoaXMubWV0aG9kLnRvVXBwZXJDYXNlKCksXG4gICAgYm9keTogYm9keSxcbiAgICBlbmFibGVDb29raWVzOiBvcHRzLmVuYWJsZUNvb2tpZXMsXG4gICAgdXNlSlF1ZXJ5OiBvcHRzLnVzZUpRdWVyeSxcbiAgICBqcXVlcnlBamF4Q2FjaGU6IG9wdHMuanF1ZXJ5QWpheENhY2hlLFxuICAgIGRlZmVycmVkOiBkZWZlcnJlZCxcbiAgICBoZWFkZXJzOiBoZWFkZXJzLFxuICAgIGNsaWVudEF1dGhvcml6YXRpb25zOiBvcHRzLmNsaWVudEF1dGhvcml6YXRpb25zLFxuICAgIG9wZXJhdGlvbjogdGhpcyxcbiAgICBjb25uZWN0aW9uQWdlbnQ6IHRoaXMuY29ubmVjdGlvbkFnZW50LFxuICAgIG9uOiB7XG4gICAgICByZXNwb25zZTogZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICAgIGlmIChkZWZlcnJlZCkge1xuICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUocmVzcG9uc2UpO1xuICAgICAgICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBzdWNjZXNzKHJlc3BvbnNlLCBwYXJlbnQpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgZXJyb3I6IGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgICAgICBpZiAoZGVmZXJyZWQpIHtcbiAgICAgICAgICBkZWZlcnJlZC5yZWplY3QocmVzcG9uc2UpO1xuICAgICAgICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBlcnJvcihyZXNwb25zZSwgcGFyZW50KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBpZiAodGltZW91dCkge1xuICAgIG9iai50aW1lb3V0ID0gdGltZW91dDtcbiAgfVxuXG4gIHRoaXMuY2xpZW50QXV0aG9yaXphdGlvbnMuYXBwbHkob2JqLCB0aGlzLm9wZXJhdGlvbi5zZWN1cml0eSk7XG4gIGlmIChvcHRzLm1vY2sgPT09IHRydWUpIHtcbiAgICBpZihvcHRzLnJlcXVlc3RJbnRlcmNlcHRvcikge1xuICAgICAgb3B0cy5yZXF1ZXN0SW50ZXJjZXB0b3IuYXBwbHkob2JqKTtcbiAgICB9XG4gICAgcmV0dXJuIG9iajtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbmV3IFN3YWdnZXJIdHRwKCkuZXhlY3V0ZShvYmosIG9wdHMpO1xuICB9XG59O1xuXG5mdW5jdGlvbiBpdGVtQnlQcmlvcml0eShjb2wsIGl0ZW1Qcmlvcml0eSkge1xuXG4gIC8vIE5vIHByaW9yaXRpZXM/IHJldHVybiBmaXJzdC4uLlxuICBpZihfLmlzRW1wdHkoaXRlbVByaW9yaXR5KSkge1xuICAgIHJldHVybiBjb2xbMF07XG4gIH1cblxuICBmb3IgKHZhciBpID0gMCwgbGVuID0gaXRlbVByaW9yaXR5Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgaWYoY29sLmluZGV4T2YoaXRlbVByaW9yaXR5W2ldKSA+IC0xKSB7XG4gICAgICByZXR1cm4gaXRlbVByaW9yaXR5W2ldO1xuICAgIH1cbiAgfVxuXG4gIC8vIE90aGVyd2lzZSByZXR1cm4gZmlyc3RcbiAgcmV0dXJuIGNvbFswXTtcbn1cblxuT3BlcmF0aW9uLnByb3RvdHlwZS5zZXRDb250ZW50VHlwZXMgPSBmdW5jdGlvbiAoYXJncywgb3B0cykge1xuICAvLyBkZWZhdWx0IHR5cGVcbiAgdmFyIGFsbERlZmluZWRQYXJhbXMgPSB0aGlzLnBhcmFtZXRlcnM7XG4gIHZhciBib2R5O1xuICB2YXIgY29uc3VtZXMgPSBhcmdzLnBhcmFtZXRlckNvbnRlbnRUeXBlIHx8IGl0ZW1CeVByaW9yaXR5KHRoaXMuY29uc3VtZXMsIFsnYXBwbGljYXRpb24vanNvbicsICdhcHBsaWNhdGlvbi95YW1sJ10pO1xuICB2YXIgYWNjZXB0cyA9IG9wdHMucmVzcG9uc2VDb250ZW50VHlwZSB8fCBpdGVtQnlQcmlvcml0eSh0aGlzLnByb2R1Y2VzLCBbJ2FwcGxpY2F0aW9uL2pzb24nLCAnYXBwbGljYXRpb24veWFtbCddKTtcbiAgdmFyIGRlZmluZWRGaWxlUGFyYW1zID0gW107XG4gIHZhciBkZWZpbmVkRm9ybVBhcmFtcyA9IFtdO1xuICB2YXIgaGVhZGVycyA9IHt9O1xuICB2YXIgaTtcblxuICAvLyBnZXQgcGFyYW1zIGZyb20gdGhlIG9wZXJhdGlvbiBhbmQgc2V0IHRoZW0gaW4gZGVmaW5lZEZpbGVQYXJhbXMsIGRlZmluZWRGb3JtUGFyYW1zLCBoZWFkZXJzXG4gIGZvciAoaSA9IDA7IGkgPCBhbGxEZWZpbmVkUGFyYW1zLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHBhcmFtID0gYWxsRGVmaW5lZFBhcmFtc1tpXTtcblxuICAgIGlmIChwYXJhbS5pbiA9PT0gJ2Zvcm1EYXRhJykge1xuICAgICAgaWYgKHBhcmFtLnR5cGUgPT09ICdmaWxlJykge1xuICAgICAgICBkZWZpbmVkRmlsZVBhcmFtcy5wdXNoKHBhcmFtKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlZmluZWRGb3JtUGFyYW1zLnB1c2gocGFyYW0pO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAocGFyYW0uaW4gPT09ICdoZWFkZXInICYmIG9wdHMpIHtcbiAgICAgIHZhciBrZXkgPSBwYXJhbS5uYW1lO1xuICAgICAgdmFyIGhlYWRlclZhbHVlID0gb3B0c1twYXJhbS5uYW1lXTtcblxuICAgICAgaWYgKHR5cGVvZiBvcHRzW3BhcmFtLm5hbWVdICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBoZWFkZXJzW2tleV0gPSBoZWFkZXJWYWx1ZTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHBhcmFtLmluID09PSAnYm9keScgJiYgdHlwZW9mIGFyZ3NbcGFyYW0ubmFtZV0gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBib2R5ID0gYXJnc1twYXJhbS5uYW1lXTtcbiAgICB9XG4gIH1cblxuICAvLyBpZiB0aGVyZSdzIGEgYm9keSwgbmVlZCB0byBzZXQgdGhlIGNvbnN1bWVzIGhlYWRlciB2aWEgcmVxdWVzdENvbnRlbnRUeXBlXG4gIHZhciBoYXNCb2R5ID0gYm9keSB8fCBkZWZpbmVkRmlsZVBhcmFtcy5sZW5ndGggfHwgZGVmaW5lZEZvcm1QYXJhbXMubGVuZ3RoO1xuICBpZiAodGhpcy5tZXRob2QgPT09ICdwb3N0JyB8fCB0aGlzLm1ldGhvZCA9PT0gJ3B1dCcgfHwgdGhpcy5tZXRob2QgPT09ICdwYXRjaCcgfHxcbiAgICAgICgodGhpcy5tZXRob2QgPT09ICdkZWxldGUnIHx8IHRoaXMubWV0aG9kID09PSAnZ2V0JykgJiYgaGFzQm9keSkpIHtcbiAgICBpZiAob3B0cy5yZXF1ZXN0Q29udGVudFR5cGUpIHtcbiAgICAgIGNvbnN1bWVzID0gb3B0cy5yZXF1ZXN0Q29udGVudFR5cGU7XG4gICAgfVxuICAgIC8vIGlmIGFueSBmb3JtIHBhcmFtcywgY29udGVudCB0eXBlIG11c3QgYmUgc2V0XG4gICAgaWYgKGRlZmluZWRGb3JtUGFyYW1zLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN1bWVzID0gdW5kZWZpbmVkO1xuICAgICAgaWYgKG9wdHMucmVxdWVzdENvbnRlbnRUeXBlKSB7ICAgICAgICAgICAgIC8vIG92ZXJyaWRlIGlmIHNldFxuICAgICAgICBjb25zdW1lcyA9IG9wdHMucmVxdWVzdENvbnRlbnRUeXBlO1xuICAgICAgfSBlbHNlIGlmIChkZWZpbmVkRmlsZVBhcmFtcy5sZW5ndGggPiAwKSB7IC8vIGlmIGEgZmlsZSwgbXVzdCBiZSBtdWx0aXBhcnQvZm9ybS1kYXRhXG4gICAgICAgIGNvbnN1bWVzID0gJ211bHRpcGFydC9mb3JtLWRhdGEnO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHRoaXMuY29uc3VtZXMgJiYgdGhpcy5jb25zdW1lcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgLy8gdXNlIHRoZSBjb25zdW1lcyBzZXR0aW5nXG4gICAgICAgICAgZm9yKHZhciBjIGluIHRoaXMuY29uc3VtZXMpIHtcbiAgICAgICAgICAgIHZhciBjaGsgPSB0aGlzLmNvbnN1bWVzW2NdO1xuICAgICAgICAgICAgaWYoY2hrLmluZGV4T2YoJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcpID09PSAwIHx8IGNoay5pbmRleE9mKCdtdWx0aXBhcnQvZm9ybS1kYXRhJykgPT09IDApIHtcbiAgICAgICAgICAgICAgY29uc3VtZXMgPSBjaGs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZih0eXBlb2YgY29uc3VtZXMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIC8vIGRlZmF1bHQgdG8geC13d3ctZnJvbS11cmxlbmNvZGVkXG4gICAgICAgIGNvbnN1bWVzID0gJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCc7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGVsc2Uge1xuICAgIGNvbnN1bWVzID0gbnVsbDtcbiAgfVxuXG4gIGlmIChjb25zdW1lcyAmJiB0aGlzLmNvbnN1bWVzKSB7XG4gICAgaWYgKHRoaXMuY29uc3VtZXMuaW5kZXhPZihjb25zdW1lcykgPT09IC0xKSB7XG4gICAgICBoZWxwZXJzLmxvZygnc2VydmVyIGRvZXNuXFwndCBjb25zdW1lICcgKyBjb25zdW1lcyArICcsIHRyeSAnICsgSlNPTi5zdHJpbmdpZnkodGhpcy5jb25zdW1lcykpO1xuICAgIH1cbiAgfVxuXG4gIGlmICghdGhpcy5tYXRjaGVzQWNjZXB0KGFjY2VwdHMpKSB7XG4gICAgaGVscGVycy5sb2coJ3NlcnZlciBjYW5cXCd0IHByb2R1Y2UgJyArIGFjY2VwdHMpO1xuICB9XG5cbiAgaWYgKChjb25zdW1lcyAmJiBib2R5ICE9PSAnJykgfHwgKGNvbnN1bWVzID09PSAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJykpIHtcbiAgICBoZWFkZXJzWydDb250ZW50LVR5cGUnXSA9IGNvbnN1bWVzO1xuICB9XG4gIGVsc2UgaWYodGhpcy5jb25zdW1lcyAmJiB0aGlzLmNvbnN1bWVzLmxlbmd0aCA+IDAgJiYgdGhpcy5jb25zdW1lc1swXSA9PT0gJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcpIHtcbiAgICBoZWFkZXJzWydDb250ZW50LVR5cGUnXSA9IHRoaXMuY29uc3VtZXNbMF07XG4gIH1cblxuICBpZiAoYWNjZXB0cykge1xuICAgIGhlYWRlcnMuQWNjZXB0ID0gYWNjZXB0cztcbiAgfVxuXG4gIHJldHVybiBoZWFkZXJzO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIHJlcXVlc3QgYWNjZXB0cyBoZWFkZXIgbWF0Y2hlcyBhbnl0aGluZyBpbiB0aGlzLnByb2R1Y2VzLlxuICogIElmIHRoaXMucHJvZHVjZXMgY29udGFpbnMgKiAvICosIGlnbm9yZSB0aGUgYWNjZXB0IGhlYWRlci5cbiAqIEBwYXJhbSB7c3RyaW5nPX0gYWNjZXB0cyBUaGUgY2xpZW50IHJlcXVlc3QgYWNjZXB0IGhlYWRlci5cbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbk9wZXJhdGlvbi5wcm90b3R5cGUubWF0Y2hlc0FjY2VwdCA9IGZ1bmN0aW9uKGFjY2VwdHMpIHtcbiAgLy8gbm8gYWNjZXB0cyBvciBwcm9kdWNlcywgbm8gcHJvYmxlbSFcbiAgaWYgKCFhY2NlcHRzIHx8ICF0aGlzLnByb2R1Y2VzKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIHRoaXMucHJvZHVjZXMuaW5kZXhPZihhY2NlcHRzKSAhPT0gLTEgfHwgdGhpcy5wcm9kdWNlcy5pbmRleE9mKCcqLyonKSAhPT0gLTE7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmFzQ3VybCA9IGZ1bmN0aW9uIChhcmdzMSwgYXJnczIpIHtcbiAgdmFyIG9wdHMgPSB7bW9jazogdHJ1ZSwgbWFza1Bhc3N3b3JkczogdHJ1ZX07XG4gIGlmICh0eXBlb2YgYXJnczIgPT09ICdvYmplY3QnKSB7XG4gICAgZm9yICh2YXIgYXJnS2V5IGluIGFyZ3MyKSB7XG4gICAgICBvcHRzW2FyZ0tleV0gPSBhcmdzMlthcmdLZXldO1xuICAgIH1cbiAgfVxuICB2YXIgb2JqID0gdGhpcy5leGVjdXRlKGFyZ3MxLCBvcHRzKTtcblxuICB0aGlzLmNsaWVudEF1dGhvcml6YXRpb25zLmFwcGx5KG9iaiwgdGhpcy5vcGVyYXRpb24uc2VjdXJpdHkpO1xuXG4gIHZhciByZXN1bHRzID0gW107XG5cbiAgcmVzdWx0cy5wdXNoKCctWCAnICsgdGhpcy5tZXRob2QudG9VcHBlckNhc2UoKSk7XG5cbiAgaWYgKHR5cGVvZiBvYmouaGVhZGVycyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICB2YXIga2V5O1xuXG4gICAgZm9yIChrZXkgaW4gb2JqLmhlYWRlcnMpIHtcbiAgICAgIHZhciB2YWx1ZSA9IG9iai5oZWFkZXJzW2tleV07XG4gICAgICBpZih0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKXtcbiAgICAgICAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKC9cXCcvZywgJ1xcXFx1MDAyNycpO1xuICAgICAgfVxuICAgICAgcmVzdWx0cy5wdXNoKCctLWhlYWRlciBcXCcnICsga2V5ICsgJzogJyArIHZhbHVlICsgJ1xcJycpO1xuICAgIH1cbiAgfVxuICB2YXIgaXNGb3JtRGF0YSA9IGZhbHNlO1xuICB2YXIgaXNNdWx0aXBhcnQgPSBmYWxzZTtcblxuICB2YXIgdHlwZSA9IG9iai5oZWFkZXJzWydDb250ZW50LVR5cGUnXTtcbiAgaWYodHlwZSAmJiB0eXBlLmluZGV4T2YoJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcpID09PSAwKSB7XG4gICAgaXNGb3JtRGF0YSA9IHRydWU7XG4gIH1cbiAgZWxzZSBpZiAodHlwZSAmJiB0eXBlLmluZGV4T2YoJ211bHRpcGFydC9mb3JtLWRhdGEnKSA9PT0gMCkge1xuICAgIGlzRm9ybURhdGEgPSB0cnVlO1xuICAgIGlzTXVsdGlwYXJ0ID0gdHJ1ZTtcbiAgfVxuXG4gIGlmIChvYmouYm9keSkge1xuICAgIHZhciBib2R5O1xuICAgIGlmIChfLmlzT2JqZWN0KG9iai5ib2R5KSkge1xuICAgICAgaWYoaXNNdWx0aXBhcnQpIHtcbiAgICAgICAgaXNNdWx0aXBhcnQgPSB0cnVlO1xuICAgICAgICAvLyBhZGQgdGhlIGZvcm0gZGF0YVxuICAgICAgICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5wYXJhbWV0ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdmFyIHBhcmFtZXRlciA9IHRoaXMucGFyYW1ldGVyc1tpXTtcbiAgICAgICAgICBpZihwYXJhbWV0ZXIuaW4gPT09ICdmb3JtRGF0YScpIHtcbiAgICAgICAgICAgIGlmICghYm9keSkge1xuICAgICAgICAgICAgICBib2R5ID0gJyc7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBwYXJhbVZhbHVlO1xuICAgICAgICAgICAgaWYodHlwZW9mIEZvcm1EYXRhID09PSAnZnVuY3Rpb24nICYmIG9iai5ib2R5IGluc3RhbmNlb2YgRm9ybURhdGEpIHtcbiAgICAgICAgICAgICAgcGFyYW1WYWx1ZSA9IG9iai5ib2R5LmdldEFsbChwYXJhbWV0ZXIubmFtZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgcGFyYW1WYWx1ZSA9IG9iai5ib2R5W3BhcmFtZXRlci5uYW1lXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChwYXJhbVZhbHVlKSB7XG4gICAgICAgICAgICAgIGlmIChwYXJhbWV0ZXIudHlwZSA9PT0gJ2ZpbGUnKSB7XG4gICAgICAgICAgICAgICAgaWYocGFyYW1WYWx1ZS5uYW1lKSB7XG4gICAgICAgICAgICAgICAgICBib2R5ICs9ICctRiAnICsgcGFyYW1ldGVyLm5hbWUgKyAnPUBcIicgKyBwYXJhbVZhbHVlLm5hbWUgKyAnXCIgJztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocGFyYW1WYWx1ZSkpIHtcbiAgICAgICAgICAgICAgICAgIGlmKHBhcmFtZXRlci5jb2xsZWN0aW9uRm9ybWF0ID09PSAnbXVsdGknKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvcih2YXIgdiBpbiBwYXJhbVZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgYm9keSArPSAnLUYgJyArIHRoaXMuZW5jb2RlUXVlcnlLZXkocGFyYW1ldGVyLm5hbWUpICsgJz0nICsgbWFzayhwYXJhbVZhbHVlW3ZdLCBwYXJhbWV0ZXIuZm9ybWF0KSArICcgJztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGJvZHkgKz0gJy1GICcgKyB0aGlzLmVuY29kZVF1ZXJ5Q29sbGVjdGlvbihwYXJhbWV0ZXIuY29sbGVjdGlvbkZvcm1hdCwgcGFyYW1ldGVyLm5hbWUsIG1hc2socGFyYW1WYWx1ZSwgcGFyYW1ldGVyLmZvcm1hdCkpICsgJyAnO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICBib2R5ICs9ICctRiAnICsgdGhpcy5lbmNvZGVRdWVyeUtleShwYXJhbWV0ZXIubmFtZSkgKyAnPScgKyBtYXNrKHBhcmFtVmFsdWUsIHBhcmFtZXRlci5mb3JtYXQpICsgJyAnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYoIWJvZHkpIHtcbiAgICAgICAgYm9keSA9IEpTT04uc3RyaW5naWZ5KG9iai5ib2R5KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgYm9keSA9IG9iai5ib2R5O1xuICAgIH1cbiAgICAvLyBlc2NhcGUgQCA9PiAlNDAsICcgPT4gJTI3XG4gICAgYm9keSA9IGJvZHkucmVwbGFjZSgvXFwnL2csICclMjcnKS5yZXBsYWNlKC9cXG4vZywgJyBcXFxcIFxcbiAnKTtcblxuICAgIGlmKCFpc0Zvcm1EYXRhKSB7XG4gICAgICAvLyBlc2NhcGUgJiA9PiAlMjZcbiAgICAgIGJvZHkgPSBib2R5LnJlcGxhY2UoLyYvZywgJyUyNicpO1xuICAgIH1cbiAgICBpZihpc011bHRpcGFydCkge1xuICAgICAgcmVzdWx0cy5wdXNoKGJvZHkpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHJlc3VsdHMucHVzaCgnLWQgXFwnJyArIGJvZHkucmVwbGFjZSgvQC9nLCAnJTQwJykgKyAnXFwnJyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuICdjdXJsICcgKyAocmVzdWx0cy5qb2luKCcgJykpICsgJyBcXCcnICsgb2JqLnVybCArICdcXCcnO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5lbmNvZGVQYXRoQ29sbGVjdGlvbiA9IGZ1bmN0aW9uICh0eXBlLCBuYW1lLCB2YWx1ZSwgbWFza1Bhc3N3b3Jkcykge1xuICB2YXIgZW5jb2RlZCA9ICcnO1xuICB2YXIgaTtcbiAgdmFyIHNlcGFyYXRvciA9ICcnO1xuXG4gIGlmICh0eXBlID09PSAnc3N2Jykge1xuICAgIHNlcGFyYXRvciA9ICclMjAnO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09ICd0c3YnKSB7XG4gICAgc2VwYXJhdG9yID0gJyUwOSc7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3BpcGVzJykge1xuICAgIHNlcGFyYXRvciA9ICd8JztcbiAgfSBlbHNlIHtcbiAgICBzZXBhcmF0b3IgPSAnLCc7XG4gIH1cblxuICBmb3IgKGkgPSAwOyBpIDwgdmFsdWUubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoaSA9PT0gMCkge1xuICAgICAgZW5jb2RlZCA9IHRoaXMuZW5jb2RlUXVlcnlQYXJhbSh2YWx1ZVtpXSwgbWFza1Bhc3N3b3Jkcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVuY29kZWQgKz0gc2VwYXJhdG9yICsgdGhpcy5lbmNvZGVRdWVyeVBhcmFtKHZhbHVlW2ldLCBtYXNrUGFzc3dvcmRzKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZW5jb2RlZDtcbn07XG5cbk9wZXJhdGlvbi5wcm90b3R5cGUuZW5jb2RlUXVlcnlDb2xsZWN0aW9uID0gZnVuY3Rpb24gKHR5cGUsIG5hbWUsIHZhbHVlLCBtYXNrUGFzc3dvcmRzKSB7XG4gIHZhciBlbmNvZGVkID0gJyc7XG4gIHZhciBpO1xuXG4gIHR5cGUgPSB0eXBlIHx8ICdkZWZhdWx0JztcbiAgaWYgKHR5cGUgPT09ICdkZWZhdWx0JyB8fCB0eXBlID09PSAnbXVsdGknKSB7XG4gICAgZm9yIChpID0gMDsgaSA8IHZhbHVlLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoaSA+IDApIHtlbmNvZGVkICs9ICcmJzt9XG5cbiAgICAgIGVuY29kZWQgKz0gdGhpcy5lbmNvZGVRdWVyeUtleShuYW1lKSArICc9JyArIG1hc2sodGhpcy5lbmNvZGVRdWVyeVBhcmFtKHZhbHVlW2ldKSwgbWFza1Bhc3N3b3Jkcyk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHZhciBzZXBhcmF0b3IgPSAnJztcblxuICAgIGlmICh0eXBlID09PSAnY3N2Jykge1xuICAgICAgc2VwYXJhdG9yID0gJywnO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3NzdicpIHtcbiAgICAgIHNlcGFyYXRvciA9ICclMjAnO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3RzdicpIHtcbiAgICAgIHNlcGFyYXRvciA9ICclMDknO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3BpcGVzJykge1xuICAgICAgc2VwYXJhdG9yID0gJ3wnO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2JyYWNrZXRzJykge1xuICAgICAgZm9yIChpID0gMDsgaSA8IHZhbHVlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChpICE9PSAwKSB7XG4gICAgICAgICAgZW5jb2RlZCArPSAnJic7XG4gICAgICAgIH1cbiAgICAgICAgZW5jb2RlZCArPSB0aGlzLmVuY29kZVF1ZXJ5S2V5KG5hbWUpICsgJ1tdPScgKyBtYXNrKHRoaXMuZW5jb2RlUXVlcnlQYXJhbSh2YWx1ZVtpXSksIG1hc2tQYXNzd29yZHMpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzZXBhcmF0b3IgIT09ICcnKSB7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgdmFsdWUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGkgPT09IDApIHtcbiAgICAgICAgICBlbmNvZGVkID0gdGhpcy5lbmNvZGVRdWVyeUtleShuYW1lKSArICc9JyArIHRoaXMuZW5jb2RlUXVlcnlQYXJhbSh2YWx1ZVtpXSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZW5jb2RlZCArPSBzZXBhcmF0b3IgKyB0aGlzLmVuY29kZVF1ZXJ5UGFyYW0odmFsdWVbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGVuY29kZWQ7XG59O1xuXG5PcGVyYXRpb24ucHJvdG90eXBlLmVuY29kZVF1ZXJ5S2V5ID0gZnVuY3Rpb24gKGFyZykge1xuICByZXR1cm4gZW5jb2RlVVJJQ29tcG9uZW50KGFyZylcbiAgICAgIC5yZXBsYWNlKCclNUInLCdbJykucmVwbGFjZSgnJTVEJywgJ10nKS5yZXBsYWNlKCclMjQnLCAnJCcpO1xufTtcblxuT3BlcmF0aW9uLnByb3RvdHlwZS5lbmNvZGVRdWVyeVBhcmFtID0gZnVuY3Rpb24gKGFyZywgbWFza1Bhc3N3b3Jkcykge1xuICBpZihtYXNrUGFzc3dvcmRzKSB7XG4gICAgcmV0dXJuIFwiKioqKioqXCI7XG4gIH1cbiAgaWYoYXJnICE9PSB1bmRlZmluZWQgJiYgYXJnICE9PSBudWxsKSB7XG4gICAgcmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudChhcmcpO1xuICB9XG4gIGVsc2Uge1xuICAgIHJldHVybiAnJztcbiAgfVxufTtcblxuLyoqXG4gKiBUT0RPIHJldmlzaXQsIG1pZ2h0IG5vdCB3YW50IHRvIGxlYXZlICcvJ1xuICoqL1xuT3BlcmF0aW9uLnByb3RvdHlwZS5lbmNvZGVQYXRoUGFyYW0gPSBmdW5jdGlvbiAocGF0aFBhcmFtLCBtYXNrUGFzc3dvcmRzKSB7XG4gIHJldHVybiBlbmNvZGVVUklDb21wb25lbnQocGF0aFBhcmFtLCBtYXNrUGFzc3dvcmRzKTtcbn07XG5cbnZhciBtYXNrID0gZnVuY3Rpb24odmFsdWUsIGZvcm1hdCkge1xuICBpZih0eXBlb2YgZm9ybWF0ID09PSAnc3RyaW5nJyAmJiBmb3JtYXQgPT09ICdwYXNzd29yZCcpIHtcbiAgICByZXR1cm4gJyoqKioqKic7XG4gIH1cbiAgcmV0dXJuIHZhbHVlO1xufVxuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgT3BlcmF0aW9uR3JvdXAgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICh0YWcsIGRlc2NyaXB0aW9uLCBleHRlcm5hbERvY3MsIG9wZXJhdGlvbikge1xuICB0aGlzLmRlc2NyaXB0aW9uID0gZGVzY3JpcHRpb247XG4gIHRoaXMuZXh0ZXJuYWxEb2NzID0gZXh0ZXJuYWxEb2NzO1xuICB0aGlzLm5hbWUgPSB0YWc7XG4gIHRoaXMub3BlcmF0aW9uID0gb3BlcmF0aW9uO1xuICB0aGlzLm9wZXJhdGlvbnNBcnJheSA9IFtdO1xuICB0aGlzLnBhdGggPSB0YWc7XG4gIHRoaXMudGFnID0gdGFnO1xufTtcblxuT3BlcmF0aW9uR3JvdXAucHJvdG90eXBlLnNvcnQgPSBmdW5jdGlvbiAoKSB7XG5cbn07XG5cbiIsIi8vIHNoaW0gZm9yIHVzaW5nIHByb2Nlc3MgaW4gYnJvd3NlclxuXG52YXIgcHJvY2VzcyA9IG1vZHVsZS5leHBvcnRzID0ge307XG52YXIgcXVldWUgPSBbXTtcbnZhciBkcmFpbmluZyA9IGZhbHNlO1xuXG5mdW5jdGlvbiBkcmFpblF1ZXVlKCkge1xuICAgIGlmIChkcmFpbmluZykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGRyYWluaW5nID0gdHJ1ZTtcbiAgICB2YXIgY3VycmVudFF1ZXVlO1xuICAgIHZhciBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgd2hpbGUobGVuKSB7XG4gICAgICAgIGN1cnJlbnRRdWV1ZSA9IHF1ZXVlO1xuICAgICAgICBxdWV1ZSA9IFtdO1xuICAgICAgICB2YXIgaSA9IC0xO1xuICAgICAgICB3aGlsZSAoKytpIDwgbGVuKSB7XG4gICAgICAgICAgICBjdXJyZW50UXVldWVbaV0oKTtcbiAgICAgICAgfVxuICAgICAgICBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgfVxuICAgIGRyYWluaW5nID0gZmFsc2U7XG59XG5wcm9jZXNzLm5leHRUaWNrID0gZnVuY3Rpb24gKGZ1bikge1xuICAgIHF1ZXVlLnB1c2goZnVuKTtcbiAgICBpZiAoIWRyYWluaW5nKSB7XG4gICAgICAgIHNldFRpbWVvdXQoZHJhaW5RdWV1ZSwgMCk7XG4gICAgfVxufTtcblxucHJvY2Vzcy50aXRsZSA9ICdicm93c2VyJztcbnByb2Nlc3MuYnJvd3NlciA9IHRydWU7XG5wcm9jZXNzLmVudiA9IHt9O1xucHJvY2Vzcy5hcmd2ID0gW107XG5wcm9jZXNzLnZlcnNpb24gPSAnJzsgLy8gZW1wdHkgc3RyaW5nIHRvIGF2b2lkIHJlZ2V4cCBpc3N1ZXNcbnByb2Nlc3MudmVyc2lvbnMgPSB7fTtcblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbnByb2Nlc3Mub24gPSBub29wO1xucHJvY2Vzcy5hZGRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLm9uY2UgPSBub29wO1xucHJvY2Vzcy5vZmYgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUFsbExpc3RlbmVycyA9IG5vb3A7XG5wcm9jZXNzLmVtaXQgPSBub29wO1xuXG5wcm9jZXNzLmJpbmRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5cbi8vIFRPRE8oc2h0eWxtYW4pXG5wcm9jZXNzLmN3ZCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuICcvJyB9O1xucHJvY2Vzcy5jaGRpciA9IGZ1bmN0aW9uIChkaXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuY2hkaXIgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcbnByb2Nlc3MudW1hc2sgPSBmdW5jdGlvbigpIHsgcmV0dXJuIDA7IH07XG4iLCIoZnVuY3Rpb24gKEJ1ZmZlcil7XG4oZnVuY3Rpb24gKCkge1xuICBcInVzZSBzdHJpY3RcIjtcblxuICBmdW5jdGlvbiBidG9hKHN0cikge1xuICAgIHZhciBidWZmZXJcbiAgICAgIDtcblxuICAgIGlmIChzdHIgaW5zdGFuY2VvZiBCdWZmZXIpIHtcbiAgICAgIGJ1ZmZlciA9IHN0cjtcbiAgICB9IGVsc2Uge1xuICAgICAgYnVmZmVyID0gbmV3IEJ1ZmZlcihzdHIudG9TdHJpbmcoKSwgJ2JpbmFyeScpO1xuICAgIH1cblxuICAgIHJldHVybiBidWZmZXIudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICB9XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBidG9hO1xufSgpKTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyKVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ6dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p6YjNWeVkyVnpJanBiSW01dlpHVmZiVzlrZFd4bGN5OWlkRzloTDJsdVpHVjRMbXB6SWwwc0ltNWhiV1Z6SWpwYlhTd2liV0Z3Y0dsdVozTWlPaUk3UVVGQlFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFTSXNJbVpwYkdVaU9pSm5aVzVsY21GMFpXUXVhbk1pTENKemIzVnlZMlZTYjI5MElqb2lJaXdpYzI5MWNtTmxjME52Ym5SbGJuUWlPbHNpS0daMWJtTjBhVzl1SUNncElIdGNiaUFnWENKMWMyVWdjM1J5YVdOMFhDSTdYRzVjYmlBZ1puVnVZM1JwYjI0Z1luUnZZU2h6ZEhJcElIdGNiaUFnSUNCMllYSWdZblZtWm1WeVhHNGdJQ0FnSUNBN1hHNWNiaUFnSUNCcFppQW9jM1J5SUdsdWMzUmhibU5sYjJZZ1FuVm1abVZ5S1NCN1hHNGdJQ0FnSUNCaWRXWm1aWElnUFNCemRISTdYRzRnSUNBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0FnSUdKMVptWmxjaUE5SUc1bGR5QkNkV1ptWlhJb2MzUnlMblJ2VTNSeWFXNW5LQ2tzSUNkaWFXNWhjbmtuS1R0Y2JpQWdJQ0I5WEc1Y2JpQWdJQ0J5WlhSMWNtNGdZblZtWm1WeUxuUnZVM1J5YVc1bktDZGlZWE5sTmpRbktUdGNiaUFnZlZ4dVhHNGdJRzF2WkhWc1pTNWxlSEJ2Y25SeklEMGdZblJ2WVR0Y2JuMG9LU2s3WEc0aVhYMD0iLCIvKiFcbiAqIFRoZSBidWZmZXIgbW9kdWxlIGZyb20gbm9kZS5qcywgZm9yIHRoZSBicm93c2VyLlxuICpcbiAqIEBhdXRob3IgICBGZXJvc3MgQWJvdWtoYWRpamVoIDxmZXJvc3NAZmVyb3NzLm9yZz4gPGh0dHA6Ly9mZXJvc3Mub3JnPlxuICogQGxpY2Vuc2UgIE1JVFxuICovXG5cbnZhciBiYXNlNjQgPSByZXF1aXJlKCdiYXNlNjQtanMnKVxudmFyIGllZWU3NTQgPSByZXF1aXJlKCdpZWVlNzU0JylcbnZhciBpc0FycmF5ID0gcmVxdWlyZSgnaXMtYXJyYXknKVxuXG5leHBvcnRzLkJ1ZmZlciA9IEJ1ZmZlclxuZXhwb3J0cy5TbG93QnVmZmVyID0gU2xvd0J1ZmZlclxuZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFUyA9IDUwXG5CdWZmZXIucG9vbFNpemUgPSA4MTkyIC8vIG5vdCB1c2VkIGJ5IHRoaXMgaW1wbGVtZW50YXRpb25cblxudmFyIHJvb3RQYXJlbnQgPSB7fVxuXG4vKipcbiAqIElmIGBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVGA6XG4gKiAgID09PSB0cnVlICAgIFVzZSBVaW50OEFycmF5IGltcGxlbWVudGF0aW9uIChmYXN0ZXN0KVxuICogICA9PT0gZmFsc2UgICBVc2UgT2JqZWN0IGltcGxlbWVudGF0aW9uIChtb3N0IGNvbXBhdGlibGUsIGV2ZW4gSUU2KVxuICpcbiAqIEJyb3dzZXJzIHRoYXQgc3VwcG9ydCB0eXBlZCBhcnJheXMgYXJlIElFIDEwKywgRmlyZWZveCA0KywgQ2hyb21lIDcrLCBTYWZhcmkgNS4xKyxcbiAqIE9wZXJhIDExLjYrLCBpT1MgNC4yKy5cbiAqXG4gKiBEdWUgdG8gdmFyaW91cyBicm93c2VyIGJ1Z3MsIHNvbWV0aW1lcyB0aGUgT2JqZWN0IGltcGxlbWVudGF0aW9uIHdpbGwgYmUgdXNlZCBldmVuXG4gKiB3aGVuIHRoZSBicm93c2VyIHN1cHBvcnRzIHR5cGVkIGFycmF5cy5cbiAqXG4gKiBOb3RlOlxuICpcbiAqICAgLSBGaXJlZm94IDQtMjkgbGFja3Mgc3VwcG9ydCBmb3IgYWRkaW5nIG5ldyBwcm9wZXJ0aWVzIHRvIGBVaW50OEFycmF5YCBpbnN0YW5jZXMsXG4gKiAgICAgU2VlOiBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD02OTU0MzguXG4gKlxuICogICAtIFNhZmFyaSA1LTcgbGFja3Mgc3VwcG9ydCBmb3IgY2hhbmdpbmcgdGhlIGBPYmplY3QucHJvdG90eXBlLmNvbnN0cnVjdG9yYCBwcm9wZXJ0eVxuICogICAgIG9uIG9iamVjdHMuXG4gKlxuICogICAtIENocm9tZSA5LTEwIGlzIG1pc3NpbmcgdGhlIGBUeXBlZEFycmF5LnByb3RvdHlwZS5zdWJhcnJheWAgZnVuY3Rpb24uXG4gKlxuICogICAtIElFMTAgaGFzIGEgYnJva2VuIGBUeXBlZEFycmF5LnByb3RvdHlwZS5zdWJhcnJheWAgZnVuY3Rpb24gd2hpY2ggcmV0dXJucyBhcnJheXMgb2ZcbiAqICAgICBpbmNvcnJlY3QgbGVuZ3RoIGluIHNvbWUgc2l0dWF0aW9ucy5cblxuICogV2UgZGV0ZWN0IHRoZXNlIGJ1Z2d5IGJyb3dzZXJzIGFuZCBzZXQgYEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUYCB0byBgZmFsc2VgIHNvIHRoZXlcbiAqIGdldCB0aGUgT2JqZWN0IGltcGxlbWVudGF0aW9uLCB3aGljaCBpcyBzbG93ZXIgYnV0IGJlaGF2ZXMgY29ycmVjdGx5LlxuICovXG5CdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCA9IChmdW5jdGlvbiAoKSB7XG4gIGZ1bmN0aW9uIEJhciAoKSB7fVxuICB0cnkge1xuICAgIHZhciBhcnIgPSBuZXcgVWludDhBcnJheSgxKVxuICAgIGFyci5mb28gPSBmdW5jdGlvbiAoKSB7IHJldHVybiA0MiB9XG4gICAgYXJyLmNvbnN0cnVjdG9yID0gQmFyXG4gICAgcmV0dXJuIGFyci5mb28oKSA9PT0gNDIgJiYgLy8gdHlwZWQgYXJyYXkgaW5zdGFuY2VzIGNhbiBiZSBhdWdtZW50ZWRcbiAgICAgICAgYXJyLmNvbnN0cnVjdG9yID09PSBCYXIgJiYgLy8gY29uc3RydWN0b3IgY2FuIGJlIHNldFxuICAgICAgICB0eXBlb2YgYXJyLnN1YmFycmF5ID09PSAnZnVuY3Rpb24nICYmIC8vIGNocm9tZSA5LTEwIGxhY2sgYHN1YmFycmF5YFxuICAgICAgICBhcnIuc3ViYXJyYXkoMSwgMSkuYnl0ZUxlbmd0aCA9PT0gMCAvLyBpZTEwIGhhcyBicm9rZW4gYHN1YmFycmF5YFxuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbn0pKClcblxuZnVuY3Rpb24ga01heExlbmd0aCAoKSB7XG4gIHJldHVybiBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVFxuICAgID8gMHg3ZmZmZmZmZlxuICAgIDogMHgzZmZmZmZmZlxufVxuXG4vKipcbiAqIENsYXNzOiBCdWZmZXJcbiAqID09PT09PT09PT09PT1cbiAqXG4gKiBUaGUgQnVmZmVyIGNvbnN0cnVjdG9yIHJldHVybnMgaW5zdGFuY2VzIG9mIGBVaW50OEFycmF5YCB0aGF0IGFyZSBhdWdtZW50ZWRcbiAqIHdpdGggZnVuY3Rpb24gcHJvcGVydGllcyBmb3IgYWxsIHRoZSBub2RlIGBCdWZmZXJgIEFQSSBmdW5jdGlvbnMuIFdlIHVzZVxuICogYFVpbnQ4QXJyYXlgIHNvIHRoYXQgc3F1YXJlIGJyYWNrZXQgbm90YXRpb24gd29ya3MgYXMgZXhwZWN0ZWQgLS0gaXQgcmV0dXJuc1xuICogYSBzaW5nbGUgb2N0ZXQuXG4gKlxuICogQnkgYXVnbWVudGluZyB0aGUgaW5zdGFuY2VzLCB3ZSBjYW4gYXZvaWQgbW9kaWZ5aW5nIHRoZSBgVWludDhBcnJheWBcbiAqIHByb3RvdHlwZS5cbiAqL1xuZnVuY3Rpb24gQnVmZmVyIChhcmcpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEJ1ZmZlcikpIHtcbiAgICAvLyBBdm9pZCBnb2luZyB0aHJvdWdoIGFuIEFyZ3VtZW50c0FkYXB0b3JUcmFtcG9saW5lIGluIHRoZSBjb21tb24gY2FzZS5cbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHJldHVybiBuZXcgQnVmZmVyKGFyZywgYXJndW1lbnRzWzFdKVxuICAgIHJldHVybiBuZXcgQnVmZmVyKGFyZylcbiAgfVxuXG4gIHRoaXMubGVuZ3RoID0gMFxuICB0aGlzLnBhcmVudCA9IHVuZGVmaW5lZFxuXG4gIC8vIENvbW1vbiBjYXNlLlxuICBpZiAodHlwZW9mIGFyZyA9PT0gJ251bWJlcicpIHtcbiAgICByZXR1cm4gZnJvbU51bWJlcih0aGlzLCBhcmcpXG4gIH1cblxuICAvLyBTbGlnaHRseSBsZXNzIGNvbW1vbiBjYXNlLlxuICBpZiAodHlwZW9mIGFyZyA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZnJvbVN0cmluZyh0aGlzLCBhcmcsIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogJ3V0ZjgnKVxuICB9XG5cbiAgLy8gVW51c3VhbC5cbiAgcmV0dXJuIGZyb21PYmplY3QodGhpcywgYXJnKVxufVxuXG5mdW5jdGlvbiBmcm9tTnVtYmVyICh0aGF0LCBsZW5ndGgpIHtcbiAgdGhhdCA9IGFsbG9jYXRlKHRoYXQsIGxlbmd0aCA8IDAgPyAwIDogY2hlY2tlZChsZW5ndGgpIHwgMClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoYXRbaV0gPSAwXG4gICAgfVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21TdHJpbmcgKHRoYXQsIHN0cmluZywgZW5jb2RpbmcpIHtcbiAgaWYgKHR5cGVvZiBlbmNvZGluZyAhPT0gJ3N0cmluZycgfHwgZW5jb2RpbmcgPT09ICcnKSBlbmNvZGluZyA9ICd1dGY4J1xuXG4gIC8vIEFzc3VtcHRpb246IGJ5dGVMZW5ndGgoKSByZXR1cm4gdmFsdWUgaXMgYWx3YXlzIDwga01heExlbmd0aC5cbiAgdmFyIGxlbmd0aCA9IGJ5dGVMZW5ndGgoc3RyaW5nLCBlbmNvZGluZykgfCAwXG4gIHRoYXQgPSBhbGxvY2F0ZSh0aGF0LCBsZW5ndGgpXG5cbiAgdGhhdC53cml0ZShzdHJpbmcsIGVuY29kaW5nKVxuICByZXR1cm4gdGhhdFxufVxuXG5mdW5jdGlvbiBmcm9tT2JqZWN0ICh0aGF0LCBvYmplY3QpIHtcbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihvYmplY3QpKSByZXR1cm4gZnJvbUJ1ZmZlcih0aGF0LCBvYmplY3QpXG5cbiAgaWYgKGlzQXJyYXkob2JqZWN0KSkgcmV0dXJuIGZyb21BcnJheSh0aGF0LCBvYmplY3QpXG5cbiAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignbXVzdCBzdGFydCB3aXRoIG51bWJlciwgYnVmZmVyLCBhcnJheSBvciBzdHJpbmcnKVxuICB9XG5cbiAgaWYgKHR5cGVvZiBBcnJheUJ1ZmZlciAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBpZiAob2JqZWN0LmJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgICByZXR1cm4gZnJvbVR5cGVkQXJyYXkodGhhdCwgb2JqZWN0KVxuICAgIH1cbiAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICAgIHJldHVybiBmcm9tQXJyYXlCdWZmZXIodGhhdCwgb2JqZWN0KVxuICAgIH1cbiAgfVxuXG4gIGlmIChvYmplY3QubGVuZ3RoKSByZXR1cm4gZnJvbUFycmF5TGlrZSh0aGF0LCBvYmplY3QpXG5cbiAgcmV0dXJuIGZyb21Kc29uT2JqZWN0KHRoYXQsIG9iamVjdClcbn1cblxuZnVuY3Rpb24gZnJvbUJ1ZmZlciAodGhhdCwgYnVmZmVyKSB7XG4gIHZhciBsZW5ndGggPSBjaGVja2VkKGJ1ZmZlci5sZW5ndGgpIHwgMFxuICB0aGF0ID0gYWxsb2NhdGUodGhhdCwgbGVuZ3RoKVxuICBidWZmZXIuY29weSh0aGF0LCAwLCAwLCBsZW5ndGgpXG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheSAodGhhdCwgYXJyYXkpIHtcbiAgdmFyIGxlbmd0aCA9IGNoZWNrZWQoYXJyYXkubGVuZ3RoKSB8IDBcbiAgdGhhdCA9IGFsbG9jYXRlKHRoYXQsIGxlbmd0aClcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgIHRoYXRbaV0gPSBhcnJheVtpXSAmIDI1NVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbi8vIER1cGxpY2F0ZSBvZiBmcm9tQXJyYXkoKSB0byBrZWVwIGZyb21BcnJheSgpIG1vbm9tb3JwaGljLlxuZnVuY3Rpb24gZnJvbVR5cGVkQXJyYXkgKHRoYXQsIGFycmF5KSB7XG4gIHZhciBsZW5ndGggPSBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIHRoYXQgPSBhbGxvY2F0ZSh0aGF0LCBsZW5ndGgpXG4gIC8vIFRydW5jYXRpbmcgdGhlIGVsZW1lbnRzIGlzIHByb2JhYmx5IG5vdCB3aGF0IHBlb3BsZSBleHBlY3QgZnJvbSB0eXBlZFxuICAvLyBhcnJheXMgd2l0aCBCWVRFU19QRVJfRUxFTUVOVCA+IDEgYnV0IGl0J3MgY29tcGF0aWJsZSB3aXRoIHRoZSBiZWhhdmlvclxuICAvLyBvZiB0aGUgb2xkIEJ1ZmZlciBjb25zdHJ1Y3Rvci5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgIHRoYXRbaV0gPSBhcnJheVtpXSAmIDI1NVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUJ1ZmZlciAodGhhdCwgYXJyYXkpIHtcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgLy8gUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2UsIGZvciBiZXN0IHBlcmZvcm1hbmNlXG4gICAgYXJyYXkuYnl0ZUxlbmd0aFxuICAgIHRoYXQgPSBCdWZmZXIuX2F1Z21lbnQobmV3IFVpbnQ4QXJyYXkoYXJyYXkpKVxuICB9IGVsc2Uge1xuICAgIC8vIEZhbGxiYWNrOiBSZXR1cm4gYW4gb2JqZWN0IGluc3RhbmNlIG9mIHRoZSBCdWZmZXIgY2xhc3NcbiAgICB0aGF0ID0gZnJvbVR5cGVkQXJyYXkodGhhdCwgbmV3IFVpbnQ4QXJyYXkoYXJyYXkpKVxuICB9XG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGZyb21BcnJheUxpa2UgKHRoYXQsIGFycmF5KSB7XG4gIHZhciBsZW5ndGggPSBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIHRoYXQgPSBhbGxvY2F0ZSh0aGF0LCBsZW5ndGgpXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICB0aGF0W2ldID0gYXJyYXlbaV0gJiAyNTVcbiAgfVxuICByZXR1cm4gdGhhdFxufVxuXG4vLyBEZXNlcmlhbGl6ZSB7IHR5cGU6ICdCdWZmZXInLCBkYXRhOiBbMSwyLDMsLi4uXSB9IGludG8gYSBCdWZmZXIgb2JqZWN0LlxuLy8gUmV0dXJucyBhIHplcm8tbGVuZ3RoIGJ1ZmZlciBmb3IgaW5wdXRzIHRoYXQgZG9uJ3QgY29uZm9ybSB0byB0aGUgc3BlYy5cbmZ1bmN0aW9uIGZyb21Kc29uT2JqZWN0ICh0aGF0LCBvYmplY3QpIHtcbiAgdmFyIGFycmF5XG4gIHZhciBsZW5ndGggPSAwXG5cbiAgaWYgKG9iamVjdC50eXBlID09PSAnQnVmZmVyJyAmJiBpc0FycmF5KG9iamVjdC5kYXRhKSkge1xuICAgIGFycmF5ID0gb2JqZWN0LmRhdGFcbiAgICBsZW5ndGggPSBjaGVja2VkKGFycmF5Lmxlbmd0aCkgfCAwXG4gIH1cbiAgdGhhdCA9IGFsbG9jYXRlKHRoYXQsIGxlbmd0aClcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgdGhhdFtpXSA9IGFycmF5W2ldICYgMjU1XG4gIH1cbiAgcmV0dXJuIHRoYXRcbn1cblxuZnVuY3Rpb24gYWxsb2NhdGUgKHRoYXQsIGxlbmd0aCkge1xuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAvLyBSZXR1cm4gYW4gYXVnbWVudGVkIGBVaW50OEFycmF5YCBpbnN0YW5jZSwgZm9yIGJlc3QgcGVyZm9ybWFuY2VcbiAgICB0aGF0ID0gQnVmZmVyLl9hdWdtZW50KG5ldyBVaW50OEFycmF5KGxlbmd0aCkpXG4gIH0gZWxzZSB7XG4gICAgLy8gRmFsbGJhY2s6IFJldHVybiBhbiBvYmplY3QgaW5zdGFuY2Ugb2YgdGhlIEJ1ZmZlciBjbGFzc1xuICAgIHRoYXQubGVuZ3RoID0gbGVuZ3RoXG4gICAgdGhhdC5faXNCdWZmZXIgPSB0cnVlXG4gIH1cblxuICB2YXIgZnJvbVBvb2wgPSBsZW5ndGggIT09IDAgJiYgbGVuZ3RoIDw9IEJ1ZmZlci5wb29sU2l6ZSA+Pj4gMVxuICBpZiAoZnJvbVBvb2wpIHRoYXQucGFyZW50ID0gcm9vdFBhcmVudFxuXG4gIHJldHVybiB0aGF0XG59XG5cbmZ1bmN0aW9uIGNoZWNrZWQgKGxlbmd0aCkge1xuICAvLyBOb3RlOiBjYW5ub3QgdXNlIGBsZW5ndGggPCBrTWF4TGVuZ3RoYCBoZXJlIGJlY2F1c2UgdGhhdCBmYWlscyB3aGVuXG4gIC8vIGxlbmd0aCBpcyBOYU4gKHdoaWNoIGlzIG90aGVyd2lzZSBjb2VyY2VkIHRvIHplcm8uKVxuICBpZiAobGVuZ3RoID49IGtNYXhMZW5ndGgoKSkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdBdHRlbXB0IHRvIGFsbG9jYXRlIEJ1ZmZlciBsYXJnZXIgdGhhbiBtYXhpbXVtICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICdzaXplOiAweCcgKyBrTWF4TGVuZ3RoKCkudG9TdHJpbmcoMTYpICsgJyBieXRlcycpXG4gIH1cbiAgcmV0dXJuIGxlbmd0aCB8IDBcbn1cblxuZnVuY3Rpb24gU2xvd0J1ZmZlciAoc3ViamVjdCwgZW5jb2RpbmcpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFNsb3dCdWZmZXIpKSByZXR1cm4gbmV3IFNsb3dCdWZmZXIoc3ViamVjdCwgZW5jb2RpbmcpXG5cbiAgdmFyIGJ1ZiA9IG5ldyBCdWZmZXIoc3ViamVjdCwgZW5jb2RpbmcpXG4gIGRlbGV0ZSBidWYucGFyZW50XG4gIHJldHVybiBidWZcbn1cblxuQnVmZmVyLmlzQnVmZmVyID0gZnVuY3Rpb24gaXNCdWZmZXIgKGIpIHtcbiAgcmV0dXJuICEhKGIgIT0gbnVsbCAmJiBiLl9pc0J1ZmZlcilcbn1cblxuQnVmZmVyLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlIChhLCBiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGEpIHx8ICFCdWZmZXIuaXNCdWZmZXIoYikpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudHMgbXVzdCBiZSBCdWZmZXJzJylcbiAgfVxuXG4gIGlmIChhID09PSBiKSByZXR1cm4gMFxuXG4gIHZhciB4ID0gYS5sZW5ndGhcbiAgdmFyIHkgPSBiLmxlbmd0aFxuXG4gIHZhciBpID0gMFxuICB2YXIgbGVuID0gTWF0aC5taW4oeCwgeSlcbiAgd2hpbGUgKGkgPCBsZW4pIHtcbiAgICBpZiAoYVtpXSAhPT0gYltpXSkgYnJlYWtcblxuICAgICsraVxuICB9XG5cbiAgaWYgKGkgIT09IGxlbikge1xuICAgIHggPSBhW2ldXG4gICAgeSA9IGJbaV1cbiAgfVxuXG4gIGlmICh4IDwgeSkgcmV0dXJuIC0xXG4gIGlmICh5IDwgeCkgcmV0dXJuIDFcbiAgcmV0dXJuIDBcbn1cblxuQnVmZmVyLmlzRW5jb2RpbmcgPSBmdW5jdGlvbiBpc0VuY29kaW5nIChlbmNvZGluZykge1xuICBzd2l0Y2ggKFN0cmluZyhlbmNvZGluZykudG9Mb3dlckNhc2UoKSkge1xuICAgIGNhc2UgJ2hleCc6XG4gICAgY2FzZSAndXRmOCc6XG4gICAgY2FzZSAndXRmLTgnOlxuICAgIGNhc2UgJ2FzY2lpJzpcbiAgICBjYXNlICdiaW5hcnknOlxuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgY2FzZSAncmF3JzpcbiAgICBjYXNlICd1Y3MyJzpcbiAgICBjYXNlICd1Y3MtMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgcmV0dXJuIHRydWVcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuQnVmZmVyLmNvbmNhdCA9IGZ1bmN0aW9uIGNvbmNhdCAobGlzdCwgbGVuZ3RoKSB7XG4gIGlmICghaXNBcnJheShsaXN0KSkgdGhyb3cgbmV3IFR5cGVFcnJvcignbGlzdCBhcmd1bWVudCBtdXN0IGJlIGFuIEFycmF5IG9mIEJ1ZmZlcnMuJylcblxuICBpZiAobGlzdC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gbmV3IEJ1ZmZlcigwKVxuICB9XG5cbiAgdmFyIGlcbiAgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgbGVuZ3RoID0gMFxuICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBsZW5ndGggKz0gbGlzdFtpXS5sZW5ndGhcbiAgICB9XG4gIH1cblxuICB2YXIgYnVmID0gbmV3IEJ1ZmZlcihsZW5ndGgpXG4gIHZhciBwb3MgPSAwXG4gIGZvciAoaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGl0ZW0gPSBsaXN0W2ldXG4gICAgaXRlbS5jb3B5KGJ1ZiwgcG9zKVxuICAgIHBvcyArPSBpdGVtLmxlbmd0aFxuICB9XG4gIHJldHVybiBidWZcbn1cblxuZnVuY3Rpb24gYnl0ZUxlbmd0aCAoc3RyaW5nLCBlbmNvZGluZykge1xuICBpZiAodHlwZW9mIHN0cmluZyAhPT0gJ3N0cmluZycpIHN0cmluZyA9ICcnICsgc3RyaW5nXG5cbiAgdmFyIGxlbiA9IHN0cmluZy5sZW5ndGhcbiAgaWYgKGxlbiA9PT0gMCkgcmV0dXJuIDBcblxuICAvLyBVc2UgYSBmb3IgbG9vcCB0byBhdm9pZCByZWN1cnNpb25cbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcbiAgZm9yICg7Oykge1xuICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICAvLyBEZXByZWNhdGVkXG4gICAgICBjYXNlICdyYXcnOlxuICAgICAgY2FzZSAncmF3cyc6XG4gICAgICAgIHJldHVybiBsZW5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gdXRmOFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGhcbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiBsZW4gKiAyXG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gbGVuID4+PiAxXG4gICAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgICByZXR1cm4gYmFzZTY0VG9CeXRlcyhzdHJpbmcpLmxlbmd0aFxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSByZXR1cm4gdXRmOFRvQnl0ZXMoc3RyaW5nKS5sZW5ndGggLy8gYXNzdW1lIHV0ZjhcbiAgICAgICAgZW5jb2RpbmcgPSAoJycgKyBlbmNvZGluZykudG9Mb3dlckNhc2UoKVxuICAgICAgICBsb3dlcmVkQ2FzZSA9IHRydWVcbiAgICB9XG4gIH1cbn1cbkJ1ZmZlci5ieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aFxuXG4vLyBwcmUtc2V0IGZvciB2YWx1ZXMgdGhhdCBtYXkgZXhpc3QgaW4gdGhlIGZ1dHVyZVxuQnVmZmVyLnByb3RvdHlwZS5sZW5ndGggPSB1bmRlZmluZWRcbkJ1ZmZlci5wcm90b3R5cGUucGFyZW50ID0gdW5kZWZpbmVkXG5cbmZ1bmN0aW9uIHNsb3dUb1N0cmluZyAoZW5jb2RpbmcsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcblxuICBzdGFydCA9IHN0YXJ0IHwgMFxuICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCB8fCBlbmQgPT09IEluZmluaXR5ID8gdGhpcy5sZW5ndGggOiBlbmQgfCAwXG5cbiAgaWYgKCFlbmNvZGluZykgZW5jb2RpbmcgPSAndXRmOCdcbiAgaWYgKHN0YXJ0IDwgMCkgc3RhcnQgPSAwXG4gIGlmIChlbmQgPiB0aGlzLmxlbmd0aCkgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKGVuZCA8PSBzdGFydCkgcmV0dXJuICcnXG5cbiAgd2hpbGUgKHRydWUpIHtcbiAgICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgICBjYXNlICdoZXgnOlxuICAgICAgICByZXR1cm4gaGV4U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAndXRmOCc6XG4gICAgICBjYXNlICd1dGYtOCc6XG4gICAgICAgIHJldHVybiB1dGY4U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnYXNjaWknOlxuICAgICAgICByZXR1cm4gYXNjaWlTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICdiaW5hcnknOlxuICAgICAgICByZXR1cm4gYmluYXJ5U2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgICAgcmV0dXJuIGJhc2U2NFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ3VjczInOlxuICAgICAgY2FzZSAndWNzLTInOlxuICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICAgIHJldHVybiB1dGYxNmxlU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKGxvd2VyZWRDYXNlKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgICAgIGVuY29kaW5nID0gKGVuY29kaW5nICsgJycpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZyAoKSB7XG4gIHZhciBsZW5ndGggPSB0aGlzLmxlbmd0aCB8IDBcbiAgaWYgKGxlbmd0aCA9PT0gMCkgcmV0dXJuICcnXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSByZXR1cm4gdXRmOFNsaWNlKHRoaXMsIDAsIGxlbmd0aClcbiAgcmV0dXJuIHNsb3dUb1N0cmluZy5hcHBseSh0aGlzLCBhcmd1bWVudHMpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuZXF1YWxzID0gZnVuY3Rpb24gZXF1YWxzIChiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyJylcbiAgaWYgKHRoaXMgPT09IGIpIHJldHVybiB0cnVlXG4gIHJldHVybiBCdWZmZXIuY29tcGFyZSh0aGlzLCBiKSA9PT0gMFxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluc3BlY3QgPSBmdW5jdGlvbiBpbnNwZWN0ICgpIHtcbiAgdmFyIHN0ciA9ICcnXG4gIHZhciBtYXggPSBleHBvcnRzLklOU1BFQ1RfTUFYX0JZVEVTXG4gIGlmICh0aGlzLmxlbmd0aCA+IDApIHtcbiAgICBzdHIgPSB0aGlzLnRvU3RyaW5nKCdoZXgnLCAwLCBtYXgpLm1hdGNoKC8uezJ9L2cpLmpvaW4oJyAnKVxuICAgIGlmICh0aGlzLmxlbmd0aCA+IG1heCkgc3RyICs9ICcgLi4uICdcbiAgfVxuICByZXR1cm4gJzxCdWZmZXIgJyArIHN0ciArICc+J1xufVxuXG5CdWZmZXIucHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlIChiKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudCBtdXN0IGJlIGEgQnVmZmVyJylcbiAgaWYgKHRoaXMgPT09IGIpIHJldHVybiAwXG4gIHJldHVybiBCdWZmZXIuY29tcGFyZSh0aGlzLCBiKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmluZGV4T2YgPSBmdW5jdGlvbiBpbmRleE9mICh2YWwsIGJ5dGVPZmZzZXQpIHtcbiAgaWYgKGJ5dGVPZmZzZXQgPiAweDdmZmZmZmZmKSBieXRlT2Zmc2V0ID0gMHg3ZmZmZmZmZlxuICBlbHNlIGlmIChieXRlT2Zmc2V0IDwgLTB4ODAwMDAwMDApIGJ5dGVPZmZzZXQgPSAtMHg4MDAwMDAwMFxuICBieXRlT2Zmc2V0ID4+PSAwXG5cbiAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm4gLTFcbiAgaWYgKGJ5dGVPZmZzZXQgPj0gdGhpcy5sZW5ndGgpIHJldHVybiAtMVxuXG4gIC8vIE5lZ2F0aXZlIG9mZnNldHMgc3RhcnQgZnJvbSB0aGUgZW5kIG9mIHRoZSBidWZmZXJcbiAgaWYgKGJ5dGVPZmZzZXQgPCAwKSBieXRlT2Zmc2V0ID0gTWF0aC5tYXgodGhpcy5sZW5ndGggKyBieXRlT2Zmc2V0LCAwKVxuXG4gIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJykge1xuICAgIGlmICh2YWwubGVuZ3RoID09PSAwKSByZXR1cm4gLTEgLy8gc3BlY2lhbCBjYXNlOiBsb29raW5nIGZvciBlbXB0eSBzdHJpbmcgYWx3YXlzIGZhaWxzXG4gICAgcmV0dXJuIFN0cmluZy5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKHRoaXMsIHZhbCwgYnl0ZU9mZnNldClcbiAgfVxuICBpZiAoQnVmZmVyLmlzQnVmZmVyKHZhbCkpIHtcbiAgICByZXR1cm4gYXJyYXlJbmRleE9mKHRoaXMsIHZhbCwgYnl0ZU9mZnNldClcbiAgfVxuICBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQgJiYgVWludDhBcnJheS5wcm90b3R5cGUuaW5kZXhPZiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIFVpbnQ4QXJyYXkucHJvdG90eXBlLmluZGV4T2YuY2FsbCh0aGlzLCB2YWwsIGJ5dGVPZmZzZXQpXG4gICAgfVxuICAgIHJldHVybiBhcnJheUluZGV4T2YodGhpcywgWyB2YWwgXSwgYnl0ZU9mZnNldClcbiAgfVxuXG4gIGZ1bmN0aW9uIGFycmF5SW5kZXhPZiAoYXJyLCB2YWwsIGJ5dGVPZmZzZXQpIHtcbiAgICB2YXIgZm91bmRJbmRleCA9IC0xXG4gICAgZm9yICh2YXIgaSA9IDA7IGJ5dGVPZmZzZXQgKyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoYXJyW2J5dGVPZmZzZXQgKyBpXSA9PT0gdmFsW2ZvdW5kSW5kZXggPT09IC0xID8gMCA6IGkgLSBmb3VuZEluZGV4XSkge1xuICAgICAgICBpZiAoZm91bmRJbmRleCA9PT0gLTEpIGZvdW5kSW5kZXggPSBpXG4gICAgICAgIGlmIChpIC0gZm91bmRJbmRleCArIDEgPT09IHZhbC5sZW5ndGgpIHJldHVybiBieXRlT2Zmc2V0ICsgZm91bmRJbmRleFxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZm91bmRJbmRleCA9IC0xXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiAtMVxuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcigndmFsIG11c3QgYmUgc3RyaW5nLCBudW1iZXIgb3IgQnVmZmVyJylcbn1cblxuLy8gYGdldGAgaXMgZGVwcmVjYXRlZFxuQnVmZmVyLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiBnZXQgKG9mZnNldCkge1xuICBjb25zb2xlLmxvZygnLmdldCgpIGlzIGRlcHJlY2F0ZWQuIEFjY2VzcyB1c2luZyBhcnJheSBpbmRleGVzIGluc3RlYWQuJylcbiAgcmV0dXJuIHRoaXMucmVhZFVJbnQ4KG9mZnNldClcbn1cblxuLy8gYHNldGAgaXMgZGVwcmVjYXRlZFxuQnVmZmVyLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbiBzZXQgKHYsIG9mZnNldCkge1xuICBjb25zb2xlLmxvZygnLnNldCgpIGlzIGRlcHJlY2F0ZWQuIEFjY2VzcyB1c2luZyBhcnJheSBpbmRleGVzIGluc3RlYWQuJylcbiAgcmV0dXJuIHRoaXMud3JpdGVVSW50OCh2LCBvZmZzZXQpXG59XG5cbmZ1bmN0aW9uIGhleFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgb2Zmc2V0ID0gTnVtYmVyKG9mZnNldCkgfHwgMFxuICB2YXIgcmVtYWluaW5nID0gYnVmLmxlbmd0aCAtIG9mZnNldFxuICBpZiAoIWxlbmd0aCkge1xuICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICB9IGVsc2Uge1xuICAgIGxlbmd0aCA9IE51bWJlcihsZW5ndGgpXG4gICAgaWYgKGxlbmd0aCA+IHJlbWFpbmluZykge1xuICAgICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gICAgfVxuICB9XG5cbiAgLy8gbXVzdCBiZSBhbiBldmVuIG51bWJlciBvZiBkaWdpdHNcbiAgdmFyIHN0ckxlbiA9IHN0cmluZy5sZW5ndGhcbiAgaWYgKHN0ckxlbiAlIDIgIT09IDApIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBoZXggc3RyaW5nJylcblxuICBpZiAobGVuZ3RoID4gc3RyTGVuIC8gMikge1xuICAgIGxlbmd0aCA9IHN0ckxlbiAvIDJcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHBhcnNlZCA9IHBhcnNlSW50KHN0cmluZy5zdWJzdHIoaSAqIDIsIDIpLCAxNilcbiAgICBpZiAoaXNOYU4ocGFyc2VkKSkgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGhleCBzdHJpbmcnKVxuICAgIGJ1ZltvZmZzZXQgKyBpXSA9IHBhcnNlZFxuICB9XG4gIHJldHVybiBpXG59XG5cbmZ1bmN0aW9uIHV0ZjhXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHJldHVybiBibGl0QnVmZmVyKHV0ZjhUb0J5dGVzKHN0cmluZywgYnVmLmxlbmd0aCAtIG9mZnNldCksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGFzY2lpV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcihhc2NpaVRvQnl0ZXMoc3RyaW5nKSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gYmluYXJ5V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYXNjaWlXcml0ZShidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGJhc2U2NFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIGJsaXRCdWZmZXIoYmFzZTY0VG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5mdW5jdGlvbiB1Y3MyV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYmxpdEJ1ZmZlcih1dGYxNmxlVG9CeXRlcyhzdHJpbmcsIGJ1Zi5sZW5ndGggLSBvZmZzZXQpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24gd3JpdGUgKHN0cmluZywgb2Zmc2V0LCBsZW5ndGgsIGVuY29kaW5nKSB7XG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcpXG4gIGlmIChvZmZzZXQgPT09IHVuZGVmaW5lZCkge1xuICAgIGVuY29kaW5nID0gJ3V0ZjgnXG4gICAgbGVuZ3RoID0gdGhpcy5sZW5ndGhcbiAgICBvZmZzZXQgPSAwXG4gIC8vIEJ1ZmZlciN3cml0ZShzdHJpbmcsIGVuY29kaW5nKVxuICB9IGVsc2UgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkICYmIHR5cGVvZiBvZmZzZXQgPT09ICdzdHJpbmcnKSB7XG4gICAgZW5jb2RpbmcgPSBvZmZzZXRcbiAgICBsZW5ndGggPSB0aGlzLmxlbmd0aFxuICAgIG9mZnNldCA9IDBcbiAgLy8gQnVmZmVyI3dyaXRlKHN0cmluZywgb2Zmc2V0WywgbGVuZ3RoXVssIGVuY29kaW5nXSlcbiAgfSBlbHNlIGlmIChpc0Zpbml0ZShvZmZzZXQpKSB7XG4gICAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICAgIGlmIChpc0Zpbml0ZShsZW5ndGgpKSB7XG4gICAgICBsZW5ndGggPSBsZW5ndGggfCAwXG4gICAgICBpZiAoZW5jb2RpbmcgPT09IHVuZGVmaW5lZCkgZW5jb2RpbmcgPSAndXRmOCdcbiAgICB9IGVsc2Uge1xuICAgICAgZW5jb2RpbmcgPSBsZW5ndGhcbiAgICAgIGxlbmd0aCA9IHVuZGVmaW5lZFxuICAgIH1cbiAgLy8gbGVnYWN5IHdyaXRlKHN0cmluZywgZW5jb2RpbmcsIG9mZnNldCwgbGVuZ3RoKSAtIHJlbW92ZSBpbiB2MC4xM1xuICB9IGVsc2Uge1xuICAgIHZhciBzd2FwID0gZW5jb2RpbmdcbiAgICBlbmNvZGluZyA9IG9mZnNldFxuICAgIG9mZnNldCA9IGxlbmd0aCB8IDBcbiAgICBsZW5ndGggPSBzd2FwXG4gIH1cblxuICB2YXIgcmVtYWluaW5nID0gdGhpcy5sZW5ndGggLSBvZmZzZXRcbiAgaWYgKGxlbmd0aCA9PT0gdW5kZWZpbmVkIHx8IGxlbmd0aCA+IHJlbWFpbmluZykgbGVuZ3RoID0gcmVtYWluaW5nXG5cbiAgaWYgKChzdHJpbmcubGVuZ3RoID4gMCAmJiAobGVuZ3RoIDwgMCB8fCBvZmZzZXQgPCAwKSkgfHwgb2Zmc2V0ID4gdGhpcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignYXR0ZW1wdCB0byB3cml0ZSBvdXRzaWRlIGJ1ZmZlciBib3VuZHMnKVxuICB9XG5cbiAgaWYgKCFlbmNvZGluZykgZW5jb2RpbmcgPSAndXRmOCdcblxuICB2YXIgbG93ZXJlZENhc2UgPSBmYWxzZVxuICBmb3IgKDs7KSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGhleFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gdXRmOFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgICAgcmV0dXJuIGFzY2lpV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcblxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGJpbmFyeVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIC8vIFdhcm5pbmc6IG1heExlbmd0aCBub3QgdGFrZW4gaW50byBhY2NvdW50IGluIGJhc2U2NFdyaXRlXG4gICAgICAgIHJldHVybiBiYXNlNjRXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gdWNzMldyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSkgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICAgICAgICBlbmNvZGluZyA9ICgnJyArIGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpXG4gICAgICAgIGxvd2VyZWRDYXNlID0gdHJ1ZVxuICAgIH1cbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTiAoKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogJ0J1ZmZlcicsXG4gICAgZGF0YTogQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwodGhpcy5fYXJyIHx8IHRoaXMsIDApXG4gIH1cbn1cblxuZnVuY3Rpb24gYmFzZTY0U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICBpZiAoc3RhcnQgPT09IDAgJiYgZW5kID09PSBidWYubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1ZilcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmLnNsaWNlKHN0YXJ0LCBlbmQpKVxuICB9XG59XG5cbmZ1bmN0aW9uIHV0ZjhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcbiAgdmFyIHJlcyA9IFtdXG5cbiAgdmFyIGkgPSBzdGFydFxuICB3aGlsZSAoaSA8IGVuZCkge1xuICAgIHZhciBmaXJzdEJ5dGUgPSBidWZbaV1cbiAgICB2YXIgY29kZVBvaW50ID0gbnVsbFxuICAgIHZhciBieXRlc1BlclNlcXVlbmNlID0gKGZpcnN0Qnl0ZSA+IDB4RUYpID8gNFxuICAgICAgOiAoZmlyc3RCeXRlID4gMHhERikgPyAzXG4gICAgICA6IChmaXJzdEJ5dGUgPiAweEJGKSA/IDJcbiAgICAgIDogMVxuXG4gICAgaWYgKGkgKyBieXRlc1BlclNlcXVlbmNlIDw9IGVuZCkge1xuICAgICAgdmFyIHNlY29uZEJ5dGUsIHRoaXJkQnl0ZSwgZm91cnRoQnl0ZSwgdGVtcENvZGVQb2ludFxuXG4gICAgICBzd2l0Y2ggKGJ5dGVzUGVyU2VxdWVuY2UpIHtcbiAgICAgICAgY2FzZSAxOlxuICAgICAgICAgIGlmIChmaXJzdEJ5dGUgPCAweDgwKSB7XG4gICAgICAgICAgICBjb2RlUG9pbnQgPSBmaXJzdEJ5dGVcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHgxRikgPDwgMHg2IHwgKHNlY29uZEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweDdGKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgdGhpcmRCeXRlID0gYnVmW2kgKyAyXVxuICAgICAgICAgIGlmICgoc2Vjb25kQnl0ZSAmIDB4QzApID09PSAweDgwICYmICh0aGlyZEJ5dGUgJiAweEMwKSA9PT0gMHg4MCkge1xuICAgICAgICAgICAgdGVtcENvZGVQb2ludCA9IChmaXJzdEJ5dGUgJiAweEYpIDw8IDB4QyB8IChzZWNvbmRCeXRlICYgMHgzRikgPDwgMHg2IHwgKHRoaXJkQnl0ZSAmIDB4M0YpXG4gICAgICAgICAgICBpZiAodGVtcENvZGVQb2ludCA+IDB4N0ZGICYmICh0ZW1wQ29kZVBvaW50IDwgMHhEODAwIHx8IHRlbXBDb2RlUG9pbnQgPiAweERGRkYpKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSA0OlxuICAgICAgICAgIHNlY29uZEJ5dGUgPSBidWZbaSArIDFdXG4gICAgICAgICAgdGhpcmRCeXRlID0gYnVmW2kgKyAyXVxuICAgICAgICAgIGZvdXJ0aEJ5dGUgPSBidWZbaSArIDNdXG4gICAgICAgICAgaWYgKChzZWNvbmRCeXRlICYgMHhDMCkgPT09IDB4ODAgJiYgKHRoaXJkQnl0ZSAmIDB4QzApID09PSAweDgwICYmIChmb3VydGhCeXRlICYgMHhDMCkgPT09IDB4ODApIHtcbiAgICAgICAgICAgIHRlbXBDb2RlUG9pbnQgPSAoZmlyc3RCeXRlICYgMHhGKSA8PCAweDEyIHwgKHNlY29uZEJ5dGUgJiAweDNGKSA8PCAweEMgfCAodGhpcmRCeXRlICYgMHgzRikgPDwgMHg2IHwgKGZvdXJ0aEJ5dGUgJiAweDNGKVxuICAgICAgICAgICAgaWYgKHRlbXBDb2RlUG9pbnQgPiAweEZGRkYgJiYgdGVtcENvZGVQb2ludCA8IDB4MTEwMDAwKSB7XG4gICAgICAgICAgICAgIGNvZGVQb2ludCA9IHRlbXBDb2RlUG9pbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNvZGVQb2ludCA9PT0gbnVsbCkge1xuICAgICAgLy8gd2UgZGlkIG5vdCBnZW5lcmF0ZSBhIHZhbGlkIGNvZGVQb2ludCBzbyBpbnNlcnQgYVxuICAgICAgLy8gcmVwbGFjZW1lbnQgY2hhciAoVStGRkZEKSBhbmQgYWR2YW5jZSBvbmx5IDEgYnl0ZVxuICAgICAgY29kZVBvaW50ID0gMHhGRkZEXG4gICAgICBieXRlc1BlclNlcXVlbmNlID0gMVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50ID4gMHhGRkZGKSB7XG4gICAgICAvLyBlbmNvZGUgdG8gdXRmMTYgKHN1cnJvZ2F0ZSBwYWlyIGRhbmNlKVxuICAgICAgY29kZVBvaW50IC09IDB4MTAwMDBcbiAgICAgIHJlcy5wdXNoKGNvZGVQb2ludCA+Pj4gMTAgJiAweDNGRiB8IDB4RDgwMClcbiAgICAgIGNvZGVQb2ludCA9IDB4REMwMCB8IGNvZGVQb2ludCAmIDB4M0ZGXG4gICAgfVxuXG4gICAgcmVzLnB1c2goY29kZVBvaW50KVxuICAgIGkgKz0gYnl0ZXNQZXJTZXF1ZW5jZVxuICB9XG5cbiAgcmV0dXJuIGRlY29kZUNvZGVQb2ludHNBcnJheShyZXMpXG59XG5cbi8vIEJhc2VkIG9uIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzIyNzQ3MjcyLzY4MDc0MiwgdGhlIGJyb3dzZXIgd2l0aFxuLy8gdGhlIGxvd2VzdCBsaW1pdCBpcyBDaHJvbWUsIHdpdGggMHgxMDAwMCBhcmdzLlxuLy8gV2UgZ28gMSBtYWduaXR1ZGUgbGVzcywgZm9yIHNhZmV0eVxudmFyIE1BWF9BUkdVTUVOVFNfTEVOR1RIID0gMHgxMDAwXG5cbmZ1bmN0aW9uIGRlY29kZUNvZGVQb2ludHNBcnJheSAoY29kZVBvaW50cykge1xuICB2YXIgbGVuID0gY29kZVBvaW50cy5sZW5ndGhcbiAgaWYgKGxlbiA8PSBNQVhfQVJHVU1FTlRTX0xFTkdUSCkge1xuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZywgY29kZVBvaW50cykgLy8gYXZvaWQgZXh0cmEgc2xpY2UoKVxuICB9XG5cbiAgLy8gRGVjb2RlIGluIGNodW5rcyB0byBhdm9pZCBcImNhbGwgc3RhY2sgc2l6ZSBleGNlZWRlZFwiLlxuICB2YXIgcmVzID0gJydcbiAgdmFyIGkgPSAwXG4gIHdoaWxlIChpIDwgbGVuKSB7XG4gICAgcmVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoXG4gICAgICBTdHJpbmcsXG4gICAgICBjb2RlUG9pbnRzLnNsaWNlKGksIGkgKz0gTUFYX0FSR1VNRU5UU19MRU5HVEgpXG4gICAgKVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuZnVuY3Rpb24gYXNjaWlTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXQgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0gJiAweDdGKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gYmluYXJ5U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgcmV0ID0gJydcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgcmV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gaGV4U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gYnVmLmxlbmd0aFxuXG4gIGlmICghc3RhcnQgfHwgc3RhcnQgPCAwKSBzdGFydCA9IDBcbiAgaWYgKCFlbmQgfHwgZW5kIDwgMCB8fCBlbmQgPiBsZW4pIGVuZCA9IGxlblxuXG4gIHZhciBvdXQgPSAnJ1xuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgIG91dCArPSB0b0hleChidWZbaV0pXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuXG5mdW5jdGlvbiB1dGYxNmxlU2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICB2YXIgYnl0ZXMgPSBidWYuc2xpY2Uoc3RhcnQsIGVuZClcbiAgdmFyIHJlcyA9ICcnXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyBpICs9IDIpIHtcbiAgICByZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSArIGJ5dGVzW2kgKyAxXSAqIDI1NilcbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc2xpY2UgPSBmdW5jdGlvbiBzbGljZSAoc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgc3RhcnQgPSB+fnN0YXJ0XG4gIGVuZCA9IGVuZCA9PT0gdW5kZWZpbmVkID8gbGVuIDogfn5lbmRcblxuICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgc3RhcnQgKz0gbGVuXG4gICAgaWYgKHN0YXJ0IDwgMCkgc3RhcnQgPSAwXG4gIH0gZWxzZSBpZiAoc3RhcnQgPiBsZW4pIHtcbiAgICBzdGFydCA9IGxlblxuICB9XG5cbiAgaWYgKGVuZCA8IDApIHtcbiAgICBlbmQgKz0gbGVuXG4gICAgaWYgKGVuZCA8IDApIGVuZCA9IDBcbiAgfSBlbHNlIGlmIChlbmQgPiBsZW4pIHtcbiAgICBlbmQgPSBsZW5cbiAgfVxuXG4gIGlmIChlbmQgPCBzdGFydCkgZW5kID0gc3RhcnRcblxuICB2YXIgbmV3QnVmXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIG5ld0J1ZiA9IEJ1ZmZlci5fYXVnbWVudCh0aGlzLnN1YmFycmF5KHN0YXJ0LCBlbmQpKVxuICB9IGVsc2Uge1xuICAgIHZhciBzbGljZUxlbiA9IGVuZCAtIHN0YXJ0XG4gICAgbmV3QnVmID0gbmV3IEJ1ZmZlcihzbGljZUxlbiwgdW5kZWZpbmVkKVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2xpY2VMZW47IGkrKykge1xuICAgICAgbmV3QnVmW2ldID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9XG5cbiAgaWYgKG5ld0J1Zi5sZW5ndGgpIG5ld0J1Zi5wYXJlbnQgPSB0aGlzLnBhcmVudCB8fCB0aGlzXG5cbiAgcmV0dXJuIG5ld0J1ZlxufVxuXG4vKlxuICogTmVlZCB0byBtYWtlIHN1cmUgdGhhdCBidWZmZXIgaXNuJ3QgdHJ5aW5nIHRvIHdyaXRlIG91dCBvZiBib3VuZHMuXG4gKi9cbmZ1bmN0aW9uIGNoZWNrT2Zmc2V0IChvZmZzZXQsIGV4dCwgbGVuZ3RoKSB7XG4gIGlmICgob2Zmc2V0ICUgMSkgIT09IDAgfHwgb2Zmc2V0IDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ29mZnNldCBpcyBub3QgdWludCcpXG4gIGlmIChvZmZzZXQgKyBleHQgPiBsZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdUcnlpbmcgdG8gYWNjZXNzIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludExFID0gZnVuY3Rpb24gcmVhZFVJbnRMRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIGJ5dGVMZW5ndGgsIHRoaXMubGVuZ3RoKVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldF1cbiAgdmFyIG11bCA9IDFcbiAgdmFyIGkgPSAwXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgaV0gKiBtdWxcbiAgfVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludEJFID0gZnVuY3Rpb24gcmVhZFVJbnRCRSAob2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoIHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcbiAgfVxuXG4gIHZhciB2YWwgPSB0aGlzW29mZnNldCArIC0tYnl0ZUxlbmd0aF1cbiAgdmFyIG11bCA9IDFcbiAgd2hpbGUgKGJ5dGVMZW5ndGggPiAwICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgLS1ieXRlTGVuZ3RoXSAqIG11bFxuICB9XG5cbiAgcmV0dXJuIHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50OCA9IGZ1bmN0aW9uIHJlYWRVSW50OCAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDEsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gdGhpc1tvZmZzZXRdXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkxFID0gZnVuY3Rpb24gcmVhZFVJbnQxNkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiB0aGlzW29mZnNldF0gfCAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZCRSA9IGZ1bmN0aW9uIHJlYWRVSW50MTZCRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSA8PCA4KSB8IHRoaXNbb2Zmc2V0ICsgMV1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyTEUgPSBmdW5jdGlvbiByZWFkVUludDMyTEUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKCh0aGlzW29mZnNldF0pIHxcbiAgICAgICh0aGlzW29mZnNldCArIDFdIDw8IDgpIHxcbiAgICAgICh0aGlzW29mZnNldCArIDJdIDw8IDE2KSkgK1xuICAgICAgKHRoaXNbb2Zmc2V0ICsgM10gKiAweDEwMDAwMDApXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkJFID0gZnVuY3Rpb24gcmVhZFVJbnQzMkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0gKiAweDEwMDAwMDApICtcbiAgICAoKHRoaXNbb2Zmc2V0ICsgMV0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAyXSA8PCA4KSB8XG4gICAgdGhpc1tvZmZzZXQgKyAzXSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50TEUgPSBmdW5jdGlvbiByZWFkSW50TEUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHZhbCArPSB0aGlzW29mZnNldCArIGldICogbXVsXG4gIH1cbiAgbXVsICo9IDB4ODBcblxuICBpZiAodmFsID49IG11bCkgdmFsIC09IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50QkUgPSBmdW5jdGlvbiByZWFkSW50QkUgKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgaSA9IGJ5dGVMZW5ndGhcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgLS1pXVxuICB3aGlsZSAoaSA+IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyAtLWldICogbXVsXG4gIH1cbiAgbXVsICo9IDB4ODBcblxuICBpZiAodmFsID49IG11bCkgdmFsIC09IE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKVxuXG4gIHJldHVybiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50OCA9IGZ1bmN0aW9uIHJlYWRJbnQ4IChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgMSwgdGhpcy5sZW5ndGgpXG4gIGlmICghKHRoaXNbb2Zmc2V0XSAmIDB4ODApKSByZXR1cm4gKHRoaXNbb2Zmc2V0XSlcbiAgcmV0dXJuICgoMHhmZiAtIHRoaXNbb2Zmc2V0XSArIDEpICogLTEpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2TEUgPSBmdW5jdGlvbiByZWFkSW50MTZMRSAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdIHwgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOClcbiAgcmV0dXJuICh2YWwgJiAweDgwMDApID8gdmFsIHwgMHhGRkZGMDAwMCA6IHZhbFxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkJFID0gZnVuY3Rpb24gcmVhZEludDE2QkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgMV0gfCAodGhpc1tvZmZzZXRdIDw8IDgpXG4gIHJldHVybiAodmFsICYgMHg4MDAwKSA/IHZhbCB8IDB4RkZGRjAwMDAgOiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJMRSA9IGZ1bmN0aW9uIHJlYWRJbnQzMkxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0pIHxcbiAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCA4KSB8XG4gICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgMTYpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAzXSA8PCAyNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJCRSA9IGZ1bmN0aW9uIHJlYWRJbnQzMkJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG5cbiAgcmV0dXJuICh0aGlzW29mZnNldF0gPDwgMjQpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCAxNikgfFxuICAgICh0aGlzW29mZnNldCArIDJdIDw8IDgpIHxcbiAgICAodGhpc1tvZmZzZXQgKyAzXSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRMRSA9IGZ1bmN0aW9uIHJlYWRGbG9hdExFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCB0cnVlLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRCRSA9IGZ1bmN0aW9uIHJlYWRGbG9hdEJFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCBmYWxzZSwgMjMsIDQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUxFID0gZnVuY3Rpb24gcmVhZERvdWJsZUxFIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrT2Zmc2V0KG9mZnNldCwgOCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCB0cnVlLCA1MiwgOClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlQkUgPSBmdW5jdGlvbiByZWFkRG91YmxlQkUgKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tPZmZzZXQob2Zmc2V0LCA4LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIGZhbHNlLCA1MiwgOClcbn1cblxuZnVuY3Rpb24gY2hlY2tJbnQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgZXh0LCBtYXgsIG1pbikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihidWYpKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdidWZmZXIgbXVzdCBiZSBhIEJ1ZmZlciBpbnN0YW5jZScpXG4gIGlmICh2YWx1ZSA+IG1heCB8fCB2YWx1ZSA8IG1pbikgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3ZhbHVlIGlzIG91dCBvZiBib3VuZHMnKVxuICBpZiAob2Zmc2V0ICsgZXh0ID4gYnVmLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2luZGV4IG91dCBvZiByYW5nZScpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50TEUgPSBmdW5jdGlvbiB3cml0ZVVJbnRMRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpLCAwKVxuXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB0aGlzW29mZnNldF0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKHZhbHVlIC8gbXVsKSAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50QkUgPSBmdW5jdGlvbiB3cml0ZVVJbnRCRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpLCAwKVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aCAtIDFcbiAgdmFyIG11bCA9IDFcbiAgdGhpc1tvZmZzZXQgKyBpXSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoLS1pID49IDAgJiYgKG11bCAqPSAweDEwMCkpIHtcbiAgICB0aGlzW29mZnNldCArIGldID0gKHZhbHVlIC8gbXVsKSAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50OCA9IGZ1bmN0aW9uIHdyaXRlVUludDggKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCB8IDBcbiAgaWYgKCFub0Fzc2VydCkgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMSwgMHhmZiwgMClcbiAgaWYgKCFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkgdmFsdWUgPSBNYXRoLmZsb29yKHZhbHVlKVxuICB0aGlzW29mZnNldF0gPSB2YWx1ZVxuICByZXR1cm4gb2Zmc2V0ICsgMVxufVxuXG5mdW5jdGlvbiBvYmplY3RXcml0ZVVJbnQxNiAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmYgKyB2YWx1ZSArIDFcbiAgZm9yICh2YXIgaSA9IDAsIGogPSBNYXRoLm1pbihidWYubGVuZ3RoIC0gb2Zmc2V0LCAyKTsgaSA8IGo7IGkrKykge1xuICAgIGJ1ZltvZmZzZXQgKyBpXSA9ICh2YWx1ZSAmICgweGZmIDw8ICg4ICogKGxpdHRsZUVuZGlhbiA/IGkgOiAxIC0gaSkpKSkgPj4+XG4gICAgICAobGl0dGxlRW5kaWFuID8gaSA6IDEgLSBpKSAqIDhcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2TEUgPSBmdW5jdGlvbiB3cml0ZVVJbnQxNkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4ZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gdmFsdWVcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIH1cbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkJFID0gZnVuY3Rpb24gd3JpdGVVSW50MTZCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweGZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDFdID0gdmFsdWVcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgMlxufVxuXG5mdW5jdGlvbiBvYmplY3RXcml0ZVVJbnQzMiAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmZmZmZmICsgdmFsdWUgKyAxXG4gIGZvciAodmFyIGkgPSAwLCBqID0gTWF0aC5taW4oYnVmLmxlbmd0aCAtIG9mZnNldCwgNCk7IGkgPCBqOyBpKyspIHtcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSAodmFsdWUgPj4+IChsaXR0bGVFbmRpYW4gPyBpIDogMyAtIGkpICogOCkgJiAweGZmXG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkxFID0gZnVuY3Rpb24gd3JpdGVVSW50MzJMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweGZmZmZmZmZmLCAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0XSA9IHZhbHVlXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyQkUgPSBmdW5jdGlvbiB3cml0ZVVJbnQzMkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4ZmZmZmZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDNdID0gdmFsdWVcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50TEUgPSBmdW5jdGlvbiB3cml0ZUludExFICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICB2YXIgbGltaXQgPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCAtIDEpXG5cbiAgICBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBsaW1pdCAtIDEsIC1saW1pdClcbiAgfVxuXG4gIHZhciBpID0gMFxuICB2YXIgbXVsID0gMVxuICB2YXIgc3ViID0gdmFsdWUgPCAwID8gMSA6IDBcbiAgdGhpc1tvZmZzZXRdID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKSB7XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICgodmFsdWUgLyBtdWwpID4+IDApIC0gc3ViICYgMHhGRlxuICB9XG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludEJFID0gZnVuY3Rpb24gd3JpdGVJbnRCRSAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgdmFyIGxpbWl0ID0gTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGggLSAxKVxuXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbGltaXQgLSAxLCAtbGltaXQpXG4gIH1cblxuICB2YXIgaSA9IGJ5dGVMZW5ndGggLSAxXG4gIHZhciBtdWwgPSAxXG4gIHZhciBzdWIgPSB2YWx1ZSA8IDAgPyAxIDogMFxuICB0aGlzW29mZnNldCArIGldID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgtLWkgPj0gMCAmJiAobXVsICo9IDB4MTAwKSkge1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAoKHZhbHVlIC8gbXVsKSA+PiAwKSAtIHN1YiAmIDB4RkZcbiAgfVxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQ4ID0gZnVuY3Rpb24gd3JpdGVJbnQ4ICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDEsIDB4N2YsIC0weDgwKVxuICBpZiAoIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB2YWx1ZSA9IE1hdGguZmxvb3IodmFsdWUpXG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZiArIHZhbHVlICsgMVxuICB0aGlzW29mZnNldF0gPSB2YWx1ZVxuICByZXR1cm4gb2Zmc2V0ICsgMVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MTZMRSA9IGZ1bmN0aW9uIHdyaXRlSW50MTZMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCAyLCAweDdmZmYsIC0weDgwMDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9IHZhbHVlXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkJFID0gZnVuY3Rpb24gd3JpdGVJbnQxNkJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4N2ZmZiwgLTB4ODAwMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSB2YWx1ZVxuICB9IGVsc2Uge1xuICAgIG9iamVjdFdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICB9XG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkxFID0gZnVuY3Rpb24gd3JpdGVJbnQzMkxFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgfCAwXG4gIGlmICghbm9Bc3NlcnQpIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4N2ZmZmZmZmYsIC0weDgwMDAwMDAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSB2YWx1ZVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSA+Pj4gMjQpXG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJCRSA9IGZ1bmN0aW9uIHdyaXRlSW50MzJCRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0IHwgMFxuICBpZiAoIW5vQXNzZXJ0KSBjaGVja0ludCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCA0LCAweDdmZmZmZmZmLCAtMHg4MDAwMDAwMClcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmZmZmZmZmICsgdmFsdWUgKyAxXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDNdID0gdmFsdWVcbiAgfSBlbHNlIHtcbiAgICBvYmplY3RXcml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgfVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5mdW5jdGlvbiBjaGVja0lFRUU3NTQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgZXh0LCBtYXgsIG1pbikge1xuICBpZiAodmFsdWUgPiBtYXggfHwgdmFsdWUgPCBtaW4pIHRocm93IG5ldyBSYW5nZUVycm9yKCd2YWx1ZSBpcyBvdXQgb2YgYm91bmRzJylcbiAgaWYgKG9mZnNldCArIGV4dCA+IGJ1Zi5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdpbmRleCBvdXQgb2YgcmFuZ2UnKVxuICBpZiAob2Zmc2V0IDwgMCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2luZGV4IG91dCBvZiByYW5nZScpXG59XG5cbmZ1bmN0aW9uIHdyaXRlRmxvYXQgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgNCwgMy40MDI4MjM0NjYzODUyODg2ZSszOCwgLTMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgpXG4gIH1cbiAgaWVlZTc1NC53cml0ZShidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgMjMsIDQpXG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdExFID0gZnVuY3Rpb24gd3JpdGVGbG9hdExFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0QkUgPSBmdW5jdGlvbiB3cml0ZUZsb2F0QkUgKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiB3cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gd3JpdGVEb3VibGUgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgOCwgMS43OTc2OTMxMzQ4NjIzMTU3RSszMDgsIC0xLjc5NzY5MzEzNDg2MjMxNTdFKzMwOClcbiAgfVxuICBpZWVlNzU0LndyaXRlKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCA1MiwgOClcbiAgcmV0dXJuIG9mZnNldCArIDhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZURvdWJsZUxFID0gZnVuY3Rpb24gd3JpdGVEb3VibGVMRSAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRG91YmxlKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlQkUgPSBmdW5jdGlvbiB3cml0ZURvdWJsZUJFICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG4vLyBjb3B5KHRhcmdldEJ1ZmZlciwgdGFyZ2V0U3RhcnQ9MCwgc291cmNlU3RhcnQ9MCwgc291cmNlRW5kPWJ1ZmZlci5sZW5ndGgpXG5CdWZmZXIucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbiBjb3B5ICh0YXJnZXQsIHRhcmdldFN0YXJ0LCBzdGFydCwgZW5kKSB7XG4gIGlmICghc3RhcnQpIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCAmJiBlbmQgIT09IDApIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmICh0YXJnZXRTdGFydCA+PSB0YXJnZXQubGVuZ3RoKSB0YXJnZXRTdGFydCA9IHRhcmdldC5sZW5ndGhcbiAgaWYgKCF0YXJnZXRTdGFydCkgdGFyZ2V0U3RhcnQgPSAwXG4gIGlmIChlbmQgPiAwICYmIGVuZCA8IHN0YXJ0KSBlbmQgPSBzdGFydFxuXG4gIC8vIENvcHkgMCBieXRlczsgd2UncmUgZG9uZVxuICBpZiAoZW5kID09PSBzdGFydCkgcmV0dXJuIDBcbiAgaWYgKHRhcmdldC5sZW5ndGggPT09IDAgfHwgdGhpcy5sZW5ndGggPT09IDApIHJldHVybiAwXG5cbiAgLy8gRmF0YWwgZXJyb3IgY29uZGl0aW9uc1xuICBpZiAodGFyZ2V0U3RhcnQgPCAwKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3RhcmdldFN0YXJ0IG91dCBvZiBib3VuZHMnKVxuICB9XG4gIGlmIChzdGFydCA8IDAgfHwgc3RhcnQgPj0gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdzb3VyY2VTdGFydCBvdXQgb2YgYm91bmRzJylcbiAgaWYgKGVuZCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdzb3VyY2VFbmQgb3V0IG9mIGJvdW5kcycpXG5cbiAgLy8gQXJlIHdlIG9vYj9cbiAgaWYgKGVuZCA+IHRoaXMubGVuZ3RoKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAodGFyZ2V0Lmxlbmd0aCAtIHRhcmdldFN0YXJ0IDwgZW5kIC0gc3RhcnQpIHtcbiAgICBlbmQgPSB0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0U3RhcnQgKyBzdGFydFxuICB9XG5cbiAgdmFyIGxlbiA9IGVuZCAtIHN0YXJ0XG4gIHZhciBpXG5cbiAgaWYgKHRoaXMgPT09IHRhcmdldCAmJiBzdGFydCA8IHRhcmdldFN0YXJ0ICYmIHRhcmdldFN0YXJ0IDwgZW5kKSB7XG4gICAgLy8gZGVzY2VuZGluZyBjb3B5IGZyb20gZW5kXG4gICAgZm9yIChpID0gbGVuIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIHRhcmdldFtpICsgdGFyZ2V0U3RhcnRdID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9IGVsc2UgaWYgKGxlbiA8IDEwMDAgfHwgIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgLy8gYXNjZW5kaW5nIGNvcHkgZnJvbSBzdGFydFxuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgdGFyZ2V0W2kgKyB0YXJnZXRTdGFydF0gPSB0aGlzW2kgKyBzdGFydF1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGFyZ2V0Ll9zZXQodGhpcy5zdWJhcnJheShzdGFydCwgc3RhcnQgKyBsZW4pLCB0YXJnZXRTdGFydClcbiAgfVxuXG4gIHJldHVybiBsZW5cbn1cblxuLy8gZmlsbCh2YWx1ZSwgc3RhcnQ9MCwgZW5kPWJ1ZmZlci5sZW5ndGgpXG5CdWZmZXIucHJvdG90eXBlLmZpbGwgPSBmdW5jdGlvbiBmaWxsICh2YWx1ZSwgc3RhcnQsIGVuZCkge1xuICBpZiAoIXZhbHVlKSB2YWx1ZSA9IDBcbiAgaWYgKCFzdGFydCkgc3RhcnQgPSAwXG4gIGlmICghZW5kKSBlbmQgPSB0aGlzLmxlbmd0aFxuXG4gIGlmIChlbmQgPCBzdGFydCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2VuZCA8IHN0YXJ0JylcblxuICAvLyBGaWxsIDAgYnl0ZXM7IHdlJ3JlIGRvbmVcbiAgaWYgKGVuZCA9PT0gc3RhcnQpIHJldHVyblxuICBpZiAodGhpcy5sZW5ndGggPT09IDApIHJldHVyblxuXG4gIGlmIChzdGFydCA8IDAgfHwgc3RhcnQgPj0gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdzdGFydCBvdXQgb2YgYm91bmRzJylcbiAgaWYgKGVuZCA8IDAgfHwgZW5kID4gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdlbmQgb3V0IG9mIGJvdW5kcycpXG5cbiAgdmFyIGlcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgICB0aGlzW2ldID0gdmFsdWVcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIGJ5dGVzID0gdXRmOFRvQnl0ZXModmFsdWUudG9TdHJpbmcoKSlcbiAgICB2YXIgbGVuID0gYnl0ZXMubGVuZ3RoXG4gICAgZm9yIChpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgICAgdGhpc1tpXSA9IGJ5dGVzW2kgJSBsZW5dXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGBBcnJheUJ1ZmZlcmAgd2l0aCB0aGUgKmNvcGllZCogbWVtb3J5IG9mIHRoZSBidWZmZXIgaW5zdGFuY2UuXG4gKiBBZGRlZCBpbiBOb2RlIDAuMTIuIE9ubHkgYXZhaWxhYmxlIGluIGJyb3dzZXJzIHRoYXQgc3VwcG9ydCBBcnJheUJ1ZmZlci5cbiAqL1xuQnVmZmVyLnByb3RvdHlwZS50b0FycmF5QnVmZmVyID0gZnVuY3Rpb24gdG9BcnJheUJ1ZmZlciAoKSB7XG4gIGlmICh0eXBlb2YgVWludDhBcnJheSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICAgIHJldHVybiAobmV3IEJ1ZmZlcih0aGlzKSkuYnVmZmVyXG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBidWYgPSBuZXcgVWludDhBcnJheSh0aGlzLmxlbmd0aClcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBidWYubGVuZ3RoOyBpIDwgbGVuOyBpICs9IDEpIHtcbiAgICAgICAgYnVmW2ldID0gdGhpc1tpXVxuICAgICAgfVxuICAgICAgcmV0dXJuIGJ1Zi5idWZmZXJcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQnVmZmVyLnRvQXJyYXlCdWZmZXIgbm90IHN1cHBvcnRlZCBpbiB0aGlzIGJyb3dzZXInKVxuICB9XG59XG5cbi8vIEhFTFBFUiBGVU5DVElPTlNcbi8vID09PT09PT09PT09PT09PT1cblxudmFyIEJQID0gQnVmZmVyLnByb3RvdHlwZVxuXG4vKipcbiAqIEF1Z21lbnQgYSBVaW50OEFycmF5ICppbnN0YW5jZSogKG5vdCB0aGUgVWludDhBcnJheSBjbGFzcyEpIHdpdGggQnVmZmVyIG1ldGhvZHNcbiAqL1xuQnVmZmVyLl9hdWdtZW50ID0gZnVuY3Rpb24gX2F1Z21lbnQgKGFycikge1xuICBhcnIuY29uc3RydWN0b3IgPSBCdWZmZXJcbiAgYXJyLl9pc0J1ZmZlciA9IHRydWVcblxuICAvLyBzYXZlIHJlZmVyZW5jZSB0byBvcmlnaW5hbCBVaW50OEFycmF5IHNldCBtZXRob2QgYmVmb3JlIG92ZXJ3cml0aW5nXG4gIGFyci5fc2V0ID0gYXJyLnNldFxuXG4gIC8vIGRlcHJlY2F0ZWRcbiAgYXJyLmdldCA9IEJQLmdldFxuICBhcnIuc2V0ID0gQlAuc2V0XG5cbiAgYXJyLndyaXRlID0gQlAud3JpdGVcbiAgYXJyLnRvU3RyaW5nID0gQlAudG9TdHJpbmdcbiAgYXJyLnRvTG9jYWxlU3RyaW5nID0gQlAudG9TdHJpbmdcbiAgYXJyLnRvSlNPTiA9IEJQLnRvSlNPTlxuICBhcnIuZXF1YWxzID0gQlAuZXF1YWxzXG4gIGFyci5jb21wYXJlID0gQlAuY29tcGFyZVxuICBhcnIuaW5kZXhPZiA9IEJQLmluZGV4T2ZcbiAgYXJyLmNvcHkgPSBCUC5jb3B5XG4gIGFyci5zbGljZSA9IEJQLnNsaWNlXG4gIGFyci5yZWFkVUludExFID0gQlAucmVhZFVJbnRMRVxuICBhcnIucmVhZFVJbnRCRSA9IEJQLnJlYWRVSW50QkVcbiAgYXJyLnJlYWRVSW50OCA9IEJQLnJlYWRVSW50OFxuICBhcnIucmVhZFVJbnQxNkxFID0gQlAucmVhZFVJbnQxNkxFXG4gIGFyci5yZWFkVUludDE2QkUgPSBCUC5yZWFkVUludDE2QkVcbiAgYXJyLnJlYWRVSW50MzJMRSA9IEJQLnJlYWRVSW50MzJMRVxuICBhcnIucmVhZFVJbnQzMkJFID0gQlAucmVhZFVJbnQzMkJFXG4gIGFyci5yZWFkSW50TEUgPSBCUC5yZWFkSW50TEVcbiAgYXJyLnJlYWRJbnRCRSA9IEJQLnJlYWRJbnRCRVxuICBhcnIucmVhZEludDggPSBCUC5yZWFkSW50OFxuICBhcnIucmVhZEludDE2TEUgPSBCUC5yZWFkSW50MTZMRVxuICBhcnIucmVhZEludDE2QkUgPSBCUC5yZWFkSW50MTZCRVxuICBhcnIucmVhZEludDMyTEUgPSBCUC5yZWFkSW50MzJMRVxuICBhcnIucmVhZEludDMyQkUgPSBCUC5yZWFkSW50MzJCRVxuICBhcnIucmVhZEZsb2F0TEUgPSBCUC5yZWFkRmxvYXRMRVxuICBhcnIucmVhZEZsb2F0QkUgPSBCUC5yZWFkRmxvYXRCRVxuICBhcnIucmVhZERvdWJsZUxFID0gQlAucmVhZERvdWJsZUxFXG4gIGFyci5yZWFkRG91YmxlQkUgPSBCUC5yZWFkRG91YmxlQkVcbiAgYXJyLndyaXRlVUludDggPSBCUC53cml0ZVVJbnQ4XG4gIGFyci53cml0ZVVJbnRMRSA9IEJQLndyaXRlVUludExFXG4gIGFyci53cml0ZVVJbnRCRSA9IEJQLndyaXRlVUludEJFXG4gIGFyci53cml0ZVVJbnQxNkxFID0gQlAud3JpdGVVSW50MTZMRVxuICBhcnIud3JpdGVVSW50MTZCRSA9IEJQLndyaXRlVUludDE2QkVcbiAgYXJyLndyaXRlVUludDMyTEUgPSBCUC53cml0ZVVJbnQzMkxFXG4gIGFyci53cml0ZVVJbnQzMkJFID0gQlAud3JpdGVVSW50MzJCRVxuICBhcnIud3JpdGVJbnRMRSA9IEJQLndyaXRlSW50TEVcbiAgYXJyLndyaXRlSW50QkUgPSBCUC53cml0ZUludEJFXG4gIGFyci53cml0ZUludDggPSBCUC53cml0ZUludDhcbiAgYXJyLndyaXRlSW50MTZMRSA9IEJQLndyaXRlSW50MTZMRVxuICBhcnIud3JpdGVJbnQxNkJFID0gQlAud3JpdGVJbnQxNkJFXG4gIGFyci53cml0ZUludDMyTEUgPSBCUC53cml0ZUludDMyTEVcbiAgYXJyLndyaXRlSW50MzJCRSA9IEJQLndyaXRlSW50MzJCRVxuICBhcnIud3JpdGVGbG9hdExFID0gQlAud3JpdGVGbG9hdExFXG4gIGFyci53cml0ZUZsb2F0QkUgPSBCUC53cml0ZUZsb2F0QkVcbiAgYXJyLndyaXRlRG91YmxlTEUgPSBCUC53cml0ZURvdWJsZUxFXG4gIGFyci53cml0ZURvdWJsZUJFID0gQlAud3JpdGVEb3VibGVCRVxuICBhcnIuZmlsbCA9IEJQLmZpbGxcbiAgYXJyLmluc3BlY3QgPSBCUC5pbnNwZWN0XG4gIGFyci50b0FycmF5QnVmZmVyID0gQlAudG9BcnJheUJ1ZmZlclxuXG4gIHJldHVybiBhcnJcbn1cblxudmFyIElOVkFMSURfQkFTRTY0X1JFID0gL1teK1xcLzAtOUEtWmEtei1fXS9nXG5cbmZ1bmN0aW9uIGJhc2U2NGNsZWFuIChzdHIpIHtcbiAgLy8gTm9kZSBzdHJpcHMgb3V0IGludmFsaWQgY2hhcmFjdGVycyBsaWtlIFxcbiBhbmQgXFx0IGZyb20gdGhlIHN0cmluZywgYmFzZTY0LWpzIGRvZXMgbm90XG4gIHN0ciA9IHN0cmluZ3RyaW0oc3RyKS5yZXBsYWNlKElOVkFMSURfQkFTRTY0X1JFLCAnJylcbiAgLy8gTm9kZSBjb252ZXJ0cyBzdHJpbmdzIHdpdGggbGVuZ3RoIDwgMiB0byAnJ1xuICBpZiAoc3RyLmxlbmd0aCA8IDIpIHJldHVybiAnJ1xuICAvLyBOb2RlIGFsbG93cyBmb3Igbm9uLXBhZGRlZCBiYXNlNjQgc3RyaW5ncyAobWlzc2luZyB0cmFpbGluZyA9PT0pLCBiYXNlNjQtanMgZG9lcyBub3RcbiAgd2hpbGUgKHN0ci5sZW5ndGggJSA0ICE9PSAwKSB7XG4gICAgc3RyID0gc3RyICsgJz0nXG4gIH1cbiAgcmV0dXJuIHN0clxufVxuXG5mdW5jdGlvbiBzdHJpbmd0cmltIChzdHIpIHtcbiAgaWYgKHN0ci50cmltKSByZXR1cm4gc3RyLnRyaW0oKVxuICByZXR1cm4gc3RyLnJlcGxhY2UoL15cXHMrfFxccyskL2csICcnKVxufVxuXG5mdW5jdGlvbiB0b0hleCAobikge1xuICBpZiAobiA8IDE2KSByZXR1cm4gJzAnICsgbi50b1N0cmluZygxNilcbiAgcmV0dXJuIG4udG9TdHJpbmcoMTYpXG59XG5cbmZ1bmN0aW9uIHV0ZjhUb0J5dGVzIChzdHJpbmcsIHVuaXRzKSB7XG4gIHVuaXRzID0gdW5pdHMgfHwgSW5maW5pdHlcbiAgdmFyIGNvZGVQb2ludFxuICB2YXIgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aFxuICB2YXIgbGVhZFN1cnJvZ2F0ZSA9IG51bGxcbiAgdmFyIGJ5dGVzID0gW11cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgY29kZVBvaW50ID0gc3RyaW5nLmNoYXJDb2RlQXQoaSlcblxuICAgIC8vIGlzIHN1cnJvZ2F0ZSBjb21wb25lbnRcbiAgICBpZiAoY29kZVBvaW50ID4gMHhEN0ZGICYmIGNvZGVQb2ludCA8IDB4RTAwMCkge1xuICAgICAgLy8gbGFzdCBjaGFyIHdhcyBhIGxlYWRcbiAgICAgIGlmICghbGVhZFN1cnJvZ2F0ZSkge1xuICAgICAgICAvLyBubyBsZWFkIHlldFxuICAgICAgICBpZiAoY29kZVBvaW50ID4gMHhEQkZGKSB7XG4gICAgICAgICAgLy8gdW5leHBlY3RlZCB0cmFpbFxuICAgICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH0gZWxzZSBpZiAoaSArIDEgPT09IGxlbmd0aCkge1xuICAgICAgICAgIC8vIHVucGFpcmVkIGxlYWRcbiAgICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gdmFsaWQgbGVhZFxuICAgICAgICBsZWFkU3Vycm9nYXRlID0gY29kZVBvaW50XG5cbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgLy8gMiBsZWFkcyBpbiBhIHJvd1xuICAgICAgaWYgKGNvZGVQb2ludCA8IDB4REMwMCkge1xuICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgbGVhZFN1cnJvZ2F0ZSA9IGNvZGVQb2ludFxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICAvLyB2YWxpZCBzdXJyb2dhdGUgcGFpclxuICAgICAgY29kZVBvaW50ID0gbGVhZFN1cnJvZ2F0ZSAtIDB4RDgwMCA8PCAxMCB8IGNvZGVQb2ludCAtIDB4REMwMCB8IDB4MTAwMDBcbiAgICB9IGVsc2UgaWYgKGxlYWRTdXJyb2dhdGUpIHtcbiAgICAgIC8vIHZhbGlkIGJtcCBjaGFyLCBidXQgbGFzdCBjaGFyIHdhcyBhIGxlYWRcbiAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgIH1cblxuICAgIGxlYWRTdXJyb2dhdGUgPSBudWxsXG5cbiAgICAvLyBlbmNvZGUgdXRmOFxuICAgIGlmIChjb2RlUG9pbnQgPCAweDgwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDEpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goY29kZVBvaW50KVxuICAgIH0gZWxzZSBpZiAoY29kZVBvaW50IDwgMHg4MDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMikgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiB8IDB4QzAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDEwMDAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDMpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgfCAweEUwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2ICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApXG4gICAgfSBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDExMDAwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSA0KSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHgxMiB8IDB4RjAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY29kZSBwb2ludCcpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVzXG59XG5cbmZ1bmN0aW9uIGFzY2lpVG9CeXRlcyAoc3RyKSB7XG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykge1xuICAgIC8vIE5vZGUncyBjb2RlIHNlZW1zIHRvIGJlIGRvaW5nIHRoaXMgYW5kIG5vdCAmIDB4N0YuLlxuICAgIGJ5dGVBcnJheS5wdXNoKHN0ci5jaGFyQ29kZUF0KGkpICYgMHhGRilcbiAgfVxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVUb0J5dGVzIChzdHIsIHVuaXRzKSB7XG4gIHZhciBjLCBoaSwgbG9cbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKCh1bml0cyAtPSAyKSA8IDApIGJyZWFrXG5cbiAgICBjID0gc3RyLmNoYXJDb2RlQXQoaSlcbiAgICBoaSA9IGMgPj4gOFxuICAgIGxvID0gYyAlIDI1NlxuICAgIGJ5dGVBcnJheS5wdXNoKGxvKVxuICAgIGJ5dGVBcnJheS5wdXNoKGhpKVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5mdW5jdGlvbiBiYXNlNjRUb0J5dGVzIChzdHIpIHtcbiAgcmV0dXJuIGJhc2U2NC50b0J5dGVBcnJheShiYXNlNjRjbGVhbihzdHIpKVxufVxuXG5mdW5jdGlvbiBibGl0QnVmZmVyIChzcmMsIGRzdCwgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgIGlmICgoaSArIG9mZnNldCA+PSBkc3QubGVuZ3RoKSB8fCAoaSA+PSBzcmMubGVuZ3RoKSkgYnJlYWtcbiAgICBkc3RbaSArIG9mZnNldF0gPSBzcmNbaV1cbiAgfVxuICByZXR1cm4gaVxufVxuIiwidmFyIGxvb2t1cCA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvJztcblxuOyhmdW5jdGlvbiAoZXhwb3J0cykge1xuXHQndXNlIHN0cmljdCc7XG5cbiAgdmFyIEFyciA9ICh0eXBlb2YgVWludDhBcnJheSAhPT0gJ3VuZGVmaW5lZCcpXG4gICAgPyBVaW50OEFycmF5XG4gICAgOiBBcnJheVxuXG5cdHZhciBQTFVTICAgPSAnKycuY2hhckNvZGVBdCgwKVxuXHR2YXIgU0xBU0ggID0gJy8nLmNoYXJDb2RlQXQoMClcblx0dmFyIE5VTUJFUiA9ICcwJy5jaGFyQ29kZUF0KDApXG5cdHZhciBMT1dFUiAgPSAnYScuY2hhckNvZGVBdCgwKVxuXHR2YXIgVVBQRVIgID0gJ0EnLmNoYXJDb2RlQXQoMClcblx0dmFyIFBMVVNfVVJMX1NBRkUgPSAnLScuY2hhckNvZGVBdCgwKVxuXHR2YXIgU0xBU0hfVVJMX1NBRkUgPSAnXycuY2hhckNvZGVBdCgwKVxuXG5cdGZ1bmN0aW9uIGRlY29kZSAoZWx0KSB7XG5cdFx0dmFyIGNvZGUgPSBlbHQuY2hhckNvZGVBdCgwKVxuXHRcdGlmIChjb2RlID09PSBQTFVTIHx8XG5cdFx0ICAgIGNvZGUgPT09IFBMVVNfVVJMX1NBRkUpXG5cdFx0XHRyZXR1cm4gNjIgLy8gJysnXG5cdFx0aWYgKGNvZGUgPT09IFNMQVNIIHx8XG5cdFx0ICAgIGNvZGUgPT09IFNMQVNIX1VSTF9TQUZFKVxuXHRcdFx0cmV0dXJuIDYzIC8vICcvJ1xuXHRcdGlmIChjb2RlIDwgTlVNQkVSKVxuXHRcdFx0cmV0dXJuIC0xIC8vbm8gbWF0Y2hcblx0XHRpZiAoY29kZSA8IE5VTUJFUiArIDEwKVxuXHRcdFx0cmV0dXJuIGNvZGUgLSBOVU1CRVIgKyAyNiArIDI2XG5cdFx0aWYgKGNvZGUgPCBVUFBFUiArIDI2KVxuXHRcdFx0cmV0dXJuIGNvZGUgLSBVUFBFUlxuXHRcdGlmIChjb2RlIDwgTE9XRVIgKyAyNilcblx0XHRcdHJldHVybiBjb2RlIC0gTE9XRVIgKyAyNlxuXHR9XG5cblx0ZnVuY3Rpb24gYjY0VG9CeXRlQXJyYXkgKGI2NCkge1xuXHRcdHZhciBpLCBqLCBsLCB0bXAsIHBsYWNlSG9sZGVycywgYXJyXG5cblx0XHRpZiAoYjY0Lmxlbmd0aCAlIDQgPiAwKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc3RyaW5nLiBMZW5ndGggbXVzdCBiZSBhIG11bHRpcGxlIG9mIDQnKVxuXHRcdH1cblxuXHRcdC8vIHRoZSBudW1iZXIgb2YgZXF1YWwgc2lnbnMgKHBsYWNlIGhvbGRlcnMpXG5cdFx0Ly8gaWYgdGhlcmUgYXJlIHR3byBwbGFjZWhvbGRlcnMsIHRoYW4gdGhlIHR3byBjaGFyYWN0ZXJzIGJlZm9yZSBpdFxuXHRcdC8vIHJlcHJlc2VudCBvbmUgYnl0ZVxuXHRcdC8vIGlmIHRoZXJlIGlzIG9ubHkgb25lLCB0aGVuIHRoZSB0aHJlZSBjaGFyYWN0ZXJzIGJlZm9yZSBpdCByZXByZXNlbnQgMiBieXRlc1xuXHRcdC8vIHRoaXMgaXMganVzdCBhIGNoZWFwIGhhY2sgdG8gbm90IGRvIGluZGV4T2YgdHdpY2Vcblx0XHR2YXIgbGVuID0gYjY0Lmxlbmd0aFxuXHRcdHBsYWNlSG9sZGVycyA9ICc9JyA9PT0gYjY0LmNoYXJBdChsZW4gLSAyKSA/IDIgOiAnPScgPT09IGI2NC5jaGFyQXQobGVuIC0gMSkgPyAxIDogMFxuXG5cdFx0Ly8gYmFzZTY0IGlzIDQvMyArIHVwIHRvIHR3byBjaGFyYWN0ZXJzIG9mIHRoZSBvcmlnaW5hbCBkYXRhXG5cdFx0YXJyID0gbmV3IEFycihiNjQubGVuZ3RoICogMyAvIDQgLSBwbGFjZUhvbGRlcnMpXG5cblx0XHQvLyBpZiB0aGVyZSBhcmUgcGxhY2Vob2xkZXJzLCBvbmx5IGdldCB1cCB0byB0aGUgbGFzdCBjb21wbGV0ZSA0IGNoYXJzXG5cdFx0bCA9IHBsYWNlSG9sZGVycyA+IDAgPyBiNjQubGVuZ3RoIC0gNCA6IGI2NC5sZW5ndGhcblxuXHRcdHZhciBMID0gMFxuXG5cdFx0ZnVuY3Rpb24gcHVzaCAodikge1xuXHRcdFx0YXJyW0wrK10gPSB2XG5cdFx0fVxuXG5cdFx0Zm9yIChpID0gMCwgaiA9IDA7IGkgPCBsOyBpICs9IDQsIGogKz0gMykge1xuXHRcdFx0dG1wID0gKGRlY29kZShiNjQuY2hhckF0KGkpKSA8PCAxOCkgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDEpKSA8PCAxMikgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDIpKSA8PCA2KSB8IGRlY29kZShiNjQuY2hhckF0KGkgKyAzKSlcblx0XHRcdHB1c2goKHRtcCAmIDB4RkYwMDAwKSA+PiAxNilcblx0XHRcdHB1c2goKHRtcCAmIDB4RkYwMCkgPj4gOClcblx0XHRcdHB1c2godG1wICYgMHhGRilcblx0XHR9XG5cblx0XHRpZiAocGxhY2VIb2xkZXJzID09PSAyKSB7XG5cdFx0XHR0bXAgPSAoZGVjb2RlKGI2NC5jaGFyQXQoaSkpIDw8IDIpIHwgKGRlY29kZShiNjQuY2hhckF0KGkgKyAxKSkgPj4gNClcblx0XHRcdHB1c2godG1wICYgMHhGRilcblx0XHR9IGVsc2UgaWYgKHBsYWNlSG9sZGVycyA9PT0gMSkge1xuXHRcdFx0dG1wID0gKGRlY29kZShiNjQuY2hhckF0KGkpKSA8PCAxMCkgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDEpKSA8PCA0KSB8IChkZWNvZGUoYjY0LmNoYXJBdChpICsgMikpID4+IDIpXG5cdFx0XHRwdXNoKCh0bXAgPj4gOCkgJiAweEZGKVxuXHRcdFx0cHVzaCh0bXAgJiAweEZGKVxuXHRcdH1cblxuXHRcdHJldHVybiBhcnJcblx0fVxuXG5cdGZ1bmN0aW9uIHVpbnQ4VG9CYXNlNjQgKHVpbnQ4KSB7XG5cdFx0dmFyIGksXG5cdFx0XHRleHRyYUJ5dGVzID0gdWludDgubGVuZ3RoICUgMywgLy8gaWYgd2UgaGF2ZSAxIGJ5dGUgbGVmdCwgcGFkIDIgYnl0ZXNcblx0XHRcdG91dHB1dCA9IFwiXCIsXG5cdFx0XHR0ZW1wLCBsZW5ndGhcblxuXHRcdGZ1bmN0aW9uIGVuY29kZSAobnVtKSB7XG5cdFx0XHRyZXR1cm4gbG9va3VwLmNoYXJBdChudW0pXG5cdFx0fVxuXG5cdFx0ZnVuY3Rpb24gdHJpcGxldFRvQmFzZTY0IChudW0pIHtcblx0XHRcdHJldHVybiBlbmNvZGUobnVtID4+IDE4ICYgMHgzRikgKyBlbmNvZGUobnVtID4+IDEyICYgMHgzRikgKyBlbmNvZGUobnVtID4+IDYgJiAweDNGKSArIGVuY29kZShudW0gJiAweDNGKVxuXHRcdH1cblxuXHRcdC8vIGdvIHRocm91Z2ggdGhlIGFycmF5IGV2ZXJ5IHRocmVlIGJ5dGVzLCB3ZSdsbCBkZWFsIHdpdGggdHJhaWxpbmcgc3R1ZmYgbGF0ZXJcblx0XHRmb3IgKGkgPSAwLCBsZW5ndGggPSB1aW50OC5sZW5ndGggLSBleHRyYUJ5dGVzOyBpIDwgbGVuZ3RoOyBpICs9IDMpIHtcblx0XHRcdHRlbXAgPSAodWludDhbaV0gPDwgMTYpICsgKHVpbnQ4W2kgKyAxXSA8PCA4KSArICh1aW50OFtpICsgMl0pXG5cdFx0XHRvdXRwdXQgKz0gdHJpcGxldFRvQmFzZTY0KHRlbXApXG5cdFx0fVxuXG5cdFx0Ly8gcGFkIHRoZSBlbmQgd2l0aCB6ZXJvcywgYnV0IG1ha2Ugc3VyZSB0byBub3QgZm9yZ2V0IHRoZSBleHRyYSBieXRlc1xuXHRcdHN3aXRjaCAoZXh0cmFCeXRlcykge1xuXHRcdFx0Y2FzZSAxOlxuXHRcdFx0XHR0ZW1wID0gdWludDhbdWludDgubGVuZ3RoIC0gMV1cblx0XHRcdFx0b3V0cHV0ICs9IGVuY29kZSh0ZW1wID4+IDIpXG5cdFx0XHRcdG91dHB1dCArPSBlbmNvZGUoKHRlbXAgPDwgNCkgJiAweDNGKVxuXHRcdFx0XHRvdXRwdXQgKz0gJz09J1xuXHRcdFx0XHRicmVha1xuXHRcdFx0Y2FzZSAyOlxuXHRcdFx0XHR0ZW1wID0gKHVpbnQ4W3VpbnQ4Lmxlbmd0aCAtIDJdIDw8IDgpICsgKHVpbnQ4W3VpbnQ4Lmxlbmd0aCAtIDFdKVxuXHRcdFx0XHRvdXRwdXQgKz0gZW5jb2RlKHRlbXAgPj4gMTApXG5cdFx0XHRcdG91dHB1dCArPSBlbmNvZGUoKHRlbXAgPj4gNCkgJiAweDNGKVxuXHRcdFx0XHRvdXRwdXQgKz0gZW5jb2RlKCh0ZW1wIDw8IDIpICYgMHgzRilcblx0XHRcdFx0b3V0cHV0ICs9ICc9J1xuXHRcdFx0XHRicmVha1xuXHRcdH1cblxuXHRcdHJldHVybiBvdXRwdXRcblx0fVxuXG5cdGV4cG9ydHMudG9CeXRlQXJyYXkgPSBiNjRUb0J5dGVBcnJheVxuXHRleHBvcnRzLmZyb21CeXRlQXJyYXkgPSB1aW50OFRvQmFzZTY0XG59KHR5cGVvZiBleHBvcnRzID09PSAndW5kZWZpbmVkJyA/ICh0aGlzLmJhc2U2NGpzID0ge30pIDogZXhwb3J0cykpXG4iLCJleHBvcnRzLnJlYWQgPSBmdW5jdGlvbiAoYnVmZmVyLCBvZmZzZXQsIGlzTEUsIG1MZW4sIG5CeXRlcykge1xuICB2YXIgZSwgbVxuICB2YXIgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMVxuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMVxuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDFcbiAgdmFyIG5CaXRzID0gLTdcbiAgdmFyIGkgPSBpc0xFID8gKG5CeXRlcyAtIDEpIDogMFxuICB2YXIgZCA9IGlzTEUgPyAtMSA6IDFcbiAgdmFyIHMgPSBidWZmZXJbb2Zmc2V0ICsgaV1cblxuICBpICs9IGRcblxuICBlID0gcyAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKVxuICBzID4+PSAoLW5CaXRzKVxuICBuQml0cyArPSBlTGVuXG4gIGZvciAoOyBuQml0cyA+IDA7IGUgPSBlICogMjU2ICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpIHt9XG5cbiAgbSA9IGUgJiAoKDEgPDwgKC1uQml0cykpIC0gMSlcbiAgZSA+Pj0gKC1uQml0cylcbiAgbkJpdHMgKz0gbUxlblxuICBmb3IgKDsgbkJpdHMgPiAwOyBtID0gbSAqIDI1NiArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KSB7fVxuXG4gIGlmIChlID09PSAwKSB7XG4gICAgZSA9IDEgLSBlQmlhc1xuICB9IGVsc2UgaWYgKGUgPT09IGVNYXgpIHtcbiAgICByZXR1cm4gbSA/IE5hTiA6ICgocyA/IC0xIDogMSkgKiBJbmZpbml0eSlcbiAgfSBlbHNlIHtcbiAgICBtID0gbSArIE1hdGgucG93KDIsIG1MZW4pXG4gICAgZSA9IGUgLSBlQmlhc1xuICB9XG4gIHJldHVybiAocyA/IC0xIDogMSkgKiBtICogTWF0aC5wb3coMiwgZSAtIG1MZW4pXG59XG5cbmV4cG9ydHMud3JpdGUgPSBmdW5jdGlvbiAoYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG0sIGNcbiAgdmFyIGVMZW4gPSBuQnl0ZXMgKiA4IC0gbUxlbiAtIDFcbiAgdmFyIGVNYXggPSAoMSA8PCBlTGVuKSAtIDFcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxXG4gIHZhciBydCA9IChtTGVuID09PSAyMyA/IE1hdGgucG93KDIsIC0yNCkgLSBNYXRoLnBvdygyLCAtNzcpIDogMClcbiAgdmFyIGkgPSBpc0xFID8gMCA6IChuQnl0ZXMgLSAxKVxuICB2YXIgZCA9IGlzTEUgPyAxIDogLTFcbiAgdmFyIHMgPSB2YWx1ZSA8IDAgfHwgKHZhbHVlID09PSAwICYmIDEgLyB2YWx1ZSA8IDApID8gMSA6IDBcblxuICB2YWx1ZSA9IE1hdGguYWJzKHZhbHVlKVxuXG4gIGlmIChpc05hTih2YWx1ZSkgfHwgdmFsdWUgPT09IEluZmluaXR5KSB7XG4gICAgbSA9IGlzTmFOKHZhbHVlKSA/IDEgOiAwXG4gICAgZSA9IGVNYXhcbiAgfSBlbHNlIHtcbiAgICBlID0gTWF0aC5mbG9vcihNYXRoLmxvZyh2YWx1ZSkgLyBNYXRoLkxOMilcbiAgICBpZiAodmFsdWUgKiAoYyA9IE1hdGgucG93KDIsIC1lKSkgPCAxKSB7XG4gICAgICBlLS1cbiAgICAgIGMgKj0gMlxuICAgIH1cbiAgICBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIHZhbHVlICs9IHJ0IC8gY1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWx1ZSArPSBydCAqIE1hdGgucG93KDIsIDEgLSBlQmlhcylcbiAgICB9XG4gICAgaWYgKHZhbHVlICogYyA+PSAyKSB7XG4gICAgICBlKytcbiAgICAgIGMgLz0gMlxuICAgIH1cblxuICAgIGlmIChlICsgZUJpYXMgPj0gZU1heCkge1xuICAgICAgbSA9IDBcbiAgICAgIGUgPSBlTWF4XG4gICAgfSBlbHNlIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgbSA9ICh2YWx1ZSAqIGMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pXG4gICAgICBlID0gZSArIGVCaWFzXG4gICAgfSBlbHNlIHtcbiAgICAgIG0gPSB2YWx1ZSAqIE1hdGgucG93KDIsIGVCaWFzIC0gMSkgKiBNYXRoLnBvdygyLCBtTGVuKVxuICAgICAgZSA9IDBcbiAgICB9XG4gIH1cblxuICBmb3IgKDsgbUxlbiA+PSA4OyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBtICYgMHhmZiwgaSArPSBkLCBtIC89IDI1NiwgbUxlbiAtPSA4KSB7fVxuXG4gIGUgPSAoZSA8PCBtTGVuKSB8IG1cbiAgZUxlbiArPSBtTGVuXG4gIGZvciAoOyBlTGVuID4gMDsgYnVmZmVyW29mZnNldCArIGldID0gZSAmIDB4ZmYsIGkgKz0gZCwgZSAvPSAyNTYsIGVMZW4gLT0gOCkge31cblxuICBidWZmZXJbb2Zmc2V0ICsgaSAtIGRdIHw9IHMgKiAxMjhcbn1cbiIsIlxuLyoqXG4gKiBpc0FycmF5XG4gKi9cblxudmFyIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5O1xuXG4vKipcbiAqIHRvU3RyaW5nXG4gKi9cblxudmFyIHN0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cbi8qKlxuICogV2hldGhlciBvciBub3QgdGhlIGdpdmVuIGB2YWxgXG4gKiBpcyBhbiBhcnJheS5cbiAqXG4gKiBleGFtcGxlOlxuICpcbiAqICAgICAgICBpc0FycmF5KFtdKTtcbiAqICAgICAgICAvLyA+IHRydWVcbiAqICAgICAgICBpc0FycmF5KGFyZ3VtZW50cyk7XG4gKiAgICAgICAgLy8gPiBmYWxzZVxuICogICAgICAgIGlzQXJyYXkoJycpO1xuICogICAgICAgIC8vID4gZmFsc2VcbiAqXG4gKiBAcGFyYW0ge21peGVkfSB2YWxcbiAqIEByZXR1cm4ge2Jvb2x9XG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBpc0FycmF5IHx8IGZ1bmN0aW9uICh2YWwpIHtcbiAgcmV0dXJuICEhIHZhbCAmJiAnW29iamVjdCBBcnJheV0nID09IHN0ci5jYWxsKHZhbCk7XG59O1xuIiwiLyoganNoaW50IG5vZGU6IHRydWUgKi9cbihmdW5jdGlvbiAoKSB7XG4gICAgXCJ1c2Ugc3RyaWN0XCI7XG5cbiAgICBmdW5jdGlvbiBDb29raWVBY2Nlc3NJbmZvKGRvbWFpbiwgcGF0aCwgc2VjdXJlLCBzY3JpcHQpIHtcbiAgICAgICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBDb29raWVBY2Nlc3NJbmZvKSB7XG4gICAgICAgICAgICB0aGlzLmRvbWFpbiA9IGRvbWFpbiB8fCB1bmRlZmluZWQ7XG4gICAgICAgICAgICB0aGlzLnBhdGggPSBwYXRoIHx8IFwiL1wiO1xuICAgICAgICAgICAgdGhpcy5zZWN1cmUgPSAhIXNlY3VyZTtcbiAgICAgICAgICAgIHRoaXMuc2NyaXB0ID0gISFzY3JpcHQ7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IENvb2tpZUFjY2Vzc0luZm8oZG9tYWluLCBwYXRoLCBzZWN1cmUsIHNjcmlwdCk7XG4gICAgfVxuICAgIGV4cG9ydHMuQ29va2llQWNjZXNzSW5mbyA9IENvb2tpZUFjY2Vzc0luZm87XG5cbiAgICBmdW5jdGlvbiBDb29raWUoY29va2llc3RyLCByZXF1ZXN0X2RvbWFpbiwgcmVxdWVzdF9wYXRoKSB7XG4gICAgICAgIGlmIChjb29raWVzdHIgaW5zdGFuY2VvZiBDb29raWUpIHtcbiAgICAgICAgICAgIHJldHVybiBjb29raWVzdHI7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMgaW5zdGFuY2VvZiBDb29raWUpIHtcbiAgICAgICAgICAgIHRoaXMubmFtZSA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLnZhbHVlID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMuZXhwaXJhdGlvbl9kYXRlID0gSW5maW5pdHk7XG4gICAgICAgICAgICB0aGlzLnBhdGggPSBTdHJpbmcocmVxdWVzdF9wYXRoIHx8IFwiL1wiKTtcbiAgICAgICAgICAgIHRoaXMuZXhwbGljaXRfcGF0aCA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5kb21haW4gPSByZXF1ZXN0X2RvbWFpbiB8fCBudWxsO1xuICAgICAgICAgICAgdGhpcy5leHBsaWNpdF9kb21haW4gPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuc2VjdXJlID0gZmFsc2U7IC8vaG93IHRvIGRlZmluZSBkZWZhdWx0P1xuICAgICAgICAgICAgdGhpcy5ub3NjcmlwdCA9IGZhbHNlOyAvL2h0dHBvbmx5XG4gICAgICAgICAgICBpZiAoY29va2llc3RyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wYXJzZShjb29raWVzdHIsIHJlcXVlc3RfZG9tYWluLCByZXF1ZXN0X3BhdGgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBDb29raWUoY29va2llc3RyLCByZXF1ZXN0X2RvbWFpbiwgcmVxdWVzdF9wYXRoKTtcbiAgICB9XG4gICAgZXhwb3J0cy5Db29raWUgPSBDb29raWU7XG5cbiAgICBDb29raWUucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcoKSB7XG4gICAgICAgIHZhciBzdHIgPSBbdGhpcy5uYW1lICsgXCI9XCIgKyB0aGlzLnZhbHVlXTtcbiAgICAgICAgaWYgKHRoaXMuZXhwaXJhdGlvbl9kYXRlICE9PSBJbmZpbml0eSkge1xuICAgICAgICAgICAgc3RyLnB1c2goXCJleHBpcmVzPVwiICsgKG5ldyBEYXRlKHRoaXMuZXhwaXJhdGlvbl9kYXRlKSkudG9HTVRTdHJpbmcoKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuZG9tYWluKSB7XG4gICAgICAgICAgICBzdHIucHVzaChcImRvbWFpbj1cIiArIHRoaXMuZG9tYWluKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5wYXRoKSB7XG4gICAgICAgICAgICBzdHIucHVzaChcInBhdGg9XCIgKyB0aGlzLnBhdGgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnNlY3VyZSkge1xuICAgICAgICAgICAgc3RyLnB1c2goXCJzZWN1cmVcIik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMubm9zY3JpcHQpIHtcbiAgICAgICAgICAgIHN0ci5wdXNoKFwiaHR0cG9ubHlcIik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHN0ci5qb2luKFwiOyBcIik7XG4gICAgfTtcblxuICAgIENvb2tpZS5wcm90b3R5cGUudG9WYWx1ZVN0cmluZyA9IGZ1bmN0aW9uIHRvVmFsdWVTdHJpbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm5hbWUgKyBcIj1cIiArIHRoaXMudmFsdWU7XG4gICAgfTtcblxuICAgIHZhciBjb29raWVfc3RyX3NwbGl0dGVyID0gL1s6XSg/PVxccypbYS16QS1aMC05X1xcLV0rXFxzKls9XSkvZztcbiAgICBDb29raWUucHJvdG90eXBlLnBhcnNlID0gZnVuY3Rpb24gcGFyc2Uoc3RyLCByZXF1ZXN0X2RvbWFpbiwgcmVxdWVzdF9wYXRoKSB7XG4gICAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgQ29va2llKSB7XG4gICAgICAgICAgICB2YXIgcGFydHMgPSBzdHIuc3BsaXQoXCI7XCIpLmZpbHRlcihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICEhdmFsdWU7XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgcGFpciA9IHBhcnRzWzBdLm1hdGNoKC8oW149XSspPShbXFxzXFxTXSopLyksXG4gICAgICAgICAgICAgICAga2V5ID0gcGFpclsxXSxcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IHBhaXJbMl0sXG4gICAgICAgICAgICAgICAgaTtcbiAgICAgICAgICAgIHRoaXMubmFtZSA9IGtleTtcbiAgICAgICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcblxuICAgICAgICAgICAgZm9yIChpID0gMTsgaSA8IHBhcnRzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgcGFpciA9IHBhcnRzW2ldLm1hdGNoKC8oW149XSspKD86PShbXFxzXFxTXSopKT8vKTtcbiAgICAgICAgICAgICAgICBrZXkgPSBwYWlyWzFdLnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICAgICAgICAgIHZhbHVlID0gcGFpclsyXTtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKGtleSkge1xuICAgICAgICAgICAgICAgIGNhc2UgXCJodHRwb25seVwiOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLm5vc2NyaXB0ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBcImV4cGlyZXNcIjpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5leHBpcmF0aW9uX2RhdGUgPSB2YWx1ZSA/XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgTnVtYmVyKERhdGUucGFyc2UodmFsdWUpKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5maW5pdHk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJwYXRoXCI6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGF0aCA9IHZhbHVlID9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZS50cmltKCkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiXCI7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXhwbGljaXRfcGF0aCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJkb21haW5cIjpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kb21haW4gPSB2YWx1ZSA/XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUudHJpbSgpIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIlwiO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmV4cGxpY2l0X2RvbWFpbiA9ICEhdGhpcy5kb21haW47XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJzZWN1cmVcIjpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZWN1cmUgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5leHBsaWNpdF9wYXRoKSB7XG4gICAgICAgICAgICAgICB0aGlzLnBhdGggPSByZXF1ZXN0X3BhdGggfHwgXCIvXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXRoaXMuZXhwbGljaXRfZG9tYWluKSB7XG4gICAgICAgICAgICAgICB0aGlzLmRvbWFpbiA9IHJlcXVlc3RfZG9tYWluO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IENvb2tpZSgpLnBhcnNlKHN0ciwgcmVxdWVzdF9kb21haW4sIHJlcXVlc3RfcGF0aCk7XG4gICAgfTtcblxuICAgIENvb2tpZS5wcm90b3R5cGUubWF0Y2hlcyA9IGZ1bmN0aW9uIG1hdGNoZXMoYWNjZXNzX2luZm8pIHtcbiAgICAgICAgaWYgKHRoaXMubm9zY3JpcHQgJiYgYWNjZXNzX2luZm8uc2NyaXB0IHx8XG4gICAgICAgICAgICAgICAgdGhpcy5zZWN1cmUgJiYgIWFjY2Vzc19pbmZvLnNlY3VyZSB8fFxuICAgICAgICAgICAgICAgICF0aGlzLmNvbGxpZGVzV2l0aChhY2Nlc3NfaW5mbykpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuXG4gICAgQ29va2llLnByb3RvdHlwZS5jb2xsaWRlc1dpdGggPSBmdW5jdGlvbiBjb2xsaWRlc1dpdGgoYWNjZXNzX2luZm8pIHtcbiAgICAgICAgaWYgKCh0aGlzLnBhdGggJiYgIWFjY2Vzc19pbmZvLnBhdGgpIHx8ICh0aGlzLmRvbWFpbiAmJiAhYWNjZXNzX2luZm8uZG9tYWluKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnBhdGggJiYgYWNjZXNzX2luZm8ucGF0aC5pbmRleE9mKHRoaXMucGF0aCkgIT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5leHBsaWNpdF9wYXRoICYmIGFjY2Vzc19pbmZvLnBhdGguaW5kZXhPZiggdGhpcy5wYXRoICkgIT09IDApIHtcbiAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHZhciBhY2Nlc3NfZG9tYWluID0gYWNjZXNzX2luZm8uZG9tYWluICYmIGFjY2Vzc19pbmZvLmRvbWFpbi5yZXBsYWNlKC9eW1xcLl0vLCcnKTtcbiAgICAgICAgdmFyIGNvb2tpZV9kb21haW4gPSB0aGlzLmRvbWFpbiAmJiB0aGlzLmRvbWFpbi5yZXBsYWNlKC9eW1xcLl0vLCcnKTtcbiAgICAgICAgaWYgKGNvb2tpZV9kb21haW4gPT09IGFjY2Vzc19kb21haW4pIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb29raWVfZG9tYWluKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuZXhwbGljaXRfZG9tYWluKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyB3ZSBhbHJlYWR5IGNoZWNrZWQgaWYgdGhlIGRvbWFpbnMgd2VyZSBleGFjdGx5IHRoZSBzYW1lXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgd2lsZGNhcmQgPSBhY2Nlc3NfZG9tYWluLmluZGV4T2YoY29va2llX2RvbWFpbik7XG4gICAgICAgICAgICBpZiAod2lsZGNhcmQgPT09IC0xIHx8IHdpbGRjYXJkICE9PSBhY2Nlc3NfZG9tYWluLmxlbmd0aCAtIGNvb2tpZV9kb21haW4ubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIENvb2tpZUphcigpIHtcbiAgICAgICAgdmFyIGNvb2tpZXMsIGNvb2tpZXNfbGlzdCwgY29sbGlkYWJsZV9jb29raWU7XG4gICAgICAgIGlmICh0aGlzIGluc3RhbmNlb2YgQ29va2llSmFyKSB7XG4gICAgICAgICAgICBjb29raWVzID0gT2JqZWN0LmNyZWF0ZShudWxsKTsgLy9uYW1lOiBbQ29va2llXVxuXG4gICAgICAgICAgICB0aGlzLnNldENvb2tpZSA9IGZ1bmN0aW9uIHNldENvb2tpZShjb29raWUsIHJlcXVlc3RfZG9tYWluLCByZXF1ZXN0X3BhdGgpIHtcbiAgICAgICAgICAgICAgICB2YXIgcmVtb3ZlLCBpO1xuICAgICAgICAgICAgICAgIGNvb2tpZSA9IG5ldyBDb29raWUoY29va2llLCByZXF1ZXN0X2RvbWFpbiwgcmVxdWVzdF9wYXRoKTtcbiAgICAgICAgICAgICAgICAvL0RlbGV0ZSB0aGUgY29va2llIGlmIHRoZSBzZXQgaXMgcGFzdCB0aGUgY3VycmVudCB0aW1lXG4gICAgICAgICAgICAgICAgcmVtb3ZlID0gY29va2llLmV4cGlyYXRpb25fZGF0ZSA8PSBEYXRlLm5vdygpO1xuICAgICAgICAgICAgICAgIGlmIChjb29raWVzW2Nvb2tpZS5uYW1lXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvb2tpZXNfbGlzdCA9IGNvb2tpZXNbY29va2llLm5hbWVdO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY29va2llc19saXN0Lmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2xsaWRhYmxlX2Nvb2tpZSA9IGNvb2tpZXNfbGlzdFtpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb2xsaWRhYmxlX2Nvb2tpZS5jb2xsaWRlc1dpdGgoY29va2llKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZW1vdmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29va2llc19saXN0LnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvb2tpZXNfbGlzdC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBjb29raWVzW2Nvb2tpZS5uYW1lXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvb2tpZXNfbGlzdFtpXSA9IGNvb2tpZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29va2llO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZW1vdmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb29raWVzX2xpc3QucHVzaChjb29raWUpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29va2llO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAocmVtb3ZlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29va2llc1tjb29raWUubmFtZV0gPSBbY29va2llXTtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29va2llc1tjb29raWUubmFtZV07XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgLy9yZXR1cm5zIGEgY29va2llXG4gICAgICAgICAgICB0aGlzLmdldENvb2tpZSA9IGZ1bmN0aW9uIGdldENvb2tpZShjb29raWVfbmFtZSwgYWNjZXNzX2luZm8pIHtcbiAgICAgICAgICAgICAgICB2YXIgY29va2llLCBpO1xuICAgICAgICAgICAgICAgIGNvb2tpZXNfbGlzdCA9IGNvb2tpZXNbY29va2llX25hbWVdO1xuICAgICAgICAgICAgICAgIGlmICghY29va2llc19saXN0KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvb2tpZXNfbGlzdC5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICBjb29raWUgPSBjb29raWVzX2xpc3RbaV07XG4gICAgICAgICAgICAgICAgICAgIGlmIChjb29raWUuZXhwaXJhdGlvbl9kYXRlIDw9IERhdGUubm93KCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb29raWVzX2xpc3QubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGNvb2tpZXNbY29va2llLm5hbWVdO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAoY29va2llLm1hdGNoZXMoYWNjZXNzX2luZm8pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29va2llO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIC8vcmV0dXJucyBhIGxpc3Qgb2YgY29va2llc1xuICAgICAgICAgICAgdGhpcy5nZXRDb29raWVzID0gZnVuY3Rpb24gZ2V0Q29va2llcyhhY2Nlc3NfaW5mbykge1xuICAgICAgICAgICAgICAgIHZhciBtYXRjaGVzID0gW10sIGNvb2tpZV9uYW1lLCBjb29raWU7XG4gICAgICAgICAgICAgICAgZm9yIChjb29raWVfbmFtZSBpbiBjb29raWVzKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvb2tpZSA9IHRoaXMuZ2V0Q29va2llKGNvb2tpZV9uYW1lLCBhY2Nlc3NfaW5mbyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChjb29raWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoZXMucHVzaChjb29raWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG1hdGNoZXMudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZygpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoZXMuam9pbihcIjpcIik7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBtYXRjaGVzLnRvVmFsdWVTdHJpbmcgPSBmdW5jdGlvbiB0b1ZhbHVlU3RyaW5nKCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbWF0Y2hlcy5tYXAoZnVuY3Rpb24gKGMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjLnRvVmFsdWVTdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgfSkuam9pbignOycpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoZXM7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IENvb2tpZUphcigpO1xuICAgIH1cbiAgICBleHBvcnRzLkNvb2tpZUphciA9IENvb2tpZUphcjtcblxuICAgIC8vcmV0dXJucyBsaXN0IG9mIGNvb2tpZXMgdGhhdCB3ZXJlIHNldCBjb3JyZWN0bHkuIENvb2tpZXMgdGhhdCBhcmUgZXhwaXJlZCBhbmQgcmVtb3ZlZCBhcmUgbm90IHJldHVybmVkLlxuICAgIENvb2tpZUphci5wcm90b3R5cGUuc2V0Q29va2llcyA9IGZ1bmN0aW9uIHNldENvb2tpZXMoY29va2llcywgcmVxdWVzdF9kb21haW4sIHJlcXVlc3RfcGF0aCkge1xuICAgICAgICBjb29raWVzID0gQXJyYXkuaXNBcnJheShjb29raWVzKSA/XG4gICAgICAgICAgICAgICAgY29va2llcyA6XG4gICAgICAgICAgICAgICAgY29va2llcy5zcGxpdChjb29raWVfc3RyX3NwbGl0dGVyKTtcbiAgICAgICAgdmFyIHN1Y2Nlc3NmdWwgPSBbXSxcbiAgICAgICAgICAgIGksXG4gICAgICAgICAgICBjb29raWU7XG4gICAgICAgIGNvb2tpZXMgPSBjb29raWVzLm1hcChmdW5jdGlvbihpdGVtKXtcbiAgICAgICAgICAgIHJldHVybiBuZXcgQ29va2llKGl0ZW0sIHJlcXVlc3RfZG9tYWluLCByZXF1ZXN0X3BhdGgpO1xuICAgICAgICB9KTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvb2tpZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGNvb2tpZSA9IGNvb2tpZXNbaV07XG4gICAgICAgICAgICBpZiAodGhpcy5zZXRDb29raWUoY29va2llLCByZXF1ZXN0X2RvbWFpbiwgcmVxdWVzdF9wYXRoKSkge1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3NmdWwucHVzaChjb29raWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzdWNjZXNzZnVsO1xuICAgIH07XG59KCkpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5cbnZhciB5YW1sID0gcmVxdWlyZSgnLi9saWIvanMteWFtbC5qcycpO1xuXG5cbm1vZHVsZS5leHBvcnRzID0geWFtbDtcbiIsIid1c2Ugc3RyaWN0JztcblxuXG52YXIgbG9hZGVyID0gcmVxdWlyZSgnLi9qcy15YW1sL2xvYWRlcicpO1xudmFyIGR1bXBlciA9IHJlcXVpcmUoJy4vanMteWFtbC9kdW1wZXInKTtcblxuXG5mdW5jdGlvbiBkZXByZWNhdGVkKG5hbWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0Z1bmN0aW9uICcgKyBuYW1lICsgJyBpcyBkZXByZWNhdGVkIGFuZCBjYW5ub3QgYmUgdXNlZC4nKTtcbiAgfTtcbn1cblxuXG5tb2R1bGUuZXhwb3J0cy5UeXBlICAgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9qcy15YW1sL3R5cGUnKTtcbm1vZHVsZS5leHBvcnRzLlNjaGVtYSAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL2pzLXlhbWwvc2NoZW1hJyk7XG5tb2R1bGUuZXhwb3J0cy5GQUlMU0FGRV9TQ0hFTUEgICAgID0gcmVxdWlyZSgnLi9qcy15YW1sL3NjaGVtYS9mYWlsc2FmZScpO1xubW9kdWxlLmV4cG9ydHMuSlNPTl9TQ0hFTUEgICAgICAgICA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEvanNvbicpO1xubW9kdWxlLmV4cG9ydHMuQ09SRV9TQ0hFTUEgICAgICAgICA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEvY29yZScpO1xubW9kdWxlLmV4cG9ydHMuREVGQVVMVF9TQUZFX1NDSEVNQSA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEvZGVmYXVsdF9zYWZlJyk7XG5tb2R1bGUuZXhwb3J0cy5ERUZBVUxUX0ZVTExfU0NIRU1BID0gcmVxdWlyZSgnLi9qcy15YW1sL3NjaGVtYS9kZWZhdWx0X2Z1bGwnKTtcbm1vZHVsZS5leHBvcnRzLmxvYWQgICAgICAgICAgICAgICAgPSBsb2FkZXIubG9hZDtcbm1vZHVsZS5leHBvcnRzLmxvYWRBbGwgICAgICAgICAgICAgPSBsb2FkZXIubG9hZEFsbDtcbm1vZHVsZS5leHBvcnRzLnNhZmVMb2FkICAgICAgICAgICAgPSBsb2FkZXIuc2FmZUxvYWQ7XG5tb2R1bGUuZXhwb3J0cy5zYWZlTG9hZEFsbCAgICAgICAgID0gbG9hZGVyLnNhZmVMb2FkQWxsO1xubW9kdWxlLmV4cG9ydHMuZHVtcCAgICAgICAgICAgICAgICA9IGR1bXBlci5kdW1wO1xubW9kdWxlLmV4cG9ydHMuc2FmZUR1bXAgICAgICAgICAgICA9IGR1bXBlci5zYWZlRHVtcDtcbm1vZHVsZS5leHBvcnRzLllBTUxFeGNlcHRpb24gICAgICAgPSByZXF1aXJlKCcuL2pzLXlhbWwvZXhjZXB0aW9uJyk7XG5cbi8vIERlcHJlY2F0ZWQgc2NoZW1hIG5hbWVzIGZyb20gSlMtWUFNTCAyLjAueFxubW9kdWxlLmV4cG9ydHMuTUlOSU1BTF9TQ0hFTUEgPSByZXF1aXJlKCcuL2pzLXlhbWwvc2NoZW1hL2ZhaWxzYWZlJyk7XG5tb2R1bGUuZXhwb3J0cy5TQUZFX1NDSEVNQSAgICA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEvZGVmYXVsdF9zYWZlJyk7XG5tb2R1bGUuZXhwb3J0cy5ERUZBVUxUX1NDSEVNQSA9IHJlcXVpcmUoJy4vanMteWFtbC9zY2hlbWEvZGVmYXVsdF9mdWxsJyk7XG5cbi8vIERlcHJlY2F0ZWQgZnVuY3Rpb25zIGZyb20gSlMtWUFNTCAxLngueFxubW9kdWxlLmV4cG9ydHMuc2NhbiAgICAgICAgICAgPSBkZXByZWNhdGVkKCdzY2FuJyk7XG5tb2R1bGUuZXhwb3J0cy5wYXJzZSAgICAgICAgICA9IGRlcHJlY2F0ZWQoJ3BhcnNlJyk7XG5tb2R1bGUuZXhwb3J0cy5jb21wb3NlICAgICAgICA9IGRlcHJlY2F0ZWQoJ2NvbXBvc2UnKTtcbm1vZHVsZS5leHBvcnRzLmFkZENvbnN0cnVjdG9yID0gZGVwcmVjYXRlZCgnYWRkQ29uc3RydWN0b3InKTtcbiIsIid1c2Ugc3RyaWN0JztcblxuXG5mdW5jdGlvbiBpc05vdGhpbmcoc3ViamVjdCkge1xuICByZXR1cm4gKHR5cGVvZiBzdWJqZWN0ID09PSAndW5kZWZpbmVkJykgfHwgKHN1YmplY3QgPT09IG51bGwpO1xufVxuXG5cbmZ1bmN0aW9uIGlzT2JqZWN0KHN1YmplY3QpIHtcbiAgcmV0dXJuICh0eXBlb2Ygc3ViamVjdCA9PT0gJ29iamVjdCcpICYmIChzdWJqZWN0ICE9PSBudWxsKTtcbn1cblxuXG5mdW5jdGlvbiB0b0FycmF5KHNlcXVlbmNlKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KHNlcXVlbmNlKSkgcmV0dXJuIHNlcXVlbmNlO1xuICBlbHNlIGlmIChpc05vdGhpbmcoc2VxdWVuY2UpKSByZXR1cm4gW107XG5cbiAgcmV0dXJuIFsgc2VxdWVuY2UgXTtcbn1cblxuXG5mdW5jdGlvbiBleHRlbmQodGFyZ2V0LCBzb3VyY2UpIHtcbiAgdmFyIGluZGV4LCBsZW5ndGgsIGtleSwgc291cmNlS2V5cztcblxuICBpZiAoc291cmNlKSB7XG4gICAgc291cmNlS2V5cyA9IE9iamVjdC5rZXlzKHNvdXJjZSk7XG5cbiAgICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gc291cmNlS2V5cy5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgICBrZXkgPSBzb3VyY2VLZXlzW2luZGV4XTtcbiAgICAgIHRhcmdldFtrZXldID0gc291cmNlW2tleV07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRhcmdldDtcbn1cblxuXG5mdW5jdGlvbiByZXBlYXQoc3RyaW5nLCBjb3VudCkge1xuICB2YXIgcmVzdWx0ID0gJycsIGN5Y2xlO1xuXG4gIGZvciAoY3ljbGUgPSAwOyBjeWNsZSA8IGNvdW50OyBjeWNsZSArPSAxKSB7XG4gICAgcmVzdWx0ICs9IHN0cmluZztcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cblxuZnVuY3Rpb24gaXNOZWdhdGl2ZVplcm8obnVtYmVyKSB7XG4gIHJldHVybiAobnVtYmVyID09PSAwKSAmJiAoTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZID09PSAxIC8gbnVtYmVyKTtcbn1cblxuXG5tb2R1bGUuZXhwb3J0cy5pc05vdGhpbmcgICAgICA9IGlzTm90aGluZztcbm1vZHVsZS5leHBvcnRzLmlzT2JqZWN0ICAgICAgID0gaXNPYmplY3Q7XG5tb2R1bGUuZXhwb3J0cy50b0FycmF5ICAgICAgICA9IHRvQXJyYXk7XG5tb2R1bGUuZXhwb3J0cy5yZXBlYXQgICAgICAgICA9IHJlcGVhdDtcbm1vZHVsZS5leHBvcnRzLmlzTmVnYXRpdmVaZXJvID0gaXNOZWdhdGl2ZVplcm87XG5tb2R1bGUuZXhwb3J0cy5leHRlbmQgICAgICAgICA9IGV4dGVuZDtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyplc2xpbnQtZGlzYWJsZSBuby11c2UtYmVmb3JlLWRlZmluZSovXG5cbnZhciBjb21tb24gICAgICAgICAgICAgID0gcmVxdWlyZSgnLi9jb21tb24nKTtcbnZhciBZQU1MRXhjZXB0aW9uICAgICAgID0gcmVxdWlyZSgnLi9leGNlcHRpb24nKTtcbnZhciBERUZBVUxUX0ZVTExfU0NIRU1BID0gcmVxdWlyZSgnLi9zY2hlbWEvZGVmYXVsdF9mdWxsJyk7XG52YXIgREVGQVVMVF9TQUZFX1NDSEVNQSA9IHJlcXVpcmUoJy4vc2NoZW1hL2RlZmF1bHRfc2FmZScpO1xuXG52YXIgX3RvU3RyaW5nICAgICAgID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcbnZhciBfaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG52YXIgQ0hBUl9UQUIgICAgICAgICAgICAgICAgICA9IDB4MDk7IC8qIFRhYiAqL1xudmFyIENIQVJfTElORV9GRUVEICAgICAgICAgICAgPSAweDBBOyAvKiBMRiAqL1xudmFyIENIQVJfU1BBQ0UgICAgICAgICAgICAgICAgPSAweDIwOyAvKiBTcGFjZSAqL1xudmFyIENIQVJfRVhDTEFNQVRJT04gICAgICAgICAgPSAweDIxOyAvKiAhICovXG52YXIgQ0hBUl9ET1VCTEVfUVVPVEUgICAgICAgICA9IDB4MjI7IC8qIFwiICovXG52YXIgQ0hBUl9TSEFSUCAgICAgICAgICAgICAgICA9IDB4MjM7IC8qICMgKi9cbnZhciBDSEFSX1BFUkNFTlQgICAgICAgICAgICAgID0gMHgyNTsgLyogJSAqL1xudmFyIENIQVJfQU1QRVJTQU5EICAgICAgICAgICAgPSAweDI2OyAvKiAmICovXG52YXIgQ0hBUl9TSU5HTEVfUVVPVEUgICAgICAgICA9IDB4Mjc7IC8qICcgKi9cbnZhciBDSEFSX0FTVEVSSVNLICAgICAgICAgICAgID0gMHgyQTsgLyogKiAqL1xudmFyIENIQVJfQ09NTUEgICAgICAgICAgICAgICAgPSAweDJDOyAvKiAsICovXG52YXIgQ0hBUl9NSU5VUyAgICAgICAgICAgICAgICA9IDB4MkQ7IC8qIC0gKi9cbnZhciBDSEFSX0NPTE9OICAgICAgICAgICAgICAgID0gMHgzQTsgLyogOiAqL1xudmFyIENIQVJfR1JFQVRFUl9USEFOICAgICAgICAgPSAweDNFOyAvKiA+ICovXG52YXIgQ0hBUl9RVUVTVElPTiAgICAgICAgICAgICA9IDB4M0Y7IC8qID8gKi9cbnZhciBDSEFSX0NPTU1FUkNJQUxfQVQgICAgICAgID0gMHg0MDsgLyogQCAqL1xudmFyIENIQVJfTEVGVF9TUVVBUkVfQlJBQ0tFVCAgPSAweDVCOyAvKiBbICovXG52YXIgQ0hBUl9SSUdIVF9TUVVBUkVfQlJBQ0tFVCA9IDB4NUQ7IC8qIF0gKi9cbnZhciBDSEFSX0dSQVZFX0FDQ0VOVCAgICAgICAgID0gMHg2MDsgLyogYCAqL1xudmFyIENIQVJfTEVGVF9DVVJMWV9CUkFDS0VUICAgPSAweDdCOyAvKiB7ICovXG52YXIgQ0hBUl9WRVJUSUNBTF9MSU5FICAgICAgICA9IDB4N0M7IC8qIHwgKi9cbnZhciBDSEFSX1JJR0hUX0NVUkxZX0JSQUNLRVQgID0gMHg3RDsgLyogfSAqL1xuXG52YXIgRVNDQVBFX1NFUVVFTkNFUyA9IHt9O1xuXG5FU0NBUEVfU0VRVUVOQ0VTWzB4MDBdICAgPSAnXFxcXDAnO1xuRVNDQVBFX1NFUVVFTkNFU1sweDA3XSAgID0gJ1xcXFxhJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHgwOF0gICA9ICdcXFxcYic7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4MDldICAgPSAnXFxcXHQnO1xuRVNDQVBFX1NFUVVFTkNFU1sweDBBXSAgID0gJ1xcXFxuJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHgwQl0gICA9ICdcXFxcdic7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4MENdICAgPSAnXFxcXGYnO1xuRVNDQVBFX1NFUVVFTkNFU1sweDBEXSAgID0gJ1xcXFxyJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHgxQl0gICA9ICdcXFxcZSc7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4MjJdICAgPSAnXFxcXFwiJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHg1Q10gICA9ICdcXFxcXFxcXCc7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4ODVdICAgPSAnXFxcXE4nO1xuRVNDQVBFX1NFUVVFTkNFU1sweEEwXSAgID0gJ1xcXFxfJztcbkVTQ0FQRV9TRVFVRU5DRVNbMHgyMDI4XSA9ICdcXFxcTCc7XG5FU0NBUEVfU0VRVUVOQ0VTWzB4MjAyOV0gPSAnXFxcXFAnO1xuXG52YXIgREVQUkVDQVRFRF9CT09MRUFOU19TWU5UQVggPSBbXG4gICd5JywgJ1knLCAneWVzJywgJ1llcycsICdZRVMnLCAnb24nLCAnT24nLCAnT04nLFxuICAnbicsICdOJywgJ25vJywgJ05vJywgJ05PJywgJ29mZicsICdPZmYnLCAnT0ZGJ1xuXTtcblxuZnVuY3Rpb24gY29tcGlsZVN0eWxlTWFwKHNjaGVtYSwgbWFwKSB7XG4gIHZhciByZXN1bHQsIGtleXMsIGluZGV4LCBsZW5ndGgsIHRhZywgc3R5bGUsIHR5cGU7XG5cbiAgaWYgKG1hcCA9PT0gbnVsbCkgcmV0dXJuIHt9O1xuXG4gIHJlc3VsdCA9IHt9O1xuICBrZXlzID0gT2JqZWN0LmtleXMobWFwKTtcblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0ga2V5cy5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgdGFnID0ga2V5c1tpbmRleF07XG4gICAgc3R5bGUgPSBTdHJpbmcobWFwW3RhZ10pO1xuXG4gICAgaWYgKHRhZy5zbGljZSgwLCAyKSA9PT0gJyEhJykge1xuICAgICAgdGFnID0gJ3RhZzp5YW1sLm9yZywyMDAyOicgKyB0YWcuc2xpY2UoMik7XG4gICAgfVxuXG4gICAgdHlwZSA9IHNjaGVtYS5jb21waWxlZFR5cGVNYXBbdGFnXTtcblxuICAgIGlmICh0eXBlICYmIF9oYXNPd25Qcm9wZXJ0eS5jYWxsKHR5cGUuc3R5bGVBbGlhc2VzLCBzdHlsZSkpIHtcbiAgICAgIHN0eWxlID0gdHlwZS5zdHlsZUFsaWFzZXNbc3R5bGVdO1xuICAgIH1cblxuICAgIHJlc3VsdFt0YWddID0gc3R5bGU7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBlbmNvZGVIZXgoY2hhcmFjdGVyKSB7XG4gIHZhciBzdHJpbmcsIGhhbmRsZSwgbGVuZ3RoO1xuXG4gIHN0cmluZyA9IGNoYXJhY3Rlci50b1N0cmluZygxNikudG9VcHBlckNhc2UoKTtcblxuICBpZiAoY2hhcmFjdGVyIDw9IDB4RkYpIHtcbiAgICBoYW5kbGUgPSAneCc7XG4gICAgbGVuZ3RoID0gMjtcbiAgfSBlbHNlIGlmIChjaGFyYWN0ZXIgPD0gMHhGRkZGKSB7XG4gICAgaGFuZGxlID0gJ3UnO1xuICAgIGxlbmd0aCA9IDQ7XG4gIH0gZWxzZSBpZiAoY2hhcmFjdGVyIDw9IDB4RkZGRkZGRkYpIHtcbiAgICBoYW5kbGUgPSAnVSc7XG4gICAgbGVuZ3RoID0gODtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgWUFNTEV4Y2VwdGlvbignY29kZSBwb2ludCB3aXRoaW4gYSBzdHJpbmcgbWF5IG5vdCBiZSBncmVhdGVyIHRoYW4gMHhGRkZGRkZGRicpO1xuICB9XG5cbiAgcmV0dXJuICdcXFxcJyArIGhhbmRsZSArIGNvbW1vbi5yZXBlYXQoJzAnLCBsZW5ndGggLSBzdHJpbmcubGVuZ3RoKSArIHN0cmluZztcbn1cblxuZnVuY3Rpb24gU3RhdGUob3B0aW9ucykge1xuICB0aGlzLnNjaGVtYSAgICAgICA9IG9wdGlvbnNbJ3NjaGVtYSddIHx8IERFRkFVTFRfRlVMTF9TQ0hFTUE7XG4gIHRoaXMuaW5kZW50ICAgICAgID0gTWF0aC5tYXgoMSwgKG9wdGlvbnNbJ2luZGVudCddIHx8IDIpKTtcbiAgdGhpcy5za2lwSW52YWxpZCAgPSBvcHRpb25zWydza2lwSW52YWxpZCddIHx8IGZhbHNlO1xuICB0aGlzLmZsb3dMZXZlbCAgICA9IChjb21tb24uaXNOb3RoaW5nKG9wdGlvbnNbJ2Zsb3dMZXZlbCddKSA/IC0xIDogb3B0aW9uc1snZmxvd0xldmVsJ10pO1xuICB0aGlzLnN0eWxlTWFwICAgICA9IGNvbXBpbGVTdHlsZU1hcCh0aGlzLnNjaGVtYSwgb3B0aW9uc1snc3R5bGVzJ10gfHwgbnVsbCk7XG4gIHRoaXMuc29ydEtleXMgICAgID0gb3B0aW9uc1snc29ydEtleXMnXSB8fCBmYWxzZTtcbiAgdGhpcy5saW5lV2lkdGggICAgPSBvcHRpb25zWydsaW5lV2lkdGgnXSB8fCA4MDtcbiAgdGhpcy5ub1JlZnMgICAgICAgPSBvcHRpb25zWydub1JlZnMnXSB8fCBmYWxzZTtcbiAgdGhpcy5ub0NvbXBhdE1vZGUgPSBvcHRpb25zWydub0NvbXBhdE1vZGUnXSB8fCBmYWxzZTtcblxuICB0aGlzLmltcGxpY2l0VHlwZXMgPSB0aGlzLnNjaGVtYS5jb21waWxlZEltcGxpY2l0O1xuICB0aGlzLmV4cGxpY2l0VHlwZXMgPSB0aGlzLnNjaGVtYS5jb21waWxlZEV4cGxpY2l0O1xuXG4gIHRoaXMudGFnID0gbnVsbDtcbiAgdGhpcy5yZXN1bHQgPSAnJztcblxuICB0aGlzLmR1cGxpY2F0ZXMgPSBbXTtcbiAgdGhpcy51c2VkRHVwbGljYXRlcyA9IG51bGw7XG59XG5cbi8vIEluZGVudHMgZXZlcnkgbGluZSBpbiBhIHN0cmluZy4gRW1wdHkgbGluZXMgKFxcbiBvbmx5KSBhcmUgbm90IGluZGVudGVkLlxuZnVuY3Rpb24gaW5kZW50U3RyaW5nKHN0cmluZywgc3BhY2VzKSB7XG4gIHZhciBpbmQgPSBjb21tb24ucmVwZWF0KCcgJywgc3BhY2VzKSxcbiAgICAgIHBvc2l0aW9uID0gMCxcbiAgICAgIG5leHQgPSAtMSxcbiAgICAgIHJlc3VsdCA9ICcnLFxuICAgICAgbGluZSxcbiAgICAgIGxlbmd0aCA9IHN0cmluZy5sZW5ndGg7XG5cbiAgd2hpbGUgKHBvc2l0aW9uIDwgbGVuZ3RoKSB7XG4gICAgbmV4dCA9IHN0cmluZy5pbmRleE9mKCdcXG4nLCBwb3NpdGlvbik7XG4gICAgaWYgKG5leHQgPT09IC0xKSB7XG4gICAgICBsaW5lID0gc3RyaW5nLnNsaWNlKHBvc2l0aW9uKTtcbiAgICAgIHBvc2l0aW9uID0gbGVuZ3RoO1xuICAgIH0gZWxzZSB7XG4gICAgICBsaW5lID0gc3RyaW5nLnNsaWNlKHBvc2l0aW9uLCBuZXh0ICsgMSk7XG4gICAgICBwb3NpdGlvbiA9IG5leHQgKyAxO1xuICAgIH1cblxuICAgIGlmIChsaW5lLmxlbmd0aCAmJiBsaW5lICE9PSAnXFxuJykgcmVzdWx0ICs9IGluZDtcblxuICAgIHJlc3VsdCArPSBsaW5lO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gZ2VuZXJhdGVOZXh0TGluZShzdGF0ZSwgbGV2ZWwpIHtcbiAgcmV0dXJuICdcXG4nICsgY29tbW9uLnJlcGVhdCgnICcsIHN0YXRlLmluZGVudCAqIGxldmVsKTtcbn1cblxuZnVuY3Rpb24gdGVzdEltcGxpY2l0UmVzb2x2aW5nKHN0YXRlLCBzdHIpIHtcbiAgdmFyIGluZGV4LCBsZW5ndGgsIHR5cGU7XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IHN0YXRlLmltcGxpY2l0VHlwZXMubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIHR5cGUgPSBzdGF0ZS5pbXBsaWNpdFR5cGVzW2luZGV4XTtcblxuICAgIGlmICh0eXBlLnJlc29sdmUoc3RyKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vLyBbMzNdIHMtd2hpdGUgOjo9IHMtc3BhY2UgfCBzLXRhYlxuZnVuY3Rpb24gaXNXaGl0ZXNwYWNlKGMpIHtcbiAgcmV0dXJuIGMgPT09IENIQVJfU1BBQ0UgfHwgYyA9PT0gQ0hBUl9UQUI7XG59XG5cbi8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgY2hhcmFjdGVyIGNhbiBiZSBwcmludGVkIHdpdGhvdXQgZXNjYXBpbmcuXG4vLyBGcm9tIFlBTUwgMS4yOiBcImFueSBhbGxvd2VkIGNoYXJhY3RlcnMga25vd24gdG8gYmUgbm9uLXByaW50YWJsZVxuLy8gc2hvdWxkIGFsc28gYmUgZXNjYXBlZC4gW0hvd2V2ZXIsXSBUaGlzIGlzbuKAmXQgbWFuZGF0b3J5XCJcbi8vIERlcml2ZWQgZnJvbSBuYi1jaGFyIC0gXFx0IC0gI3g4NSAtICN4QTAgLSAjeDIwMjggLSAjeDIwMjkuXG5mdW5jdGlvbiBpc1ByaW50YWJsZShjKSB7XG4gIHJldHVybiAgKDB4MDAwMjAgPD0gYyAmJiBjIDw9IDB4MDAwMDdFKVxuICAgICAgfHwgKCgweDAwMEExIDw9IGMgJiYgYyA8PSAweDAwRDdGRikgJiYgYyAhPT0gMHgyMDI4ICYmIGMgIT09IDB4MjAyOSlcbiAgICAgIHx8ICgoMHgwRTAwMCA8PSBjICYmIGMgPD0gMHgwMEZGRkQpICYmIGMgIT09IDB4RkVGRiAvKiBCT00gKi8pXG4gICAgICB8fCAgKDB4MTAwMDAgPD0gYyAmJiBjIDw9IDB4MTBGRkZGKTtcbn1cblxuLy8gU2ltcGxpZmllZCB0ZXN0IGZvciB2YWx1ZXMgYWxsb3dlZCBhZnRlciB0aGUgZmlyc3QgY2hhcmFjdGVyIGluIHBsYWluIHN0eWxlLlxuZnVuY3Rpb24gaXNQbGFpblNhZmUoYykge1xuICAvLyBVc2VzIGEgc3Vic2V0IG9mIG5iLWNoYXIgLSBjLWZsb3ctaW5kaWNhdG9yIC0gXCI6XCIgLSBcIiNcIlxuICAvLyB3aGVyZSBuYi1jaGFyIDo6PSBjLXByaW50YWJsZSAtIGItY2hhciAtIGMtYnl0ZS1vcmRlci1tYXJrLlxuICByZXR1cm4gaXNQcmludGFibGUoYykgJiYgYyAhPT0gMHhGRUZGXG4gICAgLy8gLSBjLWZsb3ctaW5kaWNhdG9yXG4gICAgJiYgYyAhPT0gQ0hBUl9DT01NQVxuICAgICYmIGMgIT09IENIQVJfTEVGVF9TUVVBUkVfQlJBQ0tFVFxuICAgICYmIGMgIT09IENIQVJfUklHSFRfU1FVQVJFX0JSQUNLRVRcbiAgICAmJiBjICE9PSBDSEFSX0xFRlRfQ1VSTFlfQlJBQ0tFVFxuICAgICYmIGMgIT09IENIQVJfUklHSFRfQ1VSTFlfQlJBQ0tFVFxuICAgIC8vIC0gXCI6XCIgLSBcIiNcIlxuICAgICYmIGMgIT09IENIQVJfQ09MT05cbiAgICAmJiBjICE9PSBDSEFSX1NIQVJQO1xufVxuXG4vLyBTaW1wbGlmaWVkIHRlc3QgZm9yIHZhbHVlcyBhbGxvd2VkIGFzIHRoZSBmaXJzdCBjaGFyYWN0ZXIgaW4gcGxhaW4gc3R5bGUuXG5mdW5jdGlvbiBpc1BsYWluU2FmZUZpcnN0KGMpIHtcbiAgLy8gVXNlcyBhIHN1YnNldCBvZiBucy1jaGFyIC0gYy1pbmRpY2F0b3JcbiAgLy8gd2hlcmUgbnMtY2hhciA9IG5iLWNoYXIgLSBzLXdoaXRlLlxuICByZXR1cm4gaXNQcmludGFibGUoYykgJiYgYyAhPT0gMHhGRUZGXG4gICAgJiYgIWlzV2hpdGVzcGFjZShjKSAvLyAtIHMtd2hpdGVcbiAgICAvLyAtIChjLWluZGljYXRvciA6Oj1cbiAgICAvLyDigJwt4oCdIHwg4oCcP+KAnSB8IOKAnDrigJ0gfCDigJws4oCdIHwg4oCcW+KAnSB8IOKAnF3igJ0gfCDigJx74oCdIHwg4oCcfeKAnVxuICAgICYmIGMgIT09IENIQVJfTUlOVVNcbiAgICAmJiBjICE9PSBDSEFSX1FVRVNUSU9OXG4gICAgJiYgYyAhPT0gQ0hBUl9DT0xPTlxuICAgICYmIGMgIT09IENIQVJfQ09NTUFcbiAgICAmJiBjICE9PSBDSEFSX0xFRlRfU1FVQVJFX0JSQUNLRVRcbiAgICAmJiBjICE9PSBDSEFSX1JJR0hUX1NRVUFSRV9CUkFDS0VUXG4gICAgJiYgYyAhPT0gQ0hBUl9MRUZUX0NVUkxZX0JSQUNLRVRcbiAgICAmJiBjICE9PSBDSEFSX1JJR0hUX0NVUkxZX0JSQUNLRVRcbiAgICAvLyB8IOKAnCPigJ0gfCDigJwm4oCdIHwg4oCcKuKAnSB8IOKAnCHigJ0gfCDigJx84oCdIHwg4oCcPuKAnSB8IOKAnCfigJ0gfCDigJxcIuKAnVxuICAgICYmIGMgIT09IENIQVJfU0hBUlBcbiAgICAmJiBjICE9PSBDSEFSX0FNUEVSU0FORFxuICAgICYmIGMgIT09IENIQVJfQVNURVJJU0tcbiAgICAmJiBjICE9PSBDSEFSX0VYQ0xBTUFUSU9OXG4gICAgJiYgYyAhPT0gQ0hBUl9WRVJUSUNBTF9MSU5FXG4gICAgJiYgYyAhPT0gQ0hBUl9HUkVBVEVSX1RIQU5cbiAgICAmJiBjICE9PSBDSEFSX1NJTkdMRV9RVU9URVxuICAgICYmIGMgIT09IENIQVJfRE9VQkxFX1FVT1RFXG4gICAgLy8gfCDigJwl4oCdIHwg4oCcQOKAnSB8IOKAnGDigJ0pXG4gICAgJiYgYyAhPT0gQ0hBUl9QRVJDRU5UXG4gICAgJiYgYyAhPT0gQ0hBUl9DT01NRVJDSUFMX0FUXG4gICAgJiYgYyAhPT0gQ0hBUl9HUkFWRV9BQ0NFTlQ7XG59XG5cbnZhciBTVFlMRV9QTEFJTiAgID0gMSxcbiAgICBTVFlMRV9TSU5HTEUgID0gMixcbiAgICBTVFlMRV9MSVRFUkFMID0gMyxcbiAgICBTVFlMRV9GT0xERUQgID0gNCxcbiAgICBTVFlMRV9ET1VCTEUgID0gNTtcblxuLy8gRGV0ZXJtaW5lcyB3aGljaCBzY2FsYXIgc3R5bGVzIGFyZSBwb3NzaWJsZSBhbmQgcmV0dXJucyB0aGUgcHJlZmVycmVkIHN0eWxlLlxuLy8gbGluZVdpZHRoID0gLTEgPT4gbm8gbGltaXQuXG4vLyBQcmUtY29uZGl0aW9uczogc3RyLmxlbmd0aCA+IDAuXG4vLyBQb3N0LWNvbmRpdGlvbnM6XG4vLyAgICBTVFlMRV9QTEFJTiBvciBTVFlMRV9TSU5HTEUgPT4gbm8gXFxuIGFyZSBpbiB0aGUgc3RyaW5nLlxuLy8gICAgU1RZTEVfTElURVJBTCA9PiBubyBsaW5lcyBhcmUgc3VpdGFibGUgZm9yIGZvbGRpbmcgKG9yIGxpbmVXaWR0aCBpcyAtMSkuXG4vLyAgICBTVFlMRV9GT0xERUQgPT4gYSBsaW5lID4gbGluZVdpZHRoIGFuZCBjYW4gYmUgZm9sZGVkIChhbmQgbGluZVdpZHRoICE9IC0xKS5cbmZ1bmN0aW9uIGNob29zZVNjYWxhclN0eWxlKHN0cmluZywgc2luZ2xlTGluZU9ubHksIGluZGVudFBlckxldmVsLCBsaW5lV2lkdGgsIHRlc3RBbWJpZ3VvdXNUeXBlKSB7XG4gIHZhciBpO1xuICB2YXIgY2hhcjtcbiAgdmFyIGhhc0xpbmVCcmVhayA9IGZhbHNlO1xuICB2YXIgaGFzRm9sZGFibGVMaW5lID0gZmFsc2U7IC8vIG9ubHkgY2hlY2tlZCBpZiBzaG91bGRUcmFja1dpZHRoXG4gIHZhciBzaG91bGRUcmFja1dpZHRoID0gbGluZVdpZHRoICE9PSAtMTtcbiAgdmFyIHByZXZpb3VzTGluZUJyZWFrID0gLTE7IC8vIGNvdW50IHRoZSBmaXJzdCBsaW5lIGNvcnJlY3RseVxuICB2YXIgcGxhaW4gPSBpc1BsYWluU2FmZUZpcnN0KHN0cmluZy5jaGFyQ29kZUF0KDApKVxuICAgICAgICAgICYmICFpc1doaXRlc3BhY2Uoc3RyaW5nLmNoYXJDb2RlQXQoc3RyaW5nLmxlbmd0aCAtIDEpKTtcblxuICBpZiAoc2luZ2xlTGluZU9ubHkpIHtcbiAgICAvLyBDYXNlOiBubyBibG9jayBzdHlsZXMuXG4gICAgLy8gQ2hlY2sgZm9yIGRpc2FsbG93ZWQgY2hhcmFjdGVycyB0byBydWxlIG91dCBwbGFpbiBhbmQgc2luZ2xlLlxuICAgIGZvciAoaSA9IDA7IGkgPCBzdHJpbmcubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNoYXIgPSBzdHJpbmcuY2hhckNvZGVBdChpKTtcbiAgICAgIGlmICghaXNQcmludGFibGUoY2hhcikpIHtcbiAgICAgICAgcmV0dXJuIFNUWUxFX0RPVUJMRTtcbiAgICAgIH1cbiAgICAgIHBsYWluID0gcGxhaW4gJiYgaXNQbGFpblNhZmUoY2hhcik7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIENhc2U6IGJsb2NrIHN0eWxlcyBwZXJtaXR0ZWQuXG4gICAgZm9yIChpID0gMDsgaSA8IHN0cmluZy5sZW5ndGg7IGkrKykge1xuICAgICAgY2hhciA9IHN0cmluZy5jaGFyQ29kZUF0KGkpO1xuICAgICAgaWYgKGNoYXIgPT09IENIQVJfTElORV9GRUVEKSB7XG4gICAgICAgIGhhc0xpbmVCcmVhayA9IHRydWU7XG4gICAgICAgIC8vIENoZWNrIGlmIGFueSBsaW5lIGNhbiBiZSBmb2xkZWQuXG4gICAgICAgIGlmIChzaG91bGRUcmFja1dpZHRoKSB7XG4gICAgICAgICAgaGFzRm9sZGFibGVMaW5lID0gaGFzRm9sZGFibGVMaW5lIHx8XG4gICAgICAgICAgICAvLyBGb2xkYWJsZSBsaW5lID0gdG9vIGxvbmcsIGFuZCBub3QgbW9yZS1pbmRlbnRlZC5cbiAgICAgICAgICAgIChpIC0gcHJldmlvdXNMaW5lQnJlYWsgLSAxID4gbGluZVdpZHRoICYmXG4gICAgICAgICAgICAgc3RyaW5nW3ByZXZpb3VzTGluZUJyZWFrICsgMV0gIT09ICcgJyk7XG4gICAgICAgICAgcHJldmlvdXNMaW5lQnJlYWsgPSBpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKCFpc1ByaW50YWJsZShjaGFyKSkge1xuICAgICAgICByZXR1cm4gU1RZTEVfRE9VQkxFO1xuICAgICAgfVxuICAgICAgcGxhaW4gPSBwbGFpbiAmJiBpc1BsYWluU2FmZShjaGFyKTtcbiAgICB9XG4gICAgLy8gaW4gY2FzZSB0aGUgZW5kIGlzIG1pc3NpbmcgYSBcXG5cbiAgICBoYXNGb2xkYWJsZUxpbmUgPSBoYXNGb2xkYWJsZUxpbmUgfHwgKHNob3VsZFRyYWNrV2lkdGggJiZcbiAgICAgIChpIC0gcHJldmlvdXNMaW5lQnJlYWsgLSAxID4gbGluZVdpZHRoICYmXG4gICAgICAgc3RyaW5nW3ByZXZpb3VzTGluZUJyZWFrICsgMV0gIT09ICcgJykpO1xuICB9XG4gIC8vIEFsdGhvdWdoIGV2ZXJ5IHN0eWxlIGNhbiByZXByZXNlbnQgXFxuIHdpdGhvdXQgZXNjYXBpbmcsIHByZWZlciBibG9jayBzdHlsZXNcbiAgLy8gZm9yIG11bHRpbGluZSwgc2luY2UgdGhleSdyZSBtb3JlIHJlYWRhYmxlIGFuZCB0aGV5IGRvbid0IGFkZCBlbXB0eSBsaW5lcy5cbiAgLy8gQWxzbyBwcmVmZXIgZm9sZGluZyBhIHN1cGVyLWxvbmcgbGluZS5cbiAgaWYgKCFoYXNMaW5lQnJlYWsgJiYgIWhhc0ZvbGRhYmxlTGluZSkge1xuICAgIC8vIFN0cmluZ3MgaW50ZXJwcmV0YWJsZSBhcyBhbm90aGVyIHR5cGUgaGF2ZSB0byBiZSBxdW90ZWQ7XG4gICAgLy8gZS5nLiB0aGUgc3RyaW5nICd0cnVlJyB2cy4gdGhlIGJvb2xlYW4gdHJ1ZS5cbiAgICByZXR1cm4gcGxhaW4gJiYgIXRlc3RBbWJpZ3VvdXNUeXBlKHN0cmluZylcbiAgICAgID8gU1RZTEVfUExBSU4gOiBTVFlMRV9TSU5HTEU7XG4gIH1cbiAgLy8gRWRnZSBjYXNlOiBibG9jayBpbmRlbnRhdGlvbiBpbmRpY2F0b3IgY2FuIG9ubHkgaGF2ZSBvbmUgZGlnaXQuXG4gIGlmIChzdHJpbmdbMF0gPT09ICcgJyAmJiBpbmRlbnRQZXJMZXZlbCA+IDkpIHtcbiAgICByZXR1cm4gU1RZTEVfRE9VQkxFO1xuICB9XG4gIC8vIEF0IHRoaXMgcG9pbnQgd2Uga25vdyBibG9jayBzdHlsZXMgYXJlIHZhbGlkLlxuICAvLyBQcmVmZXIgbGl0ZXJhbCBzdHlsZSB1bmxlc3Mgd2Ugd2FudCB0byBmb2xkLlxuICByZXR1cm4gaGFzRm9sZGFibGVMaW5lID8gU1RZTEVfRk9MREVEIDogU1RZTEVfTElURVJBTDtcbn1cblxuLy8gTm90ZTogbGluZSBicmVha2luZy9mb2xkaW5nIGlzIGltcGxlbWVudGVkIGZvciBvbmx5IHRoZSBmb2xkZWQgc3R5bGUuXG4vLyBOQi4gV2UgZHJvcCB0aGUgbGFzdCB0cmFpbGluZyBuZXdsaW5lIChpZiBhbnkpIG9mIGEgcmV0dXJuZWQgYmxvY2sgc2NhbGFyXG4vLyAgc2luY2UgdGhlIGR1bXBlciBhZGRzIGl0cyBvd24gbmV3bGluZS4gVGhpcyBhbHdheXMgd29ya3M6XG4vLyAgICDigKIgTm8gZW5kaW5nIG5ld2xpbmUgPT4gdW5hZmZlY3RlZDsgYWxyZWFkeSB1c2luZyBzdHJpcCBcIi1cIiBjaG9tcGluZy5cbi8vICAgIOKAoiBFbmRpbmcgbmV3bGluZSAgICA9PiByZW1vdmVkIHRoZW4gcmVzdG9yZWQuXG4vLyAgSW1wb3J0YW50bHksIHRoaXMga2VlcHMgdGhlIFwiK1wiIGNob21wIGluZGljYXRvciBmcm9tIGdhaW5pbmcgYW4gZXh0cmEgbGluZS5cbmZ1bmN0aW9uIHdyaXRlU2NhbGFyKHN0YXRlLCBzdHJpbmcsIGxldmVsLCBpc2tleSkge1xuICBzdGF0ZS5kdW1wID0gKGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoc3RyaW5nLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIFwiJydcIjtcbiAgICB9XG4gICAgaWYgKCFzdGF0ZS5ub0NvbXBhdE1vZGUgJiZcbiAgICAgICAgREVQUkVDQVRFRF9CT09MRUFOU19TWU5UQVguaW5kZXhPZihzdHJpbmcpICE9PSAtMSkge1xuICAgICAgcmV0dXJuIFwiJ1wiICsgc3RyaW5nICsgXCInXCI7XG4gICAgfVxuXG4gICAgdmFyIGluZGVudCA9IHN0YXRlLmluZGVudCAqIE1hdGgubWF4KDEsIGxldmVsKTsgLy8gbm8gMC1pbmRlbnQgc2NhbGFyc1xuICAgIC8vIEFzIGluZGVudGF0aW9uIGdldHMgZGVlcGVyLCBsZXQgdGhlIHdpZHRoIGRlY3JlYXNlIG1vbm90b25pY2FsbHlcbiAgICAvLyB0byB0aGUgbG93ZXIgYm91bmQgbWluKHN0YXRlLmxpbmVXaWR0aCwgNDApLlxuICAgIC8vIE5vdGUgdGhhdCB0aGlzIGltcGxpZXNcbiAgICAvLyAgc3RhdGUubGluZVdpZHRoIOKJpCA0MCArIHN0YXRlLmluZGVudDogd2lkdGggaXMgZml4ZWQgYXQgdGhlIGxvd2VyIGJvdW5kLlxuICAgIC8vICBzdGF0ZS5saW5lV2lkdGggPiA0MCArIHN0YXRlLmluZGVudDogd2lkdGggZGVjcmVhc2VzIHVudGlsIHRoZSBsb3dlciBib3VuZC5cbiAgICAvLyBUaGlzIGJlaGF2ZXMgYmV0dGVyIHRoYW4gYSBjb25zdGFudCBtaW5pbXVtIHdpZHRoIHdoaWNoIGRpc2FsbG93cyBuYXJyb3dlciBvcHRpb25zLFxuICAgIC8vIG9yIGFuIGluZGVudCB0aHJlc2hvbGQgd2hpY2ggY2F1c2VzIHRoZSB3aWR0aCB0byBzdWRkZW5seSBpbmNyZWFzZS5cbiAgICB2YXIgbGluZVdpZHRoID0gc3RhdGUubGluZVdpZHRoID09PSAtMVxuICAgICAgPyAtMSA6IE1hdGgubWF4KE1hdGgubWluKHN0YXRlLmxpbmVXaWR0aCwgNDApLCBzdGF0ZS5saW5lV2lkdGggLSBpbmRlbnQpO1xuXG4gICAgLy8gV2l0aG91dCBrbm93aW5nIGlmIGtleXMgYXJlIGltcGxpY2l0L2V4cGxpY2l0LCBhc3N1bWUgaW1wbGljaXQgZm9yIHNhZmV0eS5cbiAgICB2YXIgc2luZ2xlTGluZU9ubHkgPSBpc2tleVxuICAgICAgLy8gTm8gYmxvY2sgc3R5bGVzIGluIGZsb3cgbW9kZS5cbiAgICAgIHx8IChzdGF0ZS5mbG93TGV2ZWwgPiAtMSAmJiBsZXZlbCA+PSBzdGF0ZS5mbG93TGV2ZWwpO1xuICAgIGZ1bmN0aW9uIHRlc3RBbWJpZ3VpdHkoc3RyaW5nKSB7XG4gICAgICByZXR1cm4gdGVzdEltcGxpY2l0UmVzb2x2aW5nKHN0YXRlLCBzdHJpbmcpO1xuICAgIH1cblxuICAgIHN3aXRjaCAoY2hvb3NlU2NhbGFyU3R5bGUoc3RyaW5nLCBzaW5nbGVMaW5lT25seSwgc3RhdGUuaW5kZW50LCBsaW5lV2lkdGgsIHRlc3RBbWJpZ3VpdHkpKSB7XG4gICAgICBjYXNlIFNUWUxFX1BMQUlOOlxuICAgICAgICByZXR1cm4gc3RyaW5nO1xuICAgICAgY2FzZSBTVFlMRV9TSU5HTEU6XG4gICAgICAgIHJldHVybiBcIidcIiArIHN0cmluZy5yZXBsYWNlKC8nL2csIFwiJydcIikgKyBcIidcIjtcbiAgICAgIGNhc2UgU1RZTEVfTElURVJBTDpcbiAgICAgICAgcmV0dXJuICd8JyArIGJsb2NrSGVhZGVyKHN0cmluZywgc3RhdGUuaW5kZW50KVxuICAgICAgICAgICsgZHJvcEVuZGluZ05ld2xpbmUoaW5kZW50U3RyaW5nKHN0cmluZywgaW5kZW50KSk7XG4gICAgICBjYXNlIFNUWUxFX0ZPTERFRDpcbiAgICAgICAgcmV0dXJuICc+JyArIGJsb2NrSGVhZGVyKHN0cmluZywgc3RhdGUuaW5kZW50KVxuICAgICAgICAgICsgZHJvcEVuZGluZ05ld2xpbmUoaW5kZW50U3RyaW5nKGZvbGRTdHJpbmcoc3RyaW5nLCBsaW5lV2lkdGgpLCBpbmRlbnQpKTtcbiAgICAgIGNhc2UgU1RZTEVfRE9VQkxFOlxuICAgICAgICByZXR1cm4gJ1wiJyArIGVzY2FwZVN0cmluZyhzdHJpbmcsIGxpbmVXaWR0aCkgKyAnXCInO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJ2ltcG9zc2libGUgZXJyb3I6IGludmFsaWQgc2NhbGFyIHN0eWxlJyk7XG4gICAgfVxuICB9KCkpO1xufVxuXG4vLyBQcmUtY29uZGl0aW9uczogc3RyaW5nIGlzIHZhbGlkIGZvciBhIGJsb2NrIHNjYWxhciwgMSA8PSBpbmRlbnRQZXJMZXZlbCA8PSA5LlxuZnVuY3Rpb24gYmxvY2tIZWFkZXIoc3RyaW5nLCBpbmRlbnRQZXJMZXZlbCkge1xuICB2YXIgaW5kZW50SW5kaWNhdG9yID0gKHN0cmluZ1swXSA9PT0gJyAnKSA/IFN0cmluZyhpbmRlbnRQZXJMZXZlbCkgOiAnJztcblxuICAvLyBub3RlIHRoZSBzcGVjaWFsIGNhc2U6IHRoZSBzdHJpbmcgJ1xcbicgY291bnRzIGFzIGEgXCJ0cmFpbGluZ1wiIGVtcHR5IGxpbmUuXG4gIHZhciBjbGlwID0gICAgICAgICAgc3RyaW5nW3N0cmluZy5sZW5ndGggLSAxXSA9PT0gJ1xcbic7XG4gIHZhciBrZWVwID0gY2xpcCAmJiAoc3RyaW5nW3N0cmluZy5sZW5ndGggLSAyXSA9PT0gJ1xcbicgfHwgc3RyaW5nID09PSAnXFxuJyk7XG4gIHZhciBjaG9tcCA9IGtlZXAgPyAnKycgOiAoY2xpcCA/ICcnIDogJy0nKTtcblxuICByZXR1cm4gaW5kZW50SW5kaWNhdG9yICsgY2hvbXAgKyAnXFxuJztcbn1cblxuLy8gKFNlZSB0aGUgbm90ZSBmb3Igd3JpdGVTY2FsYXIuKVxuZnVuY3Rpb24gZHJvcEVuZGluZ05ld2xpbmUoc3RyaW5nKSB7XG4gIHJldHVybiBzdHJpbmdbc3RyaW5nLmxlbmd0aCAtIDFdID09PSAnXFxuJyA/IHN0cmluZy5zbGljZSgwLCAtMSkgOiBzdHJpbmc7XG59XG5cbi8vIE5vdGU6IGEgbG9uZyBsaW5lIHdpdGhvdXQgYSBzdWl0YWJsZSBicmVhayBwb2ludCB3aWxsIGV4Y2VlZCB0aGUgd2lkdGggbGltaXQuXG4vLyBQcmUtY29uZGl0aW9uczogZXZlcnkgY2hhciBpbiBzdHIgaXNQcmludGFibGUsIHN0ci5sZW5ndGggPiAwLCB3aWR0aCA+IDAuXG5mdW5jdGlvbiBmb2xkU3RyaW5nKHN0cmluZywgd2lkdGgpIHtcbiAgLy8gSW4gZm9sZGVkIHN0eWxlLCAkayQgY29uc2VjdXRpdmUgbmV3bGluZXMgb3V0cHV0IGFzICRrKzEkIG5ld2xpbmVz4oCUXG4gIC8vIHVubGVzcyB0aGV5J3JlIGJlZm9yZSBvciBhZnRlciBhIG1vcmUtaW5kZW50ZWQgbGluZSwgb3IgYXQgdGhlIHZlcnlcbiAgLy8gYmVnaW5uaW5nIG9yIGVuZCwgaW4gd2hpY2ggY2FzZSAkayQgbWFwcyB0byAkayQuXG4gIC8vIFRoZXJlZm9yZSwgcGFyc2UgZWFjaCBjaHVuayBhcyBuZXdsaW5lKHMpIGZvbGxvd2VkIGJ5IGEgY29udGVudCBsaW5lLlxuICB2YXIgbGluZVJlID0gLyhcXG4rKShbXlxcbl0qKS9nO1xuXG4gIC8vIGZpcnN0IGxpbmUgKHBvc3NpYmx5IGFuIGVtcHR5IGxpbmUpXG4gIHZhciByZXN1bHQgPSAoZnVuY3Rpb24gKCkge1xuICAgIHZhciBuZXh0TEYgPSBzdHJpbmcuaW5kZXhPZignXFxuJyk7XG4gICAgbmV4dExGID0gbmV4dExGICE9PSAtMSA/IG5leHRMRiA6IHN0cmluZy5sZW5ndGg7XG4gICAgbGluZVJlLmxhc3RJbmRleCA9IG5leHRMRjtcbiAgICByZXR1cm4gZm9sZExpbmUoc3RyaW5nLnNsaWNlKDAsIG5leHRMRiksIHdpZHRoKTtcbiAgfSgpKTtcbiAgLy8gSWYgd2UgaGF2ZW4ndCByZWFjaGVkIHRoZSBmaXJzdCBjb250ZW50IGxpbmUgeWV0LCBkb24ndCBhZGQgYW4gZXh0cmEgXFxuLlxuICB2YXIgcHJldk1vcmVJbmRlbnRlZCA9IHN0cmluZ1swXSA9PT0gJ1xcbicgfHwgc3RyaW5nWzBdID09PSAnICc7XG4gIHZhciBtb3JlSW5kZW50ZWQ7XG5cbiAgLy8gcmVzdCBvZiB0aGUgbGluZXNcbiAgdmFyIG1hdGNoO1xuICB3aGlsZSAoKG1hdGNoID0gbGluZVJlLmV4ZWMoc3RyaW5nKSkpIHtcbiAgICB2YXIgcHJlZml4ID0gbWF0Y2hbMV0sIGxpbmUgPSBtYXRjaFsyXTtcbiAgICBtb3JlSW5kZW50ZWQgPSAobGluZVswXSA9PT0gJyAnKTtcbiAgICByZXN1bHQgKz0gcHJlZml4XG4gICAgICArICghcHJldk1vcmVJbmRlbnRlZCAmJiAhbW9yZUluZGVudGVkICYmIGxpbmUgIT09ICcnXG4gICAgICAgID8gJ1xcbicgOiAnJylcbiAgICAgICsgZm9sZExpbmUobGluZSwgd2lkdGgpO1xuICAgIHByZXZNb3JlSW5kZW50ZWQgPSBtb3JlSW5kZW50ZWQ7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vLyBHcmVlZHkgbGluZSBicmVha2luZy5cbi8vIFBpY2tzIHRoZSBsb25nZXN0IGxpbmUgdW5kZXIgdGhlIGxpbWl0IGVhY2ggdGltZSxcbi8vIG90aGVyd2lzZSBzZXR0bGVzIGZvciB0aGUgc2hvcnRlc3QgbGluZSBvdmVyIHRoZSBsaW1pdC5cbi8vIE5CLiBNb3JlLWluZGVudGVkIGxpbmVzICpjYW5ub3QqIGJlIGZvbGRlZCwgYXMgdGhhdCB3b3VsZCBhZGQgYW4gZXh0cmEgXFxuLlxuZnVuY3Rpb24gZm9sZExpbmUobGluZSwgd2lkdGgpIHtcbiAgaWYgKGxpbmUgPT09ICcnIHx8IGxpbmVbMF0gPT09ICcgJykgcmV0dXJuIGxpbmU7XG5cbiAgLy8gU2luY2UgYSBtb3JlLWluZGVudGVkIGxpbmUgYWRkcyBhIFxcbiwgYnJlYWtzIGNhbid0IGJlIGZvbGxvd2VkIGJ5IGEgc3BhY2UuXG4gIHZhciBicmVha1JlID0gLyBbXiBdL2c7IC8vIG5vdGU6IHRoZSBtYXRjaCBpbmRleCB3aWxsIGFsd2F5cyBiZSA8PSBsZW5ndGgtMi5cbiAgdmFyIG1hdGNoO1xuICAvLyBzdGFydCBpcyBhbiBpbmNsdXNpdmUgaW5kZXguIGVuZCwgY3VyciwgYW5kIG5leHQgYXJlIGV4Y2x1c2l2ZS5cbiAgdmFyIHN0YXJ0ID0gMCwgZW5kLCBjdXJyID0gMCwgbmV4dCA9IDA7XG4gIHZhciByZXN1bHQgPSAnJztcblxuICAvLyBJbnZhcmlhbnRzOiAwIDw9IHN0YXJ0IDw9IGxlbmd0aC0xLlxuICAvLyAgIDAgPD0gY3VyciA8PSBuZXh0IDw9IG1heCgwLCBsZW5ndGgtMikuIGN1cnIgLSBzdGFydCA8PSB3aWR0aC5cbiAgLy8gSW5zaWRlIHRoZSBsb29wOlxuICAvLyAgIEEgbWF0Y2ggaW1wbGllcyBsZW5ndGggPj0gMiwgc28gY3VyciBhbmQgbmV4dCBhcmUgPD0gbGVuZ3RoLTIuXG4gIHdoaWxlICgobWF0Y2ggPSBicmVha1JlLmV4ZWMobGluZSkpKSB7XG4gICAgbmV4dCA9IG1hdGNoLmluZGV4O1xuICAgIC8vIG1haW50YWluIGludmFyaWFudDogY3VyciAtIHN0YXJ0IDw9IHdpZHRoXG4gICAgaWYgKG5leHQgLSBzdGFydCA+IHdpZHRoKSB7XG4gICAgICBlbmQgPSAoY3VyciA+IHN0YXJ0KSA/IGN1cnIgOiBuZXh0OyAvLyBkZXJpdmUgZW5kIDw9IGxlbmd0aC0yXG4gICAgICByZXN1bHQgKz0gJ1xcbicgKyBsaW5lLnNsaWNlKHN0YXJ0LCBlbmQpO1xuICAgICAgLy8gc2tpcCB0aGUgc3BhY2UgdGhhdCB3YXMgb3V0cHV0IGFzIFxcblxuICAgICAgc3RhcnQgPSBlbmQgKyAxOyAgICAgICAgICAgICAgICAgICAgLy8gZGVyaXZlIHN0YXJ0IDw9IGxlbmd0aC0xXG4gICAgfVxuICAgIGN1cnIgPSBuZXh0O1xuICB9XG5cbiAgLy8gQnkgdGhlIGludmFyaWFudHMsIHN0YXJ0IDw9IGxlbmd0aC0xLCBzbyB0aGVyZSBpcyBzb21ldGhpbmcgbGVmdCBvdmVyLlxuICAvLyBJdCBpcyBlaXRoZXIgdGhlIHdob2xlIHN0cmluZyBvciBhIHBhcnQgc3RhcnRpbmcgZnJvbSBub24td2hpdGVzcGFjZS5cbiAgcmVzdWx0ICs9ICdcXG4nO1xuICAvLyBJbnNlcnQgYSBicmVhayBpZiB0aGUgcmVtYWluZGVyIGlzIHRvbyBsb25nIGFuZCB0aGVyZSBpcyBhIGJyZWFrIGF2YWlsYWJsZS5cbiAgaWYgKGxpbmUubGVuZ3RoIC0gc3RhcnQgPiB3aWR0aCAmJiBjdXJyID4gc3RhcnQpIHtcbiAgICByZXN1bHQgKz0gbGluZS5zbGljZShzdGFydCwgY3VycikgKyAnXFxuJyArIGxpbmUuc2xpY2UoY3VyciArIDEpO1xuICB9IGVsc2Uge1xuICAgIHJlc3VsdCArPSBsaW5lLnNsaWNlKHN0YXJ0KTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQuc2xpY2UoMSk7IC8vIGRyb3AgZXh0cmEgXFxuIGpvaW5lclxufVxuXG4vLyBFc2NhcGVzIGEgZG91YmxlLXF1b3RlZCBzdHJpbmcuXG5mdW5jdGlvbiBlc2NhcGVTdHJpbmcoc3RyaW5nKSB7XG4gIHZhciByZXN1bHQgPSAnJztcbiAgdmFyIGNoYXI7XG4gIHZhciBlc2NhcGVTZXE7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHJpbmcubGVuZ3RoOyBpKyspIHtcbiAgICBjaGFyID0gc3RyaW5nLmNoYXJDb2RlQXQoaSk7XG4gICAgZXNjYXBlU2VxID0gRVNDQVBFX1NFUVVFTkNFU1tjaGFyXTtcbiAgICByZXN1bHQgKz0gIWVzY2FwZVNlcSAmJiBpc1ByaW50YWJsZShjaGFyKVxuICAgICAgPyBzdHJpbmdbaV1cbiAgICAgIDogZXNjYXBlU2VxIHx8IGVuY29kZUhleChjaGFyKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIHdyaXRlRmxvd1NlcXVlbmNlKHN0YXRlLCBsZXZlbCwgb2JqZWN0KSB7XG4gIHZhciBfcmVzdWx0ID0gJycsXG4gICAgICBfdGFnICAgID0gc3RhdGUudGFnLFxuICAgICAgaW5kZXgsXG4gICAgICBsZW5ndGg7XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IG9iamVjdC5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgLy8gV3JpdGUgb25seSB2YWxpZCBlbGVtZW50cy5cbiAgICBpZiAod3JpdGVOb2RlKHN0YXRlLCBsZXZlbCwgb2JqZWN0W2luZGV4XSwgZmFsc2UsIGZhbHNlKSkge1xuICAgICAgaWYgKGluZGV4ICE9PSAwKSBfcmVzdWx0ICs9ICcsICc7XG4gICAgICBfcmVzdWx0ICs9IHN0YXRlLmR1bXA7XG4gICAgfVxuICB9XG5cbiAgc3RhdGUudGFnID0gX3RhZztcbiAgc3RhdGUuZHVtcCA9ICdbJyArIF9yZXN1bHQgKyAnXSc7XG59XG5cbmZ1bmN0aW9uIHdyaXRlQmxvY2tTZXF1ZW5jZShzdGF0ZSwgbGV2ZWwsIG9iamVjdCwgY29tcGFjdCkge1xuICB2YXIgX3Jlc3VsdCA9ICcnLFxuICAgICAgX3RhZyAgICA9IHN0YXRlLnRhZyxcbiAgICAgIGluZGV4LFxuICAgICAgbGVuZ3RoO1xuXG4gIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBvYmplY3QubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIC8vIFdyaXRlIG9ubHkgdmFsaWQgZWxlbWVudHMuXG4gICAgaWYgKHdyaXRlTm9kZShzdGF0ZSwgbGV2ZWwgKyAxLCBvYmplY3RbaW5kZXhdLCB0cnVlLCB0cnVlKSkge1xuICAgICAgaWYgKCFjb21wYWN0IHx8IGluZGV4ICE9PSAwKSB7XG4gICAgICAgIF9yZXN1bHQgKz0gZ2VuZXJhdGVOZXh0TGluZShzdGF0ZSwgbGV2ZWwpO1xuICAgICAgfVxuICAgICAgX3Jlc3VsdCArPSAnLSAnICsgc3RhdGUuZHVtcDtcbiAgICB9XG4gIH1cblxuICBzdGF0ZS50YWcgPSBfdGFnO1xuICBzdGF0ZS5kdW1wID0gX3Jlc3VsdCB8fCAnW10nOyAvLyBFbXB0eSBzZXF1ZW5jZSBpZiBubyB2YWxpZCB2YWx1ZXMuXG59XG5cbmZ1bmN0aW9uIHdyaXRlRmxvd01hcHBpbmcoc3RhdGUsIGxldmVsLCBvYmplY3QpIHtcbiAgdmFyIF9yZXN1bHQgICAgICAgPSAnJyxcbiAgICAgIF90YWcgICAgICAgICAgPSBzdGF0ZS50YWcsXG4gICAgICBvYmplY3RLZXlMaXN0ID0gT2JqZWN0LmtleXMob2JqZWN0KSxcbiAgICAgIGluZGV4LFxuICAgICAgbGVuZ3RoLFxuICAgICAgb2JqZWN0S2V5LFxuICAgICAgb2JqZWN0VmFsdWUsXG4gICAgICBwYWlyQnVmZmVyO1xuXG4gIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBvYmplY3RLZXlMaXN0Lmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICBwYWlyQnVmZmVyID0gJyc7XG5cbiAgICBpZiAoaW5kZXggIT09IDApIHBhaXJCdWZmZXIgKz0gJywgJztcblxuICAgIG9iamVjdEtleSA9IG9iamVjdEtleUxpc3RbaW5kZXhdO1xuICAgIG9iamVjdFZhbHVlID0gb2JqZWN0W29iamVjdEtleV07XG5cbiAgICBpZiAoIXdyaXRlTm9kZShzdGF0ZSwgbGV2ZWwsIG9iamVjdEtleSwgZmFsc2UsIGZhbHNlKSkge1xuICAgICAgY29udGludWU7IC8vIFNraXAgdGhpcyBwYWlyIGJlY2F1c2Ugb2YgaW52YWxpZCBrZXk7XG4gICAgfVxuXG4gICAgaWYgKHN0YXRlLmR1bXAubGVuZ3RoID4gMTAyNCkgcGFpckJ1ZmZlciArPSAnPyAnO1xuXG4gICAgcGFpckJ1ZmZlciArPSBzdGF0ZS5kdW1wICsgJzogJztcblxuICAgIGlmICghd3JpdGVOb2RlKHN0YXRlLCBsZXZlbCwgb2JqZWN0VmFsdWUsIGZhbHNlLCBmYWxzZSkpIHtcbiAgICAgIGNvbnRpbnVlOyAvLyBTa2lwIHRoaXMgcGFpciBiZWNhdXNlIG9mIGludmFsaWQgdmFsdWUuXG4gICAgfVxuXG4gICAgcGFpckJ1ZmZlciArPSBzdGF0ZS5kdW1wO1xuXG4gICAgLy8gQm90aCBrZXkgYW5kIHZhbHVlIGFyZSB2YWxpZC5cbiAgICBfcmVzdWx0ICs9IHBhaXJCdWZmZXI7XG4gIH1cblxuICBzdGF0ZS50YWcgPSBfdGFnO1xuICBzdGF0ZS5kdW1wID0gJ3snICsgX3Jlc3VsdCArICd9Jztcbn1cblxuZnVuY3Rpb24gd3JpdGVCbG9ja01hcHBpbmcoc3RhdGUsIGxldmVsLCBvYmplY3QsIGNvbXBhY3QpIHtcbiAgdmFyIF9yZXN1bHQgICAgICAgPSAnJyxcbiAgICAgIF90YWcgICAgICAgICAgPSBzdGF0ZS50YWcsXG4gICAgICBvYmplY3RLZXlMaXN0ID0gT2JqZWN0LmtleXMob2JqZWN0KSxcbiAgICAgIGluZGV4LFxuICAgICAgbGVuZ3RoLFxuICAgICAgb2JqZWN0S2V5LFxuICAgICAgb2JqZWN0VmFsdWUsXG4gICAgICBleHBsaWNpdFBhaXIsXG4gICAgICBwYWlyQnVmZmVyO1xuXG4gIC8vIEFsbG93IHNvcnRpbmcga2V5cyBzbyB0aGF0IHRoZSBvdXRwdXQgZmlsZSBpcyBkZXRlcm1pbmlzdGljXG4gIGlmIChzdGF0ZS5zb3J0S2V5cyA9PT0gdHJ1ZSkge1xuICAgIC8vIERlZmF1bHQgc29ydGluZ1xuICAgIG9iamVjdEtleUxpc3Quc29ydCgpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBzdGF0ZS5zb3J0S2V5cyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIC8vIEN1c3RvbSBzb3J0IGZ1bmN0aW9uXG4gICAgb2JqZWN0S2V5TGlzdC5zb3J0KHN0YXRlLnNvcnRLZXlzKTtcbiAgfSBlbHNlIGlmIChzdGF0ZS5zb3J0S2V5cykge1xuICAgIC8vIFNvbWV0aGluZyBpcyB3cm9uZ1xuICAgIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCdzb3J0S2V5cyBtdXN0IGJlIGEgYm9vbGVhbiBvciBhIGZ1bmN0aW9uJyk7XG4gIH1cblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gb2JqZWN0S2V5TGlzdC5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgcGFpckJ1ZmZlciA9ICcnO1xuXG4gICAgaWYgKCFjb21wYWN0IHx8IGluZGV4ICE9PSAwKSB7XG4gICAgICBwYWlyQnVmZmVyICs9IGdlbmVyYXRlTmV4dExpbmUoc3RhdGUsIGxldmVsKTtcbiAgICB9XG5cbiAgICBvYmplY3RLZXkgPSBvYmplY3RLZXlMaXN0W2luZGV4XTtcbiAgICBvYmplY3RWYWx1ZSA9IG9iamVjdFtvYmplY3RLZXldO1xuXG4gICAgaWYgKCF3cml0ZU5vZGUoc3RhdGUsIGxldmVsICsgMSwgb2JqZWN0S2V5LCB0cnVlLCB0cnVlLCB0cnVlKSkge1xuICAgICAgY29udGludWU7IC8vIFNraXAgdGhpcyBwYWlyIGJlY2F1c2Ugb2YgaW52YWxpZCBrZXkuXG4gICAgfVxuXG4gICAgZXhwbGljaXRQYWlyID0gKHN0YXRlLnRhZyAhPT0gbnVsbCAmJiBzdGF0ZS50YWcgIT09ICc/JykgfHxcbiAgICAgICAgICAgICAgICAgICAoc3RhdGUuZHVtcCAmJiBzdGF0ZS5kdW1wLmxlbmd0aCA+IDEwMjQpO1xuXG4gICAgaWYgKGV4cGxpY2l0UGFpcikge1xuICAgICAgaWYgKHN0YXRlLmR1bXAgJiYgQ0hBUl9MSU5FX0ZFRUQgPT09IHN0YXRlLmR1bXAuY2hhckNvZGVBdCgwKSkge1xuICAgICAgICBwYWlyQnVmZmVyICs9ICc/JztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBhaXJCdWZmZXIgKz0gJz8gJztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBwYWlyQnVmZmVyICs9IHN0YXRlLmR1bXA7XG5cbiAgICBpZiAoZXhwbGljaXRQYWlyKSB7XG4gICAgICBwYWlyQnVmZmVyICs9IGdlbmVyYXRlTmV4dExpbmUoc3RhdGUsIGxldmVsKTtcbiAgICB9XG5cbiAgICBpZiAoIXdyaXRlTm9kZShzdGF0ZSwgbGV2ZWwgKyAxLCBvYmplY3RWYWx1ZSwgdHJ1ZSwgZXhwbGljaXRQYWlyKSkge1xuICAgICAgY29udGludWU7IC8vIFNraXAgdGhpcyBwYWlyIGJlY2F1c2Ugb2YgaW52YWxpZCB2YWx1ZS5cbiAgICB9XG5cbiAgICBpZiAoc3RhdGUuZHVtcCAmJiBDSEFSX0xJTkVfRkVFRCA9PT0gc3RhdGUuZHVtcC5jaGFyQ29kZUF0KDApKSB7XG4gICAgICBwYWlyQnVmZmVyICs9ICc6JztcbiAgICB9IGVsc2Uge1xuICAgICAgcGFpckJ1ZmZlciArPSAnOiAnO1xuICAgIH1cblxuICAgIHBhaXJCdWZmZXIgKz0gc3RhdGUuZHVtcDtcblxuICAgIC8vIEJvdGgga2V5IGFuZCB2YWx1ZSBhcmUgdmFsaWQuXG4gICAgX3Jlc3VsdCArPSBwYWlyQnVmZmVyO1xuICB9XG5cbiAgc3RhdGUudGFnID0gX3RhZztcbiAgc3RhdGUuZHVtcCA9IF9yZXN1bHQgfHwgJ3t9JzsgLy8gRW1wdHkgbWFwcGluZyBpZiBubyB2YWxpZCBwYWlycy5cbn1cblxuZnVuY3Rpb24gZGV0ZWN0VHlwZShzdGF0ZSwgb2JqZWN0LCBleHBsaWNpdCkge1xuICB2YXIgX3Jlc3VsdCwgdHlwZUxpc3QsIGluZGV4LCBsZW5ndGgsIHR5cGUsIHN0eWxlO1xuXG4gIHR5cGVMaXN0ID0gZXhwbGljaXQgPyBzdGF0ZS5leHBsaWNpdFR5cGVzIDogc3RhdGUuaW1wbGljaXRUeXBlcztcblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gdHlwZUxpc3QubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIHR5cGUgPSB0eXBlTGlzdFtpbmRleF07XG5cbiAgICBpZiAoKHR5cGUuaW5zdGFuY2VPZiAgfHwgdHlwZS5wcmVkaWNhdGUpICYmXG4gICAgICAgICghdHlwZS5pbnN0YW5jZU9mIHx8ICgodHlwZW9mIG9iamVjdCA9PT0gJ29iamVjdCcpICYmIChvYmplY3QgaW5zdGFuY2VvZiB0eXBlLmluc3RhbmNlT2YpKSkgJiZcbiAgICAgICAgKCF0eXBlLnByZWRpY2F0ZSAgfHwgdHlwZS5wcmVkaWNhdGUob2JqZWN0KSkpIHtcblxuICAgICAgc3RhdGUudGFnID0gZXhwbGljaXQgPyB0eXBlLnRhZyA6ICc/JztcblxuICAgICAgaWYgKHR5cGUucmVwcmVzZW50KSB7XG4gICAgICAgIHN0eWxlID0gc3RhdGUuc3R5bGVNYXBbdHlwZS50YWddIHx8IHR5cGUuZGVmYXVsdFN0eWxlO1xuXG4gICAgICAgIGlmIChfdG9TdHJpbmcuY2FsbCh0eXBlLnJlcHJlc2VudCkgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXScpIHtcbiAgICAgICAgICBfcmVzdWx0ID0gdHlwZS5yZXByZXNlbnQob2JqZWN0LCBzdHlsZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoX2hhc093blByb3BlcnR5LmNhbGwodHlwZS5yZXByZXNlbnQsIHN0eWxlKSkge1xuICAgICAgICAgIF9yZXN1bHQgPSB0eXBlLnJlcHJlc2VudFtzdHlsZV0ob2JqZWN0LCBzdHlsZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJyE8JyArIHR5cGUudGFnICsgJz4gdGFnIHJlc29sdmVyIGFjY2VwdHMgbm90IFwiJyArIHN0eWxlICsgJ1wiIHN0eWxlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBzdGF0ZS5kdW1wID0gX3Jlc3VsdDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vLyBTZXJpYWxpemVzIGBvYmplY3RgIGFuZCB3cml0ZXMgaXQgdG8gZ2xvYmFsIGByZXN1bHRgLlxuLy8gUmV0dXJucyB0cnVlIG9uIHN1Y2Nlc3MsIG9yIGZhbHNlIG9uIGludmFsaWQgb2JqZWN0LlxuLy9cbmZ1bmN0aW9uIHdyaXRlTm9kZShzdGF0ZSwgbGV2ZWwsIG9iamVjdCwgYmxvY2ssIGNvbXBhY3QsIGlza2V5KSB7XG4gIHN0YXRlLnRhZyA9IG51bGw7XG4gIHN0YXRlLmR1bXAgPSBvYmplY3Q7XG5cbiAgaWYgKCFkZXRlY3RUeXBlKHN0YXRlLCBvYmplY3QsIGZhbHNlKSkge1xuICAgIGRldGVjdFR5cGUoc3RhdGUsIG9iamVjdCwgdHJ1ZSk7XG4gIH1cblxuICB2YXIgdHlwZSA9IF90b1N0cmluZy5jYWxsKHN0YXRlLmR1bXApO1xuXG4gIGlmIChibG9jaykge1xuICAgIGJsb2NrID0gKHN0YXRlLmZsb3dMZXZlbCA8IDAgfHwgc3RhdGUuZmxvd0xldmVsID4gbGV2ZWwpO1xuICB9XG5cbiAgdmFyIG9iamVjdE9yQXJyYXkgPSB0eXBlID09PSAnW29iamVjdCBPYmplY3RdJyB8fCB0eXBlID09PSAnW29iamVjdCBBcnJheV0nLFxuICAgICAgZHVwbGljYXRlSW5kZXgsXG4gICAgICBkdXBsaWNhdGU7XG5cbiAgaWYgKG9iamVjdE9yQXJyYXkpIHtcbiAgICBkdXBsaWNhdGVJbmRleCA9IHN0YXRlLmR1cGxpY2F0ZXMuaW5kZXhPZihvYmplY3QpO1xuICAgIGR1cGxpY2F0ZSA9IGR1cGxpY2F0ZUluZGV4ICE9PSAtMTtcbiAgfVxuXG4gIGlmICgoc3RhdGUudGFnICE9PSBudWxsICYmIHN0YXRlLnRhZyAhPT0gJz8nKSB8fCBkdXBsaWNhdGUgfHwgKHN0YXRlLmluZGVudCAhPT0gMiAmJiBsZXZlbCA+IDApKSB7XG4gICAgY29tcGFjdCA9IGZhbHNlO1xuICB9XG5cbiAgaWYgKGR1cGxpY2F0ZSAmJiBzdGF0ZS51c2VkRHVwbGljYXRlc1tkdXBsaWNhdGVJbmRleF0pIHtcbiAgICBzdGF0ZS5kdW1wID0gJypyZWZfJyArIGR1cGxpY2F0ZUluZGV4O1xuICB9IGVsc2Uge1xuICAgIGlmIChvYmplY3RPckFycmF5ICYmIGR1cGxpY2F0ZSAmJiAhc3RhdGUudXNlZER1cGxpY2F0ZXNbZHVwbGljYXRlSW5kZXhdKSB7XG4gICAgICBzdGF0ZS51c2VkRHVwbGljYXRlc1tkdXBsaWNhdGVJbmRleF0gPSB0cnVlO1xuICAgIH1cbiAgICBpZiAodHlwZSA9PT0gJ1tvYmplY3QgT2JqZWN0XScpIHtcbiAgICAgIGlmIChibG9jayAmJiAoT2JqZWN0LmtleXMoc3RhdGUuZHVtcCkubGVuZ3RoICE9PSAwKSkge1xuICAgICAgICB3cml0ZUJsb2NrTWFwcGluZyhzdGF0ZSwgbGV2ZWwsIHN0YXRlLmR1bXAsIGNvbXBhY3QpO1xuICAgICAgICBpZiAoZHVwbGljYXRlKSB7XG4gICAgICAgICAgc3RhdGUuZHVtcCA9ICcmcmVmXycgKyBkdXBsaWNhdGVJbmRleCArIHN0YXRlLmR1bXA7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHdyaXRlRmxvd01hcHBpbmcoc3RhdGUsIGxldmVsLCBzdGF0ZS5kdW1wKTtcbiAgICAgICAgaWYgKGR1cGxpY2F0ZSkge1xuICAgICAgICAgIHN0YXRlLmR1bXAgPSAnJnJlZl8nICsgZHVwbGljYXRlSW5kZXggKyAnICcgKyBzdGF0ZS5kdW1wO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnW29iamVjdCBBcnJheV0nKSB7XG4gICAgICBpZiAoYmxvY2sgJiYgKHN0YXRlLmR1bXAubGVuZ3RoICE9PSAwKSkge1xuICAgICAgICB3cml0ZUJsb2NrU2VxdWVuY2Uoc3RhdGUsIGxldmVsLCBzdGF0ZS5kdW1wLCBjb21wYWN0KTtcbiAgICAgICAgaWYgKGR1cGxpY2F0ZSkge1xuICAgICAgICAgIHN0YXRlLmR1bXAgPSAnJnJlZl8nICsgZHVwbGljYXRlSW5kZXggKyBzdGF0ZS5kdW1wO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB3cml0ZUZsb3dTZXF1ZW5jZShzdGF0ZSwgbGV2ZWwsIHN0YXRlLmR1bXApO1xuICAgICAgICBpZiAoZHVwbGljYXRlKSB7XG4gICAgICAgICAgc3RhdGUuZHVtcCA9ICcmcmVmXycgKyBkdXBsaWNhdGVJbmRleCArICcgJyArIHN0YXRlLmR1bXA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdbb2JqZWN0IFN0cmluZ10nKSB7XG4gICAgICBpZiAoc3RhdGUudGFnICE9PSAnPycpIHtcbiAgICAgICAgd3JpdGVTY2FsYXIoc3RhdGUsIHN0YXRlLmR1bXAsIGxldmVsLCBpc2tleSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChzdGF0ZS5za2lwSW52YWxpZCkgcmV0dXJuIGZhbHNlO1xuICAgICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJ3VuYWNjZXB0YWJsZSBraW5kIG9mIGFuIG9iamVjdCB0byBkdW1wICcgKyB0eXBlKTtcbiAgICB9XG5cbiAgICBpZiAoc3RhdGUudGFnICE9PSBudWxsICYmIHN0YXRlLnRhZyAhPT0gJz8nKSB7XG4gICAgICBzdGF0ZS5kdW1wID0gJyE8JyArIHN0YXRlLnRhZyArICc+ICcgKyBzdGF0ZS5kdW1wO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBnZXREdXBsaWNhdGVSZWZlcmVuY2VzKG9iamVjdCwgc3RhdGUpIHtcbiAgdmFyIG9iamVjdHMgPSBbXSxcbiAgICAgIGR1cGxpY2F0ZXNJbmRleGVzID0gW10sXG4gICAgICBpbmRleCxcbiAgICAgIGxlbmd0aDtcblxuICBpbnNwZWN0Tm9kZShvYmplY3QsIG9iamVjdHMsIGR1cGxpY2F0ZXNJbmRleGVzKTtcblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gZHVwbGljYXRlc0luZGV4ZXMubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIHN0YXRlLmR1cGxpY2F0ZXMucHVzaChvYmplY3RzW2R1cGxpY2F0ZXNJbmRleGVzW2luZGV4XV0pO1xuICB9XG4gIHN0YXRlLnVzZWREdXBsaWNhdGVzID0gbmV3IEFycmF5KGxlbmd0aCk7XG59XG5cbmZ1bmN0aW9uIGluc3BlY3ROb2RlKG9iamVjdCwgb2JqZWN0cywgZHVwbGljYXRlc0luZGV4ZXMpIHtcbiAgdmFyIG9iamVjdEtleUxpc3QsXG4gICAgICBpbmRleCxcbiAgICAgIGxlbmd0aDtcblxuICBpZiAob2JqZWN0ICE9PSBudWxsICYmIHR5cGVvZiBvYmplY3QgPT09ICdvYmplY3QnKSB7XG4gICAgaW5kZXggPSBvYmplY3RzLmluZGV4T2Yob2JqZWN0KTtcbiAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICBpZiAoZHVwbGljYXRlc0luZGV4ZXMuaW5kZXhPZihpbmRleCkgPT09IC0xKSB7XG4gICAgICAgIGR1cGxpY2F0ZXNJbmRleGVzLnB1c2goaW5kZXgpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBvYmplY3RzLnB1c2gob2JqZWN0KTtcblxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkob2JqZWN0KSkge1xuICAgICAgICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gb2JqZWN0Lmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICAgICAgICBpbnNwZWN0Tm9kZShvYmplY3RbaW5kZXhdLCBvYmplY3RzLCBkdXBsaWNhdGVzSW5kZXhlcyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG9iamVjdEtleUxpc3QgPSBPYmplY3Qua2V5cyhvYmplY3QpO1xuXG4gICAgICAgIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBvYmplY3RLZXlMaXN0Lmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICAgICAgICBpbnNwZWN0Tm9kZShvYmplY3Rbb2JqZWN0S2V5TGlzdFtpbmRleF1dLCBvYmplY3RzLCBkdXBsaWNhdGVzSW5kZXhlcyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZHVtcChpbnB1dCwgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgc3RhdGUgPSBuZXcgU3RhdGUob3B0aW9ucyk7XG5cbiAgaWYgKCFzdGF0ZS5ub1JlZnMpIGdldER1cGxpY2F0ZVJlZmVyZW5jZXMoaW5wdXQsIHN0YXRlKTtcblxuICBpZiAod3JpdGVOb2RlKHN0YXRlLCAwLCBpbnB1dCwgdHJ1ZSwgdHJ1ZSkpIHJldHVybiBzdGF0ZS5kdW1wICsgJ1xcbic7XG5cbiAgcmV0dXJuICcnO1xufVxuXG5mdW5jdGlvbiBzYWZlRHVtcChpbnB1dCwgb3B0aW9ucykge1xuICByZXR1cm4gZHVtcChpbnB1dCwgY29tbW9uLmV4dGVuZCh7IHNjaGVtYTogREVGQVVMVF9TQUZFX1NDSEVNQSB9LCBvcHRpb25zKSk7XG59XG5cbm1vZHVsZS5leHBvcnRzLmR1bXAgICAgID0gZHVtcDtcbm1vZHVsZS5leHBvcnRzLnNhZmVEdW1wID0gc2FmZUR1bXA7XG4iLCIvLyBZQU1MIGVycm9yIGNsYXNzLiBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzg0NTg5ODRcbi8vXG4ndXNlIHN0cmljdCc7XG5cbmZ1bmN0aW9uIFlBTUxFeGNlcHRpb24ocmVhc29uLCBtYXJrKSB7XG4gIC8vIFN1cGVyIGNvbnN0cnVjdG9yXG4gIEVycm9yLmNhbGwodGhpcyk7XG5cbiAgLy8gSW5jbHVkZSBzdGFjayB0cmFjZSBpbiBlcnJvciBvYmplY3RcbiAgaWYgKEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKSB7XG4gICAgLy8gQ2hyb21lIGFuZCBOb2RlSlNcbiAgICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSh0aGlzLCB0aGlzLmNvbnN0cnVjdG9yKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBGRiwgSUUgMTArIGFuZCBTYWZhcmkgNisuIEZhbGxiYWNrIGZvciBvdGhlcnNcbiAgICB0aGlzLnN0YWNrID0gKG5ldyBFcnJvcigpKS5zdGFjayB8fCAnJztcbiAgfVxuXG4gIHRoaXMubmFtZSA9ICdZQU1MRXhjZXB0aW9uJztcbiAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gIHRoaXMubWFyayA9IG1hcms7XG4gIHRoaXMubWVzc2FnZSA9ICh0aGlzLnJlYXNvbiB8fCAnKHVua25vd24gcmVhc29uKScpICsgKHRoaXMubWFyayA/ICcgJyArIHRoaXMubWFyay50b1N0cmluZygpIDogJycpO1xufVxuXG5cbi8vIEluaGVyaXQgZnJvbSBFcnJvclxuWUFNTEV4Y2VwdGlvbi5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEVycm9yLnByb3RvdHlwZSk7XG5ZQU1MRXhjZXB0aW9uLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFlBTUxFeGNlcHRpb247XG5cblxuWUFNTEV4Y2VwdGlvbi5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZyhjb21wYWN0KSB7XG4gIHZhciByZXN1bHQgPSB0aGlzLm5hbWUgKyAnOiAnO1xuXG4gIHJlc3VsdCArPSB0aGlzLnJlYXNvbiB8fCAnKHVua25vd24gcmVhc29uKSc7XG5cbiAgaWYgKCFjb21wYWN0ICYmIHRoaXMubWFyaykge1xuICAgIHJlc3VsdCArPSAnICcgKyB0aGlzLm1hcmsudG9TdHJpbmcoKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG5cbm1vZHVsZS5leHBvcnRzID0gWUFNTEV4Y2VwdGlvbjtcbiIsIid1c2Ugc3RyaWN0JztcblxuLyplc2xpbnQtZGlzYWJsZSBtYXgtbGVuLG5vLXVzZS1iZWZvcmUtZGVmaW5lKi9cblxudmFyIGNvbW1vbiAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL2NvbW1vbicpO1xudmFyIFlBTUxFeGNlcHRpb24gICAgICAgPSByZXF1aXJlKCcuL2V4Y2VwdGlvbicpO1xudmFyIE1hcmsgICAgICAgICAgICAgICAgPSByZXF1aXJlKCcuL21hcmsnKTtcbnZhciBERUZBVUxUX1NBRkVfU0NIRU1BID0gcmVxdWlyZSgnLi9zY2hlbWEvZGVmYXVsdF9zYWZlJyk7XG52YXIgREVGQVVMVF9GVUxMX1NDSEVNQSA9IHJlcXVpcmUoJy4vc2NoZW1hL2RlZmF1bHRfZnVsbCcpO1xuXG5cbnZhciBfaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG5cbnZhciBDT05URVhUX0ZMT1dfSU4gICA9IDE7XG52YXIgQ09OVEVYVF9GTE9XX09VVCAgPSAyO1xudmFyIENPTlRFWFRfQkxPQ0tfSU4gID0gMztcbnZhciBDT05URVhUX0JMT0NLX09VVCA9IDQ7XG5cblxudmFyIENIT01QSU5HX0NMSVAgID0gMTtcbnZhciBDSE9NUElOR19TVFJJUCA9IDI7XG52YXIgQ0hPTVBJTkdfS0VFUCAgPSAzO1xuXG5cbnZhciBQQVRURVJOX05PTl9QUklOVEFCTEUgICAgICAgICA9IC9bXFx4MDAtXFx4MDhcXHgwQlxceDBDXFx4MEUtXFx4MUZcXHg3Ri1cXHg4NFxceDg2LVxceDlGXFx1RkZGRVxcdUZGRkZdfFtcXHVEODAwLVxcdURCRkZdKD8hW1xcdURDMDAtXFx1REZGRl0pfCg/OlteXFx1RDgwMC1cXHVEQkZGXXxeKVtcXHVEQzAwLVxcdURGRkZdLztcbnZhciBQQVRURVJOX05PTl9BU0NJSV9MSU5FX0JSRUFLUyA9IC9bXFx4ODVcXHUyMDI4XFx1MjAyOV0vO1xudmFyIFBBVFRFUk5fRkxPV19JTkRJQ0FUT1JTICAgICAgID0gL1ssXFxbXFxdXFx7XFx9XS87XG52YXIgUEFUVEVSTl9UQUdfSEFORExFICAgICAgICAgICAgPSAvXig/OiF8ISF8IVthLXpcXC1dKyEpJC9pO1xudmFyIFBBVFRFUk5fVEFHX1VSSSAgICAgICAgICAgICAgID0gL14oPzohfFteLFxcW1xcXVxce1xcfV0pKD86JVswLTlhLWZdezJ9fFswLTlhLXpcXC0jO1xcL1xcPzpAJj1cXCtcXCQsX1xcLiF+XFwqJ1xcKFxcKVxcW1xcXV0pKiQvaTtcblxuXG5mdW5jdGlvbiBpc19FT0woYykge1xuICByZXR1cm4gKGMgPT09IDB4MEEvKiBMRiAqLykgfHwgKGMgPT09IDB4MEQvKiBDUiAqLyk7XG59XG5cbmZ1bmN0aW9uIGlzX1dISVRFX1NQQUNFKGMpIHtcbiAgcmV0dXJuIChjID09PSAweDA5LyogVGFiICovKSB8fCAoYyA9PT0gMHgyMC8qIFNwYWNlICovKTtcbn1cblxuZnVuY3Rpb24gaXNfV1NfT1JfRU9MKGMpIHtcbiAgcmV0dXJuIChjID09PSAweDA5LyogVGFiICovKSB8fFxuICAgICAgICAgKGMgPT09IDB4MjAvKiBTcGFjZSAqLykgfHxcbiAgICAgICAgIChjID09PSAweDBBLyogTEYgKi8pIHx8XG4gICAgICAgICAoYyA9PT0gMHgwRC8qIENSICovKTtcbn1cblxuZnVuY3Rpb24gaXNfRkxPV19JTkRJQ0FUT1IoYykge1xuICByZXR1cm4gYyA9PT0gMHgyQy8qICwgKi8gfHxcbiAgICAgICAgIGMgPT09IDB4NUIvKiBbICovIHx8XG4gICAgICAgICBjID09PSAweDVELyogXSAqLyB8fFxuICAgICAgICAgYyA9PT0gMHg3Qi8qIHsgKi8gfHxcbiAgICAgICAgIGMgPT09IDB4N0QvKiB9ICovO1xufVxuXG5mdW5jdGlvbiBmcm9tSGV4Q29kZShjKSB7XG4gIHZhciBsYztcblxuICBpZiAoKDB4MzAvKiAwICovIDw9IGMpICYmIChjIDw9IDB4MzkvKiA5ICovKSkge1xuICAgIHJldHVybiBjIC0gMHgzMDtcbiAgfVxuXG4gIC8qZXNsaW50LWRpc2FibGUgbm8tYml0d2lzZSovXG4gIGxjID0gYyB8IDB4MjA7XG5cbiAgaWYgKCgweDYxLyogYSAqLyA8PSBsYykgJiYgKGxjIDw9IDB4NjYvKiBmICovKSkge1xuICAgIHJldHVybiBsYyAtIDB4NjEgKyAxMDtcbiAgfVxuXG4gIHJldHVybiAtMTtcbn1cblxuZnVuY3Rpb24gZXNjYXBlZEhleExlbihjKSB7XG4gIGlmIChjID09PSAweDc4LyogeCAqLykgeyByZXR1cm4gMjsgfVxuICBpZiAoYyA9PT0gMHg3NS8qIHUgKi8pIHsgcmV0dXJuIDQ7IH1cbiAgaWYgKGMgPT09IDB4NTUvKiBVICovKSB7IHJldHVybiA4OyB9XG4gIHJldHVybiAwO1xufVxuXG5mdW5jdGlvbiBmcm9tRGVjaW1hbENvZGUoYykge1xuICBpZiAoKDB4MzAvKiAwICovIDw9IGMpICYmIChjIDw9IDB4MzkvKiA5ICovKSkge1xuICAgIHJldHVybiBjIC0gMHgzMDtcbiAgfVxuXG4gIHJldHVybiAtMTtcbn1cblxuZnVuY3Rpb24gc2ltcGxlRXNjYXBlU2VxdWVuY2UoYykge1xuICByZXR1cm4gKGMgPT09IDB4MzAvKiAwICovKSA/ICdcXHgwMCcgOlxuICAgICAgICAoYyA9PT0gMHg2MS8qIGEgKi8pID8gJ1xceDA3JyA6XG4gICAgICAgIChjID09PSAweDYyLyogYiAqLykgPyAnXFx4MDgnIDpcbiAgICAgICAgKGMgPT09IDB4NzQvKiB0ICovKSA/ICdcXHgwOScgOlxuICAgICAgICAoYyA9PT0gMHgwOS8qIFRhYiAqLykgPyAnXFx4MDknIDpcbiAgICAgICAgKGMgPT09IDB4NkUvKiBuICovKSA/ICdcXHgwQScgOlxuICAgICAgICAoYyA9PT0gMHg3Ni8qIHYgKi8pID8gJ1xceDBCJyA6XG4gICAgICAgIChjID09PSAweDY2LyogZiAqLykgPyAnXFx4MEMnIDpcbiAgICAgICAgKGMgPT09IDB4NzIvKiByICovKSA/ICdcXHgwRCcgOlxuICAgICAgICAoYyA9PT0gMHg2NS8qIGUgKi8pID8gJ1xceDFCJyA6XG4gICAgICAgIChjID09PSAweDIwLyogU3BhY2UgKi8pID8gJyAnIDpcbiAgICAgICAgKGMgPT09IDB4MjIvKiBcIiAqLykgPyAnXFx4MjInIDpcbiAgICAgICAgKGMgPT09IDB4MkYvKiAvICovKSA/ICcvJyA6XG4gICAgICAgIChjID09PSAweDVDLyogXFwgKi8pID8gJ1xceDVDJyA6XG4gICAgICAgIChjID09PSAweDRFLyogTiAqLykgPyAnXFx4ODUnIDpcbiAgICAgICAgKGMgPT09IDB4NUYvKiBfICovKSA/ICdcXHhBMCcgOlxuICAgICAgICAoYyA9PT0gMHg0Qy8qIEwgKi8pID8gJ1xcdTIwMjgnIDpcbiAgICAgICAgKGMgPT09IDB4NTAvKiBQICovKSA/ICdcXHUyMDI5JyA6ICcnO1xufVxuXG5mdW5jdGlvbiBjaGFyRnJvbUNvZGVwb2ludChjKSB7XG4gIGlmIChjIDw9IDB4RkZGRikge1xuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKGMpO1xuICB9XG4gIC8vIEVuY29kZSBVVEYtMTYgc3Vycm9nYXRlIHBhaXJcbiAgLy8gaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvVVRGLTE2I0NvZGVfcG9pbnRzX1UuMkIwMTAwMDBfdG9fVS4yQjEwRkZGRlxuICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZSgoKGMgLSAweDAxMDAwMCkgPj4gMTApICsgMHhEODAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKGMgLSAweDAxMDAwMCkgJiAweDAzRkYpICsgMHhEQzAwKTtcbn1cblxudmFyIHNpbXBsZUVzY2FwZUNoZWNrID0gbmV3IEFycmF5KDI1Nik7IC8vIGludGVnZXIsIGZvciBmYXN0IGFjY2Vzc1xudmFyIHNpbXBsZUVzY2FwZU1hcCA9IG5ldyBBcnJheSgyNTYpO1xuZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7IGkrKykge1xuICBzaW1wbGVFc2NhcGVDaGVja1tpXSA9IHNpbXBsZUVzY2FwZVNlcXVlbmNlKGkpID8gMSA6IDA7XG4gIHNpbXBsZUVzY2FwZU1hcFtpXSA9IHNpbXBsZUVzY2FwZVNlcXVlbmNlKGkpO1xufVxuXG5cbmZ1bmN0aW9uIFN0YXRlKGlucHV0LCBvcHRpb25zKSB7XG4gIHRoaXMuaW5wdXQgPSBpbnB1dDtcblxuICB0aGlzLmZpbGVuYW1lICA9IG9wdGlvbnNbJ2ZpbGVuYW1lJ10gIHx8IG51bGw7XG4gIHRoaXMuc2NoZW1hICAgID0gb3B0aW9uc1snc2NoZW1hJ10gICAgfHwgREVGQVVMVF9GVUxMX1NDSEVNQTtcbiAgdGhpcy5vbldhcm5pbmcgPSBvcHRpb25zWydvbldhcm5pbmcnXSB8fCBudWxsO1xuICB0aGlzLmxlZ2FjeSAgICA9IG9wdGlvbnNbJ2xlZ2FjeSddICAgIHx8IGZhbHNlO1xuICB0aGlzLmpzb24gICAgICA9IG9wdGlvbnNbJ2pzb24nXSAgICAgIHx8IGZhbHNlO1xuICB0aGlzLmxpc3RlbmVyICA9IG9wdGlvbnNbJ2xpc3RlbmVyJ10gIHx8IG51bGw7XG5cbiAgdGhpcy5pbXBsaWNpdFR5cGVzID0gdGhpcy5zY2hlbWEuY29tcGlsZWRJbXBsaWNpdDtcbiAgdGhpcy50eXBlTWFwICAgICAgID0gdGhpcy5zY2hlbWEuY29tcGlsZWRUeXBlTWFwO1xuXG4gIHRoaXMubGVuZ3RoICAgICA9IGlucHV0Lmxlbmd0aDtcbiAgdGhpcy5wb3NpdGlvbiAgID0gMDtcbiAgdGhpcy5saW5lICAgICAgID0gMDtcbiAgdGhpcy5saW5lU3RhcnQgID0gMDtcbiAgdGhpcy5saW5lSW5kZW50ID0gMDtcblxuICB0aGlzLmRvY3VtZW50cyA9IFtdO1xuXG4gIC8qXG4gIHRoaXMudmVyc2lvbjtcbiAgdGhpcy5jaGVja0xpbmVCcmVha3M7XG4gIHRoaXMudGFnTWFwO1xuICB0aGlzLmFuY2hvck1hcDtcbiAgdGhpcy50YWc7XG4gIHRoaXMuYW5jaG9yO1xuICB0aGlzLmtpbmQ7XG4gIHRoaXMucmVzdWx0OyovXG5cbn1cblxuXG5mdW5jdGlvbiBnZW5lcmF0ZUVycm9yKHN0YXRlLCBtZXNzYWdlKSB7XG4gIHJldHVybiBuZXcgWUFNTEV4Y2VwdGlvbihcbiAgICBtZXNzYWdlLFxuICAgIG5ldyBNYXJrKHN0YXRlLmZpbGVuYW1lLCBzdGF0ZS5pbnB1dCwgc3RhdGUucG9zaXRpb24sIHN0YXRlLmxpbmUsIChzdGF0ZS5wb3NpdGlvbiAtIHN0YXRlLmxpbmVTdGFydCkpKTtcbn1cblxuZnVuY3Rpb24gdGhyb3dFcnJvcihzdGF0ZSwgbWVzc2FnZSkge1xuICB0aHJvdyBnZW5lcmF0ZUVycm9yKHN0YXRlLCBtZXNzYWdlKTtcbn1cblxuZnVuY3Rpb24gdGhyb3dXYXJuaW5nKHN0YXRlLCBtZXNzYWdlKSB7XG4gIGlmIChzdGF0ZS5vbldhcm5pbmcpIHtcbiAgICBzdGF0ZS5vbldhcm5pbmcuY2FsbChudWxsLCBnZW5lcmF0ZUVycm9yKHN0YXRlLCBtZXNzYWdlKSk7XG4gIH1cbn1cblxuXG52YXIgZGlyZWN0aXZlSGFuZGxlcnMgPSB7XG5cbiAgWUFNTDogZnVuY3Rpb24gaGFuZGxlWWFtbERpcmVjdGl2ZShzdGF0ZSwgbmFtZSwgYXJncykge1xuXG4gICAgdmFyIG1hdGNoLCBtYWpvciwgbWlub3I7XG5cbiAgICBpZiAoc3RhdGUudmVyc2lvbiAhPT0gbnVsbCkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2R1cGxpY2F0aW9uIG9mICVZQU1MIGRpcmVjdGl2ZScpO1xuICAgIH1cblxuICAgIGlmIChhcmdzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ1lBTUwgZGlyZWN0aXZlIGFjY2VwdHMgZXhhY3RseSBvbmUgYXJndW1lbnQnKTtcbiAgICB9XG5cbiAgICBtYXRjaCA9IC9eKFswLTldKylcXC4oWzAtOV0rKSQvLmV4ZWMoYXJnc1swXSk7XG5cbiAgICBpZiAobWF0Y2ggPT09IG51bGwpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdpbGwtZm9ybWVkIGFyZ3VtZW50IG9mIHRoZSBZQU1MIGRpcmVjdGl2ZScpO1xuICAgIH1cblxuICAgIG1ham9yID0gcGFyc2VJbnQobWF0Y2hbMV0sIDEwKTtcbiAgICBtaW5vciA9IHBhcnNlSW50KG1hdGNoWzJdLCAxMCk7XG5cbiAgICBpZiAobWFqb3IgIT09IDEpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd1bmFjY2VwdGFibGUgWUFNTCB2ZXJzaW9uIG9mIHRoZSBkb2N1bWVudCcpO1xuICAgIH1cblxuICAgIHN0YXRlLnZlcnNpb24gPSBhcmdzWzBdO1xuICAgIHN0YXRlLmNoZWNrTGluZUJyZWFrcyA9IChtaW5vciA8IDIpO1xuXG4gICAgaWYgKG1pbm9yICE9PSAxICYmIG1pbm9yICE9PSAyKSB7XG4gICAgICB0aHJvd1dhcm5pbmcoc3RhdGUsICd1bnN1cHBvcnRlZCBZQU1MIHZlcnNpb24gb2YgdGhlIGRvY3VtZW50Jyk7XG4gICAgfVxuICB9LFxuXG4gIFRBRzogZnVuY3Rpb24gaGFuZGxlVGFnRGlyZWN0aXZlKHN0YXRlLCBuYW1lLCBhcmdzKSB7XG5cbiAgICB2YXIgaGFuZGxlLCBwcmVmaXg7XG5cbiAgICBpZiAoYXJncy5sZW5ndGggIT09IDIpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdUQUcgZGlyZWN0aXZlIGFjY2VwdHMgZXhhY3RseSB0d28gYXJndW1lbnRzJyk7XG4gICAgfVxuXG4gICAgaGFuZGxlID0gYXJnc1swXTtcbiAgICBwcmVmaXggPSBhcmdzWzFdO1xuXG4gICAgaWYgKCFQQVRURVJOX1RBR19IQU5ETEUudGVzdChoYW5kbGUpKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnaWxsLWZvcm1lZCB0YWcgaGFuZGxlIChmaXJzdCBhcmd1bWVudCkgb2YgdGhlIFRBRyBkaXJlY3RpdmUnKTtcbiAgICB9XG5cbiAgICBpZiAoX2hhc093blByb3BlcnR5LmNhbGwoc3RhdGUudGFnTWFwLCBoYW5kbGUpKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAndGhlcmUgaXMgYSBwcmV2aW91c2x5IGRlY2xhcmVkIHN1ZmZpeCBmb3IgXCInICsgaGFuZGxlICsgJ1wiIHRhZyBoYW5kbGUnKTtcbiAgICB9XG5cbiAgICBpZiAoIVBBVFRFUk5fVEFHX1VSSS50ZXN0KHByZWZpeCkpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdpbGwtZm9ybWVkIHRhZyBwcmVmaXggKHNlY29uZCBhcmd1bWVudCkgb2YgdGhlIFRBRyBkaXJlY3RpdmUnKTtcbiAgICB9XG5cbiAgICBzdGF0ZS50YWdNYXBbaGFuZGxlXSA9IHByZWZpeDtcbiAgfVxufTtcblxuXG5mdW5jdGlvbiBjYXB0dXJlU2VnbWVudChzdGF0ZSwgc3RhcnQsIGVuZCwgY2hlY2tKc29uKSB7XG4gIHZhciBfcG9zaXRpb24sIF9sZW5ndGgsIF9jaGFyYWN0ZXIsIF9yZXN1bHQ7XG5cbiAgaWYgKHN0YXJ0IDwgZW5kKSB7XG4gICAgX3Jlc3VsdCA9IHN0YXRlLmlucHV0LnNsaWNlKHN0YXJ0LCBlbmQpO1xuXG4gICAgaWYgKGNoZWNrSnNvbikge1xuICAgICAgZm9yIChfcG9zaXRpb24gPSAwLCBfbGVuZ3RoID0gX3Jlc3VsdC5sZW5ndGg7XG4gICAgICAgICAgIF9wb3NpdGlvbiA8IF9sZW5ndGg7XG4gICAgICAgICAgIF9wb3NpdGlvbiArPSAxKSB7XG4gICAgICAgIF9jaGFyYWN0ZXIgPSBfcmVzdWx0LmNoYXJDb2RlQXQoX3Bvc2l0aW9uKTtcbiAgICAgICAgaWYgKCEoX2NoYXJhY3RlciA9PT0gMHgwOSB8fFxuICAgICAgICAgICAgICAoMHgyMCA8PSBfY2hhcmFjdGVyICYmIF9jaGFyYWN0ZXIgPD0gMHgxMEZGRkYpKSkge1xuICAgICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdleHBlY3RlZCB2YWxpZCBKU09OIGNoYXJhY3RlcicpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChQQVRURVJOX05PTl9QUklOVEFCTEUudGVzdChfcmVzdWx0KSkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3RoZSBzdHJlYW0gY29udGFpbnMgbm9uLXByaW50YWJsZSBjaGFyYWN0ZXJzJyk7XG4gICAgfVxuXG4gICAgc3RhdGUucmVzdWx0ICs9IF9yZXN1bHQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gbWVyZ2VNYXBwaW5ncyhzdGF0ZSwgZGVzdGluYXRpb24sIHNvdXJjZSwgb3ZlcnJpZGFibGVLZXlzKSB7XG4gIHZhciBzb3VyY2VLZXlzLCBrZXksIGluZGV4LCBxdWFudGl0eTtcblxuICBpZiAoIWNvbW1vbi5pc09iamVjdChzb3VyY2UpKSB7XG4gICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2Nhbm5vdCBtZXJnZSBtYXBwaW5nczsgdGhlIHByb3ZpZGVkIHNvdXJjZSBvYmplY3QgaXMgdW5hY2NlcHRhYmxlJyk7XG4gIH1cblxuICBzb3VyY2VLZXlzID0gT2JqZWN0LmtleXMoc291cmNlKTtcblxuICBmb3IgKGluZGV4ID0gMCwgcXVhbnRpdHkgPSBzb3VyY2VLZXlzLmxlbmd0aDsgaW5kZXggPCBxdWFudGl0eTsgaW5kZXggKz0gMSkge1xuICAgIGtleSA9IHNvdXJjZUtleXNbaW5kZXhdO1xuXG4gICAgaWYgKCFfaGFzT3duUHJvcGVydHkuY2FsbChkZXN0aW5hdGlvbiwga2V5KSkge1xuICAgICAgZGVzdGluYXRpb25ba2V5XSA9IHNvdXJjZVtrZXldO1xuICAgICAgb3ZlcnJpZGFibGVLZXlzW2tleV0gPSB0cnVlO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBzdG9yZU1hcHBpbmdQYWlyKHN0YXRlLCBfcmVzdWx0LCBvdmVycmlkYWJsZUtleXMsIGtleVRhZywga2V5Tm9kZSwgdmFsdWVOb2RlKSB7XG4gIHZhciBpbmRleCwgcXVhbnRpdHk7XG5cbiAga2V5Tm9kZSA9IFN0cmluZyhrZXlOb2RlKTtcblxuICBpZiAoX3Jlc3VsdCA9PT0gbnVsbCkge1xuICAgIF9yZXN1bHQgPSB7fTtcbiAgfVxuXG4gIGlmIChrZXlUYWcgPT09ICd0YWc6eWFtbC5vcmcsMjAwMjptZXJnZScpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZU5vZGUpKSB7XG4gICAgICBmb3IgKGluZGV4ID0gMCwgcXVhbnRpdHkgPSB2YWx1ZU5vZGUubGVuZ3RoOyBpbmRleCA8IHF1YW50aXR5OyBpbmRleCArPSAxKSB7XG4gICAgICAgIG1lcmdlTWFwcGluZ3Moc3RhdGUsIF9yZXN1bHQsIHZhbHVlTm9kZVtpbmRleF0sIG92ZXJyaWRhYmxlS2V5cyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIG1lcmdlTWFwcGluZ3Moc3RhdGUsIF9yZXN1bHQsIHZhbHVlTm9kZSwgb3ZlcnJpZGFibGVLZXlzKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKCFzdGF0ZS5qc29uICYmXG4gICAgICAgICFfaGFzT3duUHJvcGVydHkuY2FsbChvdmVycmlkYWJsZUtleXMsIGtleU5vZGUpICYmXG4gICAgICAgIF9oYXNPd25Qcm9wZXJ0eS5jYWxsKF9yZXN1bHQsIGtleU5vZGUpKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnZHVwbGljYXRlZCBtYXBwaW5nIGtleScpO1xuICAgIH1cbiAgICBfcmVzdWx0W2tleU5vZGVdID0gdmFsdWVOb2RlO1xuICAgIGRlbGV0ZSBvdmVycmlkYWJsZUtleXNba2V5Tm9kZV07XG4gIH1cblxuICByZXR1cm4gX3Jlc3VsdDtcbn1cblxuZnVuY3Rpb24gcmVhZExpbmVCcmVhayhzdGF0ZSkge1xuICB2YXIgY2g7XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICBpZiAoY2ggPT09IDB4MEEvKiBMRiAqLykge1xuICAgIHN0YXRlLnBvc2l0aW9uKys7XG4gIH0gZWxzZSBpZiAoY2ggPT09IDB4MEQvKiBDUiAqLykge1xuICAgIHN0YXRlLnBvc2l0aW9uKys7XG4gICAgaWYgKHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pID09PSAweDBBLyogTEYgKi8pIHtcbiAgICAgIHN0YXRlLnBvc2l0aW9uKys7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRocm93RXJyb3Ioc3RhdGUsICdhIGxpbmUgYnJlYWsgaXMgZXhwZWN0ZWQnKTtcbiAgfVxuXG4gIHN0YXRlLmxpbmUgKz0gMTtcbiAgc3RhdGUubGluZVN0YXJ0ID0gc3RhdGUucG9zaXRpb247XG59XG5cbmZ1bmN0aW9uIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIGFsbG93Q29tbWVudHMsIGNoZWNrSW5kZW50KSB7XG4gIHZhciBsaW5lQnJlYWtzID0gMCxcbiAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgd2hpbGUgKGNoICE9PSAwKSB7XG4gICAgd2hpbGUgKGlzX1dISVRFX1NQQUNFKGNoKSkge1xuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgIH1cblxuICAgIGlmIChhbGxvd0NvbW1lbnRzICYmIGNoID09PSAweDIzLyogIyAqLykge1xuICAgICAgZG8ge1xuICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgICB9IHdoaWxlIChjaCAhPT0gMHgwQS8qIExGICovICYmIGNoICE9PSAweDBELyogQ1IgKi8gJiYgY2ggIT09IDApO1xuICAgIH1cblxuICAgIGlmIChpc19FT0woY2gpKSB7XG4gICAgICByZWFkTGluZUJyZWFrKHN0YXRlKTtcblxuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcbiAgICAgIGxpbmVCcmVha3MrKztcbiAgICAgIHN0YXRlLmxpbmVJbmRlbnQgPSAwO1xuXG4gICAgICB3aGlsZSAoY2ggPT09IDB4MjAvKiBTcGFjZSAqLykge1xuICAgICAgICBzdGF0ZS5saW5lSW5kZW50Kys7XG4gICAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgaWYgKGNoZWNrSW5kZW50ICE9PSAtMSAmJiBsaW5lQnJlYWtzICE9PSAwICYmIHN0YXRlLmxpbmVJbmRlbnQgPCBjaGVja0luZGVudCkge1xuICAgIHRocm93V2FybmluZyhzdGF0ZSwgJ2RlZmljaWVudCBpbmRlbnRhdGlvbicpO1xuICB9XG5cbiAgcmV0dXJuIGxpbmVCcmVha3M7XG59XG5cbmZ1bmN0aW9uIHRlc3REb2N1bWVudFNlcGFyYXRvcihzdGF0ZSkge1xuICB2YXIgX3Bvc2l0aW9uID0gc3RhdGUucG9zaXRpb24sXG4gICAgICBjaDtcblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoX3Bvc2l0aW9uKTtcblxuICAvLyBDb25kaXRpb24gc3RhdGUucG9zaXRpb24gPT09IHN0YXRlLmxpbmVTdGFydCBpcyB0ZXN0ZWRcbiAgLy8gaW4gcGFyZW50IG9uIGVhY2ggY2FsbCwgZm9yIGVmZmljaWVuY3kuIE5vIG5lZWRzIHRvIHRlc3QgaGVyZSBhZ2Fpbi5cbiAgaWYgKChjaCA9PT0gMHgyRC8qIC0gKi8gfHwgY2ggPT09IDB4MkUvKiAuICovKSAmJlxuICAgICAgY2ggPT09IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoX3Bvc2l0aW9uICsgMSkgJiZcbiAgICAgIGNoID09PSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KF9wb3NpdGlvbiArIDIpKSB7XG5cbiAgICBfcG9zaXRpb24gKz0gMztcblxuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChfcG9zaXRpb24pO1xuXG4gICAgaWYgKGNoID09PSAwIHx8IGlzX1dTX09SX0VPTChjaCkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gd3JpdGVGb2xkZWRMaW5lcyhzdGF0ZSwgY291bnQpIHtcbiAgaWYgKGNvdW50ID09PSAxKSB7XG4gICAgc3RhdGUucmVzdWx0ICs9ICcgJztcbiAgfSBlbHNlIGlmIChjb3VudCA+IDEpIHtcbiAgICBzdGF0ZS5yZXN1bHQgKz0gY29tbW9uLnJlcGVhdCgnXFxuJywgY291bnQgLSAxKTtcbiAgfVxufVxuXG5cbmZ1bmN0aW9uIHJlYWRQbGFpblNjYWxhcihzdGF0ZSwgbm9kZUluZGVudCwgd2l0aGluRmxvd0NvbGxlY3Rpb24pIHtcbiAgdmFyIHByZWNlZGluZyxcbiAgICAgIGZvbGxvd2luZyxcbiAgICAgIGNhcHR1cmVTdGFydCxcbiAgICAgIGNhcHR1cmVFbmQsXG4gICAgICBoYXNQZW5kaW5nQ29udGVudCxcbiAgICAgIF9saW5lLFxuICAgICAgX2xpbmVTdGFydCxcbiAgICAgIF9saW5lSW5kZW50LFxuICAgICAgX2tpbmQgPSBzdGF0ZS5raW5kLFxuICAgICAgX3Jlc3VsdCA9IHN0YXRlLnJlc3VsdCxcbiAgICAgIGNoO1xuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgaWYgKGlzX1dTX09SX0VPTChjaCkgICAgICB8fFxuICAgICAgaXNfRkxPV19JTkRJQ0FUT1IoY2gpIHx8XG4gICAgICBjaCA9PT0gMHgyMy8qICMgKi8gICAgfHxcbiAgICAgIGNoID09PSAweDI2LyogJiAqLyAgICB8fFxuICAgICAgY2ggPT09IDB4MkEvKiAqICovICAgIHx8XG4gICAgICBjaCA9PT0gMHgyMS8qICEgKi8gICAgfHxcbiAgICAgIGNoID09PSAweDdDLyogfCAqLyAgICB8fFxuICAgICAgY2ggPT09IDB4M0UvKiA+ICovICAgIHx8XG4gICAgICBjaCA9PT0gMHgyNy8qICcgKi8gICAgfHxcbiAgICAgIGNoID09PSAweDIyLyogXCIgKi8gICAgfHxcbiAgICAgIGNoID09PSAweDI1LyogJSAqLyAgICB8fFxuICAgICAgY2ggPT09IDB4NDAvKiBAICovICAgIHx8XG4gICAgICBjaCA9PT0gMHg2MC8qIGAgKi8pIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAoY2ggPT09IDB4M0YvKiA/ICovIHx8IGNoID09PSAweDJELyogLSAqLykge1xuICAgIGZvbGxvd2luZyA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24gKyAxKTtcblxuICAgIGlmIChpc19XU19PUl9FT0woZm9sbG93aW5nKSB8fFxuICAgICAgICB3aXRoaW5GbG93Q29sbGVjdGlvbiAmJiBpc19GTE9XX0lORElDQVRPUihmb2xsb3dpbmcpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgc3RhdGUua2luZCA9ICdzY2FsYXInO1xuICBzdGF0ZS5yZXN1bHQgPSAnJztcbiAgY2FwdHVyZVN0YXJ0ID0gY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuICBoYXNQZW5kaW5nQ29udGVudCA9IGZhbHNlO1xuXG4gIHdoaWxlIChjaCAhPT0gMCkge1xuICAgIGlmIChjaCA9PT0gMHgzQS8qIDogKi8pIHtcbiAgICAgIGZvbGxvd2luZyA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24gKyAxKTtcblxuICAgICAgaWYgKGlzX1dTX09SX0VPTChmb2xsb3dpbmcpIHx8XG4gICAgICAgICAgd2l0aGluRmxvd0NvbGxlY3Rpb24gJiYgaXNfRkxPV19JTkRJQ0FUT1IoZm9sbG93aW5nKSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIH0gZWxzZSBpZiAoY2ggPT09IDB4MjMvKiAjICovKSB7XG4gICAgICBwcmVjZWRpbmcgPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uIC0gMSk7XG5cbiAgICAgIGlmIChpc19XU19PUl9FT0wocHJlY2VkaW5nKSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgIH0gZWxzZSBpZiAoKHN0YXRlLnBvc2l0aW9uID09PSBzdGF0ZS5saW5lU3RhcnQgJiYgdGVzdERvY3VtZW50U2VwYXJhdG9yKHN0YXRlKSkgfHxcbiAgICAgICAgICAgICAgIHdpdGhpbkZsb3dDb2xsZWN0aW9uICYmIGlzX0ZMT1dfSU5ESUNBVE9SKGNoKSkge1xuICAgICAgYnJlYWs7XG5cbiAgICB9IGVsc2UgaWYgKGlzX0VPTChjaCkpIHtcbiAgICAgIF9saW5lID0gc3RhdGUubGluZTtcbiAgICAgIF9saW5lU3RhcnQgPSBzdGF0ZS5saW5lU3RhcnQ7XG4gICAgICBfbGluZUluZGVudCA9IHN0YXRlLmxpbmVJbmRlbnQ7XG4gICAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCBmYWxzZSwgLTEpO1xuXG4gICAgICBpZiAoc3RhdGUubGluZUluZGVudCA+PSBub2RlSW5kZW50KSB7XG4gICAgICAgIGhhc1BlbmRpbmdDb250ZW50ID0gdHJ1ZTtcbiAgICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdGF0ZS5wb3NpdGlvbiA9IGNhcHR1cmVFbmQ7XG4gICAgICAgIHN0YXRlLmxpbmUgPSBfbGluZTtcbiAgICAgICAgc3RhdGUubGluZVN0YXJ0ID0gX2xpbmVTdGFydDtcbiAgICAgICAgc3RhdGUubGluZUluZGVudCA9IF9saW5lSW5kZW50O1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaGFzUGVuZGluZ0NvbnRlbnQpIHtcbiAgICAgIGNhcHR1cmVTZWdtZW50KHN0YXRlLCBjYXB0dXJlU3RhcnQsIGNhcHR1cmVFbmQsIGZhbHNlKTtcbiAgICAgIHdyaXRlRm9sZGVkTGluZXMoc3RhdGUsIHN0YXRlLmxpbmUgLSBfbGluZSk7XG4gICAgICBjYXB0dXJlU3RhcnQgPSBjYXB0dXJlRW5kID0gc3RhdGUucG9zaXRpb247XG4gICAgICBoYXNQZW5kaW5nQ29udGVudCA9IGZhbHNlO1xuICAgIH1cblxuICAgIGlmICghaXNfV0hJVEVfU1BBQ0UoY2gpKSB7XG4gICAgICBjYXB0dXJlRW5kID0gc3RhdGUucG9zaXRpb24gKyAxO1xuICAgIH1cblxuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgfVxuXG4gIGNhcHR1cmVTZWdtZW50KHN0YXRlLCBjYXB0dXJlU3RhcnQsIGNhcHR1cmVFbmQsIGZhbHNlKTtcblxuICBpZiAoc3RhdGUucmVzdWx0KSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBzdGF0ZS5raW5kID0gX2tpbmQ7XG4gIHN0YXRlLnJlc3VsdCA9IF9yZXN1bHQ7XG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gcmVhZFNpbmdsZVF1b3RlZFNjYWxhcihzdGF0ZSwgbm9kZUluZGVudCkge1xuICB2YXIgY2gsXG4gICAgICBjYXB0dXJlU3RhcnQsIGNhcHR1cmVFbmQ7XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICBpZiAoY2ggIT09IDB4MjcvKiAnICovKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgc3RhdGUua2luZCA9ICdzY2FsYXInO1xuICBzdGF0ZS5yZXN1bHQgPSAnJztcbiAgc3RhdGUucG9zaXRpb24rKztcbiAgY2FwdHVyZVN0YXJ0ID0gY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gIHdoaWxlICgoY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKSkgIT09IDApIHtcbiAgICBpZiAoY2ggPT09IDB4MjcvKiAnICovKSB7XG4gICAgICBjYXB0dXJlU2VnbWVudChzdGF0ZSwgY2FwdHVyZVN0YXJ0LCBzdGF0ZS5wb3NpdGlvbiwgdHJ1ZSk7XG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICAgIGlmIChjaCA9PT0gMHgyNy8qICcgKi8pIHtcbiAgICAgICAgY2FwdHVyZVN0YXJ0ID0gY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuICAgICAgICBzdGF0ZS5wb3NpdGlvbisrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICB9IGVsc2UgaWYgKGlzX0VPTChjaCkpIHtcbiAgICAgIGNhcHR1cmVTZWdtZW50KHN0YXRlLCBjYXB0dXJlU3RhcnQsIGNhcHR1cmVFbmQsIHRydWUpO1xuICAgICAgd3JpdGVGb2xkZWRMaW5lcyhzdGF0ZSwgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgZmFsc2UsIG5vZGVJbmRlbnQpKTtcbiAgICAgIGNhcHR1cmVTdGFydCA9IGNhcHR1cmVFbmQgPSBzdGF0ZS5wb3NpdGlvbjtcblxuICAgIH0gZWxzZSBpZiAoc3RhdGUucG9zaXRpb24gPT09IHN0YXRlLmxpbmVTdGFydCAmJiB0ZXN0RG9jdW1lbnRTZXBhcmF0b3Ioc3RhdGUpKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAndW5leHBlY3RlZCBlbmQgb2YgdGhlIGRvY3VtZW50IHdpdGhpbiBhIHNpbmdsZSBxdW90ZWQgc2NhbGFyJyk7XG5cbiAgICB9IGVsc2Uge1xuICAgICAgc3RhdGUucG9zaXRpb24rKztcbiAgICAgIGNhcHR1cmVFbmQgPSBzdGF0ZS5wb3NpdGlvbjtcbiAgICB9XG4gIH1cblxuICB0aHJvd0Vycm9yKHN0YXRlLCAndW5leHBlY3RlZCBlbmQgb2YgdGhlIHN0cmVhbSB3aXRoaW4gYSBzaW5nbGUgcXVvdGVkIHNjYWxhcicpO1xufVxuXG5mdW5jdGlvbiByZWFkRG91YmxlUXVvdGVkU2NhbGFyKHN0YXRlLCBub2RlSW5kZW50KSB7XG4gIHZhciBjYXB0dXJlU3RhcnQsXG4gICAgICBjYXB0dXJlRW5kLFxuICAgICAgaGV4TGVuZ3RoLFxuICAgICAgaGV4UmVzdWx0LFxuICAgICAgdG1wLFxuICAgICAgY2g7XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICBpZiAoY2ggIT09IDB4MjIvKiBcIiAqLykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHN0YXRlLmtpbmQgPSAnc2NhbGFyJztcbiAgc3RhdGUucmVzdWx0ID0gJyc7XG4gIHN0YXRlLnBvc2l0aW9uKys7XG4gIGNhcHR1cmVTdGFydCA9IGNhcHR1cmVFbmQgPSBzdGF0ZS5wb3NpdGlvbjtcblxuICB3aGlsZSAoKGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbikpICE9PSAwKSB7XG4gICAgaWYgKGNoID09PSAweDIyLyogXCIgKi8pIHtcbiAgICAgIGNhcHR1cmVTZWdtZW50KHN0YXRlLCBjYXB0dXJlU3RhcnQsIHN0YXRlLnBvc2l0aW9uLCB0cnVlKTtcbiAgICAgIHN0YXRlLnBvc2l0aW9uKys7XG4gICAgICByZXR1cm4gdHJ1ZTtcblxuICAgIH0gZWxzZSBpZiAoY2ggPT09IDB4NUMvKiBcXCAqLykge1xuICAgICAgY2FwdHVyZVNlZ21lbnQoc3RhdGUsIGNhcHR1cmVTdGFydCwgc3RhdGUucG9zaXRpb24sIHRydWUpO1xuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuXG4gICAgICBpZiAoaXNfRU9MKGNoKSkge1xuICAgICAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCBmYWxzZSwgbm9kZUluZGVudCk7XG5cbiAgICAgICAgLy8gVE9ETzogcmV3b3JrIHRvIGlubGluZSBmbiB3aXRoIG5vIHR5cGUgY2FzdD9cbiAgICAgIH0gZWxzZSBpZiAoY2ggPCAyNTYgJiYgc2ltcGxlRXNjYXBlQ2hlY2tbY2hdKSB7XG4gICAgICAgIHN0YXRlLnJlc3VsdCArPSBzaW1wbGVFc2NhcGVNYXBbY2hdO1xuICAgICAgICBzdGF0ZS5wb3NpdGlvbisrO1xuXG4gICAgICB9IGVsc2UgaWYgKCh0bXAgPSBlc2NhcGVkSGV4TGVuKGNoKSkgPiAwKSB7XG4gICAgICAgIGhleExlbmd0aCA9IHRtcDtcbiAgICAgICAgaGV4UmVzdWx0ID0gMDtcblxuICAgICAgICBmb3IgKDsgaGV4TGVuZ3RoID4gMDsgaGV4TGVuZ3RoLS0pIHtcbiAgICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICAgICAgICBpZiAoKHRtcCA9IGZyb21IZXhDb2RlKGNoKSkgPj0gMCkge1xuICAgICAgICAgICAgaGV4UmVzdWx0ID0gKGhleFJlc3VsdCA8PCA0KSArIHRtcDtcblxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnZXhwZWN0ZWQgaGV4YWRlY2ltYWwgY2hhcmFjdGVyJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgc3RhdGUucmVzdWx0ICs9IGNoYXJGcm9tQ29kZXBvaW50KGhleFJlc3VsdCk7XG5cbiAgICAgICAgc3RhdGUucG9zaXRpb24rKztcblxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3Vua25vd24gZXNjYXBlIHNlcXVlbmNlJyk7XG4gICAgICB9XG5cbiAgICAgIGNhcHR1cmVTdGFydCA9IGNhcHR1cmVFbmQgPSBzdGF0ZS5wb3NpdGlvbjtcblxuICAgIH0gZWxzZSBpZiAoaXNfRU9MKGNoKSkge1xuICAgICAgY2FwdHVyZVNlZ21lbnQoc3RhdGUsIGNhcHR1cmVTdGFydCwgY2FwdHVyZUVuZCwgdHJ1ZSk7XG4gICAgICB3cml0ZUZvbGRlZExpbmVzKHN0YXRlLCBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCBmYWxzZSwgbm9kZUluZGVudCkpO1xuICAgICAgY2FwdHVyZVN0YXJ0ID0gY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gICAgfSBlbHNlIGlmIChzdGF0ZS5wb3NpdGlvbiA9PT0gc3RhdGUubGluZVN0YXJ0ICYmIHRlc3REb2N1bWVudFNlcGFyYXRvcihzdGF0ZSkpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd1bmV4cGVjdGVkIGVuZCBvZiB0aGUgZG9jdW1lbnQgd2l0aGluIGEgZG91YmxlIHF1b3RlZCBzY2FsYXInKTtcblxuICAgIH0gZWxzZSB7XG4gICAgICBzdGF0ZS5wb3NpdGlvbisrO1xuICAgICAgY2FwdHVyZUVuZCA9IHN0YXRlLnBvc2l0aW9uO1xuICAgIH1cbiAgfVxuXG4gIHRocm93RXJyb3Ioc3RhdGUsICd1bmV4cGVjdGVkIGVuZCBvZiB0aGUgc3RyZWFtIHdpdGhpbiBhIGRvdWJsZSBxdW90ZWQgc2NhbGFyJyk7XG59XG5cbmZ1bmN0aW9uIHJlYWRGbG93Q29sbGVjdGlvbihzdGF0ZSwgbm9kZUluZGVudCkge1xuICB2YXIgcmVhZE5leHQgPSB0cnVlLFxuICAgICAgX2xpbmUsXG4gICAgICBfdGFnICAgICA9IHN0YXRlLnRhZyxcbiAgICAgIF9yZXN1bHQsXG4gICAgICBfYW5jaG9yICA9IHN0YXRlLmFuY2hvcixcbiAgICAgIGZvbGxvd2luZyxcbiAgICAgIHRlcm1pbmF0b3IsXG4gICAgICBpc1BhaXIsXG4gICAgICBpc0V4cGxpY2l0UGFpcixcbiAgICAgIGlzTWFwcGluZyxcbiAgICAgIG92ZXJyaWRhYmxlS2V5cyA9IHt9LFxuICAgICAga2V5Tm9kZSxcbiAgICAgIGtleVRhZyxcbiAgICAgIHZhbHVlTm9kZSxcbiAgICAgIGNoO1xuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgaWYgKGNoID09PSAweDVCLyogWyAqLykge1xuICAgIHRlcm1pbmF0b3IgPSAweDVEOy8qIF0gKi9cbiAgICBpc01hcHBpbmcgPSBmYWxzZTtcbiAgICBfcmVzdWx0ID0gW107XG4gIH0gZWxzZSBpZiAoY2ggPT09IDB4N0IvKiB7ICovKSB7XG4gICAgdGVybWluYXRvciA9IDB4N0Q7LyogfSAqL1xuICAgIGlzTWFwcGluZyA9IHRydWU7XG4gICAgX3Jlc3VsdCA9IHt9O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmIChzdGF0ZS5hbmNob3IgIT09IG51bGwpIHtcbiAgICBzdGF0ZS5hbmNob3JNYXBbc3RhdGUuYW5jaG9yXSA9IF9yZXN1bHQ7XG4gIH1cblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG5cbiAgd2hpbGUgKGNoICE9PSAwKSB7XG4gICAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgbm9kZUluZGVudCk7XG5cbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gICAgaWYgKGNoID09PSB0ZXJtaW5hdG9yKSB7XG4gICAgICBzdGF0ZS5wb3NpdGlvbisrO1xuICAgICAgc3RhdGUudGFnID0gX3RhZztcbiAgICAgIHN0YXRlLmFuY2hvciA9IF9hbmNob3I7XG4gICAgICBzdGF0ZS5raW5kID0gaXNNYXBwaW5nID8gJ21hcHBpbmcnIDogJ3NlcXVlbmNlJztcbiAgICAgIHN0YXRlLnJlc3VsdCA9IF9yZXN1bHQ7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKCFyZWFkTmV4dCkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ21pc3NlZCBjb21tYSBiZXR3ZWVuIGZsb3cgY29sbGVjdGlvbiBlbnRyaWVzJyk7XG4gICAgfVxuXG4gICAga2V5VGFnID0ga2V5Tm9kZSA9IHZhbHVlTm9kZSA9IG51bGw7XG4gICAgaXNQYWlyID0gaXNFeHBsaWNpdFBhaXIgPSBmYWxzZTtcblxuICAgIGlmIChjaCA9PT0gMHgzRi8qID8gKi8pIHtcbiAgICAgIGZvbGxvd2luZyA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24gKyAxKTtcblxuICAgICAgaWYgKGlzX1dTX09SX0VPTChmb2xsb3dpbmcpKSB7XG4gICAgICAgIGlzUGFpciA9IGlzRXhwbGljaXRQYWlyID0gdHJ1ZTtcbiAgICAgICAgc3RhdGUucG9zaXRpb24rKztcbiAgICAgICAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgbm9kZUluZGVudCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgX2xpbmUgPSBzdGF0ZS5saW5lO1xuICAgIGNvbXBvc2VOb2RlKHN0YXRlLCBub2RlSW5kZW50LCBDT05URVhUX0ZMT1dfSU4sIGZhbHNlLCB0cnVlKTtcbiAgICBrZXlUYWcgPSBzdGF0ZS50YWc7XG4gICAga2V5Tm9kZSA9IHN0YXRlLnJlc3VsdDtcbiAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCBub2RlSW5kZW50KTtcblxuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICBpZiAoKGlzRXhwbGljaXRQYWlyIHx8IHN0YXRlLmxpbmUgPT09IF9saW5lKSAmJiBjaCA9PT0gMHgzQS8qIDogKi8pIHtcbiAgICAgIGlzUGFpciA9IHRydWU7XG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCBub2RlSW5kZW50KTtcbiAgICAgIGNvbXBvc2VOb2RlKHN0YXRlLCBub2RlSW5kZW50LCBDT05URVhUX0ZMT1dfSU4sIGZhbHNlLCB0cnVlKTtcbiAgICAgIHZhbHVlTm9kZSA9IHN0YXRlLnJlc3VsdDtcbiAgICB9XG5cbiAgICBpZiAoaXNNYXBwaW5nKSB7XG4gICAgICBzdG9yZU1hcHBpbmdQYWlyKHN0YXRlLCBfcmVzdWx0LCBvdmVycmlkYWJsZUtleXMsIGtleVRhZywga2V5Tm9kZSwgdmFsdWVOb2RlKTtcbiAgICB9IGVsc2UgaWYgKGlzUGFpcikge1xuICAgICAgX3Jlc3VsdC5wdXNoKHN0b3JlTWFwcGluZ1BhaXIoc3RhdGUsIG51bGwsIG92ZXJyaWRhYmxlS2V5cywga2V5VGFnLCBrZXlOb2RlLCB2YWx1ZU5vZGUpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgX3Jlc3VsdC5wdXNoKGtleU5vZGUpO1xuICAgIH1cblxuICAgIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIG5vZGVJbmRlbnQpO1xuXG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICAgIGlmIChjaCA9PT0gMHgyQy8qICwgKi8pIHtcbiAgICAgIHJlYWROZXh0ID0gdHJ1ZTtcbiAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVhZE5leHQgPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICB0aHJvd0Vycm9yKHN0YXRlLCAndW5leHBlY3RlZCBlbmQgb2YgdGhlIHN0cmVhbSB3aXRoaW4gYSBmbG93IGNvbGxlY3Rpb24nKTtcbn1cblxuZnVuY3Rpb24gcmVhZEJsb2NrU2NhbGFyKHN0YXRlLCBub2RlSW5kZW50KSB7XG4gIHZhciBjYXB0dXJlU3RhcnQsXG4gICAgICBmb2xkaW5nLFxuICAgICAgY2hvbXBpbmcgICAgICAgPSBDSE9NUElOR19DTElQLFxuICAgICAgZGlkUmVhZENvbnRlbnQgPSBmYWxzZSxcbiAgICAgIGRldGVjdGVkSW5kZW50ID0gZmFsc2UsXG4gICAgICB0ZXh0SW5kZW50ICAgICA9IG5vZGVJbmRlbnQsXG4gICAgICBlbXB0eUxpbmVzICAgICA9IDAsXG4gICAgICBhdE1vcmVJbmRlbnRlZCA9IGZhbHNlLFxuICAgICAgdG1wLFxuICAgICAgY2g7XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICBpZiAoY2ggPT09IDB4N0MvKiB8ICovKSB7XG4gICAgZm9sZGluZyA9IGZhbHNlO1xuICB9IGVsc2UgaWYgKGNoID09PSAweDNFLyogPiAqLykge1xuICAgIGZvbGRpbmcgPSB0cnVlO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHN0YXRlLmtpbmQgPSAnc2NhbGFyJztcbiAgc3RhdGUucmVzdWx0ID0gJyc7XG5cbiAgd2hpbGUgKGNoICE9PSAwKSB7XG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuXG4gICAgaWYgKGNoID09PSAweDJCLyogKyAqLyB8fCBjaCA9PT0gMHgyRC8qIC0gKi8pIHtcbiAgICAgIGlmIChDSE9NUElOR19DTElQID09PSBjaG9tcGluZykge1xuICAgICAgICBjaG9tcGluZyA9IChjaCA9PT0gMHgyQi8qICsgKi8pID8gQ0hPTVBJTkdfS0VFUCA6IENIT01QSU5HX1NUUklQO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3JlcGVhdCBvZiBhIGNob21waW5nIG1vZGUgaWRlbnRpZmllcicpO1xuICAgICAgfVxuXG4gICAgfSBlbHNlIGlmICgodG1wID0gZnJvbURlY2ltYWxDb2RlKGNoKSkgPj0gMCkge1xuICAgICAgaWYgKHRtcCA9PT0gMCkge1xuICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnYmFkIGV4cGxpY2l0IGluZGVudGF0aW9uIHdpZHRoIG9mIGEgYmxvY2sgc2NhbGFyOyBpdCBjYW5ub3QgYmUgbGVzcyB0aGFuIG9uZScpO1xuICAgICAgfSBlbHNlIGlmICghZGV0ZWN0ZWRJbmRlbnQpIHtcbiAgICAgICAgdGV4dEluZGVudCA9IG5vZGVJbmRlbnQgKyB0bXAgLSAxO1xuICAgICAgICBkZXRlY3RlZEluZGVudCA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAncmVwZWF0IG9mIGFuIGluZGVudGF0aW9uIHdpZHRoIGlkZW50aWZpZXInKTtcbiAgICAgIH1cblxuICAgIH0gZWxzZSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBpZiAoaXNfV0hJVEVfU1BBQ0UoY2gpKSB7XG4gICAgZG8geyBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7IH1cbiAgICB3aGlsZSAoaXNfV0hJVEVfU1BBQ0UoY2gpKTtcblxuICAgIGlmIChjaCA9PT0gMHgyMy8qICMgKi8pIHtcbiAgICAgIGRvIHsgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pOyB9XG4gICAgICB3aGlsZSAoIWlzX0VPTChjaCkgJiYgKGNoICE9PSAwKSk7XG4gICAgfVxuICB9XG5cbiAgd2hpbGUgKGNoICE9PSAwKSB7XG4gICAgcmVhZExpbmVCcmVhayhzdGF0ZSk7XG4gICAgc3RhdGUubGluZUluZGVudCA9IDA7XG5cbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gICAgd2hpbGUgKCghZGV0ZWN0ZWRJbmRlbnQgfHwgc3RhdGUubGluZUluZGVudCA8IHRleHRJbmRlbnQpICYmXG4gICAgICAgICAgIChjaCA9PT0gMHgyMC8qIFNwYWNlICovKSkge1xuICAgICAgc3RhdGUubGluZUluZGVudCsrO1xuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgIH1cblxuICAgIGlmICghZGV0ZWN0ZWRJbmRlbnQgJiYgc3RhdGUubGluZUluZGVudCA+IHRleHRJbmRlbnQpIHtcbiAgICAgIHRleHRJbmRlbnQgPSBzdGF0ZS5saW5lSW5kZW50O1xuICAgIH1cblxuICAgIGlmIChpc19FT0woY2gpKSB7XG4gICAgICBlbXB0eUxpbmVzKys7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICAvLyBFbmQgb2YgdGhlIHNjYWxhci5cbiAgICBpZiAoc3RhdGUubGluZUluZGVudCA8IHRleHRJbmRlbnQpIHtcblxuICAgICAgLy8gUGVyZm9ybSB0aGUgY2hvbXBpbmcuXG4gICAgICBpZiAoY2hvbXBpbmcgPT09IENIT01QSU5HX0tFRVApIHtcbiAgICAgICAgc3RhdGUucmVzdWx0ICs9IGNvbW1vbi5yZXBlYXQoJ1xcbicsIGRpZFJlYWRDb250ZW50ID8gMSArIGVtcHR5TGluZXMgOiBlbXB0eUxpbmVzKTtcbiAgICAgIH0gZWxzZSBpZiAoY2hvbXBpbmcgPT09IENIT01QSU5HX0NMSVApIHtcbiAgICAgICAgaWYgKGRpZFJlYWRDb250ZW50KSB7IC8vIGkuZS4gb25seSBpZiB0aGUgc2NhbGFyIGlzIG5vdCBlbXB0eS5cbiAgICAgICAgICBzdGF0ZS5yZXN1bHQgKz0gJ1xcbic7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gQnJlYWsgdGhpcyBgd2hpbGVgIGN5Y2xlIGFuZCBnbyB0byB0aGUgZnVuY2l0b24ncyBlcGlsb2d1ZS5cbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIC8vIEZvbGRlZCBzdHlsZTogdXNlIGZhbmN5IHJ1bGVzIHRvIGhhbmRsZSBsaW5lIGJyZWFrcy5cbiAgICBpZiAoZm9sZGluZykge1xuXG4gICAgICAvLyBMaW5lcyBzdGFydGluZyB3aXRoIHdoaXRlIHNwYWNlIGNoYXJhY3RlcnMgKG1vcmUtaW5kZW50ZWQgbGluZXMpIGFyZSBub3QgZm9sZGVkLlxuICAgICAgaWYgKGlzX1dISVRFX1NQQUNFKGNoKSkge1xuICAgICAgICBhdE1vcmVJbmRlbnRlZCA9IHRydWU7XG4gICAgICAgIC8vIGV4Y2VwdCBmb3IgdGhlIGZpcnN0IGNvbnRlbnQgbGluZSAoY2YuIEV4YW1wbGUgOC4xKVxuICAgICAgICBzdGF0ZS5yZXN1bHQgKz0gY29tbW9uLnJlcGVhdCgnXFxuJywgZGlkUmVhZENvbnRlbnQgPyAxICsgZW1wdHlMaW5lcyA6IGVtcHR5TGluZXMpO1xuXG4gICAgICAvLyBFbmQgb2YgbW9yZS1pbmRlbnRlZCBibG9jay5cbiAgICAgIH0gZWxzZSBpZiAoYXRNb3JlSW5kZW50ZWQpIHtcbiAgICAgICAgYXRNb3JlSW5kZW50ZWQgPSBmYWxzZTtcbiAgICAgICAgc3RhdGUucmVzdWx0ICs9IGNvbW1vbi5yZXBlYXQoJ1xcbicsIGVtcHR5TGluZXMgKyAxKTtcblxuICAgICAgLy8gSnVzdCBvbmUgbGluZSBicmVhayAtIHBlcmNlaXZlIGFzIHRoZSBzYW1lIGxpbmUuXG4gICAgICB9IGVsc2UgaWYgKGVtcHR5TGluZXMgPT09IDApIHtcbiAgICAgICAgaWYgKGRpZFJlYWRDb250ZW50KSB7IC8vIGkuZS4gb25seSBpZiB3ZSBoYXZlIGFscmVhZHkgcmVhZCBzb21lIHNjYWxhciBjb250ZW50LlxuICAgICAgICAgIHN0YXRlLnJlc3VsdCArPSAnICc7XG4gICAgICAgIH1cblxuICAgICAgLy8gU2V2ZXJhbCBsaW5lIGJyZWFrcyAtIHBlcmNlaXZlIGFzIGRpZmZlcmVudCBsaW5lcy5cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0YXRlLnJlc3VsdCArPSBjb21tb24ucmVwZWF0KCdcXG4nLCBlbXB0eUxpbmVzKTtcbiAgICAgIH1cblxuICAgIC8vIExpdGVyYWwgc3R5bGU6IGp1c3QgYWRkIGV4YWN0IG51bWJlciBvZiBsaW5lIGJyZWFrcyBiZXR3ZWVuIGNvbnRlbnQgbGluZXMuXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEtlZXAgYWxsIGxpbmUgYnJlYWtzIGV4Y2VwdCB0aGUgaGVhZGVyIGxpbmUgYnJlYWsuXG4gICAgICBzdGF0ZS5yZXN1bHQgKz0gY29tbW9uLnJlcGVhdCgnXFxuJywgZGlkUmVhZENvbnRlbnQgPyAxICsgZW1wdHlMaW5lcyA6IGVtcHR5TGluZXMpO1xuICAgIH1cblxuICAgIGRpZFJlYWRDb250ZW50ID0gdHJ1ZTtcbiAgICBkZXRlY3RlZEluZGVudCA9IHRydWU7XG4gICAgZW1wdHlMaW5lcyA9IDA7XG4gICAgY2FwdHVyZVN0YXJ0ID0gc3RhdGUucG9zaXRpb247XG5cbiAgICB3aGlsZSAoIWlzX0VPTChjaCkgJiYgKGNoICE9PSAwKSkge1xuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgIH1cblxuICAgIGNhcHR1cmVTZWdtZW50KHN0YXRlLCBjYXB0dXJlU3RhcnQsIHN0YXRlLnBvc2l0aW9uLCBmYWxzZSk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gcmVhZEJsb2NrU2VxdWVuY2Uoc3RhdGUsIG5vZGVJbmRlbnQpIHtcbiAgdmFyIF9saW5lLFxuICAgICAgX3RhZyAgICAgID0gc3RhdGUudGFnLFxuICAgICAgX2FuY2hvciAgID0gc3RhdGUuYW5jaG9yLFxuICAgICAgX3Jlc3VsdCAgID0gW10sXG4gICAgICBmb2xsb3dpbmcsXG4gICAgICBkZXRlY3RlZCAgPSBmYWxzZSxcbiAgICAgIGNoO1xuXG4gIGlmIChzdGF0ZS5hbmNob3IgIT09IG51bGwpIHtcbiAgICBzdGF0ZS5hbmNob3JNYXBbc3RhdGUuYW5jaG9yXSA9IF9yZXN1bHQ7XG4gIH1cblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gIHdoaWxlIChjaCAhPT0gMCkge1xuXG4gICAgaWYgKGNoICE9PSAweDJELyogLSAqLykge1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgZm9sbG93aW5nID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbiArIDEpO1xuXG4gICAgaWYgKCFpc19XU19PUl9FT0woZm9sbG93aW5nKSkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgZGV0ZWN0ZWQgPSB0cnVlO1xuICAgIHN0YXRlLnBvc2l0aW9uKys7XG5cbiAgICBpZiAoc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpKSB7XG4gICAgICBpZiAoc3RhdGUubGluZUluZGVudCA8PSBub2RlSW5kZW50KSB7XG4gICAgICAgIF9yZXN1bHQucHVzaChudWxsKTtcbiAgICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgX2xpbmUgPSBzdGF0ZS5saW5lO1xuICAgIGNvbXBvc2VOb2RlKHN0YXRlLCBub2RlSW5kZW50LCBDT05URVhUX0JMT0NLX0lOLCBmYWxzZSwgdHJ1ZSk7XG4gICAgX3Jlc3VsdC5wdXNoKHN0YXRlLnJlc3VsdCk7XG4gICAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpO1xuXG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICAgIGlmICgoc3RhdGUubGluZSA9PT0gX2xpbmUgfHwgc3RhdGUubGluZUluZGVudCA+IG5vZGVJbmRlbnQpICYmIChjaCAhPT0gMCkpIHtcbiAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdiYWQgaW5kZW50YXRpb24gb2YgYSBzZXF1ZW5jZSBlbnRyeScpO1xuICAgIH0gZWxzZSBpZiAoc3RhdGUubGluZUluZGVudCA8IG5vZGVJbmRlbnQpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIGlmIChkZXRlY3RlZCkge1xuICAgIHN0YXRlLnRhZyA9IF90YWc7XG4gICAgc3RhdGUuYW5jaG9yID0gX2FuY2hvcjtcbiAgICBzdGF0ZS5raW5kID0gJ3NlcXVlbmNlJztcbiAgICBzdGF0ZS5yZXN1bHQgPSBfcmVzdWx0O1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gcmVhZEJsb2NrTWFwcGluZyhzdGF0ZSwgbm9kZUluZGVudCwgZmxvd0luZGVudCkge1xuICB2YXIgZm9sbG93aW5nLFxuICAgICAgYWxsb3dDb21wYWN0LFxuICAgICAgX2xpbmUsXG4gICAgICBfdGFnICAgICAgICAgID0gc3RhdGUudGFnLFxuICAgICAgX2FuY2hvciAgICAgICA9IHN0YXRlLmFuY2hvcixcbiAgICAgIF9yZXN1bHQgICAgICAgPSB7fSxcbiAgICAgIG92ZXJyaWRhYmxlS2V5cyA9IHt9LFxuICAgICAga2V5VGFnICAgICAgICA9IG51bGwsXG4gICAgICBrZXlOb2RlICAgICAgID0gbnVsbCxcbiAgICAgIHZhbHVlTm9kZSAgICAgPSBudWxsLFxuICAgICAgYXRFeHBsaWNpdEtleSA9IGZhbHNlLFxuICAgICAgZGV0ZWN0ZWQgICAgICA9IGZhbHNlLFxuICAgICAgY2g7XG5cbiAgaWYgKHN0YXRlLmFuY2hvciAhPT0gbnVsbCkge1xuICAgIHN0YXRlLmFuY2hvck1hcFtzdGF0ZS5hbmNob3JdID0gX3Jlc3VsdDtcbiAgfVxuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgd2hpbGUgKGNoICE9PSAwKSB7XG4gICAgZm9sbG93aW5nID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbiArIDEpO1xuICAgIF9saW5lID0gc3RhdGUubGluZTsgLy8gU2F2ZSB0aGUgY3VycmVudCBsaW5lLlxuXG4gICAgLy9cbiAgICAvLyBFeHBsaWNpdCBub3RhdGlvbiBjYXNlLiBUaGVyZSBhcmUgdHdvIHNlcGFyYXRlIGJsb2NrczpcbiAgICAvLyBmaXJzdCBmb3IgdGhlIGtleSAoZGVub3RlZCBieSBcIj9cIikgYW5kIHNlY29uZCBmb3IgdGhlIHZhbHVlIChkZW5vdGVkIGJ5IFwiOlwiKVxuICAgIC8vXG4gICAgaWYgKChjaCA9PT0gMHgzRi8qID8gKi8gfHwgY2ggPT09IDB4M0EvKiA6ICovKSAmJiBpc19XU19PUl9FT0woZm9sbG93aW5nKSkge1xuXG4gICAgICBpZiAoY2ggPT09IDB4M0YvKiA/ICovKSB7XG4gICAgICAgIGlmIChhdEV4cGxpY2l0S2V5KSB7XG4gICAgICAgICAgc3RvcmVNYXBwaW5nUGFpcihzdGF0ZSwgX3Jlc3VsdCwgb3ZlcnJpZGFibGVLZXlzLCBrZXlUYWcsIGtleU5vZGUsIG51bGwpO1xuICAgICAgICAgIGtleVRhZyA9IGtleU5vZGUgPSB2YWx1ZU5vZGUgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgZGV0ZWN0ZWQgPSB0cnVlO1xuICAgICAgICBhdEV4cGxpY2l0S2V5ID0gdHJ1ZTtcbiAgICAgICAgYWxsb3dDb21wYWN0ID0gdHJ1ZTtcblxuICAgICAgfSBlbHNlIGlmIChhdEV4cGxpY2l0S2V5KSB7XG4gICAgICAgIC8vIGkuZS4gMHgzQS8qIDogKi8gPT09IGNoYXJhY3RlciBhZnRlciB0aGUgZXhwbGljaXQga2V5LlxuICAgICAgICBhdEV4cGxpY2l0S2V5ID0gZmFsc2U7XG4gICAgICAgIGFsbG93Q29tcGFjdCA9IHRydWU7XG5cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdpbmNvbXBsZXRlIGV4cGxpY2l0IG1hcHBpbmcgcGFpcjsgYSBrZXkgbm9kZSBpcyBtaXNzZWQnKTtcbiAgICAgIH1cblxuICAgICAgc3RhdGUucG9zaXRpb24gKz0gMTtcbiAgICAgIGNoID0gZm9sbG93aW5nO1xuXG4gICAgLy9cbiAgICAvLyBJbXBsaWNpdCBub3RhdGlvbiBjYXNlLiBGbG93LXN0eWxlIG5vZGUgYXMgdGhlIGtleSBmaXJzdCwgdGhlbiBcIjpcIiwgYW5kIHRoZSB2YWx1ZS5cbiAgICAvL1xuICAgIH0gZWxzZSBpZiAoY29tcG9zZU5vZGUoc3RhdGUsIGZsb3dJbmRlbnQsIENPTlRFWFRfRkxPV19PVVQsIGZhbHNlLCB0cnVlKSkge1xuXG4gICAgICBpZiAoc3RhdGUubGluZSA9PT0gX2xpbmUpIHtcbiAgICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICAgICAgICB3aGlsZSAoaXNfV0hJVEVfU1BBQ0UoY2gpKSB7XG4gICAgICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNoID09PSAweDNBLyogOiAqLykge1xuICAgICAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcblxuICAgICAgICAgIGlmICghaXNfV1NfT1JfRU9MKGNoKSkge1xuICAgICAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2Egd2hpdGVzcGFjZSBjaGFyYWN0ZXIgaXMgZXhwZWN0ZWQgYWZ0ZXIgdGhlIGtleS12YWx1ZSBzZXBhcmF0b3Igd2l0aGluIGEgYmxvY2sgbWFwcGluZycpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChhdEV4cGxpY2l0S2V5KSB7XG4gICAgICAgICAgICBzdG9yZU1hcHBpbmdQYWlyKHN0YXRlLCBfcmVzdWx0LCBvdmVycmlkYWJsZUtleXMsIGtleVRhZywga2V5Tm9kZSwgbnVsbCk7XG4gICAgICAgICAgICBrZXlUYWcgPSBrZXlOb2RlID0gdmFsdWVOb2RlID0gbnVsbDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBkZXRlY3RlZCA9IHRydWU7XG4gICAgICAgICAgYXRFeHBsaWNpdEtleSA9IGZhbHNlO1xuICAgICAgICAgIGFsbG93Q29tcGFjdCA9IGZhbHNlO1xuICAgICAgICAgIGtleVRhZyA9IHN0YXRlLnRhZztcbiAgICAgICAgICBrZXlOb2RlID0gc3RhdGUucmVzdWx0O1xuXG4gICAgICAgIH0gZWxzZSBpZiAoZGV0ZWN0ZWQpIHtcbiAgICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnY2FuIG5vdCByZWFkIGFuIGltcGxpY2l0IG1hcHBpbmcgcGFpcjsgYSBjb2xvbiBpcyBtaXNzZWQnKTtcblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHN0YXRlLnRhZyA9IF90YWc7XG4gICAgICAgICAgc3RhdGUuYW5jaG9yID0gX2FuY2hvcjtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTsgLy8gS2VlcCB0aGUgcmVzdWx0IG9mIGBjb21wb3NlTm9kZWAuXG4gICAgICAgIH1cblxuICAgICAgfSBlbHNlIGlmIChkZXRlY3RlZCkge1xuICAgICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnY2FuIG5vdCByZWFkIGEgYmxvY2sgbWFwcGluZyBlbnRyeTsgYSBtdWx0aWxpbmUga2V5IG1heSBub3QgYmUgYW4gaW1wbGljaXQga2V5Jyk7XG5cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0YXRlLnRhZyA9IF90YWc7XG4gICAgICAgIHN0YXRlLmFuY2hvciA9IF9hbmNob3I7XG4gICAgICAgIHJldHVybiB0cnVlOyAvLyBLZWVwIHRoZSByZXN1bHQgb2YgYGNvbXBvc2VOb2RlYC5cbiAgICAgIH1cblxuICAgIH0gZWxzZSB7XG4gICAgICBicmVhazsgLy8gUmVhZGluZyBpcyBkb25lLiBHbyB0byB0aGUgZXBpbG9ndWUuXG4gICAgfVxuXG4gICAgLy9cbiAgICAvLyBDb21tb24gcmVhZGluZyBjb2RlIGZvciBib3RoIGV4cGxpY2l0IGFuZCBpbXBsaWNpdCBub3RhdGlvbnMuXG4gICAgLy9cbiAgICBpZiAoc3RhdGUubGluZSA9PT0gX2xpbmUgfHwgc3RhdGUubGluZUluZGVudCA+IG5vZGVJbmRlbnQpIHtcbiAgICAgIGlmIChjb21wb3NlTm9kZShzdGF0ZSwgbm9kZUluZGVudCwgQ09OVEVYVF9CTE9DS19PVVQsIHRydWUsIGFsbG93Q29tcGFjdCkpIHtcbiAgICAgICAgaWYgKGF0RXhwbGljaXRLZXkpIHtcbiAgICAgICAgICBrZXlOb2RlID0gc3RhdGUucmVzdWx0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhbHVlTm9kZSA9IHN0YXRlLnJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoIWF0RXhwbGljaXRLZXkpIHtcbiAgICAgICAgc3RvcmVNYXBwaW5nUGFpcihzdGF0ZSwgX3Jlc3VsdCwgb3ZlcnJpZGFibGVLZXlzLCBrZXlUYWcsIGtleU5vZGUsIHZhbHVlTm9kZSk7XG4gICAgICAgIGtleVRhZyA9IGtleU5vZGUgPSB2YWx1ZU5vZGUgPSBudWxsO1xuICAgICAgfVxuXG4gICAgICBza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCAtMSk7XG4gICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuICAgIH1cblxuICAgIGlmIChzdGF0ZS5saW5lSW5kZW50ID4gbm9kZUluZGVudCAmJiAoY2ggIT09IDApKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAnYmFkIGluZGVudGF0aW9uIG9mIGEgbWFwcGluZyBlbnRyeScpO1xuICAgIH0gZWxzZSBpZiAoc3RhdGUubGluZUluZGVudCA8IG5vZGVJbmRlbnQpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIC8vXG4gIC8vIEVwaWxvZ3VlLlxuICAvL1xuXG4gIC8vIFNwZWNpYWwgY2FzZTogbGFzdCBtYXBwaW5nJ3Mgbm9kZSBjb250YWlucyBvbmx5IHRoZSBrZXkgaW4gZXhwbGljaXQgbm90YXRpb24uXG4gIGlmIChhdEV4cGxpY2l0S2V5KSB7XG4gICAgc3RvcmVNYXBwaW5nUGFpcihzdGF0ZSwgX3Jlc3VsdCwgb3ZlcnJpZGFibGVLZXlzLCBrZXlUYWcsIGtleU5vZGUsIG51bGwpO1xuICB9XG5cbiAgLy8gRXhwb3NlIHRoZSByZXN1bHRpbmcgbWFwcGluZy5cbiAgaWYgKGRldGVjdGVkKSB7XG4gICAgc3RhdGUudGFnID0gX3RhZztcbiAgICBzdGF0ZS5hbmNob3IgPSBfYW5jaG9yO1xuICAgIHN0YXRlLmtpbmQgPSAnbWFwcGluZyc7XG4gICAgc3RhdGUucmVzdWx0ID0gX3Jlc3VsdDtcbiAgfVxuXG4gIHJldHVybiBkZXRlY3RlZDtcbn1cblxuZnVuY3Rpb24gcmVhZFRhZ1Byb3BlcnR5KHN0YXRlKSB7XG4gIHZhciBfcG9zaXRpb24sXG4gICAgICBpc1ZlcmJhdGltID0gZmFsc2UsXG4gICAgICBpc05hbWVkICAgID0gZmFsc2UsXG4gICAgICB0YWdIYW5kbGUsXG4gICAgICB0YWdOYW1lLFxuICAgICAgY2g7XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKTtcblxuICBpZiAoY2ggIT09IDB4MjEvKiAhICovKSByZXR1cm4gZmFsc2U7XG5cbiAgaWYgKHN0YXRlLnRhZyAhPT0gbnVsbCkge1xuICAgIHRocm93RXJyb3Ioc3RhdGUsICdkdXBsaWNhdGlvbiBvZiBhIHRhZyBwcm9wZXJ0eScpO1xuICB9XG5cbiAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuXG4gIGlmIChjaCA9PT0gMHgzQy8qIDwgKi8pIHtcbiAgICBpc1ZlcmJhdGltID0gdHJ1ZTtcbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG5cbiAgfSBlbHNlIGlmIChjaCA9PT0gMHgyMS8qICEgKi8pIHtcbiAgICBpc05hbWVkID0gdHJ1ZTtcbiAgICB0YWdIYW5kbGUgPSAnISEnO1xuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcblxuICB9IGVsc2Uge1xuICAgIHRhZ0hhbmRsZSA9ICchJztcbiAgfVxuXG4gIF9wb3NpdGlvbiA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gIGlmIChpc1ZlcmJhdGltKSB7XG4gICAgZG8geyBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7IH1cbiAgICB3aGlsZSAoY2ggIT09IDAgJiYgY2ggIT09IDB4M0UvKiA+ICovKTtcblxuICAgIGlmIChzdGF0ZS5wb3NpdGlvbiA8IHN0YXRlLmxlbmd0aCkge1xuICAgICAgdGFnTmFtZSA9IHN0YXRlLmlucHV0LnNsaWNlKF9wb3NpdGlvbiwgc3RhdGUucG9zaXRpb24pO1xuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAndW5leHBlY3RlZCBlbmQgb2YgdGhlIHN0cmVhbSB3aXRoaW4gYSB2ZXJiYXRpbSB0YWcnKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgd2hpbGUgKGNoICE9PSAwICYmICFpc19XU19PUl9FT0woY2gpKSB7XG5cbiAgICAgIGlmIChjaCA9PT0gMHgyMS8qICEgKi8pIHtcbiAgICAgICAgaWYgKCFpc05hbWVkKSB7XG4gICAgICAgICAgdGFnSGFuZGxlID0gc3RhdGUuaW5wdXQuc2xpY2UoX3Bvc2l0aW9uIC0gMSwgc3RhdGUucG9zaXRpb24gKyAxKTtcblxuICAgICAgICAgIGlmICghUEFUVEVSTl9UQUdfSEFORExFLnRlc3QodGFnSGFuZGxlKSkge1xuICAgICAgICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ25hbWVkIHRhZyBoYW5kbGUgY2Fubm90IGNvbnRhaW4gc3VjaCBjaGFyYWN0ZXJzJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaXNOYW1lZCA9IHRydWU7XG4gICAgICAgICAgX3Bvc2l0aW9uID0gc3RhdGUucG9zaXRpb24gKyAxO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd0YWcgc3VmZml4IGNhbm5vdCBjb250YWluIGV4Y2xhbWF0aW9uIG1hcmtzJyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICAgIH1cblxuICAgIHRhZ05hbWUgPSBzdGF0ZS5pbnB1dC5zbGljZShfcG9zaXRpb24sIHN0YXRlLnBvc2l0aW9uKTtcblxuICAgIGlmIChQQVRURVJOX0ZMT1dfSU5ESUNBVE9SUy50ZXN0KHRhZ05hbWUpKSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAndGFnIHN1ZmZpeCBjYW5ub3QgY29udGFpbiBmbG93IGluZGljYXRvciBjaGFyYWN0ZXJzJyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHRhZ05hbWUgJiYgIVBBVFRFUk5fVEFHX1VSSS50ZXN0KHRhZ05hbWUpKSB7XG4gICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3RhZyBuYW1lIGNhbm5vdCBjb250YWluIHN1Y2ggY2hhcmFjdGVyczogJyArIHRhZ05hbWUpO1xuICB9XG5cbiAgaWYgKGlzVmVyYmF0aW0pIHtcbiAgICBzdGF0ZS50YWcgPSB0YWdOYW1lO1xuXG4gIH0gZWxzZSBpZiAoX2hhc093blByb3BlcnR5LmNhbGwoc3RhdGUudGFnTWFwLCB0YWdIYW5kbGUpKSB7XG4gICAgc3RhdGUudGFnID0gc3RhdGUudGFnTWFwW3RhZ0hhbmRsZV0gKyB0YWdOYW1lO1xuXG4gIH0gZWxzZSBpZiAodGFnSGFuZGxlID09PSAnIScpIHtcbiAgICBzdGF0ZS50YWcgPSAnIScgKyB0YWdOYW1lO1xuXG4gIH0gZWxzZSBpZiAodGFnSGFuZGxlID09PSAnISEnKSB7XG4gICAgc3RhdGUudGFnID0gJ3RhZzp5YW1sLm9yZywyMDAyOicgKyB0YWdOYW1lO1xuXG4gIH0gZWxzZSB7XG4gICAgdGhyb3dFcnJvcihzdGF0ZSwgJ3VuZGVjbGFyZWQgdGFnIGhhbmRsZSBcIicgKyB0YWdIYW5kbGUgKyAnXCInKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiByZWFkQW5jaG9yUHJvcGVydHkoc3RhdGUpIHtcbiAgdmFyIF9wb3NpdGlvbixcbiAgICAgIGNoO1xuXG4gIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgaWYgKGNoICE9PSAweDI2LyogJiAqLykgcmV0dXJuIGZhbHNlO1xuXG4gIGlmIChzdGF0ZS5hbmNob3IgIT09IG51bGwpIHtcbiAgICB0aHJvd0Vycm9yKHN0YXRlLCAnZHVwbGljYXRpb24gb2YgYW4gYW5jaG9yIHByb3BlcnR5Jyk7XG4gIH1cblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gIF9wb3NpdGlvbiA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gIHdoaWxlIChjaCAhPT0gMCAmJiAhaXNfV1NfT1JfRU9MKGNoKSAmJiAhaXNfRkxPV19JTkRJQ0FUT1IoY2gpKSB7XG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICB9XG5cbiAgaWYgKHN0YXRlLnBvc2l0aW9uID09PSBfcG9zaXRpb24pIHtcbiAgICB0aHJvd0Vycm9yKHN0YXRlLCAnbmFtZSBvZiBhbiBhbmNob3Igbm9kZSBtdXN0IGNvbnRhaW4gYXQgbGVhc3Qgb25lIGNoYXJhY3RlcicpO1xuICB9XG5cbiAgc3RhdGUuYW5jaG9yID0gc3RhdGUuaW5wdXQuc2xpY2UoX3Bvc2l0aW9uLCBzdGF0ZS5wb3NpdGlvbik7XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiByZWFkQWxpYXMoc3RhdGUpIHtcbiAgdmFyIF9wb3NpdGlvbiwgYWxpYXMsXG4gICAgICBjaDtcblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pO1xuXG4gIGlmIChjaCAhPT0gMHgyQS8qICogKi8pIHJldHVybiBmYWxzZTtcblxuICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gIF9wb3NpdGlvbiA9IHN0YXRlLnBvc2l0aW9uO1xuXG4gIHdoaWxlIChjaCAhPT0gMCAmJiAhaXNfV1NfT1JfRU9MKGNoKSAmJiAhaXNfRkxPV19JTkRJQ0FUT1IoY2gpKSB7XG4gICAgY2ggPSBzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KCsrc3RhdGUucG9zaXRpb24pO1xuICB9XG5cbiAgaWYgKHN0YXRlLnBvc2l0aW9uID09PSBfcG9zaXRpb24pIHtcbiAgICB0aHJvd0Vycm9yKHN0YXRlLCAnbmFtZSBvZiBhbiBhbGlhcyBub2RlIG11c3QgY29udGFpbiBhdCBsZWFzdCBvbmUgY2hhcmFjdGVyJyk7XG4gIH1cblxuICBhbGlhcyA9IHN0YXRlLmlucHV0LnNsaWNlKF9wb3NpdGlvbiwgc3RhdGUucG9zaXRpb24pO1xuXG4gIGlmICghc3RhdGUuYW5jaG9yTWFwLmhhc093blByb3BlcnR5KGFsaWFzKSkge1xuICAgIHRocm93RXJyb3Ioc3RhdGUsICd1bmlkZW50aWZpZWQgYWxpYXMgXCInICsgYWxpYXMgKyAnXCInKTtcbiAgfVxuXG4gIHN0YXRlLnJlc3VsdCA9IHN0YXRlLmFuY2hvck1hcFthbGlhc107XG4gIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKTtcbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGNvbXBvc2VOb2RlKHN0YXRlLCBwYXJlbnRJbmRlbnQsIG5vZGVDb250ZXh0LCBhbGxvd1RvU2VlaywgYWxsb3dDb21wYWN0KSB7XG4gIHZhciBhbGxvd0Jsb2NrU3R5bGVzLFxuICAgICAgYWxsb3dCbG9ja1NjYWxhcnMsXG4gICAgICBhbGxvd0Jsb2NrQ29sbGVjdGlvbnMsXG4gICAgICBpbmRlbnRTdGF0dXMgPSAxLCAvLyAxOiB0aGlzPnBhcmVudCwgMDogdGhpcz1wYXJlbnQsIC0xOiB0aGlzPHBhcmVudFxuICAgICAgYXROZXdMaW5lICA9IGZhbHNlLFxuICAgICAgaGFzQ29udGVudCA9IGZhbHNlLFxuICAgICAgdHlwZUluZGV4LFxuICAgICAgdHlwZVF1YW50aXR5LFxuICAgICAgdHlwZSxcbiAgICAgIGZsb3dJbmRlbnQsXG4gICAgICBibG9ja0luZGVudDtcblxuICBpZiAoc3RhdGUubGlzdGVuZXIgIT09IG51bGwpIHtcbiAgICBzdGF0ZS5saXN0ZW5lcignb3BlbicsIHN0YXRlKTtcbiAgfVxuXG4gIHN0YXRlLnRhZyAgICA9IG51bGw7XG4gIHN0YXRlLmFuY2hvciA9IG51bGw7XG4gIHN0YXRlLmtpbmQgICA9IG51bGw7XG4gIHN0YXRlLnJlc3VsdCA9IG51bGw7XG5cbiAgYWxsb3dCbG9ja1N0eWxlcyA9IGFsbG93QmxvY2tTY2FsYXJzID0gYWxsb3dCbG9ja0NvbGxlY3Rpb25zID1cbiAgICBDT05URVhUX0JMT0NLX09VVCA9PT0gbm9kZUNvbnRleHQgfHxcbiAgICBDT05URVhUX0JMT0NLX0lOICA9PT0gbm9kZUNvbnRleHQ7XG5cbiAgaWYgKGFsbG93VG9TZWVrKSB7XG4gICAgaWYgKHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKSkge1xuICAgICAgYXROZXdMaW5lID0gdHJ1ZTtcblxuICAgICAgaWYgKHN0YXRlLmxpbmVJbmRlbnQgPiBwYXJlbnRJbmRlbnQpIHtcbiAgICAgICAgaW5kZW50U3RhdHVzID0gMTtcbiAgICAgIH0gZWxzZSBpZiAoc3RhdGUubGluZUluZGVudCA9PT0gcGFyZW50SW5kZW50KSB7XG4gICAgICAgIGluZGVudFN0YXR1cyA9IDA7XG4gICAgICB9IGVsc2UgaWYgKHN0YXRlLmxpbmVJbmRlbnQgPCBwYXJlbnRJbmRlbnQpIHtcbiAgICAgICAgaW5kZW50U3RhdHVzID0gLTE7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKGluZGVudFN0YXR1cyA9PT0gMSkge1xuICAgIHdoaWxlIChyZWFkVGFnUHJvcGVydHkoc3RhdGUpIHx8IHJlYWRBbmNob3JQcm9wZXJ0eShzdGF0ZSkpIHtcbiAgICAgIGlmIChza2lwU2VwYXJhdGlvblNwYWNlKHN0YXRlLCB0cnVlLCAtMSkpIHtcbiAgICAgICAgYXROZXdMaW5lID0gdHJ1ZTtcbiAgICAgICAgYWxsb3dCbG9ja0NvbGxlY3Rpb25zID0gYWxsb3dCbG9ja1N0eWxlcztcblxuICAgICAgICBpZiAoc3RhdGUubGluZUluZGVudCA+IHBhcmVudEluZGVudCkge1xuICAgICAgICAgIGluZGVudFN0YXR1cyA9IDE7XG4gICAgICAgIH0gZWxzZSBpZiAoc3RhdGUubGluZUluZGVudCA9PT0gcGFyZW50SW5kZW50KSB7XG4gICAgICAgICAgaW5kZW50U3RhdHVzID0gMDtcbiAgICAgICAgfSBlbHNlIGlmIChzdGF0ZS5saW5lSW5kZW50IDwgcGFyZW50SW5kZW50KSB7XG4gICAgICAgICAgaW5kZW50U3RhdHVzID0gLTE7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFsbG93QmxvY2tDb2xsZWN0aW9ucyA9IGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChhbGxvd0Jsb2NrQ29sbGVjdGlvbnMpIHtcbiAgICBhbGxvd0Jsb2NrQ29sbGVjdGlvbnMgPSBhdE5ld0xpbmUgfHwgYWxsb3dDb21wYWN0O1xuICB9XG5cbiAgaWYgKGluZGVudFN0YXR1cyA9PT0gMSB8fCBDT05URVhUX0JMT0NLX09VVCA9PT0gbm9kZUNvbnRleHQpIHtcbiAgICBpZiAoQ09OVEVYVF9GTE9XX0lOID09PSBub2RlQ29udGV4dCB8fCBDT05URVhUX0ZMT1dfT1VUID09PSBub2RlQ29udGV4dCkge1xuICAgICAgZmxvd0luZGVudCA9IHBhcmVudEluZGVudDtcbiAgICB9IGVsc2Uge1xuICAgICAgZmxvd0luZGVudCA9IHBhcmVudEluZGVudCArIDE7XG4gICAgfVxuXG4gICAgYmxvY2tJbmRlbnQgPSBzdGF0ZS5wb3NpdGlvbiAtIHN0YXRlLmxpbmVTdGFydDtcblxuICAgIGlmIChpbmRlbnRTdGF0dXMgPT09IDEpIHtcbiAgICAgIGlmIChhbGxvd0Jsb2NrQ29sbGVjdGlvbnMgJiZcbiAgICAgICAgICAocmVhZEJsb2NrU2VxdWVuY2Uoc3RhdGUsIGJsb2NrSW5kZW50KSB8fFxuICAgICAgICAgICByZWFkQmxvY2tNYXBwaW5nKHN0YXRlLCBibG9ja0luZGVudCwgZmxvd0luZGVudCkpIHx8XG4gICAgICAgICAgcmVhZEZsb3dDb2xsZWN0aW9uKHN0YXRlLCBmbG93SW5kZW50KSkge1xuICAgICAgICBoYXNDb250ZW50ID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICgoYWxsb3dCbG9ja1NjYWxhcnMgJiYgcmVhZEJsb2NrU2NhbGFyKHN0YXRlLCBmbG93SW5kZW50KSkgfHxcbiAgICAgICAgICAgIHJlYWRTaW5nbGVRdW90ZWRTY2FsYXIoc3RhdGUsIGZsb3dJbmRlbnQpIHx8XG4gICAgICAgICAgICByZWFkRG91YmxlUXVvdGVkU2NhbGFyKHN0YXRlLCBmbG93SW5kZW50KSkge1xuICAgICAgICAgIGhhc0NvbnRlbnQgPSB0cnVlO1xuXG4gICAgICAgIH0gZWxzZSBpZiAocmVhZEFsaWFzKHN0YXRlKSkge1xuICAgICAgICAgIGhhc0NvbnRlbnQgPSB0cnVlO1xuXG4gICAgICAgICAgaWYgKHN0YXRlLnRhZyAhPT0gbnVsbCB8fCBzdGF0ZS5hbmNob3IgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdhbGlhcyBub2RlIHNob3VsZCBub3QgaGF2ZSBhbnkgcHJvcGVydGllcycpO1xuICAgICAgICAgIH1cblxuICAgICAgICB9IGVsc2UgaWYgKHJlYWRQbGFpblNjYWxhcihzdGF0ZSwgZmxvd0luZGVudCwgQ09OVEVYVF9GTE9XX0lOID09PSBub2RlQ29udGV4dCkpIHtcbiAgICAgICAgICBoYXNDb250ZW50ID0gdHJ1ZTtcblxuICAgICAgICAgIGlmIChzdGF0ZS50YWcgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHN0YXRlLnRhZyA9ICc/JztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc3RhdGUuYW5jaG9yICE9PSBudWxsKSB7XG4gICAgICAgICAgc3RhdGUuYW5jaG9yTWFwW3N0YXRlLmFuY2hvcl0gPSBzdGF0ZS5yZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGluZGVudFN0YXR1cyA9PT0gMCkge1xuICAgICAgLy8gU3BlY2lhbCBjYXNlOiBibG9jayBzZXF1ZW5jZXMgYXJlIGFsbG93ZWQgdG8gaGF2ZSBzYW1lIGluZGVudGF0aW9uIGxldmVsIGFzIHRoZSBwYXJlbnQuXG4gICAgICAvLyBodHRwOi8vd3d3LnlhbWwub3JnL3NwZWMvMS4yL3NwZWMuaHRtbCNpZDI3OTk3ODRcbiAgICAgIGhhc0NvbnRlbnQgPSBhbGxvd0Jsb2NrQ29sbGVjdGlvbnMgJiYgcmVhZEJsb2NrU2VxdWVuY2Uoc3RhdGUsIGJsb2NrSW5kZW50KTtcbiAgICB9XG4gIH1cblxuICBpZiAoc3RhdGUudGFnICE9PSBudWxsICYmIHN0YXRlLnRhZyAhPT0gJyEnKSB7XG4gICAgaWYgKHN0YXRlLnRhZyA9PT0gJz8nKSB7XG4gICAgICBmb3IgKHR5cGVJbmRleCA9IDAsIHR5cGVRdWFudGl0eSA9IHN0YXRlLmltcGxpY2l0VHlwZXMubGVuZ3RoO1xuICAgICAgICAgICB0eXBlSW5kZXggPCB0eXBlUXVhbnRpdHk7XG4gICAgICAgICAgIHR5cGVJbmRleCArPSAxKSB7XG4gICAgICAgIHR5cGUgPSBzdGF0ZS5pbXBsaWNpdFR5cGVzW3R5cGVJbmRleF07XG5cbiAgICAgICAgLy8gSW1wbGljaXQgcmVzb2x2aW5nIGlzIG5vdCBhbGxvd2VkIGZvciBub24tc2NhbGFyIHR5cGVzLCBhbmQgJz8nXG4gICAgICAgIC8vIG5vbi1zcGVjaWZpYyB0YWcgaXMgb25seSBhc3NpZ25lZCB0byBwbGFpbiBzY2FsYXJzLiBTbywgaXQgaXNuJ3RcbiAgICAgICAgLy8gbmVlZGVkIHRvIGNoZWNrIGZvciAna2luZCcgY29uZm9ybWl0eS5cblxuICAgICAgICBpZiAodHlwZS5yZXNvbHZlKHN0YXRlLnJlc3VsdCkpIHsgLy8gYHN0YXRlLnJlc3VsdGAgdXBkYXRlZCBpbiByZXNvbHZlciBpZiBtYXRjaGVkXG4gICAgICAgICAgc3RhdGUucmVzdWx0ID0gdHlwZS5jb25zdHJ1Y3Qoc3RhdGUucmVzdWx0KTtcbiAgICAgICAgICBzdGF0ZS50YWcgPSB0eXBlLnRhZztcbiAgICAgICAgICBpZiAoc3RhdGUuYW5jaG9yICE9PSBudWxsKSB7XG4gICAgICAgICAgICBzdGF0ZS5hbmNob3JNYXBbc3RhdGUuYW5jaG9yXSA9IHN0YXRlLnJlc3VsdDtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKF9oYXNPd25Qcm9wZXJ0eS5jYWxsKHN0YXRlLnR5cGVNYXAsIHN0YXRlLnRhZykpIHtcbiAgICAgIHR5cGUgPSBzdGF0ZS50eXBlTWFwW3N0YXRlLnRhZ107XG5cbiAgICAgIGlmIChzdGF0ZS5yZXN1bHQgIT09IG51bGwgJiYgdHlwZS5raW5kICE9PSBzdGF0ZS5raW5kKSB7XG4gICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICd1bmFjY2VwdGFibGUgbm9kZSBraW5kIGZvciAhPCcgKyBzdGF0ZS50YWcgKyAnPiB0YWc7IGl0IHNob3VsZCBiZSBcIicgKyB0eXBlLmtpbmQgKyAnXCIsIG5vdCBcIicgKyBzdGF0ZS5raW5kICsgJ1wiJyk7XG4gICAgICB9XG5cbiAgICAgIGlmICghdHlwZS5yZXNvbHZlKHN0YXRlLnJlc3VsdCkpIHsgLy8gYHN0YXRlLnJlc3VsdGAgdXBkYXRlZCBpbiByZXNvbHZlciBpZiBtYXRjaGVkXG4gICAgICAgIHRocm93RXJyb3Ioc3RhdGUsICdjYW5ub3QgcmVzb2x2ZSBhIG5vZGUgd2l0aCAhPCcgKyBzdGF0ZS50YWcgKyAnPiBleHBsaWNpdCB0YWcnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0YXRlLnJlc3VsdCA9IHR5cGUuY29uc3RydWN0KHN0YXRlLnJlc3VsdCk7XG4gICAgICAgIGlmIChzdGF0ZS5hbmNob3IgIT09IG51bGwpIHtcbiAgICAgICAgICBzdGF0ZS5hbmNob3JNYXBbc3RhdGUuYW5jaG9yXSA9IHN0YXRlLnJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvd0Vycm9yKHN0YXRlLCAndW5rbm93biB0YWcgITwnICsgc3RhdGUudGFnICsgJz4nKTtcbiAgICB9XG4gIH1cblxuICBpZiAoc3RhdGUubGlzdGVuZXIgIT09IG51bGwpIHtcbiAgICBzdGF0ZS5saXN0ZW5lcignY2xvc2UnLCBzdGF0ZSk7XG4gIH1cbiAgcmV0dXJuIHN0YXRlLnRhZyAhPT0gbnVsbCB8fCAgc3RhdGUuYW5jaG9yICE9PSBudWxsIHx8IGhhc0NvbnRlbnQ7XG59XG5cbmZ1bmN0aW9uIHJlYWREb2N1bWVudChzdGF0ZSkge1xuICB2YXIgZG9jdW1lbnRTdGFydCA9IHN0YXRlLnBvc2l0aW9uLFxuICAgICAgX3Bvc2l0aW9uLFxuICAgICAgZGlyZWN0aXZlTmFtZSxcbiAgICAgIGRpcmVjdGl2ZUFyZ3MsXG4gICAgICBoYXNEaXJlY3RpdmVzID0gZmFsc2UsXG4gICAgICBjaDtcblxuICBzdGF0ZS52ZXJzaW9uID0gbnVsbDtcbiAgc3RhdGUuY2hlY2tMaW5lQnJlYWtzID0gc3RhdGUubGVnYWN5O1xuICBzdGF0ZS50YWdNYXAgPSB7fTtcbiAgc3RhdGUuYW5jaG9yTWFwID0ge307XG5cbiAgd2hpbGUgKChjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pKSAhPT0gMCkge1xuICAgIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKTtcblxuICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbik7XG5cbiAgICBpZiAoc3RhdGUubGluZUluZGVudCA+IDAgfHwgY2ggIT09IDB4MjUvKiAlICovKSB7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICBoYXNEaXJlY3RpdmVzID0gdHJ1ZTtcbiAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgX3Bvc2l0aW9uID0gc3RhdGUucG9zaXRpb247XG5cbiAgICB3aGlsZSAoY2ggIT09IDAgJiYgIWlzX1dTX09SX0VPTChjaCkpIHtcbiAgICAgIGNoID0gc3RhdGUuaW5wdXQuY2hhckNvZGVBdCgrK3N0YXRlLnBvc2l0aW9uKTtcbiAgICB9XG5cbiAgICBkaXJlY3RpdmVOYW1lID0gc3RhdGUuaW5wdXQuc2xpY2UoX3Bvc2l0aW9uLCBzdGF0ZS5wb3NpdGlvbik7XG4gICAgZGlyZWN0aXZlQXJncyA9IFtdO1xuXG4gICAgaWYgKGRpcmVjdGl2ZU5hbWUubGVuZ3RoIDwgMSkge1xuICAgICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2RpcmVjdGl2ZSBuYW1lIG11c3Qgbm90IGJlIGxlc3MgdGhhbiBvbmUgY2hhcmFjdGVyIGluIGxlbmd0aCcpO1xuICAgIH1cblxuICAgIHdoaWxlIChjaCAhPT0gMCkge1xuICAgICAgd2hpbGUgKGlzX1dISVRFX1NQQUNFKGNoKSkge1xuICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgICB9XG5cbiAgICAgIGlmIChjaCA9PT0gMHgyMy8qICMgKi8pIHtcbiAgICAgICAgZG8geyBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7IH1cbiAgICAgICAgd2hpbGUgKGNoICE9PSAwICYmICFpc19FT0woY2gpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGlmIChpc19FT0woY2gpKSBicmVhaztcblxuICAgICAgX3Bvc2l0aW9uID0gc3RhdGUucG9zaXRpb247XG5cbiAgICAgIHdoaWxlIChjaCAhPT0gMCAmJiAhaXNfV1NfT1JfRU9MKGNoKSkge1xuICAgICAgICBjaCA9IHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoKytzdGF0ZS5wb3NpdGlvbik7XG4gICAgICB9XG5cbiAgICAgIGRpcmVjdGl2ZUFyZ3MucHVzaChzdGF0ZS5pbnB1dC5zbGljZShfcG9zaXRpb24sIHN0YXRlLnBvc2l0aW9uKSk7XG4gICAgfVxuXG4gICAgaWYgKGNoICE9PSAwKSByZWFkTGluZUJyZWFrKHN0YXRlKTtcblxuICAgIGlmIChfaGFzT3duUHJvcGVydHkuY2FsbChkaXJlY3RpdmVIYW5kbGVycywgZGlyZWN0aXZlTmFtZSkpIHtcbiAgICAgIGRpcmVjdGl2ZUhhbmRsZXJzW2RpcmVjdGl2ZU5hbWVdKHN0YXRlLCBkaXJlY3RpdmVOYW1lLCBkaXJlY3RpdmVBcmdzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3dXYXJuaW5nKHN0YXRlLCAndW5rbm93biBkb2N1bWVudCBkaXJlY3RpdmUgXCInICsgZGlyZWN0aXZlTmFtZSArICdcIicpO1xuICAgIH1cbiAgfVxuXG4gIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKTtcblxuICBpZiAoc3RhdGUubGluZUluZGVudCA9PT0gMCAmJlxuICAgICAgc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbikgICAgID09PSAweDJELyogLSAqLyAmJlxuICAgICAgc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbiArIDEpID09PSAweDJELyogLSAqLyAmJlxuICAgICAgc3RhdGUuaW5wdXQuY2hhckNvZGVBdChzdGF0ZS5wb3NpdGlvbiArIDIpID09PSAweDJELyogLSAqLykge1xuICAgIHN0YXRlLnBvc2l0aW9uICs9IDM7XG4gICAgc2tpcFNlcGFyYXRpb25TcGFjZShzdGF0ZSwgdHJ1ZSwgLTEpO1xuXG4gIH0gZWxzZSBpZiAoaGFzRGlyZWN0aXZlcykge1xuICAgIHRocm93RXJyb3Ioc3RhdGUsICdkaXJlY3RpdmVzIGVuZCBtYXJrIGlzIGV4cGVjdGVkJyk7XG4gIH1cblxuICBjb21wb3NlTm9kZShzdGF0ZSwgc3RhdGUubGluZUluZGVudCAtIDEsIENPTlRFWFRfQkxPQ0tfT1VULCBmYWxzZSwgdHJ1ZSk7XG4gIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKTtcblxuICBpZiAoc3RhdGUuY2hlY2tMaW5lQnJlYWtzICYmXG4gICAgICBQQVRURVJOX05PTl9BU0NJSV9MSU5FX0JSRUFLUy50ZXN0KHN0YXRlLmlucHV0LnNsaWNlKGRvY3VtZW50U3RhcnQsIHN0YXRlLnBvc2l0aW9uKSkpIHtcbiAgICB0aHJvd1dhcm5pbmcoc3RhdGUsICdub24tQVNDSUkgbGluZSBicmVha3MgYXJlIGludGVycHJldGVkIGFzIGNvbnRlbnQnKTtcbiAgfVxuXG4gIHN0YXRlLmRvY3VtZW50cy5wdXNoKHN0YXRlLnJlc3VsdCk7XG5cbiAgaWYgKHN0YXRlLnBvc2l0aW9uID09PSBzdGF0ZS5saW5lU3RhcnQgJiYgdGVzdERvY3VtZW50U2VwYXJhdG9yKHN0YXRlKSkge1xuXG4gICAgaWYgKHN0YXRlLmlucHV0LmNoYXJDb2RlQXQoc3RhdGUucG9zaXRpb24pID09PSAweDJFLyogLiAqLykge1xuICAgICAgc3RhdGUucG9zaXRpb24gKz0gMztcbiAgICAgIHNraXBTZXBhcmF0aW9uU3BhY2Uoc3RhdGUsIHRydWUsIC0xKTtcbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKHN0YXRlLnBvc2l0aW9uIDwgKHN0YXRlLmxlbmd0aCAtIDEpKSB7XG4gICAgdGhyb3dFcnJvcihzdGF0ZSwgJ2VuZCBvZiB0aGUgc3RyZWFtIG9yIGEgZG9jdW1lbnQgc2VwYXJhdG9yIGlzIGV4cGVjdGVkJyk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuO1xuICB9XG59XG5cblxuZnVuY3Rpb24gbG9hZERvY3VtZW50cyhpbnB1dCwgb3B0aW9ucykge1xuICBpbnB1dCA9IFN0cmluZyhpbnB1dCk7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIGlmIChpbnB1dC5sZW5ndGggIT09IDApIHtcblxuICAgIC8vIEFkZCB0YWlsaW5nIGBcXG5gIGlmIG5vdCBleGlzdHNcbiAgICBpZiAoaW5wdXQuY2hhckNvZGVBdChpbnB1dC5sZW5ndGggLSAxKSAhPT0gMHgwQS8qIExGICovICYmXG4gICAgICAgIGlucHV0LmNoYXJDb2RlQXQoaW5wdXQubGVuZ3RoIC0gMSkgIT09IDB4MEQvKiBDUiAqLykge1xuICAgICAgaW5wdXQgKz0gJ1xcbic7XG4gICAgfVxuXG4gICAgLy8gU3RyaXAgQk9NXG4gICAgaWYgKGlucHV0LmNoYXJDb2RlQXQoMCkgPT09IDB4RkVGRikge1xuICAgICAgaW5wdXQgPSBpbnB1dC5zbGljZSgxKTtcbiAgICB9XG4gIH1cblxuICB2YXIgc3RhdGUgPSBuZXcgU3RhdGUoaW5wdXQsIG9wdGlvbnMpO1xuXG4gIC8vIFVzZSAwIGFzIHN0cmluZyB0ZXJtaW5hdG9yLiBUaGF0IHNpZ25pZmljYW50bHkgc2ltcGxpZmllcyBib3VuZHMgY2hlY2suXG4gIHN0YXRlLmlucHV0ICs9ICdcXDAnO1xuXG4gIHdoaWxlIChzdGF0ZS5pbnB1dC5jaGFyQ29kZUF0KHN0YXRlLnBvc2l0aW9uKSA9PT0gMHgyMC8qIFNwYWNlICovKSB7XG4gICAgc3RhdGUubGluZUluZGVudCArPSAxO1xuICAgIHN0YXRlLnBvc2l0aW9uICs9IDE7XG4gIH1cblxuICB3aGlsZSAoc3RhdGUucG9zaXRpb24gPCAoc3RhdGUubGVuZ3RoIC0gMSkpIHtcbiAgICByZWFkRG9jdW1lbnQoc3RhdGUpO1xuICB9XG5cbiAgcmV0dXJuIHN0YXRlLmRvY3VtZW50cztcbn1cblxuXG5mdW5jdGlvbiBsb2FkQWxsKGlucHV0LCBpdGVyYXRvciwgb3B0aW9ucykge1xuICB2YXIgZG9jdW1lbnRzID0gbG9hZERvY3VtZW50cyhpbnB1dCwgb3B0aW9ucyksIGluZGV4LCBsZW5ndGg7XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IGRvY3VtZW50cy5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgaXRlcmF0b3IoZG9jdW1lbnRzW2luZGV4XSk7XG4gIH1cbn1cblxuXG5mdW5jdGlvbiBsb2FkKGlucHV0LCBvcHRpb25zKSB7XG4gIHZhciBkb2N1bWVudHMgPSBsb2FkRG9jdW1lbnRzKGlucHV0LCBvcHRpb25zKTtcblxuICBpZiAoZG9jdW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgIC8qZXNsaW50LWRpc2FibGUgbm8tdW5kZWZpbmVkKi9cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9IGVsc2UgaWYgKGRvY3VtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICByZXR1cm4gZG9jdW1lbnRzWzBdO1xuICB9XG4gIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCdleHBlY3RlZCBhIHNpbmdsZSBkb2N1bWVudCBpbiB0aGUgc3RyZWFtLCBidXQgZm91bmQgbW9yZScpO1xufVxuXG5cbmZ1bmN0aW9uIHNhZmVMb2FkQWxsKGlucHV0LCBvdXRwdXQsIG9wdGlvbnMpIHtcbiAgbG9hZEFsbChpbnB1dCwgb3V0cHV0LCBjb21tb24uZXh0ZW5kKHsgc2NoZW1hOiBERUZBVUxUX1NBRkVfU0NIRU1BIH0sIG9wdGlvbnMpKTtcbn1cblxuXG5mdW5jdGlvbiBzYWZlTG9hZChpbnB1dCwgb3B0aW9ucykge1xuICByZXR1cm4gbG9hZChpbnB1dCwgY29tbW9uLmV4dGVuZCh7IHNjaGVtYTogREVGQVVMVF9TQUZFX1NDSEVNQSB9LCBvcHRpb25zKSk7XG59XG5cblxubW9kdWxlLmV4cG9ydHMubG9hZEFsbCAgICAgPSBsb2FkQWxsO1xubW9kdWxlLmV4cG9ydHMubG9hZCAgICAgICAgPSBsb2FkO1xubW9kdWxlLmV4cG9ydHMuc2FmZUxvYWRBbGwgPSBzYWZlTG9hZEFsbDtcbm1vZHVsZS5leHBvcnRzLnNhZmVMb2FkICAgID0gc2FmZUxvYWQ7XG4iLCIndXNlIHN0cmljdCc7XG5cblxudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG5cblxuZnVuY3Rpb24gTWFyayhuYW1lLCBidWZmZXIsIHBvc2l0aW9uLCBsaW5lLCBjb2x1bW4pIHtcbiAgdGhpcy5uYW1lICAgICA9IG5hbWU7XG4gIHRoaXMuYnVmZmVyICAgPSBidWZmZXI7XG4gIHRoaXMucG9zaXRpb24gPSBwb3NpdGlvbjtcbiAgdGhpcy5saW5lICAgICA9IGxpbmU7XG4gIHRoaXMuY29sdW1uICAgPSBjb2x1bW47XG59XG5cblxuTWFyay5wcm90b3R5cGUuZ2V0U25pcHBldCA9IGZ1bmN0aW9uIGdldFNuaXBwZXQoaW5kZW50LCBtYXhMZW5ndGgpIHtcbiAgdmFyIGhlYWQsIHN0YXJ0LCB0YWlsLCBlbmQsIHNuaXBwZXQ7XG5cbiAgaWYgKCF0aGlzLmJ1ZmZlcikgcmV0dXJuIG51bGw7XG5cbiAgaW5kZW50ID0gaW5kZW50IHx8IDQ7XG4gIG1heExlbmd0aCA9IG1heExlbmd0aCB8fCA3NTtcblxuICBoZWFkID0gJyc7XG4gIHN0YXJ0ID0gdGhpcy5wb3NpdGlvbjtcblxuICB3aGlsZSAoc3RhcnQgPiAwICYmICdcXHgwMFxcclxcblxceDg1XFx1MjAyOFxcdTIwMjknLmluZGV4T2YodGhpcy5idWZmZXIuY2hhckF0KHN0YXJ0IC0gMSkpID09PSAtMSkge1xuICAgIHN0YXJ0IC09IDE7XG4gICAgaWYgKHRoaXMucG9zaXRpb24gLSBzdGFydCA+IChtYXhMZW5ndGggLyAyIC0gMSkpIHtcbiAgICAgIGhlYWQgPSAnIC4uLiAnO1xuICAgICAgc3RhcnQgKz0gNTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHRhaWwgPSAnJztcbiAgZW5kID0gdGhpcy5wb3NpdGlvbjtcblxuICB3aGlsZSAoZW5kIDwgdGhpcy5idWZmZXIubGVuZ3RoICYmICdcXHgwMFxcclxcblxceDg1XFx1MjAyOFxcdTIwMjknLmluZGV4T2YodGhpcy5idWZmZXIuY2hhckF0KGVuZCkpID09PSAtMSkge1xuICAgIGVuZCArPSAxO1xuICAgIGlmIChlbmQgLSB0aGlzLnBvc2l0aW9uID4gKG1heExlbmd0aCAvIDIgLSAxKSkge1xuICAgICAgdGFpbCA9ICcgLi4uICc7XG4gICAgICBlbmQgLT0gNTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHNuaXBwZXQgPSB0aGlzLmJ1ZmZlci5zbGljZShzdGFydCwgZW5kKTtcblxuICByZXR1cm4gY29tbW9uLnJlcGVhdCgnICcsIGluZGVudCkgKyBoZWFkICsgc25pcHBldCArIHRhaWwgKyAnXFxuJyArXG4gICAgICAgICBjb21tb24ucmVwZWF0KCcgJywgaW5kZW50ICsgdGhpcy5wb3NpdGlvbiAtIHN0YXJ0ICsgaGVhZC5sZW5ndGgpICsgJ14nO1xufTtcblxuXG5NYXJrLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKGNvbXBhY3QpIHtcbiAgdmFyIHNuaXBwZXQsIHdoZXJlID0gJyc7XG5cbiAgaWYgKHRoaXMubmFtZSkge1xuICAgIHdoZXJlICs9ICdpbiBcIicgKyB0aGlzLm5hbWUgKyAnXCIgJztcbiAgfVxuXG4gIHdoZXJlICs9ICdhdCBsaW5lICcgKyAodGhpcy5saW5lICsgMSkgKyAnLCBjb2x1bW4gJyArICh0aGlzLmNvbHVtbiArIDEpO1xuXG4gIGlmICghY29tcGFjdCkge1xuICAgIHNuaXBwZXQgPSB0aGlzLmdldFNuaXBwZXQoKTtcblxuICAgIGlmIChzbmlwcGV0KSB7XG4gICAgICB3aGVyZSArPSAnOlxcbicgKyBzbmlwcGV0O1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB3aGVyZTtcbn07XG5cblxubW9kdWxlLmV4cG9ydHMgPSBNYXJrO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKmVzbGludC1kaXNhYmxlIG1heC1sZW4qL1xuXG52YXIgY29tbW9uICAgICAgICA9IHJlcXVpcmUoJy4vY29tbW9uJyk7XG52YXIgWUFNTEV4Y2VwdGlvbiA9IHJlcXVpcmUoJy4vZXhjZXB0aW9uJyk7XG52YXIgVHlwZSAgICAgICAgICA9IHJlcXVpcmUoJy4vdHlwZScpO1xuXG5cbmZ1bmN0aW9uIGNvbXBpbGVMaXN0KHNjaGVtYSwgbmFtZSwgcmVzdWx0KSB7XG4gIHZhciBleGNsdWRlID0gW107XG5cbiAgc2NoZW1hLmluY2x1ZGUuZm9yRWFjaChmdW5jdGlvbiAoaW5jbHVkZWRTY2hlbWEpIHtcbiAgICByZXN1bHQgPSBjb21waWxlTGlzdChpbmNsdWRlZFNjaGVtYSwgbmFtZSwgcmVzdWx0KTtcbiAgfSk7XG5cbiAgc2NoZW1hW25hbWVdLmZvckVhY2goZnVuY3Rpb24gKGN1cnJlbnRUeXBlKSB7XG4gICAgcmVzdWx0LmZvckVhY2goZnVuY3Rpb24gKHByZXZpb3VzVHlwZSwgcHJldmlvdXNJbmRleCkge1xuICAgICAgaWYgKHByZXZpb3VzVHlwZS50YWcgPT09IGN1cnJlbnRUeXBlLnRhZykge1xuICAgICAgICBleGNsdWRlLnB1c2gocHJldmlvdXNJbmRleCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXN1bHQucHVzaChjdXJyZW50VHlwZSk7XG4gIH0pO1xuXG4gIHJldHVybiByZXN1bHQuZmlsdGVyKGZ1bmN0aW9uICh0eXBlLCBpbmRleCkge1xuICAgIHJldHVybiBleGNsdWRlLmluZGV4T2YoaW5kZXgpID09PSAtMTtcbiAgfSk7XG59XG5cblxuZnVuY3Rpb24gY29tcGlsZU1hcCgvKiBsaXN0cy4uLiAqLykge1xuICB2YXIgcmVzdWx0ID0ge30sIGluZGV4LCBsZW5ndGg7XG5cbiAgZnVuY3Rpb24gY29sbGVjdFR5cGUodHlwZSkge1xuICAgIHJlc3VsdFt0eXBlLnRhZ10gPSB0eXBlO1xuICB9XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgYXJndW1lbnRzW2luZGV4XS5mb3JFYWNoKGNvbGxlY3RUeXBlKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cblxuZnVuY3Rpb24gU2NoZW1hKGRlZmluaXRpb24pIHtcbiAgdGhpcy5pbmNsdWRlICA9IGRlZmluaXRpb24uaW5jbHVkZSAgfHwgW107XG4gIHRoaXMuaW1wbGljaXQgPSBkZWZpbml0aW9uLmltcGxpY2l0IHx8IFtdO1xuICB0aGlzLmV4cGxpY2l0ID0gZGVmaW5pdGlvbi5leHBsaWNpdCB8fCBbXTtcblxuICB0aGlzLmltcGxpY2l0LmZvckVhY2goZnVuY3Rpb24gKHR5cGUpIHtcbiAgICBpZiAodHlwZS5sb2FkS2luZCAmJiB0eXBlLmxvYWRLaW5kICE9PSAnc2NhbGFyJykge1xuICAgICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJ1RoZXJlIGlzIGEgbm9uLXNjYWxhciB0eXBlIGluIHRoZSBpbXBsaWNpdCBsaXN0IG9mIGEgc2NoZW1hLiBJbXBsaWNpdCByZXNvbHZpbmcgb2Ygc3VjaCB0eXBlcyBpcyBub3Qgc3VwcG9ydGVkLicpO1xuICAgIH1cbiAgfSk7XG5cbiAgdGhpcy5jb21waWxlZEltcGxpY2l0ID0gY29tcGlsZUxpc3QodGhpcywgJ2ltcGxpY2l0JywgW10pO1xuICB0aGlzLmNvbXBpbGVkRXhwbGljaXQgPSBjb21waWxlTGlzdCh0aGlzLCAnZXhwbGljaXQnLCBbXSk7XG4gIHRoaXMuY29tcGlsZWRUeXBlTWFwICA9IGNvbXBpbGVNYXAodGhpcy5jb21waWxlZEltcGxpY2l0LCB0aGlzLmNvbXBpbGVkRXhwbGljaXQpO1xufVxuXG5cblNjaGVtYS5ERUZBVUxUID0gbnVsbDtcblxuXG5TY2hlbWEuY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlU2NoZW1hKCkge1xuICB2YXIgc2NoZW1hcywgdHlwZXM7XG5cbiAgc3dpdGNoIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgY2FzZSAxOlxuICAgICAgc2NoZW1hcyA9IFNjaGVtYS5ERUZBVUxUO1xuICAgICAgdHlwZXMgPSBhcmd1bWVudHNbMF07XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgMjpcbiAgICAgIHNjaGVtYXMgPSBhcmd1bWVudHNbMF07XG4gICAgICB0eXBlcyA9IGFyZ3VtZW50c1sxXTtcbiAgICAgIGJyZWFrO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCdXcm9uZyBudW1iZXIgb2YgYXJndW1lbnRzIGZvciBTY2hlbWEuY3JlYXRlIGZ1bmN0aW9uJyk7XG4gIH1cblxuICBzY2hlbWFzID0gY29tbW9uLnRvQXJyYXkoc2NoZW1hcyk7XG4gIHR5cGVzID0gY29tbW9uLnRvQXJyYXkodHlwZXMpO1xuXG4gIGlmICghc2NoZW1hcy5ldmVyeShmdW5jdGlvbiAoc2NoZW1hKSB7IHJldHVybiBzY2hlbWEgaW5zdGFuY2VvZiBTY2hlbWE7IH0pKSB7XG4gICAgdGhyb3cgbmV3IFlBTUxFeGNlcHRpb24oJ1NwZWNpZmllZCBsaXN0IG9mIHN1cGVyIHNjaGVtYXMgKG9yIGEgc2luZ2xlIFNjaGVtYSBvYmplY3QpIGNvbnRhaW5zIGEgbm9uLVNjaGVtYSBvYmplY3QuJyk7XG4gIH1cblxuICBpZiAoIXR5cGVzLmV2ZXJ5KGZ1bmN0aW9uICh0eXBlKSB7IHJldHVybiB0eXBlIGluc3RhbmNlb2YgVHlwZTsgfSkpIHtcbiAgICB0aHJvdyBuZXcgWUFNTEV4Y2VwdGlvbignU3BlY2lmaWVkIGxpc3Qgb2YgWUFNTCB0eXBlcyAob3IgYSBzaW5nbGUgVHlwZSBvYmplY3QpIGNvbnRhaW5zIGEgbm9uLVR5cGUgb2JqZWN0LicpO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBTY2hlbWEoe1xuICAgIGluY2x1ZGU6IHNjaGVtYXMsXG4gICAgZXhwbGljaXQ6IHR5cGVzXG4gIH0pO1xufTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IFNjaGVtYTtcbiIsIi8vIFN0YW5kYXJkIFlBTUwncyBDb3JlIHNjaGVtYS5cbi8vIGh0dHA6Ly93d3cueWFtbC5vcmcvc3BlYy8xLjIvc3BlYy5odG1sI2lkMjgwNDkyM1xuLy9cbi8vIE5PVEU6IEpTLVlBTUwgZG9lcyBub3Qgc3VwcG9ydCBzY2hlbWEtc3BlY2lmaWMgdGFnIHJlc29sdXRpb24gcmVzdHJpY3Rpb25zLlxuLy8gU28sIENvcmUgc2NoZW1hIGhhcyBubyBkaXN0aW5jdGlvbnMgZnJvbSBKU09OIHNjaGVtYSBpcyBKUy1ZQU1MLlxuXG5cbid1c2Ugc3RyaWN0JztcblxuXG52YXIgU2NoZW1hID0gcmVxdWlyZSgnLi4vc2NoZW1hJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgU2NoZW1hKHtcbiAgaW5jbHVkZTogW1xuICAgIHJlcXVpcmUoJy4vanNvbicpXG4gIF1cbn0pO1xuIiwiLy8gSlMtWUFNTCdzIGRlZmF1bHQgc2NoZW1hIGZvciBgbG9hZGAgZnVuY3Rpb24uXG4vLyBJdCBpcyBub3QgZGVzY3JpYmVkIGluIHRoZSBZQU1MIHNwZWNpZmljYXRpb24uXG4vL1xuLy8gVGhpcyBzY2hlbWEgaXMgYmFzZWQgb24gSlMtWUFNTCdzIGRlZmF1bHQgc2FmZSBzY2hlbWEgYW5kIGluY2x1ZGVzXG4vLyBKYXZhU2NyaXB0LXNwZWNpZmljIHR5cGVzOiAhIWpzL3VuZGVmaW5lZCwgISFqcy9yZWdleHAgYW5kICEhanMvZnVuY3Rpb24uXG4vL1xuLy8gQWxzbyB0aGlzIHNjaGVtYSBpcyB1c2VkIGFzIGRlZmF1bHQgYmFzZSBzY2hlbWEgYXQgYFNjaGVtYS5jcmVhdGVgIGZ1bmN0aW9uLlxuXG5cbid1c2Ugc3RyaWN0JztcblxuXG52YXIgU2NoZW1hID0gcmVxdWlyZSgnLi4vc2NoZW1hJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSBTY2hlbWEuREVGQVVMVCA9IG5ldyBTY2hlbWEoe1xuICBpbmNsdWRlOiBbXG4gICAgcmVxdWlyZSgnLi9kZWZhdWx0X3NhZmUnKVxuICBdLFxuICBleHBsaWNpdDogW1xuICAgIHJlcXVpcmUoJy4uL3R5cGUvanMvdW5kZWZpbmVkJyksXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9qcy9yZWdleHAnKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL2pzL2Z1bmN0aW9uJylcbiAgXVxufSk7XG4iLCIvLyBKUy1ZQU1MJ3MgZGVmYXVsdCBzY2hlbWEgZm9yIGBzYWZlTG9hZGAgZnVuY3Rpb24uXG4vLyBJdCBpcyBub3QgZGVzY3JpYmVkIGluIHRoZSBZQU1MIHNwZWNpZmljYXRpb24uXG4vL1xuLy8gVGhpcyBzY2hlbWEgaXMgYmFzZWQgb24gc3RhbmRhcmQgWUFNTCdzIENvcmUgc2NoZW1hIGFuZCBpbmNsdWRlcyBtb3N0IG9mXG4vLyBleHRyYSB0eXBlcyBkZXNjcmliZWQgYXQgWUFNTCB0YWcgcmVwb3NpdG9yeS4gKGh0dHA6Ly95YW1sLm9yZy90eXBlLylcblxuXG4ndXNlIHN0cmljdCc7XG5cblxudmFyIFNjaGVtYSA9IHJlcXVpcmUoJy4uL3NjaGVtYScpO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFNjaGVtYSh7XG4gIGluY2x1ZGU6IFtcbiAgICByZXF1aXJlKCcuL2NvcmUnKVxuICBdLFxuICBpbXBsaWNpdDogW1xuICAgIHJlcXVpcmUoJy4uL3R5cGUvdGltZXN0YW1wJyksXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9tZXJnZScpXG4gIF0sXG4gIGV4cGxpY2l0OiBbXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9iaW5hcnknKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL29tYXAnKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL3BhaXJzJyksXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9zZXQnKVxuICBdXG59KTtcbiIsIi8vIFN0YW5kYXJkIFlBTUwncyBGYWlsc2FmZSBzY2hlbWEuXG4vLyBodHRwOi8vd3d3LnlhbWwub3JnL3NwZWMvMS4yL3NwZWMuaHRtbCNpZDI4MDIzNDZcblxuXG4ndXNlIHN0cmljdCc7XG5cblxudmFyIFNjaGVtYSA9IHJlcXVpcmUoJy4uL3NjaGVtYScpO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFNjaGVtYSh7XG4gIGV4cGxpY2l0OiBbXG4gICAgcmVxdWlyZSgnLi4vdHlwZS9zdHInKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL3NlcScpLFxuICAgIHJlcXVpcmUoJy4uL3R5cGUvbWFwJylcbiAgXVxufSk7XG4iLCIvLyBTdGFuZGFyZCBZQU1MJ3MgSlNPTiBzY2hlbWEuXG4vLyBodHRwOi8vd3d3LnlhbWwub3JnL3NwZWMvMS4yL3NwZWMuaHRtbCNpZDI4MDMyMzFcbi8vXG4vLyBOT1RFOiBKUy1ZQU1MIGRvZXMgbm90IHN1cHBvcnQgc2NoZW1hLXNwZWNpZmljIHRhZyByZXNvbHV0aW9uIHJlc3RyaWN0aW9ucy5cbi8vIFNvLCB0aGlzIHNjaGVtYSBpcyBub3Qgc3VjaCBzdHJpY3QgYXMgZGVmaW5lZCBpbiB0aGUgWUFNTCBzcGVjaWZpY2F0aW9uLlxuLy8gSXQgYWxsb3dzIG51bWJlcnMgaW4gYmluYXJ5IG5vdGFpb24sIHVzZSBgTnVsbGAgYW5kIGBOVUxMYCBhcyBgbnVsbGAsIGV0Yy5cblxuXG4ndXNlIHN0cmljdCc7XG5cblxudmFyIFNjaGVtYSA9IHJlcXVpcmUoJy4uL3NjaGVtYScpO1xuXG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFNjaGVtYSh7XG4gIGluY2x1ZGU6IFtcbiAgICByZXF1aXJlKCcuL2ZhaWxzYWZlJylcbiAgXSxcbiAgaW1wbGljaXQ6IFtcbiAgICByZXF1aXJlKCcuLi90eXBlL251bGwnKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL2Jvb2wnKSxcbiAgICByZXF1aXJlKCcuLi90eXBlL2ludCcpLFxuICAgIHJlcXVpcmUoJy4uL3R5cGUvZmxvYXQnKVxuICBdXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFlBTUxFeGNlcHRpb24gPSByZXF1aXJlKCcuL2V4Y2VwdGlvbicpO1xuXG52YXIgVFlQRV9DT05TVFJVQ1RPUl9PUFRJT05TID0gW1xuICAna2luZCcsXG4gICdyZXNvbHZlJyxcbiAgJ2NvbnN0cnVjdCcsXG4gICdpbnN0YW5jZU9mJyxcbiAgJ3ByZWRpY2F0ZScsXG4gICdyZXByZXNlbnQnLFxuICAnZGVmYXVsdFN0eWxlJyxcbiAgJ3N0eWxlQWxpYXNlcydcbl07XG5cbnZhciBZQU1MX05PREVfS0lORFMgPSBbXG4gICdzY2FsYXInLFxuICAnc2VxdWVuY2UnLFxuICAnbWFwcGluZydcbl07XG5cbmZ1bmN0aW9uIGNvbXBpbGVTdHlsZUFsaWFzZXMobWFwKSB7XG4gIHZhciByZXN1bHQgPSB7fTtcblxuICBpZiAobWFwICE9PSBudWxsKSB7XG4gICAgT2JqZWN0LmtleXMobWFwKS5mb3JFYWNoKGZ1bmN0aW9uIChzdHlsZSkge1xuICAgICAgbWFwW3N0eWxlXS5mb3JFYWNoKGZ1bmN0aW9uIChhbGlhcykge1xuICAgICAgICByZXN1bHRbU3RyaW5nKGFsaWFzKV0gPSBzdHlsZTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gVHlwZSh0YWcsIG9wdGlvbnMpIHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgT2JqZWN0LmtleXMob3B0aW9ucykuZm9yRWFjaChmdW5jdGlvbiAobmFtZSkge1xuICAgIGlmIChUWVBFX0NPTlNUUlVDVE9SX09QVElPTlMuaW5kZXhPZihuYW1lKSA9PT0gLTEpIHtcbiAgICAgIHRocm93IG5ldyBZQU1MRXhjZXB0aW9uKCdVbmtub3duIG9wdGlvbiBcIicgKyBuYW1lICsgJ1wiIGlzIG1ldCBpbiBkZWZpbml0aW9uIG9mIFwiJyArIHRhZyArICdcIiBZQU1MIHR5cGUuJyk7XG4gICAgfVxuICB9KTtcblxuICAvLyBUT0RPOiBBZGQgdGFnIGZvcm1hdCBjaGVjay5cbiAgdGhpcy50YWcgICAgICAgICAgPSB0YWc7XG4gIHRoaXMua2luZCAgICAgICAgID0gb3B0aW9uc1sna2luZCddICAgICAgICAgfHwgbnVsbDtcbiAgdGhpcy5yZXNvbHZlICAgICAgPSBvcHRpb25zWydyZXNvbHZlJ10gICAgICB8fCBmdW5jdGlvbiAoKSB7IHJldHVybiB0cnVlOyB9O1xuICB0aGlzLmNvbnN0cnVjdCAgICA9IG9wdGlvbnNbJ2NvbnN0cnVjdCddICAgIHx8IGZ1bmN0aW9uIChkYXRhKSB7IHJldHVybiBkYXRhOyB9O1xuICB0aGlzLmluc3RhbmNlT2YgICA9IG9wdGlvbnNbJ2luc3RhbmNlT2YnXSAgIHx8IG51bGw7XG4gIHRoaXMucHJlZGljYXRlICAgID0gb3B0aW9uc1sncHJlZGljYXRlJ10gICAgfHwgbnVsbDtcbiAgdGhpcy5yZXByZXNlbnQgICAgPSBvcHRpb25zWydyZXByZXNlbnQnXSAgICB8fCBudWxsO1xuICB0aGlzLmRlZmF1bHRTdHlsZSA9IG9wdGlvbnNbJ2RlZmF1bHRTdHlsZSddIHx8IG51bGw7XG4gIHRoaXMuc3R5bGVBbGlhc2VzID0gY29tcGlsZVN0eWxlQWxpYXNlcyhvcHRpb25zWydzdHlsZUFsaWFzZXMnXSB8fCBudWxsKTtcblxuICBpZiAoWUFNTF9OT0RFX0tJTkRTLmluZGV4T2YodGhpcy5raW5kKSA9PT0gLTEpIHtcbiAgICB0aHJvdyBuZXcgWUFNTEV4Y2VwdGlvbignVW5rbm93biBraW5kIFwiJyArIHRoaXMua2luZCArICdcIiBpcyBzcGVjaWZpZWQgZm9yIFwiJyArIHRhZyArICdcIiBZQU1MIHR5cGUuJyk7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBUeXBlO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKmVzbGludC1kaXNhYmxlIG5vLWJpdHdpc2UqL1xuXG52YXIgTm9kZUJ1ZmZlcjtcblxudHJ5IHtcbiAgLy8gQSB0cmljayBmb3IgYnJvd3NlcmlmaWVkIHZlcnNpb24sIHRvIG5vdCBpbmNsdWRlIGBCdWZmZXJgIHNoaW1cbiAgdmFyIF9yZXF1aXJlID0gcmVxdWlyZTtcbiAgTm9kZUJ1ZmZlciA9IF9yZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7XG59IGNhdGNoIChfXykge31cblxudmFyIFR5cGUgICAgICAgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cblxuLy8gWyA2NCwgNjUsIDY2IF0gLT4gWyBwYWRkaW5nLCBDUiwgTEYgXVxudmFyIEJBU0U2NF9NQVAgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLz1cXG5cXHInO1xuXG5cbmZ1bmN0aW9uIHJlc29sdmVZYW1sQmluYXJ5KGRhdGEpIHtcbiAgaWYgKGRhdGEgPT09IG51bGwpIHJldHVybiBmYWxzZTtcblxuICB2YXIgY29kZSwgaWR4LCBiaXRsZW4gPSAwLCBtYXggPSBkYXRhLmxlbmd0aCwgbWFwID0gQkFTRTY0X01BUDtcblxuICAvLyBDb252ZXJ0IG9uZSBieSBvbmUuXG4gIGZvciAoaWR4ID0gMDsgaWR4IDwgbWF4OyBpZHgrKykge1xuICAgIGNvZGUgPSBtYXAuaW5kZXhPZihkYXRhLmNoYXJBdChpZHgpKTtcblxuICAgIC8vIFNraXAgQ1IvTEZcbiAgICBpZiAoY29kZSA+IDY0KSBjb250aW51ZTtcblxuICAgIC8vIEZhaWwgb24gaWxsZWdhbCBjaGFyYWN0ZXJzXG4gICAgaWYgKGNvZGUgPCAwKSByZXR1cm4gZmFsc2U7XG5cbiAgICBiaXRsZW4gKz0gNjtcbiAgfVxuXG4gIC8vIElmIHRoZXJlIGFyZSBhbnkgYml0cyBsZWZ0LCBzb3VyY2Ugd2FzIGNvcnJ1cHRlZFxuICByZXR1cm4gKGJpdGxlbiAlIDgpID09PSAwO1xufVxuXG5mdW5jdGlvbiBjb25zdHJ1Y3RZYW1sQmluYXJ5KGRhdGEpIHtcbiAgdmFyIGlkeCwgdGFpbGJpdHMsXG4gICAgICBpbnB1dCA9IGRhdGEucmVwbGFjZSgvW1xcclxcbj1dL2csICcnKSwgLy8gcmVtb3ZlIENSL0xGICYgcGFkZGluZyB0byBzaW1wbGlmeSBzY2FuXG4gICAgICBtYXggPSBpbnB1dC5sZW5ndGgsXG4gICAgICBtYXAgPSBCQVNFNjRfTUFQLFxuICAgICAgYml0cyA9IDAsXG4gICAgICByZXN1bHQgPSBbXTtcblxuICAvLyBDb2xsZWN0IGJ5IDYqNCBiaXRzICgzIGJ5dGVzKVxuXG4gIGZvciAoaWR4ID0gMDsgaWR4IDwgbWF4OyBpZHgrKykge1xuICAgIGlmICgoaWR4ICUgNCA9PT0gMCkgJiYgaWR4KSB7XG4gICAgICByZXN1bHQucHVzaCgoYml0cyA+PiAxNikgJiAweEZGKTtcbiAgICAgIHJlc3VsdC5wdXNoKChiaXRzID4+IDgpICYgMHhGRik7XG4gICAgICByZXN1bHQucHVzaChiaXRzICYgMHhGRik7XG4gICAgfVxuXG4gICAgYml0cyA9IChiaXRzIDw8IDYpIHwgbWFwLmluZGV4T2YoaW5wdXQuY2hhckF0KGlkeCkpO1xuICB9XG5cbiAgLy8gRHVtcCB0YWlsXG5cbiAgdGFpbGJpdHMgPSAobWF4ICUgNCkgKiA2O1xuXG4gIGlmICh0YWlsYml0cyA9PT0gMCkge1xuICAgIHJlc3VsdC5wdXNoKChiaXRzID4+IDE2KSAmIDB4RkYpO1xuICAgIHJlc3VsdC5wdXNoKChiaXRzID4+IDgpICYgMHhGRik7XG4gICAgcmVzdWx0LnB1c2goYml0cyAmIDB4RkYpO1xuICB9IGVsc2UgaWYgKHRhaWxiaXRzID09PSAxOCkge1xuICAgIHJlc3VsdC5wdXNoKChiaXRzID4+IDEwKSAmIDB4RkYpO1xuICAgIHJlc3VsdC5wdXNoKChiaXRzID4+IDIpICYgMHhGRik7XG4gIH0gZWxzZSBpZiAodGFpbGJpdHMgPT09IDEyKSB7XG4gICAgcmVzdWx0LnB1c2goKGJpdHMgPj4gNCkgJiAweEZGKTtcbiAgfVxuXG4gIC8vIFdyYXAgaW50byBCdWZmZXIgZm9yIE5vZGVKUyBhbmQgbGVhdmUgQXJyYXkgZm9yIGJyb3dzZXJcbiAgaWYgKE5vZGVCdWZmZXIpIHJldHVybiBuZXcgTm9kZUJ1ZmZlcihyZXN1bHQpO1xuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIHJlcHJlc2VudFlhbWxCaW5hcnkob2JqZWN0IC8qLCBzdHlsZSovKSB7XG4gIHZhciByZXN1bHQgPSAnJywgYml0cyA9IDAsIGlkeCwgdGFpbCxcbiAgICAgIG1heCA9IG9iamVjdC5sZW5ndGgsXG4gICAgICBtYXAgPSBCQVNFNjRfTUFQO1xuXG4gIC8vIENvbnZlcnQgZXZlcnkgdGhyZWUgYnl0ZXMgdG8gNCBBU0NJSSBjaGFyYWN0ZXJzLlxuXG4gIGZvciAoaWR4ID0gMDsgaWR4IDwgbWF4OyBpZHgrKykge1xuICAgIGlmICgoaWR4ICUgMyA9PT0gMCkgJiYgaWR4KSB7XG4gICAgICByZXN1bHQgKz0gbWFwWyhiaXRzID4+IDE4KSAmIDB4M0ZdO1xuICAgICAgcmVzdWx0ICs9IG1hcFsoYml0cyA+PiAxMikgJiAweDNGXTtcbiAgICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPj4gNikgJiAweDNGXTtcbiAgICAgIHJlc3VsdCArPSBtYXBbYml0cyAmIDB4M0ZdO1xuICAgIH1cblxuICAgIGJpdHMgPSAoYml0cyA8PCA4KSArIG9iamVjdFtpZHhdO1xuICB9XG5cbiAgLy8gRHVtcCB0YWlsXG5cbiAgdGFpbCA9IG1heCAlIDM7XG5cbiAgaWYgKHRhaWwgPT09IDApIHtcbiAgICByZXN1bHQgKz0gbWFwWyhiaXRzID4+IDE4KSAmIDB4M0ZdO1xuICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPj4gMTIpICYgMHgzRl07XG4gICAgcmVzdWx0ICs9IG1hcFsoYml0cyA+PiA2KSAmIDB4M0ZdO1xuICAgIHJlc3VsdCArPSBtYXBbYml0cyAmIDB4M0ZdO1xuICB9IGVsc2UgaWYgKHRhaWwgPT09IDIpIHtcbiAgICByZXN1bHQgKz0gbWFwWyhiaXRzID4+IDEwKSAmIDB4M0ZdO1xuICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPj4gNCkgJiAweDNGXTtcbiAgICByZXN1bHQgKz0gbWFwWyhiaXRzIDw8IDIpICYgMHgzRl07XG4gICAgcmVzdWx0ICs9IG1hcFs2NF07XG4gIH0gZWxzZSBpZiAodGFpbCA9PT0gMSkge1xuICAgIHJlc3VsdCArPSBtYXBbKGJpdHMgPj4gMikgJiAweDNGXTtcbiAgICByZXN1bHQgKz0gbWFwWyhiaXRzIDw8IDQpICYgMHgzRl07XG4gICAgcmVzdWx0ICs9IG1hcFs2NF07XG4gICAgcmVzdWx0ICs9IG1hcFs2NF07XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBpc0JpbmFyeShvYmplY3QpIHtcbiAgcmV0dXJuIE5vZGVCdWZmZXIgJiYgTm9kZUJ1ZmZlci5pc0J1ZmZlcihvYmplY3QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpiaW5hcnknLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICByZXNvbHZlOiByZXNvbHZlWWFtbEJpbmFyeSxcbiAgY29uc3RydWN0OiBjb25zdHJ1Y3RZYW1sQmluYXJ5LFxuICBwcmVkaWNhdGU6IGlzQmluYXJ5LFxuICByZXByZXNlbnQ6IHJlcHJlc2VudFlhbWxCaW5hcnlcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxuZnVuY3Rpb24gcmVzb2x2ZVlhbWxCb29sZWFuKGRhdGEpIHtcbiAgaWYgKGRhdGEgPT09IG51bGwpIHJldHVybiBmYWxzZTtcblxuICB2YXIgbWF4ID0gZGF0YS5sZW5ndGg7XG5cbiAgcmV0dXJuIChtYXggPT09IDQgJiYgKGRhdGEgPT09ICd0cnVlJyB8fCBkYXRhID09PSAnVHJ1ZScgfHwgZGF0YSA9PT0gJ1RSVUUnKSkgfHxcbiAgICAgICAgIChtYXggPT09IDUgJiYgKGRhdGEgPT09ICdmYWxzZScgfHwgZGF0YSA9PT0gJ0ZhbHNlJyB8fCBkYXRhID09PSAnRkFMU0UnKSk7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxCb29sZWFuKGRhdGEpIHtcbiAgcmV0dXJuIGRhdGEgPT09ICd0cnVlJyB8fFxuICAgICAgICAgZGF0YSA9PT0gJ1RydWUnIHx8XG4gICAgICAgICBkYXRhID09PSAnVFJVRSc7XG59XG5cbmZ1bmN0aW9uIGlzQm9vbGVhbihvYmplY3QpIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmplY3QpID09PSAnW29iamVjdCBCb29sZWFuXSc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOmJvb2wnLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICByZXNvbHZlOiByZXNvbHZlWWFtbEJvb2xlYW4sXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbEJvb2xlYW4sXG4gIHByZWRpY2F0ZTogaXNCb29sZWFuLFxuICByZXByZXNlbnQ6IHtcbiAgICBsb3dlcmNhc2U6IGZ1bmN0aW9uIChvYmplY3QpIHsgcmV0dXJuIG9iamVjdCA/ICd0cnVlJyA6ICdmYWxzZSc7IH0sXG4gICAgdXBwZXJjYXNlOiBmdW5jdGlvbiAob2JqZWN0KSB7IHJldHVybiBvYmplY3QgPyAnVFJVRScgOiAnRkFMU0UnOyB9LFxuICAgIGNhbWVsY2FzZTogZnVuY3Rpb24gKG9iamVjdCkgeyByZXR1cm4gb2JqZWN0ID8gJ1RydWUnIDogJ0ZhbHNlJzsgfVxuICB9LFxuICBkZWZhdWx0U3R5bGU6ICdsb3dlcmNhc2UnXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4uL2NvbW1vbicpO1xudmFyIFR5cGUgICA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxudmFyIFlBTUxfRkxPQVRfUEFUVEVSTiA9IG5ldyBSZWdFeHAoXG4gICdeKD86Wy0rXT8oPzpbMC05XVswLTlfXSopXFxcXC5bMC05X10qKD86W2VFXVstK11bMC05XSspPycgK1xuICAnfFxcXFwuWzAtOV9dKyg/OltlRV1bLStdWzAtOV0rKT8nICtcbiAgJ3xbLStdP1swLTldWzAtOV9dKig/OjpbMC01XT9bMC05XSkrXFxcXC5bMC05X10qJyArXG4gICd8Wy0rXT9cXFxcLig/OmluZnxJbmZ8SU5GKScgK1xuICAnfFxcXFwuKD86bmFufE5hTnxOQU4pKSQnKTtcblxuZnVuY3Rpb24gcmVzb2x2ZVlhbWxGbG9hdChkYXRhKSB7XG4gIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gZmFsc2U7XG5cbiAgaWYgKCFZQU1MX0ZMT0FUX1BBVFRFUk4udGVzdChkYXRhKSkgcmV0dXJuIGZhbHNlO1xuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBjb25zdHJ1Y3RZYW1sRmxvYXQoZGF0YSkge1xuICB2YXIgdmFsdWUsIHNpZ24sIGJhc2UsIGRpZ2l0cztcblxuICB2YWx1ZSAgPSBkYXRhLnJlcGxhY2UoL18vZywgJycpLnRvTG93ZXJDYXNlKCk7XG4gIHNpZ24gICA9IHZhbHVlWzBdID09PSAnLScgPyAtMSA6IDE7XG4gIGRpZ2l0cyA9IFtdO1xuXG4gIGlmICgnKy0nLmluZGV4T2YodmFsdWVbMF0pID49IDApIHtcbiAgICB2YWx1ZSA9IHZhbHVlLnNsaWNlKDEpO1xuICB9XG5cbiAgaWYgKHZhbHVlID09PSAnLmluZicpIHtcbiAgICByZXR1cm4gKHNpZ24gPT09IDEpID8gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZIDogTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZO1xuXG4gIH0gZWxzZSBpZiAodmFsdWUgPT09ICcubmFuJykge1xuICAgIHJldHVybiBOYU47XG5cbiAgfSBlbHNlIGlmICh2YWx1ZS5pbmRleE9mKCc6JykgPj0gMCkge1xuICAgIHZhbHVlLnNwbGl0KCc6JykuZm9yRWFjaChmdW5jdGlvbiAodikge1xuICAgICAgZGlnaXRzLnVuc2hpZnQocGFyc2VGbG9hdCh2LCAxMCkpO1xuICAgIH0pO1xuXG4gICAgdmFsdWUgPSAwLjA7XG4gICAgYmFzZSA9IDE7XG5cbiAgICBkaWdpdHMuZm9yRWFjaChmdW5jdGlvbiAoZCkge1xuICAgICAgdmFsdWUgKz0gZCAqIGJhc2U7XG4gICAgICBiYXNlICo9IDYwO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHNpZ24gKiB2YWx1ZTtcblxuICB9XG4gIHJldHVybiBzaWduICogcGFyc2VGbG9hdCh2YWx1ZSwgMTApO1xufVxuXG5cbnZhciBTQ0lFTlRJRklDX1dJVEhPVVRfRE9UID0gL15bLStdP1swLTldK2UvO1xuXG5mdW5jdGlvbiByZXByZXNlbnRZYW1sRmxvYXQob2JqZWN0LCBzdHlsZSkge1xuICB2YXIgcmVzO1xuXG4gIGlmIChpc05hTihvYmplY3QpKSB7XG4gICAgc3dpdGNoIChzdHlsZSkge1xuICAgICAgY2FzZSAnbG93ZXJjYXNlJzogcmV0dXJuICcubmFuJztcbiAgICAgIGNhc2UgJ3VwcGVyY2FzZSc6IHJldHVybiAnLk5BTic7XG4gICAgICBjYXNlICdjYW1lbGNhc2UnOiByZXR1cm4gJy5OYU4nO1xuICAgIH1cbiAgfSBlbHNlIGlmIChOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkgPT09IG9iamVjdCkge1xuICAgIHN3aXRjaCAoc3R5bGUpIHtcbiAgICAgIGNhc2UgJ2xvd2VyY2FzZSc6IHJldHVybiAnLmluZic7XG4gICAgICBjYXNlICd1cHBlcmNhc2UnOiByZXR1cm4gJy5JTkYnO1xuICAgICAgY2FzZSAnY2FtZWxjYXNlJzogcmV0dXJuICcuSW5mJztcbiAgICB9XG4gIH0gZWxzZSBpZiAoTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZID09PSBvYmplY3QpIHtcbiAgICBzd2l0Y2ggKHN0eWxlKSB7XG4gICAgICBjYXNlICdsb3dlcmNhc2UnOiByZXR1cm4gJy0uaW5mJztcbiAgICAgIGNhc2UgJ3VwcGVyY2FzZSc6IHJldHVybiAnLS5JTkYnO1xuICAgICAgY2FzZSAnY2FtZWxjYXNlJzogcmV0dXJuICctLkluZic7XG4gICAgfVxuICB9IGVsc2UgaWYgKGNvbW1vbi5pc05lZ2F0aXZlWmVybyhvYmplY3QpKSB7XG4gICAgcmV0dXJuICctMC4wJztcbiAgfVxuXG4gIHJlcyA9IG9iamVjdC50b1N0cmluZygxMCk7XG5cbiAgLy8gSlMgc3RyaW5naWZpZXIgY2FuIGJ1aWxkIHNjaWVudGlmaWMgZm9ybWF0IHdpdGhvdXQgZG90czogNWUtMTAwLFxuICAvLyB3aGlsZSBZQU1MIHJlcXVyZXMgZG90OiA1LmUtMTAwLiBGaXggaXQgd2l0aCBzaW1wbGUgaGFja1xuXG4gIHJldHVybiBTQ0lFTlRJRklDX1dJVEhPVVRfRE9ULnRlc3QocmVzKSA/IHJlcy5yZXBsYWNlKCdlJywgJy5lJykgOiByZXM7XG59XG5cbmZ1bmN0aW9uIGlzRmxvYXQob2JqZWN0KSB7XG4gIHJldHVybiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iamVjdCkgPT09ICdbb2JqZWN0IE51bWJlcl0nKSAmJlxuICAgICAgICAgKG9iamVjdCAlIDEgIT09IDAgfHwgY29tbW9uLmlzTmVnYXRpdmVaZXJvKG9iamVjdCkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpmbG9hdCcsIHtcbiAga2luZDogJ3NjYWxhcicsXG4gIHJlc29sdmU6IHJlc29sdmVZYW1sRmxvYXQsXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbEZsb2F0LFxuICBwcmVkaWNhdGU6IGlzRmxvYXQsXG4gIHJlcHJlc2VudDogcmVwcmVzZW50WWFtbEZsb2F0LFxuICBkZWZhdWx0U3R5bGU6ICdsb3dlcmNhc2UnXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGNvbW1vbiA9IHJlcXVpcmUoJy4uL2NvbW1vbicpO1xudmFyIFR5cGUgICA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxuZnVuY3Rpb24gaXNIZXhDb2RlKGMpIHtcbiAgcmV0dXJuICgoMHgzMC8qIDAgKi8gPD0gYykgJiYgKGMgPD0gMHgzOS8qIDkgKi8pKSB8fFxuICAgICAgICAgKCgweDQxLyogQSAqLyA8PSBjKSAmJiAoYyA8PSAweDQ2LyogRiAqLykpIHx8XG4gICAgICAgICAoKDB4NjEvKiBhICovIDw9IGMpICYmIChjIDw9IDB4NjYvKiBmICovKSk7XG59XG5cbmZ1bmN0aW9uIGlzT2N0Q29kZShjKSB7XG4gIHJldHVybiAoKDB4MzAvKiAwICovIDw9IGMpICYmIChjIDw9IDB4MzcvKiA3ICovKSk7XG59XG5cbmZ1bmN0aW9uIGlzRGVjQ29kZShjKSB7XG4gIHJldHVybiAoKDB4MzAvKiAwICovIDw9IGMpICYmIChjIDw9IDB4MzkvKiA5ICovKSk7XG59XG5cbmZ1bmN0aW9uIHJlc29sdmVZYW1sSW50ZWdlcihkYXRhKSB7XG4gIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gZmFsc2U7XG5cbiAgdmFyIG1heCA9IGRhdGEubGVuZ3RoLFxuICAgICAgaW5kZXggPSAwLFxuICAgICAgaGFzRGlnaXRzID0gZmFsc2UsXG4gICAgICBjaDtcblxuICBpZiAoIW1heCkgcmV0dXJuIGZhbHNlO1xuXG4gIGNoID0gZGF0YVtpbmRleF07XG5cbiAgLy8gc2lnblxuICBpZiAoY2ggPT09ICctJyB8fCBjaCA9PT0gJysnKSB7XG4gICAgY2ggPSBkYXRhWysraW5kZXhdO1xuICB9XG5cbiAgaWYgKGNoID09PSAnMCcpIHtcbiAgICAvLyAwXG4gICAgaWYgKGluZGV4ICsgMSA9PT0gbWF4KSByZXR1cm4gdHJ1ZTtcbiAgICBjaCA9IGRhdGFbKytpbmRleF07XG5cbiAgICAvLyBiYXNlIDIsIGJhc2UgOCwgYmFzZSAxNlxuXG4gICAgaWYgKGNoID09PSAnYicpIHtcbiAgICAgIC8vIGJhc2UgMlxuICAgICAgaW5kZXgrKztcblxuICAgICAgZm9yICg7IGluZGV4IDwgbWF4OyBpbmRleCsrKSB7XG4gICAgICAgIGNoID0gZGF0YVtpbmRleF07XG4gICAgICAgIGlmIChjaCA9PT0gJ18nKSBjb250aW51ZTtcbiAgICAgICAgaWYgKGNoICE9PSAnMCcgJiYgY2ggIT09ICcxJykgcmV0dXJuIGZhbHNlO1xuICAgICAgICBoYXNEaWdpdHMgPSB0cnVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGhhc0RpZ2l0cztcbiAgICB9XG5cblxuICAgIGlmIChjaCA9PT0gJ3gnKSB7XG4gICAgICAvLyBiYXNlIDE2XG4gICAgICBpbmRleCsrO1xuXG4gICAgICBmb3IgKDsgaW5kZXggPCBtYXg7IGluZGV4KyspIHtcbiAgICAgICAgY2ggPSBkYXRhW2luZGV4XTtcbiAgICAgICAgaWYgKGNoID09PSAnXycpIGNvbnRpbnVlO1xuICAgICAgICBpZiAoIWlzSGV4Q29kZShkYXRhLmNoYXJDb2RlQXQoaW5kZXgpKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICBoYXNEaWdpdHMgPSB0cnVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGhhc0RpZ2l0cztcbiAgICB9XG5cbiAgICAvLyBiYXNlIDhcbiAgICBmb3IgKDsgaW5kZXggPCBtYXg7IGluZGV4KyspIHtcbiAgICAgIGNoID0gZGF0YVtpbmRleF07XG4gICAgICBpZiAoY2ggPT09ICdfJykgY29udGludWU7XG4gICAgICBpZiAoIWlzT2N0Q29kZShkYXRhLmNoYXJDb2RlQXQoaW5kZXgpKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgaGFzRGlnaXRzID0gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGhhc0RpZ2l0cztcbiAgfVxuXG4gIC8vIGJhc2UgMTAgKGV4Y2VwdCAwKSBvciBiYXNlIDYwXG5cbiAgZm9yICg7IGluZGV4IDwgbWF4OyBpbmRleCsrKSB7XG4gICAgY2ggPSBkYXRhW2luZGV4XTtcbiAgICBpZiAoY2ggPT09ICdfJykgY29udGludWU7XG4gICAgaWYgKGNoID09PSAnOicpIGJyZWFrO1xuICAgIGlmICghaXNEZWNDb2RlKGRhdGEuY2hhckNvZGVBdChpbmRleCkpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGhhc0RpZ2l0cyA9IHRydWU7XG4gIH1cblxuICBpZiAoIWhhc0RpZ2l0cykgcmV0dXJuIGZhbHNlO1xuXG4gIC8vIGlmICFiYXNlNjAgLSBkb25lO1xuICBpZiAoY2ggIT09ICc6JykgcmV0dXJuIHRydWU7XG5cbiAgLy8gYmFzZTYwIGFsbW9zdCBub3QgdXNlZCwgbm8gbmVlZHMgdG8gb3B0aW1pemVcbiAgcmV0dXJuIC9eKDpbMC01XT9bMC05XSkrJC8udGVzdChkYXRhLnNsaWNlKGluZGV4KSk7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxJbnRlZ2VyKGRhdGEpIHtcbiAgdmFyIHZhbHVlID0gZGF0YSwgc2lnbiA9IDEsIGNoLCBiYXNlLCBkaWdpdHMgPSBbXTtcblxuICBpZiAodmFsdWUuaW5kZXhPZignXycpICE9PSAtMSkge1xuICAgIHZhbHVlID0gdmFsdWUucmVwbGFjZSgvXy9nLCAnJyk7XG4gIH1cblxuICBjaCA9IHZhbHVlWzBdO1xuXG4gIGlmIChjaCA9PT0gJy0nIHx8IGNoID09PSAnKycpIHtcbiAgICBpZiAoY2ggPT09ICctJykgc2lnbiA9IC0xO1xuICAgIHZhbHVlID0gdmFsdWUuc2xpY2UoMSk7XG4gICAgY2ggPSB2YWx1ZVswXTtcbiAgfVxuXG4gIGlmICh2YWx1ZSA9PT0gJzAnKSByZXR1cm4gMDtcblxuICBpZiAoY2ggPT09ICcwJykge1xuICAgIGlmICh2YWx1ZVsxXSA9PT0gJ2InKSByZXR1cm4gc2lnbiAqIHBhcnNlSW50KHZhbHVlLnNsaWNlKDIpLCAyKTtcbiAgICBpZiAodmFsdWVbMV0gPT09ICd4JykgcmV0dXJuIHNpZ24gKiBwYXJzZUludCh2YWx1ZSwgMTYpO1xuICAgIHJldHVybiBzaWduICogcGFyc2VJbnQodmFsdWUsIDgpO1xuICB9XG5cbiAgaWYgKHZhbHVlLmluZGV4T2YoJzonKSAhPT0gLTEpIHtcbiAgICB2YWx1ZS5zcGxpdCgnOicpLmZvckVhY2goZnVuY3Rpb24gKHYpIHtcbiAgICAgIGRpZ2l0cy51bnNoaWZ0KHBhcnNlSW50KHYsIDEwKSk7XG4gICAgfSk7XG5cbiAgICB2YWx1ZSA9IDA7XG4gICAgYmFzZSA9IDE7XG5cbiAgICBkaWdpdHMuZm9yRWFjaChmdW5jdGlvbiAoZCkge1xuICAgICAgdmFsdWUgKz0gKGQgKiBiYXNlKTtcbiAgICAgIGJhc2UgKj0gNjA7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gc2lnbiAqIHZhbHVlO1xuXG4gIH1cblxuICByZXR1cm4gc2lnbiAqIHBhcnNlSW50KHZhbHVlLCAxMCk7XG59XG5cbmZ1bmN0aW9uIGlzSW50ZWdlcihvYmplY3QpIHtcbiAgcmV0dXJuIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqZWN0KSkgPT09ICdbb2JqZWN0IE51bWJlcl0nICYmXG4gICAgICAgICAob2JqZWN0ICUgMSA9PT0gMCAmJiAhY29tbW9uLmlzTmVnYXRpdmVaZXJvKG9iamVjdCkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjppbnQnLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICByZXNvbHZlOiByZXNvbHZlWWFtbEludGVnZXIsXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbEludGVnZXIsXG4gIHByZWRpY2F0ZTogaXNJbnRlZ2VyLFxuICByZXByZXNlbnQ6IHtcbiAgICBiaW5hcnk6ICAgICAgZnVuY3Rpb24gKG9iamVjdCkgeyByZXR1cm4gJzBiJyArIG9iamVjdC50b1N0cmluZygyKTsgfSxcbiAgICBvY3RhbDogICAgICAgZnVuY3Rpb24gKG9iamVjdCkgeyByZXR1cm4gJzAnICArIG9iamVjdC50b1N0cmluZyg4KTsgfSxcbiAgICBkZWNpbWFsOiAgICAgZnVuY3Rpb24gKG9iamVjdCkgeyByZXR1cm4gICAgICAgIG9iamVjdC50b1N0cmluZygxMCk7IH0sXG4gICAgaGV4YWRlY2ltYWw6IGZ1bmN0aW9uIChvYmplY3QpIHsgcmV0dXJuICcweCcgKyBvYmplY3QudG9TdHJpbmcoMTYpLnRvVXBwZXJDYXNlKCk7IH1cbiAgfSxcbiAgZGVmYXVsdFN0eWxlOiAnZGVjaW1hbCcsXG4gIHN0eWxlQWxpYXNlczoge1xuICAgIGJpbmFyeTogICAgICBbIDIsICAnYmluJyBdLFxuICAgIG9jdGFsOiAgICAgICBbIDgsICAnb2N0JyBdLFxuICAgIGRlY2ltYWw6ICAgICBbIDEwLCAnZGVjJyBdLFxuICAgIGhleGFkZWNpbWFsOiBbIDE2LCAnaGV4JyBdXG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZXNwcmltYTtcblxuLy8gQnJvd3NlcmlmaWVkIHZlcnNpb24gZG9lcyBub3QgaGF2ZSBlc3ByaW1hXG4vL1xuLy8gMS4gRm9yIG5vZGUuanMganVzdCByZXF1aXJlIG1vZHVsZSBhcyBkZXBzXG4vLyAyLiBGb3IgYnJvd3NlciB0cnkgdG8gcmVxdWlyZSBtdWR1bGUgdmlhIGV4dGVybmFsIEFNRCBzeXN0ZW0uXG4vLyAgICBJZiBub3QgZm91bmQgLSB0cnkgdG8gZmFsbGJhY2sgdG8gd2luZG93LmVzcHJpbWEuIElmIG5vdFxuLy8gICAgZm91bmQgdG9vIC0gdGhlbiBmYWlsIHRvIHBhcnNlLlxuLy9cbnRyeSB7XG4gIC8vIHdvcmthcm91bmQgdG8gZXhjbHVkZSBwYWNrYWdlIGZyb20gYnJvd3NlcmlmeSBsaXN0LlxuICB2YXIgX3JlcXVpcmUgPSByZXF1aXJlO1xuICBlc3ByaW1hID0gX3JlcXVpcmUoJ2VzcHJpbWEnKTtcbn0gY2F0Y2ggKF8pIHtcbiAgLypnbG9iYWwgd2luZG93ICovXG4gIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykgZXNwcmltYSA9IHdpbmRvdy5lc3ByaW1hO1xufVxuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uLy4uL3R5cGUnKTtcblxuZnVuY3Rpb24gcmVzb2x2ZUphdmFzY3JpcHRGdW5jdGlvbihkYXRhKSB7XG4gIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gZmFsc2U7XG5cbiAgdHJ5IHtcbiAgICB2YXIgc291cmNlID0gJygnICsgZGF0YSArICcpJyxcbiAgICAgICAgYXN0ICAgID0gZXNwcmltYS5wYXJzZShzb3VyY2UsIHsgcmFuZ2U6IHRydWUgfSk7XG5cbiAgICBpZiAoYXN0LnR5cGUgICAgICAgICAgICAgICAgICAgICE9PSAnUHJvZ3JhbScgICAgICAgICAgICAgfHxcbiAgICAgICAgYXN0LmJvZHkubGVuZ3RoICAgICAgICAgICAgICE9PSAxICAgICAgICAgICAgICAgICAgICAgfHxcbiAgICAgICAgYXN0LmJvZHlbMF0udHlwZSAgICAgICAgICAgICE9PSAnRXhwcmVzc2lvblN0YXRlbWVudCcgfHxcbiAgICAgICAgYXN0LmJvZHlbMF0uZXhwcmVzc2lvbi50eXBlICE9PSAnRnVuY3Rpb25FeHByZXNzaW9uJykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29uc3RydWN0SmF2YXNjcmlwdEZ1bmN0aW9uKGRhdGEpIHtcbiAgLypqc2xpbnQgZXZpbDp0cnVlKi9cblxuICB2YXIgc291cmNlID0gJygnICsgZGF0YSArICcpJyxcbiAgICAgIGFzdCAgICA9IGVzcHJpbWEucGFyc2Uoc291cmNlLCB7IHJhbmdlOiB0cnVlIH0pLFxuICAgICAgcGFyYW1zID0gW10sXG4gICAgICBib2R5O1xuXG4gIGlmIChhc3QudHlwZSAgICAgICAgICAgICAgICAgICAgIT09ICdQcm9ncmFtJyAgICAgICAgICAgICB8fFxuICAgICAgYXN0LmJvZHkubGVuZ3RoICAgICAgICAgICAgICE9PSAxICAgICAgICAgICAgICAgICAgICAgfHxcbiAgICAgIGFzdC5ib2R5WzBdLnR5cGUgICAgICAgICAgICAhPT0gJ0V4cHJlc3Npb25TdGF0ZW1lbnQnIHx8XG4gICAgICBhc3QuYm9keVswXS5leHByZXNzaW9uLnR5cGUgIT09ICdGdW5jdGlvbkV4cHJlc3Npb24nKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gcmVzb2x2ZSBmdW5jdGlvbicpO1xuICB9XG5cbiAgYXN0LmJvZHlbMF0uZXhwcmVzc2lvbi5wYXJhbXMuZm9yRWFjaChmdW5jdGlvbiAocGFyYW0pIHtcbiAgICBwYXJhbXMucHVzaChwYXJhbS5uYW1lKTtcbiAgfSk7XG5cbiAgYm9keSA9IGFzdC5ib2R5WzBdLmV4cHJlc3Npb24uYm9keS5yYW5nZTtcblxuICAvLyBFc3ByaW1hJ3MgcmFuZ2VzIGluY2x1ZGUgdGhlIGZpcnN0ICd7JyBhbmQgdGhlIGxhc3QgJ30nIGNoYXJhY3RlcnMgb25cbiAgLy8gZnVuY3Rpb24gZXhwcmVzc2lvbnMuIFNvIGN1dCB0aGVtIG91dC5cbiAgLyplc2xpbnQtZGlzYWJsZSBuby1uZXctZnVuYyovXG4gIHJldHVybiBuZXcgRnVuY3Rpb24ocGFyYW1zLCBzb3VyY2Uuc2xpY2UoYm9keVswXSArIDEsIGJvZHlbMV0gLSAxKSk7XG59XG5cbmZ1bmN0aW9uIHJlcHJlc2VudEphdmFzY3JpcHRGdW5jdGlvbihvYmplY3QgLyosIHN0eWxlKi8pIHtcbiAgcmV0dXJuIG9iamVjdC50b1N0cmluZygpO1xufVxuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKG9iamVjdCkge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iamVjdCkgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOmpzL2Z1bmN0aW9uJywge1xuICBraW5kOiAnc2NhbGFyJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZUphdmFzY3JpcHRGdW5jdGlvbixcbiAgY29uc3RydWN0OiBjb25zdHJ1Y3RKYXZhc2NyaXB0RnVuY3Rpb24sXG4gIHByZWRpY2F0ZTogaXNGdW5jdGlvbixcbiAgcmVwcmVzZW50OiByZXByZXNlbnRKYXZhc2NyaXB0RnVuY3Rpb25cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uLy4uL3R5cGUnKTtcblxuZnVuY3Rpb24gcmVzb2x2ZUphdmFzY3JpcHRSZWdFeHAoZGF0YSkge1xuICBpZiAoZGF0YSA9PT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuICBpZiAoZGF0YS5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTtcblxuICB2YXIgcmVnZXhwID0gZGF0YSxcbiAgICAgIHRhaWwgICA9IC9cXC8oW2dpbV0qKSQvLmV4ZWMoZGF0YSksXG4gICAgICBtb2RpZmllcnMgPSAnJztcblxuICAvLyBpZiByZWdleHAgc3RhcnRzIHdpdGggJy8nIGl0IGNhbiBoYXZlIG1vZGlmaWVycyBhbmQgbXVzdCBiZSBwcm9wZXJseSBjbG9zZWRcbiAgLy8gYC9mb28vZ2ltYCAtIG1vZGlmaWVycyB0YWlsIGNhbiBiZSBtYXhpbXVtIDMgY2hhcnNcbiAgaWYgKHJlZ2V4cFswXSA9PT0gJy8nKSB7XG4gICAgaWYgKHRhaWwpIG1vZGlmaWVycyA9IHRhaWxbMV07XG5cbiAgICBpZiAobW9kaWZpZXJzLmxlbmd0aCA+IDMpIHJldHVybiBmYWxzZTtcbiAgICAvLyBpZiBleHByZXNzaW9uIHN0YXJ0cyB3aXRoIC8sIGlzIHNob3VsZCBiZSBwcm9wZXJseSB0ZXJtaW5hdGVkXG4gICAgaWYgKHJlZ2V4cFtyZWdleHAubGVuZ3RoIC0gbW9kaWZpZXJzLmxlbmd0aCAtIDFdICE9PSAnLycpIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBjb25zdHJ1Y3RKYXZhc2NyaXB0UmVnRXhwKGRhdGEpIHtcbiAgdmFyIHJlZ2V4cCA9IGRhdGEsXG4gICAgICB0YWlsICAgPSAvXFwvKFtnaW1dKikkLy5leGVjKGRhdGEpLFxuICAgICAgbW9kaWZpZXJzID0gJyc7XG5cbiAgLy8gYC9mb28vZ2ltYCAtIHRhaWwgY2FuIGJlIG1heGltdW0gNCBjaGFyc1xuICBpZiAocmVnZXhwWzBdID09PSAnLycpIHtcbiAgICBpZiAodGFpbCkgbW9kaWZpZXJzID0gdGFpbFsxXTtcbiAgICByZWdleHAgPSByZWdleHAuc2xpY2UoMSwgcmVnZXhwLmxlbmd0aCAtIG1vZGlmaWVycy5sZW5ndGggLSAxKTtcbiAgfVxuXG4gIHJldHVybiBuZXcgUmVnRXhwKHJlZ2V4cCwgbW9kaWZpZXJzKTtcbn1cblxuZnVuY3Rpb24gcmVwcmVzZW50SmF2YXNjcmlwdFJlZ0V4cChvYmplY3QgLyosIHN0eWxlKi8pIHtcbiAgdmFyIHJlc3VsdCA9ICcvJyArIG9iamVjdC5zb3VyY2UgKyAnLyc7XG5cbiAgaWYgKG9iamVjdC5nbG9iYWwpIHJlc3VsdCArPSAnZyc7XG4gIGlmIChvYmplY3QubXVsdGlsaW5lKSByZXN1bHQgKz0gJ20nO1xuICBpZiAob2JqZWN0Lmlnbm9yZUNhc2UpIHJlc3VsdCArPSAnaSc7XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gaXNSZWdFeHAob2JqZWN0KSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqZWN0KSA9PT0gJ1tvYmplY3QgUmVnRXhwXSc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOmpzL3JlZ2V4cCcsIHtcbiAga2luZDogJ3NjYWxhcicsXG4gIHJlc29sdmU6IHJlc29sdmVKYXZhc2NyaXB0UmVnRXhwLFxuICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdEphdmFzY3JpcHRSZWdFeHAsXG4gIHByZWRpY2F0ZTogaXNSZWdFeHAsXG4gIHJlcHJlc2VudDogcmVwcmVzZW50SmF2YXNjcmlwdFJlZ0V4cFxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vLi4vdHlwZScpO1xuXG5mdW5jdGlvbiByZXNvbHZlSmF2YXNjcmlwdFVuZGVmaW5lZCgpIHtcbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdEphdmFzY3JpcHRVbmRlZmluZWQoKSB7XG4gIC8qZXNsaW50LWRpc2FibGUgbm8tdW5kZWZpbmVkKi9cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gcmVwcmVzZW50SmF2YXNjcmlwdFVuZGVmaW5lZCgpIHtcbiAgcmV0dXJuICcnO1xufVxuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChvYmplY3QpIHtcbiAgcmV0dXJuIHR5cGVvZiBvYmplY3QgPT09ICd1bmRlZmluZWQnO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpqcy91bmRlZmluZWQnLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICByZXNvbHZlOiByZXNvbHZlSmF2YXNjcmlwdFVuZGVmaW5lZCxcbiAgY29uc3RydWN0OiBjb25zdHJ1Y3RKYXZhc2NyaXB0VW5kZWZpbmVkLFxuICBwcmVkaWNhdGU6IGlzVW5kZWZpbmVkLFxuICByZXByZXNlbnQ6IHJlcHJlc2VudEphdmFzY3JpcHRVbmRlZmluZWRcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6bWFwJywge1xuICBraW5kOiAnbWFwcGluZycsXG4gIGNvbnN0cnVjdDogZnVuY3Rpb24gKGRhdGEpIHsgcmV0dXJuIGRhdGEgIT09IG51bGwgPyBkYXRhIDoge307IH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgVHlwZSA9IHJlcXVpcmUoJy4uL3R5cGUnKTtcblxuZnVuY3Rpb24gcmVzb2x2ZVlhbWxNZXJnZShkYXRhKSB7XG4gIHJldHVybiBkYXRhID09PSAnPDwnIHx8IGRhdGEgPT09IG51bGw7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOm1lcmdlJywge1xuICBraW5kOiAnc2NhbGFyJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxNZXJnZVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG5mdW5jdGlvbiByZXNvbHZlWWFtbE51bGwoZGF0YSkge1xuICBpZiAoZGF0YSA9PT0gbnVsbCkgcmV0dXJuIHRydWU7XG5cbiAgdmFyIG1heCA9IGRhdGEubGVuZ3RoO1xuXG4gIHJldHVybiAobWF4ID09PSAxICYmIGRhdGEgPT09ICd+JykgfHxcbiAgICAgICAgIChtYXggPT09IDQgJiYgKGRhdGEgPT09ICdudWxsJyB8fCBkYXRhID09PSAnTnVsbCcgfHwgZGF0YSA9PT0gJ05VTEwnKSk7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxOdWxsKCkge1xuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gaXNOdWxsKG9iamVjdCkge1xuICByZXR1cm4gb2JqZWN0ID09PSBudWxsO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpudWxsJywge1xuICBraW5kOiAnc2NhbGFyJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxOdWxsLFxuICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdFlhbWxOdWxsLFxuICBwcmVkaWNhdGU6IGlzTnVsbCxcbiAgcmVwcmVzZW50OiB7XG4gICAgY2Fub25pY2FsOiBmdW5jdGlvbiAoKSB7IHJldHVybiAnfic7ICAgIH0sXG4gICAgbG93ZXJjYXNlOiBmdW5jdGlvbiAoKSB7IHJldHVybiAnbnVsbCc7IH0sXG4gICAgdXBwZXJjYXNlOiBmdW5jdGlvbiAoKSB7IHJldHVybiAnTlVMTCc7IH0sXG4gICAgY2FtZWxjYXNlOiBmdW5jdGlvbiAoKSB7IHJldHVybiAnTnVsbCc7IH1cbiAgfSxcbiAgZGVmYXVsdFN0eWxlOiAnbG93ZXJjYXNlJ1xufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG52YXIgX2hhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcbnZhciBfdG9TdHJpbmcgICAgICAgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG5mdW5jdGlvbiByZXNvbHZlWWFtbE9tYXAoZGF0YSkge1xuICBpZiAoZGF0YSA9PT0gbnVsbCkgcmV0dXJuIHRydWU7XG5cbiAgdmFyIG9iamVjdEtleXMgPSBbXSwgaW5kZXgsIGxlbmd0aCwgcGFpciwgcGFpcktleSwgcGFpckhhc0tleSxcbiAgICAgIG9iamVjdCA9IGRhdGE7XG5cbiAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IG9iamVjdC5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgcGFpciA9IG9iamVjdFtpbmRleF07XG4gICAgcGFpckhhc0tleSA9IGZhbHNlO1xuXG4gICAgaWYgKF90b1N0cmluZy5jYWxsKHBhaXIpICE9PSAnW29iamVjdCBPYmplY3RdJykgcmV0dXJuIGZhbHNlO1xuXG4gICAgZm9yIChwYWlyS2V5IGluIHBhaXIpIHtcbiAgICAgIGlmIChfaGFzT3duUHJvcGVydHkuY2FsbChwYWlyLCBwYWlyS2V5KSkge1xuICAgICAgICBpZiAoIXBhaXJIYXNLZXkpIHBhaXJIYXNLZXkgPSB0cnVlO1xuICAgICAgICBlbHNlIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXBhaXJIYXNLZXkpIHJldHVybiBmYWxzZTtcblxuICAgIGlmIChvYmplY3RLZXlzLmluZGV4T2YocGFpcktleSkgPT09IC0xKSBvYmplY3RLZXlzLnB1c2gocGFpcktleSk7XG4gICAgZWxzZSByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gY29uc3RydWN0WWFtbE9tYXAoZGF0YSkge1xuICByZXR1cm4gZGF0YSAhPT0gbnVsbCA/IGRhdGEgOiBbXTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6b21hcCcsIHtcbiAga2luZDogJ3NlcXVlbmNlJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxPbWFwLFxuICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdFlhbWxPbWFwXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cbnZhciBfdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG5mdW5jdGlvbiByZXNvbHZlWWFtbFBhaXJzKGRhdGEpIHtcbiAgaWYgKGRhdGEgPT09IG51bGwpIHJldHVybiB0cnVlO1xuXG4gIHZhciBpbmRleCwgbGVuZ3RoLCBwYWlyLCBrZXlzLCByZXN1bHQsXG4gICAgICBvYmplY3QgPSBkYXRhO1xuXG4gIHJlc3VsdCA9IG5ldyBBcnJheShvYmplY3QubGVuZ3RoKTtcblxuICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gb2JqZWN0Lmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICBwYWlyID0gb2JqZWN0W2luZGV4XTtcblxuICAgIGlmIChfdG9TdHJpbmcuY2FsbChwYWlyKSAhPT0gJ1tvYmplY3QgT2JqZWN0XScpIHJldHVybiBmYWxzZTtcblxuICAgIGtleXMgPSBPYmplY3Qua2V5cyhwYWlyKTtcblxuICAgIGlmIChrZXlzLmxlbmd0aCAhPT0gMSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgcmVzdWx0W2luZGV4XSA9IFsga2V5c1swXSwgcGFpcltrZXlzWzBdXSBdO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGNvbnN0cnVjdFlhbWxQYWlycyhkYXRhKSB7XG4gIGlmIChkYXRhID09PSBudWxsKSByZXR1cm4gW107XG5cbiAgdmFyIGluZGV4LCBsZW5ndGgsIHBhaXIsIGtleXMsIHJlc3VsdCxcbiAgICAgIG9iamVjdCA9IGRhdGE7XG5cbiAgcmVzdWx0ID0gbmV3IEFycmF5KG9iamVjdC5sZW5ndGgpO1xuXG4gIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSBvYmplY3QubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIHBhaXIgPSBvYmplY3RbaW5kZXhdO1xuXG4gICAga2V5cyA9IE9iamVjdC5rZXlzKHBhaXIpO1xuXG4gICAgcmVzdWx0W2luZGV4XSA9IFsga2V5c1swXSwgcGFpcltrZXlzWzBdXSBdO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgVHlwZSgndGFnOnlhbWwub3JnLDIwMDI6cGFpcnMnLCB7XG4gIGtpbmQ6ICdzZXF1ZW5jZScsXG4gIHJlc29sdmU6IHJlc29sdmVZYW1sUGFpcnMsXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbFBhaXJzXG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOnNlcScsIHtcbiAga2luZDogJ3NlcXVlbmNlJyxcbiAgY29uc3RydWN0OiBmdW5jdGlvbiAoZGF0YSkgeyByZXR1cm4gZGF0YSAhPT0gbnVsbCA/IGRhdGEgOiBbXTsgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG52YXIgX2hhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcblxuZnVuY3Rpb24gcmVzb2x2ZVlhbWxTZXQoZGF0YSkge1xuICBpZiAoZGF0YSA9PT0gbnVsbCkgcmV0dXJuIHRydWU7XG5cbiAgdmFyIGtleSwgb2JqZWN0ID0gZGF0YTtcblxuICBmb3IgKGtleSBpbiBvYmplY3QpIHtcbiAgICBpZiAoX2hhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpKSB7XG4gICAgICBpZiAob2JqZWN0W2tleV0gIT09IG51bGwpIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gY29uc3RydWN0WWFtbFNldChkYXRhKSB7XG4gIHJldHVybiBkYXRhICE9PSBudWxsID8gZGF0YSA6IHt9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpzZXQnLCB7XG4gIGtpbmQ6ICdtYXBwaW5nJyxcbiAgcmVzb2x2ZTogcmVzb2x2ZVlhbWxTZXQsXG4gIGNvbnN0cnVjdDogY29uc3RydWN0WWFtbFNldFxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBUeXBlID0gcmVxdWlyZSgnLi4vdHlwZScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUeXBlKCd0YWc6eWFtbC5vcmcsMjAwMjpzdHInLCB7XG4gIGtpbmQ6ICdzY2FsYXInLFxuICBjb25zdHJ1Y3Q6IGZ1bmN0aW9uIChkYXRhKSB7IHJldHVybiBkYXRhICE9PSBudWxsID8gZGF0YSA6ICcnOyB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIFR5cGUgPSByZXF1aXJlKCcuLi90eXBlJyk7XG5cbnZhciBZQU1MX0RBVEVfUkVHRVhQID0gbmV3IFJlZ0V4cChcbiAgJ14oWzAtOV1bMC05XVswLTldWzAtOV0pJyAgICAgICAgICArIC8vIFsxXSB5ZWFyXG4gICctKFswLTldWzAtOV0pJyAgICAgICAgICAgICAgICAgICAgKyAvLyBbMl0gbW9udGhcbiAgJy0oWzAtOV1bMC05XSkkJyk7ICAgICAgICAgICAgICAgICAgIC8vIFszXSBkYXlcblxudmFyIFlBTUxfVElNRVNUQU1QX1JFR0VYUCA9IG5ldyBSZWdFeHAoXG4gICdeKFswLTldWzAtOV1bMC05XVswLTldKScgICAgICAgICAgKyAvLyBbMV0geWVhclxuICAnLShbMC05XVswLTldPyknICAgICAgICAgICAgICAgICAgICsgLy8gWzJdIG1vbnRoXG4gICctKFswLTldWzAtOV0/KScgICAgICAgICAgICAgICAgICAgKyAvLyBbM10gZGF5XG4gICcoPzpbVHRdfFsgXFxcXHRdKyknICAgICAgICAgICAgICAgICArIC8vIC4uLlxuICAnKFswLTldWzAtOV0/KScgICAgICAgICAgICAgICAgICAgICsgLy8gWzRdIGhvdXJcbiAgJzooWzAtOV1bMC05XSknICAgICAgICAgICAgICAgICAgICArIC8vIFs1XSBtaW51dGVcbiAgJzooWzAtOV1bMC05XSknICAgICAgICAgICAgICAgICAgICArIC8vIFs2XSBzZWNvbmRcbiAgJyg/OlxcXFwuKFswLTldKikpPycgICAgICAgICAgICAgICAgICsgLy8gWzddIGZyYWN0aW9uXG4gICcoPzpbIFxcXFx0XSooWnwoWy0rXSkoWzAtOV1bMC05XT8pJyArIC8vIFs4XSB0eiBbOV0gdHpfc2lnbiBbMTBdIHR6X2hvdXJcbiAgJyg/OjooWzAtOV1bMC05XSkpPykpPyQnKTsgICAgICAgICAgIC8vIFsxMV0gdHpfbWludXRlXG5cbmZ1bmN0aW9uIHJlc29sdmVZYW1sVGltZXN0YW1wKGRhdGEpIHtcbiAgaWYgKGRhdGEgPT09IG51bGwpIHJldHVybiBmYWxzZTtcbiAgaWYgKFlBTUxfREFURV9SRUdFWFAuZXhlYyhkYXRhKSAhPT0gbnVsbCkgcmV0dXJuIHRydWU7XG4gIGlmIChZQU1MX1RJTUVTVEFNUF9SRUdFWFAuZXhlYyhkYXRhKSAhPT0gbnVsbCkgcmV0dXJuIHRydWU7XG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gY29uc3RydWN0WWFtbFRpbWVzdGFtcChkYXRhKSB7XG4gIHZhciBtYXRjaCwgeWVhciwgbW9udGgsIGRheSwgaG91ciwgbWludXRlLCBzZWNvbmQsIGZyYWN0aW9uID0gMCxcbiAgICAgIGRlbHRhID0gbnVsbCwgdHpfaG91ciwgdHpfbWludXRlLCBkYXRlO1xuXG4gIG1hdGNoID0gWUFNTF9EQVRFX1JFR0VYUC5leGVjKGRhdGEpO1xuICBpZiAobWF0Y2ggPT09IG51bGwpIG1hdGNoID0gWUFNTF9USU1FU1RBTVBfUkVHRVhQLmV4ZWMoZGF0YSk7XG5cbiAgaWYgKG1hdGNoID09PSBudWxsKSB0aHJvdyBuZXcgRXJyb3IoJ0RhdGUgcmVzb2x2ZSBlcnJvcicpO1xuXG4gIC8vIG1hdGNoOiBbMV0geWVhciBbMl0gbW9udGggWzNdIGRheVxuXG4gIHllYXIgPSArKG1hdGNoWzFdKTtcbiAgbW9udGggPSArKG1hdGNoWzJdKSAtIDE7IC8vIEpTIG1vbnRoIHN0YXJ0cyB3aXRoIDBcbiAgZGF5ID0gKyhtYXRjaFszXSk7XG5cbiAgaWYgKCFtYXRjaFs0XSkgeyAvLyBubyBob3VyXG4gICAgcmV0dXJuIG5ldyBEYXRlKERhdGUuVVRDKHllYXIsIG1vbnRoLCBkYXkpKTtcbiAgfVxuXG4gIC8vIG1hdGNoOiBbNF0gaG91ciBbNV0gbWludXRlIFs2XSBzZWNvbmQgWzddIGZyYWN0aW9uXG5cbiAgaG91ciA9ICsobWF0Y2hbNF0pO1xuICBtaW51dGUgPSArKG1hdGNoWzVdKTtcbiAgc2Vjb25kID0gKyhtYXRjaFs2XSk7XG5cbiAgaWYgKG1hdGNoWzddKSB7XG4gICAgZnJhY3Rpb24gPSBtYXRjaFs3XS5zbGljZSgwLCAzKTtcbiAgICB3aGlsZSAoZnJhY3Rpb24ubGVuZ3RoIDwgMykgeyAvLyBtaWxsaS1zZWNvbmRzXG4gICAgICBmcmFjdGlvbiArPSAnMCc7XG4gICAgfVxuICAgIGZyYWN0aW9uID0gK2ZyYWN0aW9uO1xuICB9XG5cbiAgLy8gbWF0Y2g6IFs4XSB0eiBbOV0gdHpfc2lnbiBbMTBdIHR6X2hvdXIgWzExXSB0el9taW51dGVcblxuICBpZiAobWF0Y2hbOV0pIHtcbiAgICB0el9ob3VyID0gKyhtYXRjaFsxMF0pO1xuICAgIHR6X21pbnV0ZSA9ICsobWF0Y2hbMTFdIHx8IDApO1xuICAgIGRlbHRhID0gKHR6X2hvdXIgKiA2MCArIHR6X21pbnV0ZSkgKiA2MDAwMDsgLy8gZGVsdGEgaW4gbWlsaS1zZWNvbmRzXG4gICAgaWYgKG1hdGNoWzldID09PSAnLScpIGRlbHRhID0gLWRlbHRhO1xuICB9XG5cbiAgZGF0ZSA9IG5ldyBEYXRlKERhdGUuVVRDKHllYXIsIG1vbnRoLCBkYXksIGhvdXIsIG1pbnV0ZSwgc2Vjb25kLCBmcmFjdGlvbikpO1xuXG4gIGlmIChkZWx0YSkgZGF0ZS5zZXRUaW1lKGRhdGUuZ2V0VGltZSgpIC0gZGVsdGEpO1xuXG4gIHJldHVybiBkYXRlO1xufVxuXG5mdW5jdGlvbiByZXByZXNlbnRZYW1sVGltZXN0YW1wKG9iamVjdCAvKiwgc3R5bGUqLykge1xuICByZXR1cm4gb2JqZWN0LnRvSVNPU3RyaW5nKCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFR5cGUoJ3RhZzp5YW1sLm9yZywyMDAyOnRpbWVzdGFtcCcsIHtcbiAga2luZDogJ3NjYWxhcicsXG4gIHJlc29sdmU6IHJlc29sdmVZYW1sVGltZXN0YW1wLFxuICBjb25zdHJ1Y3Q6IGNvbnN0cnVjdFlhbWxUaW1lc3RhbXAsXG4gIGluc3RhbmNlT2Y6IERhdGUsXG4gIHJlcHJlc2VudDogcmVwcmVzZW50WWFtbFRpbWVzdGFtcFxufSk7XG4iLCJ2YXIgYmFzZUluZGV4T2YgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlSW5kZXhPZicpLFxuICAgIGJpbmFyeUluZGV4ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmluYXJ5SW5kZXgnKTtcblxuLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heDtcblxuLyoqXG4gKiBHZXRzIHRoZSBpbmRleCBhdCB3aGljaCB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiBgdmFsdWVgIGlzIGZvdW5kIGluIGBhcnJheWBcbiAqIHVzaW5nIFtgU2FtZVZhbHVlWmVyb2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXNhbWV2YWx1ZXplcm8pXG4gKiBmb3IgZXF1YWxpdHkgY29tcGFyaXNvbnMuIElmIGBmcm9tSW5kZXhgIGlzIG5lZ2F0aXZlLCBpdCdzIHVzZWQgYXMgdGhlIG9mZnNldFxuICogZnJvbSB0aGUgZW5kIG9mIGBhcnJheWAuIElmIGBhcnJheWAgaXMgc29ydGVkIHByb3ZpZGluZyBgdHJ1ZWAgZm9yIGBmcm9tSW5kZXhgXG4gKiBwZXJmb3JtcyBhIGZhc3RlciBiaW5hcnkgc2VhcmNoLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgQXJyYXlcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBzZWFyY2guXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICogQHBhcmFtIHtib29sZWFufG51bWJlcn0gW2Zyb21JbmRleD0wXSBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20gb3IgYHRydWVgXG4gKiAgdG8gcGVyZm9ybSBhIGJpbmFyeSBzZWFyY2ggb24gYSBzb3J0ZWQgYXJyYXkuXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmluZGV4T2YoWzEsIDIsIDEsIDJdLCAyKTtcbiAqIC8vID0+IDFcbiAqXG4gKiAvLyB1c2luZyBgZnJvbUluZGV4YFxuICogXy5pbmRleE9mKFsxLCAyLCAxLCAyXSwgMiwgMik7XG4gKiAvLyA9PiAzXG4gKlxuICogLy8gcGVyZm9ybWluZyBhIGJpbmFyeSBzZWFyY2hcbiAqIF8uaW5kZXhPZihbMSwgMSwgMiwgMl0sIDIsIHRydWUpO1xuICogLy8gPT4gMlxuICovXG5mdW5jdGlvbiBpbmRleE9mKGFycmF5LCB2YWx1ZSwgZnJvbUluZGV4KSB7XG4gIHZhciBsZW5ndGggPSBhcnJheSA/IGFycmF5Lmxlbmd0aCA6IDA7XG4gIGlmICghbGVuZ3RoKSB7XG4gICAgcmV0dXJuIC0xO1xuICB9XG4gIGlmICh0eXBlb2YgZnJvbUluZGV4ID09ICdudW1iZXInKSB7XG4gICAgZnJvbUluZGV4ID0gZnJvbUluZGV4IDwgMCA/IG5hdGl2ZU1heChsZW5ndGggKyBmcm9tSW5kZXgsIDApIDogZnJvbUluZGV4O1xuICB9IGVsc2UgaWYgKGZyb21JbmRleCkge1xuICAgIHZhciBpbmRleCA9IGJpbmFyeUluZGV4KGFycmF5LCB2YWx1ZSk7XG4gICAgaWYgKGluZGV4IDwgbGVuZ3RoICYmXG4gICAgICAgICh2YWx1ZSA9PT0gdmFsdWUgPyAodmFsdWUgPT09IGFycmF5W2luZGV4XSkgOiAoYXJyYXlbaW5kZXhdICE9PSBhcnJheVtpbmRleF0pKSkge1xuICAgICAgcmV0dXJuIGluZGV4O1xuICAgIH1cbiAgICByZXR1cm4gLTE7XG4gIH1cbiAgcmV0dXJuIGJhc2VJbmRleE9mKGFycmF5LCB2YWx1ZSwgZnJvbUluZGV4IHx8IDApO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGluZGV4T2Y7XG4iLCIvKipcbiAqIEdldHMgdGhlIGxhc3QgZWxlbWVudCBvZiBgYXJyYXlgLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgQXJyYXlcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBsYXN0IGVsZW1lbnQgb2YgYGFycmF5YC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5sYXN0KFsxLCAyLCAzXSk7XG4gKiAvLyA9PiAzXG4gKi9cbmZ1bmN0aW9uIGxhc3QoYXJyYXkpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5ID8gYXJyYXkubGVuZ3RoIDogMDtcbiAgcmV0dXJuIGxlbmd0aCA/IGFycmF5W2xlbmd0aCAtIDFdIDogdW5kZWZpbmVkO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGxhc3Q7XG4iLCJ2YXIgTGF6eVdyYXBwZXIgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9MYXp5V3JhcHBlcicpLFxuICAgIExvZGFzaFdyYXBwZXIgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9Mb2Rhc2hXcmFwcGVyJyksXG4gICAgYmFzZUxvZGFzaCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2Jhc2VMb2Rhc2gnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FycmF5JyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNPYmplY3RMaWtlJyksXG4gICAgd3JhcHBlckNsb25lID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvd3JhcHBlckNsb25lJyk7XG5cbi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBgbG9kYXNoYCBvYmplY3Qgd2hpY2ggd3JhcHMgYHZhbHVlYCB0byBlbmFibGUgaW1wbGljaXQgY2hhaW5pbmcuXG4gKiBNZXRob2RzIHRoYXQgb3BlcmF0ZSBvbiBhbmQgcmV0dXJuIGFycmF5cywgY29sbGVjdGlvbnMsIGFuZCBmdW5jdGlvbnMgY2FuXG4gKiBiZSBjaGFpbmVkIHRvZ2V0aGVyLiBNZXRob2RzIHRoYXQgcmV0cmlldmUgYSBzaW5nbGUgdmFsdWUgb3IgbWF5IHJldHVybiBhXG4gKiBwcmltaXRpdmUgdmFsdWUgd2lsbCBhdXRvbWF0aWNhbGx5IGVuZCB0aGUgY2hhaW4gcmV0dXJuaW5nIHRoZSB1bndyYXBwZWRcbiAqIHZhbHVlLiBFeHBsaWNpdCBjaGFpbmluZyBtYXkgYmUgZW5hYmxlZCB1c2luZyBgXy5jaGFpbmAuIFRoZSBleGVjdXRpb24gb2ZcbiAqIGNoYWluZWQgbWV0aG9kcyBpcyBsYXp5LCB0aGF0IGlzLCBleGVjdXRpb24gaXMgZGVmZXJyZWQgdW50aWwgYF8jdmFsdWVgXG4gKiBpcyBpbXBsaWNpdGx5IG9yIGV4cGxpY2l0bHkgY2FsbGVkLlxuICpcbiAqIExhenkgZXZhbHVhdGlvbiBhbGxvd3Mgc2V2ZXJhbCBtZXRob2RzIHRvIHN1cHBvcnQgc2hvcnRjdXQgZnVzaW9uLiBTaG9ydGN1dFxuICogZnVzaW9uIGlzIGFuIG9wdGltaXphdGlvbiBzdHJhdGVneSB3aGljaCBtZXJnZSBpdGVyYXRlZSBjYWxsczsgdGhpcyBjYW4gaGVscFxuICogdG8gYXZvaWQgdGhlIGNyZWF0aW9uIG9mIGludGVybWVkaWF0ZSBkYXRhIHN0cnVjdHVyZXMgYW5kIGdyZWF0bHkgcmVkdWNlIHRoZVxuICogbnVtYmVyIG9mIGl0ZXJhdGVlIGV4ZWN1dGlvbnMuXG4gKlxuICogQ2hhaW5pbmcgaXMgc3VwcG9ydGVkIGluIGN1c3RvbSBidWlsZHMgYXMgbG9uZyBhcyB0aGUgYF8jdmFsdWVgIG1ldGhvZCBpc1xuICogZGlyZWN0bHkgb3IgaW5kaXJlY3RseSBpbmNsdWRlZCBpbiB0aGUgYnVpbGQuXG4gKlxuICogSW4gYWRkaXRpb24gdG8gbG9kYXNoIG1ldGhvZHMsIHdyYXBwZXJzIGhhdmUgYEFycmF5YCBhbmQgYFN0cmluZ2AgbWV0aG9kcy5cbiAqXG4gKiBUaGUgd3JhcHBlciBgQXJyYXlgIG1ldGhvZHMgYXJlOlxuICogYGNvbmNhdGAsIGBqb2luYCwgYHBvcGAsIGBwdXNoYCwgYHJldmVyc2VgLCBgc2hpZnRgLCBgc2xpY2VgLCBgc29ydGAsXG4gKiBgc3BsaWNlYCwgYW5kIGB1bnNoaWZ0YFxuICpcbiAqIFRoZSB3cmFwcGVyIGBTdHJpbmdgIG1ldGhvZHMgYXJlOlxuICogYHJlcGxhY2VgIGFuZCBgc3BsaXRgXG4gKlxuICogVGhlIHdyYXBwZXIgbWV0aG9kcyB0aGF0IHN1cHBvcnQgc2hvcnRjdXQgZnVzaW9uIGFyZTpcbiAqIGBjb21wYWN0YCwgYGRyb3BgLCBgZHJvcFJpZ2h0YCwgYGRyb3BSaWdodFdoaWxlYCwgYGRyb3BXaGlsZWAsIGBmaWx0ZXJgLFxuICogYGZpcnN0YCwgYGluaXRpYWxgLCBgbGFzdGAsIGBtYXBgLCBgcGx1Y2tgLCBgcmVqZWN0YCwgYHJlc3RgLCBgcmV2ZXJzZWAsXG4gKiBgc2xpY2VgLCBgdGFrZWAsIGB0YWtlUmlnaHRgLCBgdGFrZVJpZ2h0V2hpbGVgLCBgdGFrZVdoaWxlYCwgYHRvQXJyYXlgLFxuICogYW5kIGB3aGVyZWBcbiAqXG4gKiBUaGUgY2hhaW5hYmxlIHdyYXBwZXIgbWV0aG9kcyBhcmU6XG4gKiBgYWZ0ZXJgLCBgYXJ5YCwgYGFzc2lnbmAsIGBhdGAsIGBiZWZvcmVgLCBgYmluZGAsIGBiaW5kQWxsYCwgYGJpbmRLZXlgLFxuICogYGNhbGxiYWNrYCwgYGNoYWluYCwgYGNodW5rYCwgYGNvbW1pdGAsIGBjb21wYWN0YCwgYGNvbmNhdGAsIGBjb25zdGFudGAsXG4gKiBgY291bnRCeWAsIGBjcmVhdGVgLCBgY3VycnlgLCBgZGVib3VuY2VgLCBgZGVmYXVsdHNgLCBgZGVmYXVsdHNEZWVwYCxcbiAqIGBkZWZlcmAsIGBkZWxheWAsIGBkaWZmZXJlbmNlYCwgYGRyb3BgLCBgZHJvcFJpZ2h0YCwgYGRyb3BSaWdodFdoaWxlYCxcbiAqIGBkcm9wV2hpbGVgLCBgZmlsbGAsIGBmaWx0ZXJgLCBgZmxhdHRlbmAsIGBmbGF0dGVuRGVlcGAsIGBmbG93YCwgYGZsb3dSaWdodGAsXG4gKiBgZm9yRWFjaGAsIGBmb3JFYWNoUmlnaHRgLCBgZm9ySW5gLCBgZm9ySW5SaWdodGAsIGBmb3JPd25gLCBgZm9yT3duUmlnaHRgLFxuICogYGZ1bmN0aW9uc2AsIGBncm91cEJ5YCwgYGluZGV4QnlgLCBgaW5pdGlhbGAsIGBpbnRlcnNlY3Rpb25gLCBgaW52ZXJ0YCxcbiAqIGBpbnZva2VgLCBga2V5c2AsIGBrZXlzSW5gLCBgbWFwYCwgYG1hcEtleXNgLCBgbWFwVmFsdWVzYCwgYG1hdGNoZXNgLFxuICogYG1hdGNoZXNQcm9wZXJ0eWAsIGBtZW1vaXplYCwgYG1lcmdlYCwgYG1ldGhvZGAsIGBtZXRob2RPZmAsIGBtaXhpbmAsXG4gKiBgbW9kQXJnc2AsIGBuZWdhdGVgLCBgb21pdGAsIGBvbmNlYCwgYHBhaXJzYCwgYHBhcnRpYWxgLCBgcGFydGlhbFJpZ2h0YCxcbiAqIGBwYXJ0aXRpb25gLCBgcGlja2AsIGBwbGFudGAsIGBwbHVja2AsIGBwcm9wZXJ0eWAsIGBwcm9wZXJ0eU9mYCwgYHB1bGxgLFxuICogYHB1bGxBdGAsIGBwdXNoYCwgYHJhbmdlYCwgYHJlYXJnYCwgYHJlamVjdGAsIGByZW1vdmVgLCBgcmVzdGAsIGByZXN0UGFyYW1gLFxuICogYHJldmVyc2VgLCBgc2V0YCwgYHNodWZmbGVgLCBgc2xpY2VgLCBgc29ydGAsIGBzb3J0QnlgLCBgc29ydEJ5QWxsYCxcbiAqIGBzb3J0QnlPcmRlcmAsIGBzcGxpY2VgLCBgc3ByZWFkYCwgYHRha2VgLCBgdGFrZVJpZ2h0YCwgYHRha2VSaWdodFdoaWxlYCxcbiAqIGB0YWtlV2hpbGVgLCBgdGFwYCwgYHRocm90dGxlYCwgYHRocnVgLCBgdGltZXNgLCBgdG9BcnJheWAsIGB0b1BsYWluT2JqZWN0YCxcbiAqIGB0cmFuc2Zvcm1gLCBgdW5pb25gLCBgdW5pcWAsIGB1bnNoaWZ0YCwgYHVuemlwYCwgYHVuemlwV2l0aGAsIGB2YWx1ZXNgLFxuICogYHZhbHVlc0luYCwgYHdoZXJlYCwgYHdpdGhvdXRgLCBgd3JhcGAsIGB4b3JgLCBgemlwYCwgYHppcE9iamVjdGAsIGB6aXBXaXRoYFxuICpcbiAqIFRoZSB3cmFwcGVyIG1ldGhvZHMgdGhhdCBhcmUgKipub3QqKiBjaGFpbmFibGUgYnkgZGVmYXVsdCBhcmU6XG4gKiBgYWRkYCwgYGF0dGVtcHRgLCBgY2FtZWxDYXNlYCwgYGNhcGl0YWxpemVgLCBgY2VpbGAsIGBjbG9uZWAsIGBjbG9uZURlZXBgLFxuICogYGRlYnVycmAsIGBlbmRzV2l0aGAsIGBlc2NhcGVgLCBgZXNjYXBlUmVnRXhwYCwgYGV2ZXJ5YCwgYGZpbmRgLCBgZmluZEluZGV4YCxcbiAqIGBmaW5kS2V5YCwgYGZpbmRMYXN0YCwgYGZpbmRMYXN0SW5kZXhgLCBgZmluZExhc3RLZXlgLCBgZmluZFdoZXJlYCwgYGZpcnN0YCxcbiAqIGBmbG9vcmAsIGBnZXRgLCBgZ3RgLCBgZ3RlYCwgYGhhc2AsIGBpZGVudGl0eWAsIGBpbmNsdWRlc2AsIGBpbmRleE9mYCxcbiAqIGBpblJhbmdlYCwgYGlzQXJndW1lbnRzYCwgYGlzQXJyYXlgLCBgaXNCb29sZWFuYCwgYGlzRGF0ZWAsIGBpc0VsZW1lbnRgLFxuICogYGlzRW1wdHlgLCBgaXNFcXVhbGAsIGBpc0Vycm9yYCwgYGlzRmluaXRlYCBgaXNGdW5jdGlvbmAsIGBpc01hdGNoYCxcbiAqIGBpc05hdGl2ZWAsIGBpc05hTmAsIGBpc051bGxgLCBgaXNOdW1iZXJgLCBgaXNPYmplY3RgLCBgaXNQbGFpbk9iamVjdGAsXG4gKiBgaXNSZWdFeHBgLCBgaXNTdHJpbmdgLCBgaXNVbmRlZmluZWRgLCBgaXNUeXBlZEFycmF5YCwgYGpvaW5gLCBga2ViYWJDYXNlYCxcbiAqIGBsYXN0YCwgYGxhc3RJbmRleE9mYCwgYGx0YCwgYGx0ZWAsIGBtYXhgLCBgbWluYCwgYG5vQ29uZmxpY3RgLCBgbm9vcGAsXG4gKiBgbm93YCwgYHBhZGAsIGBwYWRMZWZ0YCwgYHBhZFJpZ2h0YCwgYHBhcnNlSW50YCwgYHBvcGAsIGByYW5kb21gLCBgcmVkdWNlYCxcbiAqIGByZWR1Y2VSaWdodGAsIGByZXBlYXRgLCBgcmVzdWx0YCwgYHJvdW5kYCwgYHJ1bkluQ29udGV4dGAsIGBzaGlmdGAsIGBzaXplYCxcbiAqIGBzbmFrZUNhc2VgLCBgc29tZWAsIGBzb3J0ZWRJbmRleGAsIGBzb3J0ZWRMYXN0SW5kZXhgLCBgc3RhcnRDYXNlYCxcbiAqIGBzdGFydHNXaXRoYCwgYHN1bWAsIGB0ZW1wbGF0ZWAsIGB0cmltYCwgYHRyaW1MZWZ0YCwgYHRyaW1SaWdodGAsIGB0cnVuY2AsXG4gKiBgdW5lc2NhcGVgLCBgdW5pcXVlSWRgLCBgdmFsdWVgLCBhbmQgYHdvcmRzYFxuICpcbiAqIFRoZSB3cmFwcGVyIG1ldGhvZCBgc2FtcGxlYCB3aWxsIHJldHVybiBhIHdyYXBwZWQgdmFsdWUgd2hlbiBgbmAgaXMgcHJvdmlkZWQsXG4gKiBvdGhlcndpc2UgYW4gdW53cmFwcGVkIHZhbHVlIGlzIHJldHVybmVkLlxuICpcbiAqIEBuYW1lIF9cbiAqIEBjb25zdHJ1Y3RvclxuICogQGNhdGVnb3J5IENoYWluXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byB3cmFwIGluIGEgYGxvZGFzaGAgaW5zdGFuY2UuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgYGxvZGFzaGAgd3JhcHBlciBpbnN0YW5jZS5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIHdyYXBwZWQgPSBfKFsxLCAyLCAzXSk7XG4gKlxuICogLy8gcmV0dXJucyBhbiB1bndyYXBwZWQgdmFsdWVcbiAqIHdyYXBwZWQucmVkdWNlKGZ1bmN0aW9uKHRvdGFsLCBuKSB7XG4gKiAgIHJldHVybiB0b3RhbCArIG47XG4gKiB9KTtcbiAqIC8vID0+IDZcbiAqXG4gKiAvLyByZXR1cm5zIGEgd3JhcHBlZCB2YWx1ZVxuICogdmFyIHNxdWFyZXMgPSB3cmFwcGVkLm1hcChmdW5jdGlvbihuKSB7XG4gKiAgIHJldHVybiBuICogbjtcbiAqIH0pO1xuICpcbiAqIF8uaXNBcnJheShzcXVhcmVzKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc0FycmF5KHNxdWFyZXMudmFsdWUoKSk7XG4gKiAvLyA9PiB0cnVlXG4gKi9cbmZ1bmN0aW9uIGxvZGFzaCh2YWx1ZSkge1xuICBpZiAoaXNPYmplY3RMaWtlKHZhbHVlKSAmJiAhaXNBcnJheSh2YWx1ZSkgJiYgISh2YWx1ZSBpbnN0YW5jZW9mIExhenlXcmFwcGVyKSkge1xuICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIExvZGFzaFdyYXBwZXIpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsICdfX2NoYWluX18nKSAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbHVlLCAnX193cmFwcGVkX18nKSkge1xuICAgICAgcmV0dXJuIHdyYXBwZXJDbG9uZSh2YWx1ZSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBuZXcgTG9kYXNoV3JhcHBlcih2YWx1ZSk7XG59XG5cbi8vIEVuc3VyZSB3cmFwcGVycyBhcmUgaW5zdGFuY2VzIG9mIGBiYXNlTG9kYXNoYC5cbmxvZGFzaC5wcm90b3R5cGUgPSBiYXNlTG9kYXNoLnByb3RvdHlwZTtcblxubW9kdWxlLmV4cG9ydHMgPSBsb2Rhc2g7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vZm9yRWFjaCcpO1xuIiwidmFyIGJhc2VFYWNoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZUVhY2gnKSxcbiAgICBjcmVhdGVGaW5kID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvY3JlYXRlRmluZCcpO1xuXG4vKipcbiAqIEl0ZXJhdGVzIG92ZXIgZWxlbWVudHMgb2YgYGNvbGxlY3Rpb25gLCByZXR1cm5pbmcgdGhlIGZpcnN0IGVsZW1lbnRcbiAqIGBwcmVkaWNhdGVgIHJldHVybnMgdHJ1dGh5IGZvci4gVGhlIHByZWRpY2F0ZSBpcyBib3VuZCB0byBgdGhpc0FyZ2AgYW5kXG4gKiBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGluZGV4fGtleSwgY29sbGVjdGlvbikuXG4gKlxuICogSWYgYSBwcm9wZXJ0eSBuYW1lIGlzIHByb3ZpZGVkIGZvciBgcHJlZGljYXRlYCB0aGUgY3JlYXRlZCBgXy5wcm9wZXJ0eWBcbiAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlIG9mIHRoZSBnaXZlbiBlbGVtZW50LlxuICpcbiAqIElmIGEgdmFsdWUgaXMgYWxzbyBwcm92aWRlZCBmb3IgYHRoaXNBcmdgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNQcm9wZXJ0eWBcbiAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgYSBtYXRjaGluZyBwcm9wZXJ0eVxuICogdmFsdWUsIGVsc2UgYGZhbHNlYC5cbiAqXG4gKiBJZiBhbiBvYmplY3QgaXMgcHJvdmlkZWQgZm9yIGBwcmVkaWNhdGVgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNgIHN0eWxlXG4gKiBjYWxsYmFjayByZXR1cm5zIGB0cnVlYCBmb3IgZWxlbWVudHMgdGhhdCBoYXZlIHRoZSBwcm9wZXJ0aWVzIG9mIHRoZSBnaXZlblxuICogb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBhbGlhcyBkZXRlY3RcbiAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gc2VhcmNoLlxuICogQHBhcmFtIHtGdW5jdGlvbnxPYmplY3R8c3RyaW5nfSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkXG4gKiAgcGVyIGl0ZXJhdGlvbi5cbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgcHJlZGljYXRlYC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBtYXRjaGVkIGVsZW1lbnQsIGVsc2UgYHVuZGVmaW5lZGAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciB1c2VycyA9IFtcbiAqICAgeyAndXNlcic6ICdiYXJuZXknLCAgJ2FnZSc6IDM2LCAnYWN0aXZlJzogdHJ1ZSB9LFxuICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICAnYWdlJzogNDAsICdhY3RpdmUnOiBmYWxzZSB9LFxuICogICB7ICd1c2VyJzogJ3BlYmJsZXMnLCAnYWdlJzogMSwgICdhY3RpdmUnOiB0cnVlIH1cbiAqIF07XG4gKlxuICogXy5yZXN1bHQoXy5maW5kKHVzZXJzLCBmdW5jdGlvbihjaHIpIHtcbiAqICAgcmV0dXJuIGNoci5hZ2UgPCA0MDtcbiAqIH0pLCAndXNlcicpO1xuICogLy8gPT4gJ2Jhcm5leSdcbiAqXG4gKiAvLyB1c2luZyB0aGUgYF8ubWF0Y2hlc2AgY2FsbGJhY2sgc2hvcnRoYW5kXG4gKiBfLnJlc3VsdChfLmZpbmQodXNlcnMsIHsgJ2FnZSc6IDEsICdhY3RpdmUnOiB0cnVlIH0pLCAndXNlcicpO1xuICogLy8gPT4gJ3BlYmJsZXMnXG4gKlxuICogLy8gdXNpbmcgdGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgY2FsbGJhY2sgc2hvcnRoYW5kXG4gKiBfLnJlc3VsdChfLmZpbmQodXNlcnMsICdhY3RpdmUnLCBmYWxzZSksICd1c2VyJyk7XG4gKiAvLyA9PiAnZnJlZCdcbiAqXG4gKiAvLyB1c2luZyB0aGUgYF8ucHJvcGVydHlgIGNhbGxiYWNrIHNob3J0aGFuZFxuICogXy5yZXN1bHQoXy5maW5kKHVzZXJzLCAnYWN0aXZlJyksICd1c2VyJyk7XG4gKiAvLyA9PiAnYmFybmV5J1xuICovXG52YXIgZmluZCA9IGNyZWF0ZUZpbmQoYmFzZUVhY2gpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZpbmQ7XG4iLCJ2YXIgYXJyYXlFYWNoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYXJyYXlFYWNoJyksXG4gICAgYmFzZUVhY2ggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlRWFjaCcpLFxuICAgIGNyZWF0ZUZvckVhY2ggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9jcmVhdGVGb3JFYWNoJyk7XG5cbi8qKlxuICogSXRlcmF0ZXMgb3ZlciBlbGVtZW50cyBvZiBgY29sbGVjdGlvbmAgaW52b2tpbmcgYGl0ZXJhdGVlYCBmb3IgZWFjaCBlbGVtZW50LlxuICogVGhlIGBpdGVyYXRlZWAgaXMgYm91bmQgdG8gYHRoaXNBcmdgIGFuZCBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOlxuICogKHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLiBJdGVyYXRlZSBmdW5jdGlvbnMgbWF5IGV4aXQgaXRlcmF0aW9uIGVhcmx5XG4gKiBieSBleHBsaWNpdGx5IHJldHVybmluZyBgZmFsc2VgLlxuICpcbiAqICoqTm90ZToqKiBBcyB3aXRoIG90aGVyIFwiQ29sbGVjdGlvbnNcIiBtZXRob2RzLCBvYmplY3RzIHdpdGggYSBcImxlbmd0aFwiIHByb3BlcnR5XG4gKiBhcmUgaXRlcmF0ZWQgbGlrZSBhcnJheXMuIFRvIGF2b2lkIHRoaXMgYmVoYXZpb3IgYF8uZm9ySW5gIG9yIGBfLmZvck93bmBcbiAqIG1heSBiZSB1c2VkIGZvciBvYmplY3QgaXRlcmF0aW9uLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAYWxpYXMgZWFjaFxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgaXRlcmF0ZWVgLlxuICogQHJldHVybnMge0FycmF5fE9iamVjdHxzdHJpbmd9IFJldHVybnMgYGNvbGxlY3Rpb25gLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfKFsxLCAyXSkuZm9yRWFjaChmdW5jdGlvbihuKSB7XG4gKiAgIGNvbnNvbGUubG9nKG4pO1xuICogfSkudmFsdWUoKTtcbiAqIC8vID0+IGxvZ3MgZWFjaCB2YWx1ZSBmcm9tIGxlZnQgdG8gcmlnaHQgYW5kIHJldHVybnMgdGhlIGFycmF5XG4gKlxuICogXy5mb3JFYWNoKHsgJ2EnOiAxLCAnYic6IDIgfSwgZnVuY3Rpb24obiwga2V5KSB7XG4gKiAgIGNvbnNvbGUubG9nKG4sIGtleSk7XG4gKiB9KTtcbiAqIC8vID0+IGxvZ3MgZWFjaCB2YWx1ZS1rZXkgcGFpciBhbmQgcmV0dXJucyB0aGUgb2JqZWN0IChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gKi9cbnZhciBmb3JFYWNoID0gY3JlYXRlRm9yRWFjaChhcnJheUVhY2gsIGJhc2VFYWNoKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmb3JFYWNoO1xuIiwidmFyIGJhc2VJbmRleE9mID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZUluZGV4T2YnKSxcbiAgICBnZXRMZW5ndGggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9nZXRMZW5ndGgnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FycmF5JyksXG4gICAgaXNJdGVyYXRlZUNhbGwgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0l0ZXJhdGVlQ2FsbCcpLFxuICAgIGlzTGVuZ3RoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNMZW5ndGgnKSxcbiAgICBpc1N0cmluZyA9IHJlcXVpcmUoJy4uL2xhbmcvaXNTdHJpbmcnKSxcbiAgICB2YWx1ZXMgPSByZXF1aXJlKCcuLi9vYmplY3QvdmFsdWVzJyk7XG5cbi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlTWF4ID0gTWF0aC5tYXg7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB0YXJnZXRgIGlzIGluIGBjb2xsZWN0aW9uYCB1c2luZ1xuICogW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAqIGZvciBlcXVhbGl0eSBjb21wYXJpc29ucy4gSWYgYGZyb21JbmRleGAgaXMgbmVnYXRpdmUsIGl0J3MgdXNlZCBhcyB0aGUgb2Zmc2V0XG4gKiBmcm9tIHRoZSBlbmQgb2YgYGNvbGxlY3Rpb25gLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAYWxpYXMgY29udGFpbnMsIGluY2x1ZGVcbiAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gc2VhcmNoLlxuICogQHBhcmFtIHsqfSB0YXJnZXQgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gKiBAcGFyYW0ge251bWJlcn0gW2Zyb21JbmRleD0wXSBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gKiBAcGFyYW0tIHtPYmplY3R9IFtndWFyZF0gRW5hYmxlcyB1c2UgYXMgYSBjYWxsYmFjayBmb3IgZnVuY3Rpb25zIGxpa2UgYF8ucmVkdWNlYC5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhIG1hdGNoaW5nIGVsZW1lbnQgaXMgZm91bmQsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pbmNsdWRlcyhbMSwgMiwgM10sIDEpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaW5jbHVkZXMoWzEsIDIsIDNdLCAxLCAyKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pbmNsdWRlcyh7ICd1c2VyJzogJ2ZyZWQnLCAnYWdlJzogNDAgfSwgJ2ZyZWQnKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmluY2x1ZGVzKCdwZWJibGVzJywgJ2ViJyk7XG4gKiAvLyA9PiB0cnVlXG4gKi9cbmZ1bmN0aW9uIGluY2x1ZGVzKGNvbGxlY3Rpb24sIHRhcmdldCwgZnJvbUluZGV4LCBndWFyZCkge1xuICB2YXIgbGVuZ3RoID0gY29sbGVjdGlvbiA/IGdldExlbmd0aChjb2xsZWN0aW9uKSA6IDA7XG4gIGlmICghaXNMZW5ndGgobGVuZ3RoKSkge1xuICAgIGNvbGxlY3Rpb24gPSB2YWx1ZXMoY29sbGVjdGlvbik7XG4gICAgbGVuZ3RoID0gY29sbGVjdGlvbi5sZW5ndGg7XG4gIH1cbiAgaWYgKHR5cGVvZiBmcm9tSW5kZXggIT0gJ251bWJlcicgfHwgKGd1YXJkICYmIGlzSXRlcmF0ZWVDYWxsKHRhcmdldCwgZnJvbUluZGV4LCBndWFyZCkpKSB7XG4gICAgZnJvbUluZGV4ID0gMDtcbiAgfSBlbHNlIHtcbiAgICBmcm9tSW5kZXggPSBmcm9tSW5kZXggPCAwID8gbmF0aXZlTWF4KGxlbmd0aCArIGZyb21JbmRleCwgMCkgOiAoZnJvbUluZGV4IHx8IDApO1xuICB9XG4gIHJldHVybiAodHlwZW9mIGNvbGxlY3Rpb24gPT0gJ3N0cmluZycgfHwgIWlzQXJyYXkoY29sbGVjdGlvbikgJiYgaXNTdHJpbmcoY29sbGVjdGlvbikpXG4gICAgPyAoZnJvbUluZGV4IDw9IGxlbmd0aCAmJiBjb2xsZWN0aW9uLmluZGV4T2YodGFyZ2V0LCBmcm9tSW5kZXgpID4gLTEpXG4gICAgOiAoISFsZW5ndGggJiYgYmFzZUluZGV4T2YoY29sbGVjdGlvbiwgdGFyZ2V0LCBmcm9tSW5kZXgpID4gLTEpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGluY2x1ZGVzO1xuIiwidmFyIGFycmF5TWFwID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYXJyYXlNYXAnKSxcbiAgICBiYXNlQ2FsbGJhY2sgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlQ2FsbGJhY2snKSxcbiAgICBiYXNlTWFwID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZU1hcCcpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKTtcblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IG9mIHZhbHVlcyBieSBydW5uaW5nIGVhY2ggZWxlbWVudCBpbiBgY29sbGVjdGlvbmAgdGhyb3VnaFxuICogYGl0ZXJhdGVlYC4gVGhlIGBpdGVyYXRlZWAgaXMgYm91bmQgdG8gYHRoaXNBcmdgIGFuZCBpbnZva2VkIHdpdGggdGhyZWVcbiAqIGFyZ3VtZW50czogKHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLlxuICpcbiAqIElmIGEgcHJvcGVydHkgbmFtZSBpcyBwcm92aWRlZCBmb3IgYGl0ZXJhdGVlYCB0aGUgY3JlYXRlZCBgXy5wcm9wZXJ0eWBcbiAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlIG9mIHRoZSBnaXZlbiBlbGVtZW50LlxuICpcbiAqIElmIGEgdmFsdWUgaXMgYWxzbyBwcm92aWRlZCBmb3IgYHRoaXNBcmdgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNQcm9wZXJ0eWBcbiAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgYSBtYXRjaGluZyBwcm9wZXJ0eVxuICogdmFsdWUsIGVsc2UgYGZhbHNlYC5cbiAqXG4gKiBJZiBhbiBvYmplY3QgaXMgcHJvdmlkZWQgZm9yIGBpdGVyYXRlZWAgdGhlIGNyZWF0ZWQgYF8ubWF0Y2hlc2Agc3R5bGVcbiAqIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgdGhlIHByb3BlcnRpZXMgb2YgdGhlIGdpdmVuXG4gKiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAqXG4gKiBNYW55IGxvZGFzaCBtZXRob2RzIGFyZSBndWFyZGVkIHRvIHdvcmsgYXMgaXRlcmF0ZWVzIGZvciBtZXRob2RzIGxpa2VcbiAqIGBfLmV2ZXJ5YCwgYF8uZmlsdGVyYCwgYF8ubWFwYCwgYF8ubWFwVmFsdWVzYCwgYF8ucmVqZWN0YCwgYW5kIGBfLnNvbWVgLlxuICpcbiAqIFRoZSBndWFyZGVkIG1ldGhvZHMgYXJlOlxuICogYGFyeWAsIGBjYWxsYmFja2AsIGBjaHVua2AsIGBjbG9uZWAsIGBjcmVhdGVgLCBgY3VycnlgLCBgY3VycnlSaWdodGAsXG4gKiBgZHJvcGAsIGBkcm9wUmlnaHRgLCBgZXZlcnlgLCBgZmlsbGAsIGBmbGF0dGVuYCwgYGludmVydGAsIGBtYXhgLCBgbWluYCxcbiAqIGBwYXJzZUludGAsIGBzbGljZWAsIGBzb3J0QnlgLCBgdGFrZWAsIGB0YWtlUmlnaHRgLCBgdGVtcGxhdGVgLCBgdHJpbWAsXG4gKiBgdHJpbUxlZnRgLCBgdHJpbVJpZ2h0YCwgYHRydW5jYCwgYHJhbmRvbWAsIGByYW5nZWAsIGBzYW1wbGVgLCBgc29tZWAsXG4gKiBgc3VtYCwgYHVuaXFgLCBhbmQgYHdvcmRzYFxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAYWxpYXMgY29sbGVjdFxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufE9iamVjdHxzdHJpbmd9IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZFxuICogIHBlciBpdGVyYXRpb24uXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGl0ZXJhdGVlYC5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IG1hcHBlZCBhcnJheS5cbiAqIEBleGFtcGxlXG4gKlxuICogZnVuY3Rpb24gdGltZXNUaHJlZShuKSB7XG4gKiAgIHJldHVybiBuICogMztcbiAqIH1cbiAqXG4gKiBfLm1hcChbMSwgMl0sIHRpbWVzVGhyZWUpO1xuICogLy8gPT4gWzMsIDZdXG4gKlxuICogXy5tYXAoeyAnYSc6IDEsICdiJzogMiB9LCB0aW1lc1RocmVlKTtcbiAqIC8vID0+IFszLCA2XSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICpcbiAqIHZhciB1c2VycyA9IFtcbiAqICAgeyAndXNlcic6ICdiYXJuZXknIH0sXG4gKiAgIHsgJ3VzZXInOiAnZnJlZCcgfVxuICogXTtcbiAqXG4gKiAvLyB1c2luZyB0aGUgYF8ucHJvcGVydHlgIGNhbGxiYWNrIHNob3J0aGFuZFxuICogXy5tYXAodXNlcnMsICd1c2VyJyk7XG4gKiAvLyA9PiBbJ2Jhcm5leScsICdmcmVkJ11cbiAqL1xuZnVuY3Rpb24gbWFwKGNvbGxlY3Rpb24sIGl0ZXJhdGVlLCB0aGlzQXJnKSB7XG4gIHZhciBmdW5jID0gaXNBcnJheShjb2xsZWN0aW9uKSA/IGFycmF5TWFwIDogYmFzZU1hcDtcbiAgaXRlcmF0ZWUgPSBiYXNlQ2FsbGJhY2soaXRlcmF0ZWUsIHRoaXNBcmcsIDMpO1xuICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uLCBpdGVyYXRlZSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbWFwO1xuIiwidmFyIGdldE5hdGl2ZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2dldE5hdGl2ZScpO1xuXG4vKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU5vdyA9IGdldE5hdGl2ZShEYXRlLCAnbm93Jyk7XG5cbi8qKlxuICogR2V0cyB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0aGF0IGhhdmUgZWxhcHNlZCBzaW5jZSB0aGUgVW5peCBlcG9jaFxuICogKDEgSmFudWFyeSAxOTcwIDAwOjAwOjAwIFVUQykuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBEYXRlXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uZGVmZXIoZnVuY3Rpb24oc3RhbXApIHtcbiAqICAgY29uc29sZS5sb2coXy5ub3coKSAtIHN0YW1wKTtcbiAqIH0sIF8ubm93KCkpO1xuICogLy8gPT4gbG9ncyB0aGUgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBpdCB0b29rIGZvciB0aGUgZGVmZXJyZWQgZnVuY3Rpb24gdG8gYmUgaW52b2tlZFxuICovXG52YXIgbm93ID0gbmF0aXZlTm93IHx8IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5vdztcbiIsInZhciBjcmVhdGVXcmFwcGVyID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvY3JlYXRlV3JhcHBlcicpLFxuICAgIHJlcGxhY2VIb2xkZXJzID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvcmVwbGFjZUhvbGRlcnMnKSxcbiAgICByZXN0UGFyYW0gPSByZXF1aXJlKCcuL3Jlc3RQYXJhbScpO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB3cmFwcGVyIG1ldGFkYXRhLiAqL1xudmFyIEJJTkRfRkxBRyA9IDEsXG4gICAgUEFSVElBTF9GTEFHID0gMzI7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgb2YgYHRoaXNBcmdgXG4gKiBhbmQgcHJlcGVuZHMgYW55IGFkZGl0aW9uYWwgYF8uYmluZGAgYXJndW1lbnRzIHRvIHRob3NlIHByb3ZpZGVkIHRvIHRoZVxuICogYm91bmQgZnVuY3Rpb24uXG4gKlxuICogVGhlIGBfLmJpbmQucGxhY2Vob2xkZXJgIHZhbHVlLCB3aGljaCBkZWZhdWx0cyB0byBgX2AgaW4gbW9ub2xpdGhpYyBidWlsZHMsXG4gKiBtYXkgYmUgdXNlZCBhcyBhIHBsYWNlaG9sZGVyIGZvciBwYXJ0aWFsbHkgYXBwbGllZCBhcmd1bWVudHMuXG4gKlxuICogKipOb3RlOioqIFVubGlrZSBuYXRpdmUgYEZ1bmN0aW9uI2JpbmRgIHRoaXMgbWV0aG9kIGRvZXMgbm90IHNldCB0aGUgXCJsZW5ndGhcIlxuICogcHJvcGVydHkgb2YgYm91bmQgZnVuY3Rpb25zLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGJpbmQuXG4gKiBAcGFyYW0geyp9IHRoaXNBcmcgVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7Li4uKn0gW3BhcnRpYWxzXSBUaGUgYXJndW1lbnRzIHRvIGJlIHBhcnRpYWxseSBhcHBsaWVkLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYm91bmQgZnVuY3Rpb24uXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBncmVldCA9IGZ1bmN0aW9uKGdyZWV0aW5nLCBwdW5jdHVhdGlvbikge1xuICogICByZXR1cm4gZ3JlZXRpbmcgKyAnICcgKyB0aGlzLnVzZXIgKyBwdW5jdHVhdGlvbjtcbiAqIH07XG4gKlxuICogdmFyIG9iamVjdCA9IHsgJ3VzZXInOiAnZnJlZCcgfTtcbiAqXG4gKiB2YXIgYm91bmQgPSBfLmJpbmQoZ3JlZXQsIG9iamVjdCwgJ2hpJyk7XG4gKiBib3VuZCgnIScpO1xuICogLy8gPT4gJ2hpIGZyZWQhJ1xuICpcbiAqIC8vIHVzaW5nIHBsYWNlaG9sZGVyc1xuICogdmFyIGJvdW5kID0gXy5iaW5kKGdyZWV0LCBvYmplY3QsIF8sICchJyk7XG4gKiBib3VuZCgnaGknKTtcbiAqIC8vID0+ICdoaSBmcmVkISdcbiAqL1xudmFyIGJpbmQgPSByZXN0UGFyYW0oZnVuY3Rpb24oZnVuYywgdGhpc0FyZywgcGFydGlhbHMpIHtcbiAgdmFyIGJpdG1hc2sgPSBCSU5EX0ZMQUc7XG4gIGlmIChwYXJ0aWFscy5sZW5ndGgpIHtcbiAgICB2YXIgaG9sZGVycyA9IHJlcGxhY2VIb2xkZXJzKHBhcnRpYWxzLCBiaW5kLnBsYWNlaG9sZGVyKTtcbiAgICBiaXRtYXNrIHw9IFBBUlRJQUxfRkxBRztcbiAgfVxuICByZXR1cm4gY3JlYXRlV3JhcHBlcihmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBwYXJ0aWFscywgaG9sZGVycyk7XG59KTtcblxuLy8gQXNzaWduIGRlZmF1bHQgcGxhY2Vob2xkZXJzLlxuYmluZC5wbGFjZWhvbGRlciA9IHt9O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJpbmQ7XG4iLCIvKiogVXNlZCBhcyB0aGUgYFR5cGVFcnJvcmAgbWVzc2FnZSBmb3IgXCJGdW5jdGlvbnNcIiBtZXRob2RzLiAqL1xudmFyIEZVTkNfRVJST1JfVEVYVCA9ICdFeHBlY3RlZCBhIGZ1bmN0aW9uJztcblxuLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heDtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBpbnZva2VzIGBmdW5jYCB3aXRoIHRoZSBgdGhpc2AgYmluZGluZyBvZiB0aGVcbiAqIGNyZWF0ZWQgZnVuY3Rpb24gYW5kIGFyZ3VtZW50cyBmcm9tIGBzdGFydGAgYW5kIGJleW9uZCBwcm92aWRlZCBhcyBhbiBhcnJheS5cbiAqXG4gKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgYmFzZWQgb24gdGhlIFtyZXN0IHBhcmFtZXRlcl0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0Z1bmN0aW9ucy9yZXN0X3BhcmFtZXRlcnMpLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFwcGx5IGEgcmVzdCBwYXJhbWV0ZXIgdG8uXG4gKiBAcGFyYW0ge251bWJlcn0gW3N0YXJ0PWZ1bmMubGVuZ3RoLTFdIFRoZSBzdGFydCBwb3NpdGlvbiBvZiB0aGUgcmVzdCBwYXJhbWV0ZXIuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIHNheSA9IF8ucmVzdFBhcmFtKGZ1bmN0aW9uKHdoYXQsIG5hbWVzKSB7XG4gKiAgIHJldHVybiB3aGF0ICsgJyAnICsgXy5pbml0aWFsKG5hbWVzKS5qb2luKCcsICcpICtcbiAqICAgICAoXy5zaXplKG5hbWVzKSA+IDEgPyAnLCAmICcgOiAnJykgKyBfLmxhc3QobmFtZXMpO1xuICogfSk7XG4gKlxuICogc2F5KCdoZWxsbycsICdmcmVkJywgJ2Jhcm5leScsICdwZWJibGVzJyk7XG4gKiAvLyA9PiAnaGVsbG8gZnJlZCwgYmFybmV5LCAmIHBlYmJsZXMnXG4gKi9cbmZ1bmN0aW9uIHJlc3RQYXJhbShmdW5jLCBzdGFydCkge1xuICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRlVOQ19FUlJPUl9URVhUKTtcbiAgfVxuICBzdGFydCA9IG5hdGl2ZU1heChzdGFydCA9PT0gdW5kZWZpbmVkID8gKGZ1bmMubGVuZ3RoIC0gMSkgOiAoK3N0YXJ0IHx8IDApLCAwKTtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHZhciBhcmdzID0gYXJndW1lbnRzLFxuICAgICAgICBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSBuYXRpdmVNYXgoYXJncy5sZW5ndGggLSBzdGFydCwgMCksXG4gICAgICAgIHJlc3QgPSBBcnJheShsZW5ndGgpO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIHJlc3RbaW5kZXhdID0gYXJnc1tzdGFydCArIGluZGV4XTtcbiAgICB9XG4gICAgc3dpdGNoIChzdGFydCkge1xuICAgICAgY2FzZSAwOiByZXR1cm4gZnVuYy5jYWxsKHRoaXMsIHJlc3QpO1xuICAgICAgY2FzZSAxOiByZXR1cm4gZnVuYy5jYWxsKHRoaXMsIGFyZ3NbMF0sIHJlc3QpO1xuICAgICAgY2FzZSAyOiByZXR1cm4gZnVuYy5jYWxsKHRoaXMsIGFyZ3NbMF0sIGFyZ3NbMV0sIHJlc3QpO1xuICAgIH1cbiAgICB2YXIgb3RoZXJBcmdzID0gQXJyYXkoc3RhcnQgKyAxKTtcbiAgICBpbmRleCA9IC0xO1xuICAgIHdoaWxlICgrK2luZGV4IDwgc3RhcnQpIHtcbiAgICAgIG90aGVyQXJnc1tpbmRleF0gPSBhcmdzW2luZGV4XTtcbiAgICB9XG4gICAgb3RoZXJBcmdzW3N0YXJ0XSA9IHJlc3Q7XG4gICAgcmV0dXJuIGZ1bmMuYXBwbHkodGhpcywgb3RoZXJBcmdzKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSByZXN0UGFyYW07XG4iLCJ2YXIgYmFzZUNyZWF0ZSA9IHJlcXVpcmUoJy4vYmFzZUNyZWF0ZScpLFxuICAgIGJhc2VMb2Rhc2ggPSByZXF1aXJlKCcuL2Jhc2VMb2Rhc2gnKTtcblxuLyoqIFVzZWQgYXMgcmVmZXJlbmNlcyBmb3IgYC1JbmZpbml0eWAgYW5kIGBJbmZpbml0eWAuICovXG52YXIgUE9TSVRJVkVfSU5GSU5JVFkgPSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGxhenkgd3JhcHBlciBvYmplY3Qgd2hpY2ggd3JhcHMgYHZhbHVlYCB0byBlbmFibGUgbGF6eSBldmFsdWF0aW9uLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byB3cmFwLlxuICovXG5mdW5jdGlvbiBMYXp5V3JhcHBlcih2YWx1ZSkge1xuICB0aGlzLl9fd3JhcHBlZF9fID0gdmFsdWU7XG4gIHRoaXMuX19hY3Rpb25zX18gPSBbXTtcbiAgdGhpcy5fX2Rpcl9fID0gMTtcbiAgdGhpcy5fX2ZpbHRlcmVkX18gPSBmYWxzZTtcbiAgdGhpcy5fX2l0ZXJhdGVlc19fID0gW107XG4gIHRoaXMuX190YWtlQ291bnRfXyA9IFBPU0lUSVZFX0lORklOSVRZO1xuICB0aGlzLl9fdmlld3NfXyA9IFtdO1xufVxuXG5MYXp5V3JhcHBlci5wcm90b3R5cGUgPSBiYXNlQ3JlYXRlKGJhc2VMb2Rhc2gucHJvdG90eXBlKTtcbkxhenlXcmFwcGVyLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IExhenlXcmFwcGVyO1xuXG5tb2R1bGUuZXhwb3J0cyA9IExhenlXcmFwcGVyO1xuIiwidmFyIGJhc2VDcmVhdGUgPSByZXF1aXJlKCcuL2Jhc2VDcmVhdGUnKSxcbiAgICBiYXNlTG9kYXNoID0gcmVxdWlyZSgnLi9iYXNlTG9kYXNoJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgY29uc3RydWN0b3IgZm9yIGNyZWF0aW5nIGBsb2Rhc2hgIHdyYXBwZXIgb2JqZWN0cy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gd3JhcC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2NoYWluQWxsXSBFbmFibGUgY2hhaW5pbmcgZm9yIGFsbCB3cmFwcGVyIG1ldGhvZHMuXG4gKiBAcGFyYW0ge0FycmF5fSBbYWN0aW9ucz1bXV0gQWN0aW9ucyB0byBwZWZvcm0gdG8gcmVzb2x2ZSB0aGUgdW53cmFwcGVkIHZhbHVlLlxuICovXG5mdW5jdGlvbiBMb2Rhc2hXcmFwcGVyKHZhbHVlLCBjaGFpbkFsbCwgYWN0aW9ucykge1xuICB0aGlzLl9fd3JhcHBlZF9fID0gdmFsdWU7XG4gIHRoaXMuX19hY3Rpb25zX18gPSBhY3Rpb25zIHx8IFtdO1xuICB0aGlzLl9fY2hhaW5fXyA9ICEhY2hhaW5BbGw7XG59XG5cbkxvZGFzaFdyYXBwZXIucHJvdG90eXBlID0gYmFzZUNyZWF0ZShiYXNlTG9kYXNoLnByb3RvdHlwZSk7XG5Mb2Rhc2hXcmFwcGVyLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IExvZGFzaFdyYXBwZXI7XG5cbm1vZHVsZS5leHBvcnRzID0gTG9kYXNoV3JhcHBlcjtcbiIsIi8qKlxuICogQ29waWVzIHRoZSB2YWx1ZXMgb2YgYHNvdXJjZWAgdG8gYGFycmF5YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gc291cmNlIFRoZSBhcnJheSB0byBjb3B5IHZhbHVlcyBmcm9tLlxuICogQHBhcmFtIHtBcnJheX0gW2FycmF5PVtdXSBUaGUgYXJyYXkgdG8gY29weSB2YWx1ZXMgdG8uXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAqL1xuZnVuY3Rpb24gYXJyYXlDb3B5KHNvdXJjZSwgYXJyYXkpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBzb3VyY2UubGVuZ3RoO1xuXG4gIGFycmF5IHx8IChhcnJheSA9IEFycmF5KGxlbmd0aCkpO1xuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIGFycmF5W2luZGV4XSA9IHNvdXJjZVtpbmRleF07XG4gIH1cbiAgcmV0dXJuIGFycmF5O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFycmF5Q29weTtcbiIsIi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLmZvckVhY2hgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGFycmF5RWFjaChhcnJheSwgaXRlcmF0ZWUpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBpZiAoaXRlcmF0ZWUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpID09PSBmYWxzZSkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIHJldHVybiBhcnJheTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhcnJheUVhY2g7XG4iLCIvKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5tYXBgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgbWFwcGVkIGFycmF5LlxuICovXG5mdW5jdGlvbiBhcnJheU1hcChhcnJheSwgaXRlcmF0ZWUpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBBcnJheShsZW5ndGgpO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgcmVzdWx0W2luZGV4XSA9IGl0ZXJhdGVlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFycmF5TWFwO1xuIiwiLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uc29tZWAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrXG4gKiBzaG9ydGhhbmRzIGFuZCBgdGhpc2AgYmluZGluZy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGFueSBlbGVtZW50IHBhc3NlcyB0aGUgcHJlZGljYXRlIGNoZWNrLFxuICogIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYXJyYXlTb21lKGFycmF5LCBwcmVkaWNhdGUpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBpZiAocHJlZGljYXRlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhcnJheVNvbWU7XG4iLCJ2YXIgYmFzZUNvcHkgPSByZXF1aXJlKCcuL2Jhc2VDb3B5JyksXG4gICAga2V5cyA9IHJlcXVpcmUoJy4uL29iamVjdC9rZXlzJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uYXNzaWduYCB3aXRob3V0IHN1cHBvcnQgZm9yIGFyZ3VtZW50IGp1Z2dsaW5nLFxuICogbXVsdGlwbGUgc291cmNlcywgYW5kIGBjdXN0b21pemVyYCBmdW5jdGlvbnMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIGRlc3RpbmF0aW9uIG9iamVjdC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIHNvdXJjZSBvYmplY3QuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICovXG5mdW5jdGlvbiBiYXNlQXNzaWduKG9iamVjdCwgc291cmNlKSB7XG4gIHJldHVybiBzb3VyY2UgPT0gbnVsbFxuICAgID8gb2JqZWN0XG4gICAgOiBiYXNlQ29weShzb3VyY2UsIGtleXMoc291cmNlKSwgb2JqZWN0KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlQXNzaWduO1xuIiwidmFyIGJhc2VNYXRjaGVzID0gcmVxdWlyZSgnLi9iYXNlTWF0Y2hlcycpLFxuICAgIGJhc2VNYXRjaGVzUHJvcGVydHkgPSByZXF1aXJlKCcuL2Jhc2VNYXRjaGVzUHJvcGVydHknKSxcbiAgICBiaW5kQ2FsbGJhY2sgPSByZXF1aXJlKCcuL2JpbmRDYWxsYmFjaycpLFxuICAgIGlkZW50aXR5ID0gcmVxdWlyZSgnLi4vdXRpbGl0eS9pZGVudGl0eScpLFxuICAgIHByb3BlcnR5ID0gcmVxdWlyZSgnLi4vdXRpbGl0eS9wcm9wZXJ0eScpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmNhbGxiYWNrYCB3aGljaCBzdXBwb3J0cyBzcGVjaWZ5aW5nIHRoZVxuICogbnVtYmVyIG9mIGFyZ3VtZW50cyB0byBwcm92aWRlIHRvIGBmdW5jYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSBbZnVuYz1fLmlkZW50aXR5XSBUaGUgdmFsdWUgdG8gY29udmVydCB0byBhIGNhbGxiYWNrLlxuICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXJnQ291bnRdIFRoZSBudW1iZXIgb2YgYXJndW1lbnRzIHRvIHByb3ZpZGUgdG8gYGZ1bmNgLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBjYWxsYmFjay5cbiAqL1xuZnVuY3Rpb24gYmFzZUNhbGxiYWNrKGZ1bmMsIHRoaXNBcmcsIGFyZ0NvdW50KSB7XG4gIHZhciB0eXBlID0gdHlwZW9mIGZ1bmM7XG4gIGlmICh0eXBlID09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gdGhpc0FyZyA9PT0gdW5kZWZpbmVkXG4gICAgICA/IGZ1bmNcbiAgICAgIDogYmluZENhbGxiYWNrKGZ1bmMsIHRoaXNBcmcsIGFyZ0NvdW50KTtcbiAgfVxuICBpZiAoZnVuYyA9PSBudWxsKSB7XG4gICAgcmV0dXJuIGlkZW50aXR5O1xuICB9XG4gIGlmICh0eXBlID09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIGJhc2VNYXRjaGVzKGZ1bmMpO1xuICB9XG4gIHJldHVybiB0aGlzQXJnID09PSB1bmRlZmluZWRcbiAgICA/IHByb3BlcnR5KGZ1bmMpXG4gICAgOiBiYXNlTWF0Y2hlc1Byb3BlcnR5KGZ1bmMsIHRoaXNBcmcpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VDYWxsYmFjaztcbiIsInZhciBhcnJheUNvcHkgPSByZXF1aXJlKCcuL2FycmF5Q29weScpLFxuICAgIGFycmF5RWFjaCA9IHJlcXVpcmUoJy4vYXJyYXlFYWNoJyksXG4gICAgYmFzZUFzc2lnbiA9IHJlcXVpcmUoJy4vYmFzZUFzc2lnbicpLFxuICAgIGJhc2VGb3JPd24gPSByZXF1aXJlKCcuL2Jhc2VGb3JPd24nKSxcbiAgICBpbml0Q2xvbmVBcnJheSA9IHJlcXVpcmUoJy4vaW5pdENsb25lQXJyYXknKSxcbiAgICBpbml0Q2xvbmVCeVRhZyA9IHJlcXVpcmUoJy4vaW5pdENsb25lQnlUYWcnKSxcbiAgICBpbml0Q2xvbmVPYmplY3QgPSByZXF1aXJlKCcuL2luaXRDbG9uZU9iamVjdCcpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKSxcbiAgICBpc0hvc3RPYmplY3QgPSByZXF1aXJlKCcuL2lzSG9zdE9iamVjdCcpLFxuICAgIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vbGFuZy9pc09iamVjdCcpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgYXJnc1RhZyA9ICdbb2JqZWN0IEFyZ3VtZW50c10nLFxuICAgIGFycmF5VGFnID0gJ1tvYmplY3QgQXJyYXldJyxcbiAgICBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgIGRhdGVUYWcgPSAnW29iamVjdCBEYXRlXScsXG4gICAgZXJyb3JUYWcgPSAnW29iamVjdCBFcnJvcl0nLFxuICAgIGZ1bmNUYWcgPSAnW29iamVjdCBGdW5jdGlvbl0nLFxuICAgIG1hcFRhZyA9ICdbb2JqZWN0IE1hcF0nLFxuICAgIG51bWJlclRhZyA9ICdbb2JqZWN0IE51bWJlcl0nLFxuICAgIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nLFxuICAgIHJlZ2V4cFRhZyA9ICdbb2JqZWN0IFJlZ0V4cF0nLFxuICAgIHNldFRhZyA9ICdbb2JqZWN0IFNldF0nLFxuICAgIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nLFxuICAgIHdlYWtNYXBUYWcgPSAnW29iamVjdCBXZWFrTWFwXSc7XG5cbnZhciBhcnJheUJ1ZmZlclRhZyA9ICdbb2JqZWN0IEFycmF5QnVmZmVyXScsXG4gICAgZmxvYXQzMlRhZyA9ICdbb2JqZWN0IEZsb2F0MzJBcnJheV0nLFxuICAgIGZsb2F0NjRUYWcgPSAnW29iamVjdCBGbG9hdDY0QXJyYXldJyxcbiAgICBpbnQ4VGFnID0gJ1tvYmplY3QgSW50OEFycmF5XScsXG4gICAgaW50MTZUYWcgPSAnW29iamVjdCBJbnQxNkFycmF5XScsXG4gICAgaW50MzJUYWcgPSAnW29iamVjdCBJbnQzMkFycmF5XScsXG4gICAgdWludDhUYWcgPSAnW29iamVjdCBVaW50OEFycmF5XScsXG4gICAgdWludDhDbGFtcGVkVGFnID0gJ1tvYmplY3QgVWludDhDbGFtcGVkQXJyYXldJyxcbiAgICB1aW50MTZUYWcgPSAnW29iamVjdCBVaW50MTZBcnJheV0nLFxuICAgIHVpbnQzMlRhZyA9ICdbb2JqZWN0IFVpbnQzMkFycmF5XSc7XG5cbi8qKiBVc2VkIHRvIGlkZW50aWZ5IGB0b1N0cmluZ1RhZ2AgdmFsdWVzIHN1cHBvcnRlZCBieSBgXy5jbG9uZWAuICovXG52YXIgY2xvbmVhYmxlVGFncyA9IHt9O1xuY2xvbmVhYmxlVGFnc1thcmdzVGFnXSA9IGNsb25lYWJsZVRhZ3NbYXJyYXlUYWddID1cbmNsb25lYWJsZVRhZ3NbYXJyYXlCdWZmZXJUYWddID0gY2xvbmVhYmxlVGFnc1tib29sVGFnXSA9XG5jbG9uZWFibGVUYWdzW2RhdGVUYWddID0gY2xvbmVhYmxlVGFnc1tmbG9hdDMyVGFnXSA9XG5jbG9uZWFibGVUYWdzW2Zsb2F0NjRUYWddID0gY2xvbmVhYmxlVGFnc1tpbnQ4VGFnXSA9XG5jbG9uZWFibGVUYWdzW2ludDE2VGFnXSA9IGNsb25lYWJsZVRhZ3NbaW50MzJUYWddID1cbmNsb25lYWJsZVRhZ3NbbnVtYmVyVGFnXSA9IGNsb25lYWJsZVRhZ3Nbb2JqZWN0VGFnXSA9XG5jbG9uZWFibGVUYWdzW3JlZ2V4cFRhZ10gPSBjbG9uZWFibGVUYWdzW3N0cmluZ1RhZ10gPVxuY2xvbmVhYmxlVGFnc1t1aW50OFRhZ10gPSBjbG9uZWFibGVUYWdzW3VpbnQ4Q2xhbXBlZFRhZ10gPVxuY2xvbmVhYmxlVGFnc1t1aW50MTZUYWddID0gY2xvbmVhYmxlVGFnc1t1aW50MzJUYWddID0gdHJ1ZTtcbmNsb25lYWJsZVRhZ3NbZXJyb3JUYWddID0gY2xvbmVhYmxlVGFnc1tmdW5jVGFnXSA9XG5jbG9uZWFibGVUYWdzW21hcFRhZ10gPSBjbG9uZWFibGVUYWdzW3NldFRhZ10gPVxuY2xvbmVhYmxlVGFnc1t3ZWFrTWFwVGFnXSA9IGZhbHNlO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqVG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5jbG9uZWAgd2l0aG91dCBzdXBwb3J0IGZvciBhcmd1bWVudCBqdWdnbGluZ1xuICogYW5kIGB0aGlzYCBiaW5kaW5nIGBjdXN0b21pemVyYCBmdW5jdGlvbnMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNsb25lLlxuICogQHBhcmFtIHtib29sZWFufSBbaXNEZWVwXSBTcGVjaWZ5IGEgZGVlcCBjbG9uZS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNsb25pbmcgdmFsdWVzLlxuICogQHBhcmFtIHtzdHJpbmd9IFtrZXldIFRoZSBrZXkgb2YgYHZhbHVlYC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0XSBUaGUgb2JqZWN0IGB2YWx1ZWAgYmVsb25ncyB0by5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0E9W11dIFRyYWNrcyB0cmF2ZXJzZWQgc291cmNlIG9iamVjdHMuXG4gKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tCPVtdXSBBc3NvY2lhdGVzIGNsb25lcyB3aXRoIHNvdXJjZSBjb3VudGVycGFydHMuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgY2xvbmVkIHZhbHVlLlxuICovXG5mdW5jdGlvbiBiYXNlQ2xvbmUodmFsdWUsIGlzRGVlcCwgY3VzdG9taXplciwga2V5LCBvYmplY3QsIHN0YWNrQSwgc3RhY2tCKSB7XG4gIHZhciByZXN1bHQ7XG4gIGlmIChjdXN0b21pemVyKSB7XG4gICAgcmVzdWx0ID0gb2JqZWN0ID8gY3VzdG9taXplcih2YWx1ZSwga2V5LCBvYmplY3QpIDogY3VzdG9taXplcih2YWx1ZSk7XG4gIH1cbiAgaWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICBpZiAoIWlzT2JqZWN0KHZhbHVlKSkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuICB2YXIgaXNBcnIgPSBpc0FycmF5KHZhbHVlKTtcbiAgaWYgKGlzQXJyKSB7XG4gICAgcmVzdWx0ID0gaW5pdENsb25lQXJyYXkodmFsdWUpO1xuICAgIGlmICghaXNEZWVwKSB7XG4gICAgICByZXR1cm4gYXJyYXlDb3B5KHZhbHVlLCByZXN1bHQpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YXIgdGFnID0gb2JqVG9TdHJpbmcuY2FsbCh2YWx1ZSksXG4gICAgICAgIGlzRnVuYyA9IHRhZyA9PSBmdW5jVGFnO1xuXG4gICAgaWYgKHRhZyA9PSBvYmplY3RUYWcgfHwgdGFnID09IGFyZ3NUYWcgfHwgKGlzRnVuYyAmJiAhb2JqZWN0KSkge1xuICAgICAgaWYgKGlzSG9zdE9iamVjdCh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIG9iamVjdCA/IHZhbHVlIDoge307XG4gICAgICB9XG4gICAgICByZXN1bHQgPSBpbml0Q2xvbmVPYmplY3QoaXNGdW5jID8ge30gOiB2YWx1ZSk7XG4gICAgICBpZiAoIWlzRGVlcCkge1xuICAgICAgICByZXR1cm4gYmFzZUFzc2lnbihyZXN1bHQsIHZhbHVlKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGNsb25lYWJsZVRhZ3NbdGFnXVxuICAgICAgICA/IGluaXRDbG9uZUJ5VGFnKHZhbHVlLCB0YWcsIGlzRGVlcClcbiAgICAgICAgOiAob2JqZWN0ID8gdmFsdWUgOiB7fSk7XG4gICAgfVxuICB9XG4gIC8vIENoZWNrIGZvciBjaXJjdWxhciByZWZlcmVuY2VzIGFuZCByZXR1cm4gaXRzIGNvcnJlc3BvbmRpbmcgY2xvbmUuXG4gIHN0YWNrQSB8fCAoc3RhY2tBID0gW10pO1xuICBzdGFja0IgfHwgKHN0YWNrQiA9IFtdKTtcblxuICB2YXIgbGVuZ3RoID0gc3RhY2tBLmxlbmd0aDtcbiAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgaWYgKHN0YWNrQVtsZW5ndGhdID09IHZhbHVlKSB7XG4gICAgICByZXR1cm4gc3RhY2tCW2xlbmd0aF07XG4gICAgfVxuICB9XG4gIC8vIEFkZCB0aGUgc291cmNlIHZhbHVlIHRvIHRoZSBzdGFjayBvZiB0cmF2ZXJzZWQgb2JqZWN0cyBhbmQgYXNzb2NpYXRlIGl0IHdpdGggaXRzIGNsb25lLlxuICBzdGFja0EucHVzaCh2YWx1ZSk7XG4gIHN0YWNrQi5wdXNoKHJlc3VsdCk7XG5cbiAgLy8gUmVjdXJzaXZlbHkgcG9wdWxhdGUgY2xvbmUgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgKGlzQXJyID8gYXJyYXlFYWNoIDogYmFzZUZvck93bikodmFsdWUsIGZ1bmN0aW9uKHN1YlZhbHVlLCBrZXkpIHtcbiAgICByZXN1bHRba2V5XSA9IGJhc2VDbG9uZShzdWJWYWx1ZSwgaXNEZWVwLCBjdXN0b21pemVyLCBrZXksIHZhbHVlLCBzdGFja0EsIHN0YWNrQik7XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VDbG9uZTtcbiIsIi8qKlxuICogQ29waWVzIHByb3BlcnRpZXMgb2YgYHNvdXJjZWAgdG8gYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCB0byBjb3B5IHByb3BlcnRpZXMgZnJvbS5cbiAqIEBwYXJhbSB7QXJyYXl9IHByb3BzIFRoZSBwcm9wZXJ0eSBuYW1lcyB0byBjb3B5LlxuICogQHBhcmFtIHtPYmplY3R9IFtvYmplY3Q9e31dIFRoZSBvYmplY3QgdG8gY29weSBwcm9wZXJ0aWVzIHRvLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gYmFzZUNvcHkoc291cmNlLCBwcm9wcywgb2JqZWN0KSB7XG4gIG9iamVjdCB8fCAob2JqZWN0ID0ge30pO1xuXG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gcHJvcHMubGVuZ3RoO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgdmFyIGtleSA9IHByb3BzW2luZGV4XTtcbiAgICBvYmplY3Rba2V5XSA9IHNvdXJjZVtrZXldO1xuICB9XG4gIHJldHVybiBvYmplY3Q7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUNvcHk7XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uY3JlYXRlYCB3aXRob3V0IHN1cHBvcnQgZm9yIGFzc2lnbmluZ1xuICogcHJvcGVydGllcyB0byB0aGUgY3JlYXRlZCBvYmplY3QuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBwcm90b3R5cGUgVGhlIG9iamVjdCB0byBpbmhlcml0IGZyb20uXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgb2JqZWN0LlxuICovXG52YXIgYmFzZUNyZWF0ZSA9IChmdW5jdGlvbigpIHtcbiAgZnVuY3Rpb24gb2JqZWN0KCkge31cbiAgcmV0dXJuIGZ1bmN0aW9uKHByb3RvdHlwZSkge1xuICAgIGlmIChpc09iamVjdChwcm90b3R5cGUpKSB7XG4gICAgICBvYmplY3QucHJvdG90eXBlID0gcHJvdG90eXBlO1xuICAgICAgdmFyIHJlc3VsdCA9IG5ldyBvYmplY3Q7XG4gICAgICBvYmplY3QucHJvdG90eXBlID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0IHx8IHt9O1xuICB9O1xufSgpKTtcblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlQ3JlYXRlO1xuIiwidmFyIGJhc2VGb3JPd24gPSByZXF1aXJlKCcuL2Jhc2VGb3JPd24nKSxcbiAgICBjcmVhdGVCYXNlRWFjaCA9IHJlcXVpcmUoJy4vY3JlYXRlQmFzZUVhY2gnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mb3JFYWNoYCB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrXG4gKiBzaG9ydGhhbmRzIGFuZCBgdGhpc2AgYmluZGluZy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcmV0dXJucyB7QXJyYXl8T2JqZWN0fHN0cmluZ30gUmV0dXJucyBgY29sbGVjdGlvbmAuXG4gKi9cbnZhciBiYXNlRWFjaCA9IGNyZWF0ZUJhc2VFYWNoKGJhc2VGb3JPd24pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VFYWNoO1xuIiwiLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5maW5kYCwgYF8uZmluZExhc3RgLCBgXy5maW5kS2V5YCwgYW5kIGBfLmZpbmRMYXN0S2V5YCxcbiAqIHdpdGhvdXQgc3VwcG9ydCBmb3IgY2FsbGJhY2sgc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcsIHdoaWNoIGl0ZXJhdGVzXG4gKiBvdmVyIGBjb2xsZWN0aW9uYCB1c2luZyB0aGUgcHJvdmlkZWQgYGVhY2hGdW5jYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIHNlYXJjaC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZWFjaEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGl0ZXJhdGUgb3ZlciBgY29sbGVjdGlvbmAuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtyZXRLZXldIFNwZWNpZnkgcmV0dXJuaW5nIHRoZSBrZXkgb2YgdGhlIGZvdW5kIGVsZW1lbnRcbiAqICBpbnN0ZWFkIG9mIHRoZSBlbGVtZW50IGl0c2VsZi5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBmb3VuZCBlbGVtZW50IG9yIGl0cyBrZXksIGVsc2UgYHVuZGVmaW5lZGAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VGaW5kKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSwgZWFjaEZ1bmMsIHJldEtleSkge1xuICB2YXIgcmVzdWx0O1xuICBlYWNoRnVuYyhjb2xsZWN0aW9uLCBmdW5jdGlvbih2YWx1ZSwga2V5LCBjb2xsZWN0aW9uKSB7XG4gICAgaWYgKHByZWRpY2F0ZSh2YWx1ZSwga2V5LCBjb2xsZWN0aW9uKSkge1xuICAgICAgcmVzdWx0ID0gcmV0S2V5ID8ga2V5IDogdmFsdWU7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlRmluZDtcbiIsIi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZmluZEluZGV4YCBhbmQgYF8uZmluZExhc3RJbmRleGAgd2l0aG91dFxuICogc3VwcG9ydCBmb3IgY2FsbGJhY2sgc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBzZWFyY2guXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIG1hdGNoZWQgdmFsdWUsIGVsc2UgYC0xYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUZpbmRJbmRleChhcnJheSwgcHJlZGljYXRlLCBmcm9tUmlnaHQpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIGluZGV4ID0gZnJvbVJpZ2h0ID8gbGVuZ3RoIDogLTE7XG5cbiAgd2hpbGUgKChmcm9tUmlnaHQgPyBpbmRleC0tIDogKytpbmRleCA8IGxlbmd0aCkpIHtcbiAgICBpZiAocHJlZGljYXRlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KSkge1xuICAgICAgcmV0dXJuIGluZGV4O1xuICAgIH1cbiAgfVxuICByZXR1cm4gLTE7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUZpbmRJbmRleDtcbiIsInZhciBjcmVhdGVCYXNlRm9yID0gcmVxdWlyZSgnLi9jcmVhdGVCYXNlRm9yJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGJhc2VGb3JJbmAgYW5kIGBiYXNlRm9yT3duYCB3aGljaCBpdGVyYXRlc1xuICogb3ZlciBgb2JqZWN0YCBwcm9wZXJ0aWVzIHJldHVybmVkIGJ5IGBrZXlzRnVuY2AgaW52b2tpbmcgYGl0ZXJhdGVlYCBmb3JcbiAqIGVhY2ggcHJvcGVydHkuIEl0ZXJhdGVlIGZ1bmN0aW9ucyBtYXkgZXhpdCBpdGVyYXRpb24gZWFybHkgYnkgZXhwbGljaXRseVxuICogcmV0dXJuaW5nIGBmYWxzZWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHBhcmFtIHtGdW5jdGlvbn0ga2V5c0Z1bmMgVGhlIGZ1bmN0aW9uIHRvIGdldCB0aGUga2V5cyBvZiBgb2JqZWN0YC5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gKi9cbnZhciBiYXNlRm9yID0gY3JlYXRlQmFzZUZvcigpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VGb3I7XG4iLCJ2YXIgYmFzZUZvciA9IHJlcXVpcmUoJy4vYmFzZUZvcicpLFxuICAgIGtleXNJbiA9IHJlcXVpcmUoJy4uL29iamVjdC9rZXlzSW4nKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mb3JJbmAgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gYmFzZUZvckluKG9iamVjdCwgaXRlcmF0ZWUpIHtcbiAgcmV0dXJuIGJhc2VGb3Iob2JqZWN0LCBpdGVyYXRlZSwga2V5c0luKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlRm9ySW47XG4iLCJ2YXIgYmFzZUZvciA9IHJlcXVpcmUoJy4vYmFzZUZvcicpLFxuICAgIGtleXMgPSByZXF1aXJlKCcuLi9vYmplY3Qva2V5cycpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZvck93bmAgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gYmFzZUZvck93bihvYmplY3QsIGl0ZXJhdGVlKSB7XG4gIHJldHVybiBiYXNlRm9yKG9iamVjdCwgaXRlcmF0ZWUsIGtleXMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VGb3JPd247XG4iLCJ2YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL3RvT2JqZWN0Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGdldGAgd2l0aG91dCBzdXBwb3J0IGZvciBzdHJpbmcgcGF0aHNcbiAqIGFuZCBkZWZhdWx0IHZhbHVlcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHBhcmFtIHtBcnJheX0gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHBhcmFtIHtzdHJpbmd9IFtwYXRoS2V5XSBUaGUga2V5IHJlcHJlc2VudGF0aW9uIG9mIHBhdGguXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcmVzb2x2ZWQgdmFsdWUuXG4gKi9cbmZ1bmN0aW9uIGJhc2VHZXQob2JqZWN0LCBwYXRoLCBwYXRoS2V5KSB7XG4gIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgIHJldHVybjtcbiAgfVxuICBvYmplY3QgPSB0b09iamVjdChvYmplY3QpO1xuICBpZiAocGF0aEtleSAhPT0gdW5kZWZpbmVkICYmIHBhdGhLZXkgaW4gb2JqZWN0KSB7XG4gICAgcGF0aCA9IFtwYXRoS2V5XTtcbiAgfVxuICB2YXIgaW5kZXggPSAwLFxuICAgICAgbGVuZ3RoID0gcGF0aC5sZW5ndGg7XG5cbiAgd2hpbGUgKG9iamVjdCAhPSBudWxsICYmIGluZGV4IDwgbGVuZ3RoKSB7XG4gICAgb2JqZWN0ID0gdG9PYmplY3Qob2JqZWN0KVtwYXRoW2luZGV4KytdXTtcbiAgfVxuICByZXR1cm4gKGluZGV4ICYmIGluZGV4ID09IGxlbmd0aCkgPyBvYmplY3QgOiB1bmRlZmluZWQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUdldDtcbiIsInZhciBpbmRleE9mTmFOID0gcmVxdWlyZSgnLi9pbmRleE9mTmFOJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaW5kZXhPZmAgd2l0aG91dCBzdXBwb3J0IGZvciBiaW5hcnkgc2VhcmNoZXMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBzZWFyY2guXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICogQHBhcmFtIHtudW1iZXJ9IGZyb21JbmRleCBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICovXG5mdW5jdGlvbiBiYXNlSW5kZXhPZihhcnJheSwgdmFsdWUsIGZyb21JbmRleCkge1xuICBpZiAodmFsdWUgIT09IHZhbHVlKSB7XG4gICAgcmV0dXJuIGluZGV4T2ZOYU4oYXJyYXksIGZyb21JbmRleCk7XG4gIH1cbiAgdmFyIGluZGV4ID0gZnJvbUluZGV4IC0gMSxcbiAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIGlmIChhcnJheVtpbmRleF0gPT09IHZhbHVlKSB7XG4gICAgICByZXR1cm4gaW5kZXg7XG4gICAgfVxuICB9XG4gIHJldHVybiAtMTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSW5kZXhPZjtcbiIsInZhciBiYXNlSXNFcXVhbERlZXAgPSByZXF1aXJlKCcuL2Jhc2VJc0VxdWFsRGVlcCcpLFxuICAgIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vbGFuZy9pc09iamVjdCcpLFxuICAgIGlzT2JqZWN0TGlrZSA9IHJlcXVpcmUoJy4vaXNPYmplY3RMaWtlJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNFcXVhbGAgd2l0aG91dCBzdXBwb3J0IGZvciBgdGhpc2AgYmluZGluZ1xuICogYGN1c3RvbWl6ZXJgIGZ1bmN0aW9ucy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpbmcgdmFsdWVzLlxuICogQHBhcmFtIHtib29sZWFufSBbaXNMb29zZV0gU3BlY2lmeSBwZXJmb3JtaW5nIHBhcnRpYWwgY29tcGFyaXNvbnMuXG4gKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tBXSBUcmFja3MgdHJhdmVyc2VkIGB2YWx1ZWAgb2JqZWN0cy5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0JdIFRyYWNrcyB0cmF2ZXJzZWQgYG90aGVyYCBvYmplY3RzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUlzRXF1YWwodmFsdWUsIG90aGVyLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQikge1xuICBpZiAodmFsdWUgPT09IG90aGVyKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKHZhbHVlID09IG51bGwgfHwgb3RoZXIgPT0gbnVsbCB8fCAoIWlzT2JqZWN0KHZhbHVlKSAmJiAhaXNPYmplY3RMaWtlKG90aGVyKSkpIHtcbiAgICByZXR1cm4gdmFsdWUgIT09IHZhbHVlICYmIG90aGVyICE9PSBvdGhlcjtcbiAgfVxuICByZXR1cm4gYmFzZUlzRXF1YWxEZWVwKHZhbHVlLCBvdGhlciwgYmFzZUlzRXF1YWwsIGN1c3RvbWl6ZXIsIGlzTG9vc2UsIHN0YWNrQSwgc3RhY2tCKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNFcXVhbDtcbiIsInZhciBlcXVhbEFycmF5cyA9IHJlcXVpcmUoJy4vZXF1YWxBcnJheXMnKSxcbiAgICBlcXVhbEJ5VGFnID0gcmVxdWlyZSgnLi9lcXVhbEJ5VGFnJyksXG4gICAgZXF1YWxPYmplY3RzID0gcmVxdWlyZSgnLi9lcXVhbE9iamVjdHMnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FycmF5JyksXG4gICAgaXNIb3N0T2JqZWN0ID0gcmVxdWlyZSgnLi9pc0hvc3RPYmplY3QnKSxcbiAgICBpc1R5cGVkQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzVHlwZWRBcnJheScpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgYXJnc1RhZyA9ICdbb2JqZWN0IEFyZ3VtZW50c10nLFxuICAgIGFycmF5VGFnID0gJ1tvYmplY3QgQXJyYXldJyxcbiAgICBvYmplY3RUYWcgPSAnW29iamVjdCBPYmplY3RdJztcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9ialRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlSXNFcXVhbGAgZm9yIGFycmF5cyBhbmQgb2JqZWN0cyB3aGljaCBwZXJmb3Jtc1xuICogZGVlcCBjb21wYXJpc29ucyBhbmQgdHJhY2tzIHRyYXZlcnNlZCBvYmplY3RzIGVuYWJsaW5nIG9iamVjdHMgd2l0aCBjaXJjdWxhclxuICogcmVmZXJlbmNlcyB0byBiZSBjb21wYXJlZC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge09iamVjdH0gb3RoZXIgVGhlIG90aGVyIG9iamVjdCB0byBjb21wYXJlLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaW5nIG9iamVjdHMuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpc0xvb3NlXSBTcGVjaWZ5IHBlcmZvcm1pbmcgcGFydGlhbCBjb21wYXJpc29ucy5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0E9W11dIFRyYWNrcyB0cmF2ZXJzZWQgYHZhbHVlYCBvYmplY3RzLlxuICogQHBhcmFtIHtBcnJheX0gW3N0YWNrQj1bXV0gVHJhY2tzIHRyYXZlcnNlZCBgb3RoZXJgIG9iamVjdHMuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG9iamVjdHMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUlzRXF1YWxEZWVwKG9iamVjdCwgb3RoZXIsIGVxdWFsRnVuYywgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpIHtcbiAgdmFyIG9iaklzQXJyID0gaXNBcnJheShvYmplY3QpLFxuICAgICAgb3RoSXNBcnIgPSBpc0FycmF5KG90aGVyKSxcbiAgICAgIG9ialRhZyA9IGFycmF5VGFnLFxuICAgICAgb3RoVGFnID0gYXJyYXlUYWc7XG5cbiAgaWYgKCFvYmpJc0Fycikge1xuICAgIG9ialRhZyA9IG9ialRvU3RyaW5nLmNhbGwob2JqZWN0KTtcbiAgICBpZiAob2JqVGFnID09IGFyZ3NUYWcpIHtcbiAgICAgIG9ialRhZyA9IG9iamVjdFRhZztcbiAgICB9IGVsc2UgaWYgKG9ialRhZyAhPSBvYmplY3RUYWcpIHtcbiAgICAgIG9iaklzQXJyID0gaXNUeXBlZEFycmF5KG9iamVjdCk7XG4gICAgfVxuICB9XG4gIGlmICghb3RoSXNBcnIpIHtcbiAgICBvdGhUYWcgPSBvYmpUb1N0cmluZy5jYWxsKG90aGVyKTtcbiAgICBpZiAob3RoVGFnID09IGFyZ3NUYWcpIHtcbiAgICAgIG90aFRhZyA9IG9iamVjdFRhZztcbiAgICB9IGVsc2UgaWYgKG90aFRhZyAhPSBvYmplY3RUYWcpIHtcbiAgICAgIG90aElzQXJyID0gaXNUeXBlZEFycmF5KG90aGVyKTtcbiAgICB9XG4gIH1cbiAgdmFyIG9iaklzT2JqID0gb2JqVGFnID09IG9iamVjdFRhZyAmJiAhaXNIb3N0T2JqZWN0KG9iamVjdCksXG4gICAgICBvdGhJc09iaiA9IG90aFRhZyA9PSBvYmplY3RUYWcgJiYgIWlzSG9zdE9iamVjdChvdGhlciksXG4gICAgICBpc1NhbWVUYWcgPSBvYmpUYWcgPT0gb3RoVGFnO1xuXG4gIGlmIChpc1NhbWVUYWcgJiYgIShvYmpJc0FyciB8fCBvYmpJc09iaikpIHtcbiAgICByZXR1cm4gZXF1YWxCeVRhZyhvYmplY3QsIG90aGVyLCBvYmpUYWcpO1xuICB9XG4gIGlmICghaXNMb29zZSkge1xuICAgIHZhciBvYmpJc1dyYXBwZWQgPSBvYmpJc09iaiAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgJ19fd3JhcHBlZF9fJyksXG4gICAgICAgIG90aElzV3JhcHBlZCA9IG90aElzT2JqICYmIGhhc093blByb3BlcnR5LmNhbGwob3RoZXIsICdfX3dyYXBwZWRfXycpO1xuXG4gICAgaWYgKG9iaklzV3JhcHBlZCB8fCBvdGhJc1dyYXBwZWQpIHtcbiAgICAgIHJldHVybiBlcXVhbEZ1bmMob2JqSXNXcmFwcGVkID8gb2JqZWN0LnZhbHVlKCkgOiBvYmplY3QsIG90aElzV3JhcHBlZCA/IG90aGVyLnZhbHVlKCkgOiBvdGhlciwgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpO1xuICAgIH1cbiAgfVxuICBpZiAoIWlzU2FtZVRhZykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICAvLyBBc3N1bWUgY3ljbGljIHZhbHVlcyBhcmUgZXF1YWwuXG4gIC8vIEZvciBtb3JlIGluZm9ybWF0aW9uIG9uIGRldGVjdGluZyBjaXJjdWxhciByZWZlcmVuY2VzIHNlZSBodHRwczovL2VzNS5naXRodWIuaW8vI0pPLlxuICBzdGFja0EgfHwgKHN0YWNrQSA9IFtdKTtcbiAgc3RhY2tCIHx8IChzdGFja0IgPSBbXSk7XG5cbiAgdmFyIGxlbmd0aCA9IHN0YWNrQS5sZW5ndGg7XG4gIHdoaWxlIChsZW5ndGgtLSkge1xuICAgIGlmIChzdGFja0FbbGVuZ3RoXSA9PSBvYmplY3QpIHtcbiAgICAgIHJldHVybiBzdGFja0JbbGVuZ3RoXSA9PSBvdGhlcjtcbiAgICB9XG4gIH1cbiAgLy8gQWRkIGBvYmplY3RgIGFuZCBgb3RoZXJgIHRvIHRoZSBzdGFjayBvZiB0cmF2ZXJzZWQgb2JqZWN0cy5cbiAgc3RhY2tBLnB1c2gob2JqZWN0KTtcbiAgc3RhY2tCLnB1c2gob3RoZXIpO1xuXG4gIHZhciByZXN1bHQgPSAob2JqSXNBcnIgPyBlcXVhbEFycmF5cyA6IGVxdWFsT2JqZWN0cykob2JqZWN0LCBvdGhlciwgZXF1YWxGdW5jLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQik7XG5cbiAgc3RhY2tBLnBvcCgpO1xuICBzdGFja0IucG9wKCk7XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNFcXVhbERlZXA7XG4iLCJ2YXIgYmFzZUlzRXF1YWwgPSByZXF1aXJlKCcuL2Jhc2VJc0VxdWFsJyksXG4gICAgdG9PYmplY3QgPSByZXF1aXJlKCcuL3RvT2JqZWN0Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNNYXRjaGAgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnNwZWN0LlxuICogQHBhcmFtIHtBcnJheX0gbWF0Y2hEYXRhIFRoZSBwcm9wZXJ5IG5hbWVzLCB2YWx1ZXMsIGFuZCBjb21wYXJlIGZsYWdzIHRvIG1hdGNoLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaW5nIG9iamVjdHMuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYG9iamVjdGAgaXMgYSBtYXRjaCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBiYXNlSXNNYXRjaChvYmplY3QsIG1hdGNoRGF0YSwgY3VzdG9taXplcikge1xuICB2YXIgaW5kZXggPSBtYXRjaERhdGEubGVuZ3RoLFxuICAgICAgbGVuZ3RoID0gaW5kZXgsXG4gICAgICBub0N1c3RvbWl6ZXIgPSAhY3VzdG9taXplcjtcblxuICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICByZXR1cm4gIWxlbmd0aDtcbiAgfVxuICBvYmplY3QgPSB0b09iamVjdChvYmplY3QpO1xuICB3aGlsZSAoaW5kZXgtLSkge1xuICAgIHZhciBkYXRhID0gbWF0Y2hEYXRhW2luZGV4XTtcbiAgICBpZiAoKG5vQ3VzdG9taXplciAmJiBkYXRhWzJdKVxuICAgICAgICAgID8gZGF0YVsxXSAhPT0gb2JqZWN0W2RhdGFbMF1dXG4gICAgICAgICAgOiAhKGRhdGFbMF0gaW4gb2JqZWN0KVxuICAgICAgICApIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBkYXRhID0gbWF0Y2hEYXRhW2luZGV4XTtcbiAgICB2YXIga2V5ID0gZGF0YVswXSxcbiAgICAgICAgb2JqVmFsdWUgPSBvYmplY3Rba2V5XSxcbiAgICAgICAgc3JjVmFsdWUgPSBkYXRhWzFdO1xuXG4gICAgaWYgKG5vQ3VzdG9taXplciAmJiBkYXRhWzJdKSB7XG4gICAgICBpZiAob2JqVmFsdWUgPT09IHVuZGVmaW5lZCAmJiAhKGtleSBpbiBvYmplY3QpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHJlc3VsdCA9IGN1c3RvbWl6ZXIgPyBjdXN0b21pemVyKG9ialZhbHVlLCBzcmNWYWx1ZSwga2V5KSA6IHVuZGVmaW5lZDtcbiAgICAgIGlmICghKHJlc3VsdCA9PT0gdW5kZWZpbmVkID8gYmFzZUlzRXF1YWwoc3JjVmFsdWUsIG9ialZhbHVlLCBjdXN0b21pemVyLCB0cnVlKSA6IHJlc3VsdCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNNYXRjaDtcbiIsIi8qKlxuICogVGhlIGZ1bmN0aW9uIHdob3NlIHByb3RvdHlwZSBhbGwgY2hhaW5pbmcgd3JhcHBlcnMgaW5oZXJpdCBmcm9tLlxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGJhc2VMb2Rhc2goKSB7XG4gIC8vIE5vIG9wZXJhdGlvbiBwZXJmb3JtZWQuXG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUxvZGFzaDtcbiIsInZhciBiYXNlRWFjaCA9IHJlcXVpcmUoJy4vYmFzZUVhY2gnKSxcbiAgICBpc0FycmF5TGlrZSA9IHJlcXVpcmUoJy4vaXNBcnJheUxpa2UnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5tYXBgIHdpdGhvdXQgc3VwcG9ydCBmb3IgY2FsbGJhY2sgc2hvcnRoYW5kc1xuICogYW5kIGB0aGlzYCBiaW5kaW5nLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IG1hcHBlZCBhcnJheS5cbiAqL1xuZnVuY3Rpb24gYmFzZU1hcChjb2xsZWN0aW9uLCBpdGVyYXRlZSkge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIHJlc3VsdCA9IGlzQXJyYXlMaWtlKGNvbGxlY3Rpb24pID8gQXJyYXkoY29sbGVjdGlvbi5sZW5ndGgpIDogW107XG5cbiAgYmFzZUVhY2goY29sbGVjdGlvbiwgZnVuY3Rpb24odmFsdWUsIGtleSwgY29sbGVjdGlvbikge1xuICAgIHJlc3VsdFsrK2luZGV4XSA9IGl0ZXJhdGVlKHZhbHVlLCBrZXksIGNvbGxlY3Rpb24pO1xuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlTWFwO1xuIiwidmFyIGJhc2VJc01hdGNoID0gcmVxdWlyZSgnLi9iYXNlSXNNYXRjaCcpLFxuICAgIGdldE1hdGNoRGF0YSA9IHJlcXVpcmUoJy4vZ2V0TWF0Y2hEYXRhJyksXG4gICAgdG9PYmplY3QgPSByZXF1aXJlKCcuL3RvT2JqZWN0Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ubWF0Y2hlc2Agd2hpY2ggZG9lcyBub3QgY2xvbmUgYHNvdXJjZWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCBvZiBwcm9wZXJ0eSB2YWx1ZXMgdG8gbWF0Y2guXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gYmFzZU1hdGNoZXMoc291cmNlKSB7XG4gIHZhciBtYXRjaERhdGEgPSBnZXRNYXRjaERhdGEoc291cmNlKTtcbiAgaWYgKG1hdGNoRGF0YS5sZW5ndGggPT0gMSAmJiBtYXRjaERhdGFbMF1bMl0pIHtcbiAgICB2YXIga2V5ID0gbWF0Y2hEYXRhWzBdWzBdLFxuICAgICAgICB2YWx1ZSA9IG1hdGNoRGF0YVswXVsxXTtcblxuICAgIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICAgIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBvYmplY3QgPSB0b09iamVjdChvYmplY3QpO1xuICAgICAgcmV0dXJuIG9iamVjdFtrZXldID09PSB2YWx1ZSAmJiAodmFsdWUgIT09IHVuZGVmaW5lZCB8fCAoa2V5IGluIG9iamVjdCkpO1xuICAgIH07XG4gIH1cbiAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIHJldHVybiBiYXNlSXNNYXRjaChvYmplY3QsIG1hdGNoRGF0YSk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZU1hdGNoZXM7XG4iLCJ2YXIgYmFzZUdldCA9IHJlcXVpcmUoJy4vYmFzZUdldCcpLFxuICAgIGJhc2VJc0VxdWFsID0gcmVxdWlyZSgnLi9iYXNlSXNFcXVhbCcpLFxuICAgIGJhc2VTbGljZSA9IHJlcXVpcmUoJy4vYmFzZVNsaWNlJyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4uL2xhbmcvaXNBcnJheScpLFxuICAgIGlzS2V5ID0gcmVxdWlyZSgnLi9pc0tleScpLFxuICAgIGlzU3RyaWN0Q29tcGFyYWJsZSA9IHJlcXVpcmUoJy4vaXNTdHJpY3RDb21wYXJhYmxlJyksXG4gICAgbGFzdCA9IHJlcXVpcmUoJy4uL2FycmF5L2xhc3QnKSxcbiAgICB0b09iamVjdCA9IHJlcXVpcmUoJy4vdG9PYmplY3QnKSxcbiAgICB0b1BhdGggPSByZXF1aXJlKCcuL3RvUGF0aCcpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm1hdGNoZXNQcm9wZXJ0eWAgd2hpY2ggZG9lcyBub3QgY2xvbmUgYHNyY1ZhbHVlYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIGdldC5cbiAqIEBwYXJhbSB7Kn0gc3JjVmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gYmFzZU1hdGNoZXNQcm9wZXJ0eShwYXRoLCBzcmNWYWx1ZSkge1xuICB2YXIgaXNBcnIgPSBpc0FycmF5KHBhdGgpLFxuICAgICAgaXNDb21tb24gPSBpc0tleShwYXRoKSAmJiBpc1N0cmljdENvbXBhcmFibGUoc3JjVmFsdWUpLFxuICAgICAgcGF0aEtleSA9IChwYXRoICsgJycpO1xuXG4gIHBhdGggPSB0b1BhdGgocGF0aCk7XG4gIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdmFyIGtleSA9IHBhdGhLZXk7XG4gICAgb2JqZWN0ID0gdG9PYmplY3Qob2JqZWN0KTtcbiAgICBpZiAoKGlzQXJyIHx8ICFpc0NvbW1vbikgJiYgIShrZXkgaW4gb2JqZWN0KSkge1xuICAgICAgb2JqZWN0ID0gcGF0aC5sZW5ndGggPT0gMSA/IG9iamVjdCA6IGJhc2VHZXQob2JqZWN0LCBiYXNlU2xpY2UocGF0aCwgMCwgLTEpKTtcbiAgICAgIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBrZXkgPSBsYXN0KHBhdGgpO1xuICAgICAgb2JqZWN0ID0gdG9PYmplY3Qob2JqZWN0KTtcbiAgICB9XG4gICAgcmV0dXJuIG9iamVjdFtrZXldID09PSBzcmNWYWx1ZVxuICAgICAgPyAoc3JjVmFsdWUgIT09IHVuZGVmaW5lZCB8fCAoa2V5IGluIG9iamVjdCkpXG4gICAgICA6IGJhc2VJc0VxdWFsKHNyY1ZhbHVlLCBvYmplY3Rba2V5XSwgdW5kZWZpbmVkLCB0cnVlKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlTWF0Y2hlc1Byb3BlcnR5O1xuIiwidmFyIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi90b09iamVjdCcpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnByb3BlcnR5YCB3aXRob3V0IHN1cHBvcnQgZm9yIGRlZXAgcGF0aHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGJhc2VQcm9wZXJ0eShrZXkpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IHRvT2JqZWN0KG9iamVjdClba2V5XTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlUHJvcGVydHk7XG4iLCJ2YXIgYmFzZUdldCA9IHJlcXVpcmUoJy4vYmFzZUdldCcpLFxuICAgIHRvUGF0aCA9IHJlcXVpcmUoJy4vdG9QYXRoJyk7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlUHJvcGVydHlgIHdoaWNoIHN1cHBvcnRzIGRlZXAgcGF0aHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gYmFzZVByb3BlcnR5RGVlcChwYXRoKSB7XG4gIHZhciBwYXRoS2V5ID0gKHBhdGggKyAnJyk7XG4gIHBhdGggPSB0b1BhdGgocGF0aCk7XG4gIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICByZXR1cm4gYmFzZUdldChvYmplY3QsIHBhdGgsIHBhdGhLZXkpO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VQcm9wZXJ0eURlZXA7XG4iLCJ2YXIgaWRlbnRpdHkgPSByZXF1aXJlKCcuLi91dGlsaXR5L2lkZW50aXR5JyksXG4gICAgbWV0YU1hcCA9IHJlcXVpcmUoJy4vbWV0YU1hcCcpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBzZXREYXRhYCB3aXRob3V0IHN1cHBvcnQgZm9yIGhvdCBsb29wIGRldGVjdGlvbi5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gYXNzb2NpYXRlIG1ldGFkYXRhIHdpdGguXG4gKiBAcGFyYW0geyp9IGRhdGEgVGhlIG1ldGFkYXRhLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIGBmdW5jYC5cbiAqL1xudmFyIGJhc2VTZXREYXRhID0gIW1ldGFNYXAgPyBpZGVudGl0eSA6IGZ1bmN0aW9uKGZ1bmMsIGRhdGEpIHtcbiAgbWV0YU1hcC5zZXQoZnVuYywgZGF0YSk7XG4gIHJldHVybiBmdW5jO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlU2V0RGF0YTtcbiIsIi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uc2xpY2VgIHdpdGhvdXQgYW4gaXRlcmF0ZWUgY2FsbCBndWFyZC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNsaWNlLlxuICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD0wXSBUaGUgc3RhcnQgcG9zaXRpb24uXG4gKiBAcGFyYW0ge251bWJlcn0gW2VuZD1hcnJheS5sZW5ndGhdIFRoZSBlbmQgcG9zaXRpb24uXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHNsaWNlIG9mIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VTbGljZShhcnJheSwgc3RhcnQsIGVuZCkge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICBzdGFydCA9IHN0YXJ0ID09IG51bGwgPyAwIDogKCtzdGFydCB8fCAwKTtcbiAgaWYgKHN0YXJ0IDwgMCkge1xuICAgIHN0YXJ0ID0gLXN0YXJ0ID4gbGVuZ3RoID8gMCA6IChsZW5ndGggKyBzdGFydCk7XG4gIH1cbiAgZW5kID0gKGVuZCA9PT0gdW5kZWZpbmVkIHx8IGVuZCA+IGxlbmd0aCkgPyBsZW5ndGggOiAoK2VuZCB8fCAwKTtcbiAgaWYgKGVuZCA8IDApIHtcbiAgICBlbmQgKz0gbGVuZ3RoO1xuICB9XG4gIGxlbmd0aCA9IHN0YXJ0ID4gZW5kID8gMCA6ICgoZW5kIC0gc3RhcnQpID4+PiAwKTtcbiAgc3RhcnQgPj4+PSAwO1xuXG4gIHZhciByZXN1bHQgPSBBcnJheShsZW5ndGgpO1xuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHJlc3VsdFtpbmRleF0gPSBhcnJheVtpbmRleCArIHN0YXJ0XTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VTbGljZTtcbiIsIi8qKlxuICogQ29udmVydHMgYHZhbHVlYCB0byBhIHN0cmluZyBpZiBpdCdzIG5vdCBvbmUuIEFuIGVtcHR5IHN0cmluZyBpcyByZXR1cm5lZFxuICogZm9yIGBudWxsYCBvciBgdW5kZWZpbmVkYCB2YWx1ZXMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHByb2Nlc3MuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBzdHJpbmcuXG4gKi9cbmZ1bmN0aW9uIGJhc2VUb1N0cmluZyh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgPT0gbnVsbCA/ICcnIDogKHZhbHVlICsgJycpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VUb1N0cmluZztcbiIsIi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8udmFsdWVzYCBhbmQgYF8udmFsdWVzSW5gIHdoaWNoIGNyZWF0ZXMgYW5cbiAqIGFycmF5IG9mIGBvYmplY3RgIHByb3BlcnR5IHZhbHVlcyBjb3JyZXNwb25kaW5nIHRvIHRoZSBwcm9wZXJ0eSBuYW1lc1xuICogb2YgYHByb3BzYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHBhcmFtIHtBcnJheX0gcHJvcHMgVGhlIHByb3BlcnR5IG5hbWVzIHRvIGdldCB2YWx1ZXMgZm9yLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgdmFsdWVzLlxuICovXG5mdW5jdGlvbiBiYXNlVmFsdWVzKG9iamVjdCwgcHJvcHMpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBwcm9wcy5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBBcnJheShsZW5ndGgpO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgcmVzdWx0W2luZGV4XSA9IG9iamVjdFtwcm9wc1tpbmRleF1dO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZVZhbHVlcztcbiIsInZhciBiaW5hcnlJbmRleEJ5ID0gcmVxdWlyZSgnLi9iaW5hcnlJbmRleEJ5JyksXG4gICAgaWRlbnRpdHkgPSByZXF1aXJlKCcuLi91dGlsaXR5L2lkZW50aXR5Jyk7XG5cbi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHRoZSBtYXhpbXVtIGxlbmd0aCBhbmQgaW5kZXggb2YgYW4gYXJyYXkuICovXG52YXIgTUFYX0FSUkFZX0xFTkdUSCA9IDQyOTQ5NjcyOTUsXG4gICAgSEFMRl9NQVhfQVJSQVlfTEVOR1RIID0gTUFYX0FSUkFZX0xFTkdUSCA+Pj4gMTtcblxuLyoqXG4gKiBQZXJmb3JtcyBhIGJpbmFyeSBzZWFyY2ggb2YgYGFycmF5YCB0byBkZXRlcm1pbmUgdGhlIGluZGV4IGF0IHdoaWNoIGB2YWx1ZWBcbiAqIHNob3VsZCBiZSBpbnNlcnRlZCBpbnRvIGBhcnJheWAgaW4gb3JkZXIgdG8gbWFpbnRhaW4gaXRzIHNvcnQgb3JkZXIuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBzb3J0ZWQgYXJyYXkgdG8gaW5zcGVjdC5cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGV2YWx1YXRlLlxuICogQHBhcmFtIHtib29sZWFufSBbcmV0SGlnaGVzdF0gU3BlY2lmeSByZXR1cm5pbmcgdGhlIGhpZ2hlc3QgcXVhbGlmaWVkIGluZGV4LlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggYXQgd2hpY2ggYHZhbHVlYCBzaG91bGQgYmUgaW5zZXJ0ZWRcbiAqICBpbnRvIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGJpbmFyeUluZGV4KGFycmF5LCB2YWx1ZSwgcmV0SGlnaGVzdCkge1xuICB2YXIgbG93ID0gMCxcbiAgICAgIGhpZ2ggPSBhcnJheSA/IGFycmF5Lmxlbmd0aCA6IGxvdztcblxuICBpZiAodHlwZW9mIHZhbHVlID09ICdudW1iZXInICYmIHZhbHVlID09PSB2YWx1ZSAmJiBoaWdoIDw9IEhBTEZfTUFYX0FSUkFZX0xFTkdUSCkge1xuICAgIHdoaWxlIChsb3cgPCBoaWdoKSB7XG4gICAgICB2YXIgbWlkID0gKGxvdyArIGhpZ2gpID4+PiAxLFxuICAgICAgICAgIGNvbXB1dGVkID0gYXJyYXlbbWlkXTtcblxuICAgICAgaWYgKChyZXRIaWdoZXN0ID8gKGNvbXB1dGVkIDw9IHZhbHVlKSA6IChjb21wdXRlZCA8IHZhbHVlKSkgJiYgY29tcHV0ZWQgIT09IG51bGwpIHtcbiAgICAgICAgbG93ID0gbWlkICsgMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGhpZ2ggPSBtaWQ7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBoaWdoO1xuICB9XG4gIHJldHVybiBiaW5hcnlJbmRleEJ5KGFycmF5LCB2YWx1ZSwgaWRlbnRpdHksIHJldEhpZ2hlc3QpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJpbmFyeUluZGV4O1xuIiwiLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVGbG9vciA9IE1hdGguZmxvb3IsXG4gICAgbmF0aXZlTWluID0gTWF0aC5taW47XG5cbi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHRoZSBtYXhpbXVtIGxlbmd0aCBhbmQgaW5kZXggb2YgYW4gYXJyYXkuICovXG52YXIgTUFYX0FSUkFZX0xFTkdUSCA9IDQyOTQ5NjcyOTUsXG4gICAgTUFYX0FSUkFZX0lOREVYID0gTUFYX0FSUkFZX0xFTkdUSCAtIDE7XG5cbi8qKlxuICogVGhpcyBmdW5jdGlvbiBpcyBsaWtlIGBiaW5hcnlJbmRleGAgZXhjZXB0IHRoYXQgaXQgaW52b2tlcyBgaXRlcmF0ZWVgIGZvclxuICogYHZhbHVlYCBhbmQgZWFjaCBlbGVtZW50IG9mIGBhcnJheWAgdG8gY29tcHV0ZSB0aGVpciBzb3J0IHJhbmtpbmcuIFRoZVxuICogaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDsgKHZhbHVlKS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIHNvcnRlZCBhcnJheSB0byBpbnNwZWN0LlxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gZXZhbHVhdGUuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHBhcmFtIHtib29sZWFufSBbcmV0SGlnaGVzdF0gU3BlY2lmeSByZXR1cm5pbmcgdGhlIGhpZ2hlc3QgcXVhbGlmaWVkIGluZGV4LlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggYXQgd2hpY2ggYHZhbHVlYCBzaG91bGQgYmUgaW5zZXJ0ZWRcbiAqICBpbnRvIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGJpbmFyeUluZGV4QnkoYXJyYXksIHZhbHVlLCBpdGVyYXRlZSwgcmV0SGlnaGVzdCkge1xuICB2YWx1ZSA9IGl0ZXJhdGVlKHZhbHVlKTtcblxuICB2YXIgbG93ID0gMCxcbiAgICAgIGhpZ2ggPSBhcnJheSA/IGFycmF5Lmxlbmd0aCA6IDAsXG4gICAgICB2YWxJc05hTiA9IHZhbHVlICE9PSB2YWx1ZSxcbiAgICAgIHZhbElzTnVsbCA9IHZhbHVlID09PSBudWxsLFxuICAgICAgdmFsSXNVbmRlZiA9IHZhbHVlID09PSB1bmRlZmluZWQ7XG5cbiAgd2hpbGUgKGxvdyA8IGhpZ2gpIHtcbiAgICB2YXIgbWlkID0gbmF0aXZlRmxvb3IoKGxvdyArIGhpZ2gpIC8gMiksXG4gICAgICAgIGNvbXB1dGVkID0gaXRlcmF0ZWUoYXJyYXlbbWlkXSksXG4gICAgICAgIGlzRGVmID0gY29tcHV0ZWQgIT09IHVuZGVmaW5lZCxcbiAgICAgICAgaXNSZWZsZXhpdmUgPSBjb21wdXRlZCA9PT0gY29tcHV0ZWQ7XG5cbiAgICBpZiAodmFsSXNOYU4pIHtcbiAgICAgIHZhciBzZXRMb3cgPSBpc1JlZmxleGl2ZSB8fCByZXRIaWdoZXN0O1xuICAgIH0gZWxzZSBpZiAodmFsSXNOdWxsKSB7XG4gICAgICBzZXRMb3cgPSBpc1JlZmxleGl2ZSAmJiBpc0RlZiAmJiAocmV0SGlnaGVzdCB8fCBjb21wdXRlZCAhPSBudWxsKTtcbiAgICB9IGVsc2UgaWYgKHZhbElzVW5kZWYpIHtcbiAgICAgIHNldExvdyA9IGlzUmVmbGV4aXZlICYmIChyZXRIaWdoZXN0IHx8IGlzRGVmKTtcbiAgICB9IGVsc2UgaWYgKGNvbXB1dGVkID09IG51bGwpIHtcbiAgICAgIHNldExvdyA9IGZhbHNlO1xuICAgIH0gZWxzZSB7XG4gICAgICBzZXRMb3cgPSByZXRIaWdoZXN0ID8gKGNvbXB1dGVkIDw9IHZhbHVlKSA6IChjb21wdXRlZCA8IHZhbHVlKTtcbiAgICB9XG4gICAgaWYgKHNldExvdykge1xuICAgICAgbG93ID0gbWlkICsgMTtcbiAgICB9IGVsc2Uge1xuICAgICAgaGlnaCA9IG1pZDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG5hdGl2ZU1pbihoaWdoLCBNQVhfQVJSQVlfSU5ERVgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJpbmFyeUluZGV4Qnk7XG4iLCJ2YXIgaWRlbnRpdHkgPSByZXF1aXJlKCcuLi91dGlsaXR5L2lkZW50aXR5Jyk7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlQ2FsbGJhY2tgIHdoaWNoIG9ubHkgc3VwcG9ydHMgYHRoaXNgIGJpbmRpbmdcbiAqIGFuZCBzcGVjaWZ5aW5nIHRoZSBudW1iZXIgb2YgYXJndW1lbnRzIHRvIHByb3ZpZGUgdG8gYGZ1bmNgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBiaW5kLlxuICogQHBhcmFtIHsqfSB0aGlzQXJnIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gKiBAcGFyYW0ge251bWJlcn0gW2FyZ0NvdW50XSBUaGUgbnVtYmVyIG9mIGFyZ3VtZW50cyB0byBwcm92aWRlIHRvIGBmdW5jYC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgY2FsbGJhY2suXG4gKi9cbmZ1bmN0aW9uIGJpbmRDYWxsYmFjayhmdW5jLCB0aGlzQXJnLCBhcmdDb3VudCkge1xuICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBpZGVudGl0eTtcbiAgfVxuICBpZiAodGhpc0FyZyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGZ1bmM7XG4gIH1cbiAgc3dpdGNoIChhcmdDb3VudCkge1xuICAgIGNhc2UgMTogcmV0dXJuIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcsIHZhbHVlKTtcbiAgICB9O1xuICAgIGNhc2UgMzogcmV0dXJuIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikge1xuICAgICAgcmV0dXJuIGZ1bmMuY2FsbCh0aGlzQXJnLCB2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pO1xuICAgIH07XG4gICAgY2FzZSA0OiByZXR1cm4gZnVuY3Rpb24oYWNjdW11bGF0b3IsIHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikge1xuICAgICAgcmV0dXJuIGZ1bmMuY2FsbCh0aGlzQXJnLCBhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKTtcbiAgICB9O1xuICAgIGNhc2UgNTogcmV0dXJuIGZ1bmN0aW9uKHZhbHVlLCBvdGhlciwga2V5LCBvYmplY3QsIHNvdXJjZSkge1xuICAgICAgcmV0dXJuIGZ1bmMuY2FsbCh0aGlzQXJnLCB2YWx1ZSwgb3RoZXIsIGtleSwgb2JqZWN0LCBzb3VyY2UpO1xuICAgIH07XG4gIH1cbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBmdW5jLmFwcGx5KHRoaXNBcmcsIGFyZ3VtZW50cyk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmluZENhbGxiYWNrO1xuIiwiKGZ1bmN0aW9uIChnbG9iYWwpe1xuLyoqIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBBcnJheUJ1ZmZlciA9IGdsb2JhbC5BcnJheUJ1ZmZlcixcbiAgICBVaW50OEFycmF5ID0gZ2xvYmFsLlVpbnQ4QXJyYXk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGNsb25lIG9mIHRoZSBnaXZlbiBhcnJheSBidWZmZXIuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXlCdWZmZXJ9IGJ1ZmZlciBUaGUgYXJyYXkgYnVmZmVyIHRvIGNsb25lLlxuICogQHJldHVybnMge0FycmF5QnVmZmVyfSBSZXR1cm5zIHRoZSBjbG9uZWQgYXJyYXkgYnVmZmVyLlxuICovXG5mdW5jdGlvbiBidWZmZXJDbG9uZShidWZmZXIpIHtcbiAgdmFyIHJlc3VsdCA9IG5ldyBBcnJheUJ1ZmZlcihidWZmZXIuYnl0ZUxlbmd0aCksXG4gICAgICB2aWV3ID0gbmV3IFVpbnQ4QXJyYXkocmVzdWx0KTtcblxuICB2aWV3LnNldChuZXcgVWludDhBcnJheShidWZmZXIpKTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBidWZmZXJDbG9uZTtcblxufSkuY2FsbCh0aGlzLHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOiB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30pXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldDp1dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbTV2WkdWZmJXOWtkV3hsY3k5c2IyUmhjMmd0WTI5dGNHRjBMMmx1ZEdWeWJtRnNMMkoxWm1abGNrTnNiMjVsTG1weklsMHNJbTVoYldWeklqcGJYU3dpYldGd2NHbHVaM01pT2lJN1FVRkJRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEVpTENKbWFXeGxJam9pWjJWdVpYSmhkR1ZrTG1weklpd2ljMjkxY21ObFVtOXZkQ0k2SWlJc0luTnZkWEpqWlhORGIyNTBaVzUwSWpwYklpOHFLaUJPWVhScGRtVWdiV1YwYUc5a0lISmxabVZ5Wlc1alpYTXVJQ292WEc1MllYSWdRWEp5WVhsQ2RXWm1aWElnUFNCbmJHOWlZV3d1UVhKeVlYbENkV1ptWlhJc1hHNGdJQ0FnVldsdWREaEJjbkpoZVNBOUlHZHNiMkpoYkM1VmFXNTBPRUZ5Y21GNU8xeHVYRzR2S2lwY2JpQXFJRU55WldGMFpYTWdZU0JqYkc5dVpTQnZaaUIwYUdVZ1oybDJaVzRnWVhKeVlYa2dZblZtWm1WeUxseHVJQ3BjYmlBcUlFQndjbWwyWVhSbFhHNGdLaUJBY0dGeVlXMGdlMEZ5Y21GNVFuVm1abVZ5ZlNCaWRXWm1aWElnVkdobElHRnljbUY1SUdKMVptWmxjaUIwYnlCamJHOXVaUzVjYmlBcUlFQnlaWFIxY201eklIdEJjbkpoZVVKMVptWmxjbjBnVW1WMGRYSnVjeUIwYUdVZ1kyeHZibVZrSUdGeWNtRjVJR0oxWm1abGNpNWNiaUFxTDF4dVpuVnVZM1JwYjI0Z1luVm1abVZ5UTJ4dmJtVW9ZblZtWm1WeUtTQjdYRzRnSUhaaGNpQnlaWE4xYkhRZ1BTQnVaWGNnUVhKeVlYbENkV1ptWlhJb1luVm1abVZ5TG1KNWRHVk1aVzVuZEdncExGeHVJQ0FnSUNBZ2RtbGxkeUE5SUc1bGR5QlZhVzUwT0VGeWNtRjVLSEpsYzNWc2RDazdYRzVjYmlBZ2RtbGxkeTV6WlhRb2JtVjNJRlZwYm5RNFFYSnlZWGtvWW5WbVptVnlLU2s3WEc0Z0lISmxkSFZ5YmlCeVpYTjFiSFE3WEc1OVhHNWNibTF2WkhWc1pTNWxlSEJ2Y25SeklEMGdZblZtWm1WeVEyeHZibVU3WEc0aVhYMD0iLCIvKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1heCA9IE1hdGgubWF4O1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gYXJyYXkgdGhhdCBpcyB0aGUgY29tcG9zaXRpb24gb2YgcGFydGlhbGx5IGFwcGxpZWQgYXJndW1lbnRzLFxuICogcGxhY2Vob2xkZXJzLCBhbmQgcHJvdmlkZWQgYXJndW1lbnRzIGludG8gYSBzaW5nbGUgYXJyYXkgb2YgYXJndW1lbnRzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gYXJncyBUaGUgcHJvdmlkZWQgYXJndW1lbnRzLlxuICogQHBhcmFtIHtBcnJheX0gcGFydGlhbHMgVGhlIGFyZ3VtZW50cyB0byBwcmVwZW5kIHRvIHRob3NlIHByb3ZpZGVkLlxuICogQHBhcmFtIHtBcnJheX0gaG9sZGVycyBUaGUgYHBhcnRpYWxzYCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgY29tcG9zZWQgYXJndW1lbnRzLlxuICovXG5mdW5jdGlvbiBjb21wb3NlQXJncyhhcmdzLCBwYXJ0aWFscywgaG9sZGVycykge1xuICB2YXIgaG9sZGVyc0xlbmd0aCA9IGhvbGRlcnMubGVuZ3RoLFxuICAgICAgYXJnc0luZGV4ID0gLTEsXG4gICAgICBhcmdzTGVuZ3RoID0gbmF0aXZlTWF4KGFyZ3MubGVuZ3RoIC0gaG9sZGVyc0xlbmd0aCwgMCksXG4gICAgICBsZWZ0SW5kZXggPSAtMSxcbiAgICAgIGxlZnRMZW5ndGggPSBwYXJ0aWFscy5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBBcnJheShsZWZ0TGVuZ3RoICsgYXJnc0xlbmd0aCk7XG5cbiAgd2hpbGUgKCsrbGVmdEluZGV4IDwgbGVmdExlbmd0aCkge1xuICAgIHJlc3VsdFtsZWZ0SW5kZXhdID0gcGFydGlhbHNbbGVmdEluZGV4XTtcbiAgfVxuICB3aGlsZSAoKythcmdzSW5kZXggPCBob2xkZXJzTGVuZ3RoKSB7XG4gICAgcmVzdWx0W2hvbGRlcnNbYXJnc0luZGV4XV0gPSBhcmdzW2FyZ3NJbmRleF07XG4gIH1cbiAgd2hpbGUgKGFyZ3NMZW5ndGgtLSkge1xuICAgIHJlc3VsdFtsZWZ0SW5kZXgrK10gPSBhcmdzW2FyZ3NJbmRleCsrXTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNvbXBvc2VBcmdzO1xuIiwiLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heDtcblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGlzIGxpa2UgYGNvbXBvc2VBcmdzYCBleGNlcHQgdGhhdCB0aGUgYXJndW1lbnRzIGNvbXBvc2l0aW9uXG4gKiBpcyB0YWlsb3JlZCBmb3IgYF8ucGFydGlhbFJpZ2h0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGFyZ3MgVGhlIHByb3ZpZGVkIGFyZ3VtZW50cy5cbiAqIEBwYXJhbSB7QXJyYXl9IHBhcnRpYWxzIFRoZSBhcmd1bWVudHMgdG8gYXBwZW5kIHRvIHRob3NlIHByb3ZpZGVkLlxuICogQHBhcmFtIHtBcnJheX0gaG9sZGVycyBUaGUgYHBhcnRpYWxzYCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgY29tcG9zZWQgYXJndW1lbnRzLlxuICovXG5mdW5jdGlvbiBjb21wb3NlQXJnc1JpZ2h0KGFyZ3MsIHBhcnRpYWxzLCBob2xkZXJzKSB7XG4gIHZhciBob2xkZXJzSW5kZXggPSAtMSxcbiAgICAgIGhvbGRlcnNMZW5ndGggPSBob2xkZXJzLmxlbmd0aCxcbiAgICAgIGFyZ3NJbmRleCA9IC0xLFxuICAgICAgYXJnc0xlbmd0aCA9IG5hdGl2ZU1heChhcmdzLmxlbmd0aCAtIGhvbGRlcnNMZW5ndGgsIDApLFxuICAgICAgcmlnaHRJbmRleCA9IC0xLFxuICAgICAgcmlnaHRMZW5ndGggPSBwYXJ0aWFscy5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBBcnJheShhcmdzTGVuZ3RoICsgcmlnaHRMZW5ndGgpO1xuXG4gIHdoaWxlICgrK2FyZ3NJbmRleCA8IGFyZ3NMZW5ndGgpIHtcbiAgICByZXN1bHRbYXJnc0luZGV4XSA9IGFyZ3NbYXJnc0luZGV4XTtcbiAgfVxuICB2YXIgb2Zmc2V0ID0gYXJnc0luZGV4O1xuICB3aGlsZSAoKytyaWdodEluZGV4IDwgcmlnaHRMZW5ndGgpIHtcbiAgICByZXN1bHRbb2Zmc2V0ICsgcmlnaHRJbmRleF0gPSBwYXJ0aWFsc1tyaWdodEluZGV4XTtcbiAgfVxuICB3aGlsZSAoKytob2xkZXJzSW5kZXggPCBob2xkZXJzTGVuZ3RoKSB7XG4gICAgcmVzdWx0W29mZnNldCArIGhvbGRlcnNbaG9sZGVyc0luZGV4XV0gPSBhcmdzW2FyZ3NJbmRleCsrXTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNvbXBvc2VBcmdzUmlnaHQ7XG4iLCJ2YXIgZ2V0TGVuZ3RoID0gcmVxdWlyZSgnLi9nZXRMZW5ndGgnKSxcbiAgICBpc0xlbmd0aCA9IHJlcXVpcmUoJy4vaXNMZW5ndGgnKSxcbiAgICB0b09iamVjdCA9IHJlcXVpcmUoJy4vdG9PYmplY3QnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgYGJhc2VFYWNoYCBvciBgYmFzZUVhY2hSaWdodGAgZnVuY3Rpb24uXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGVhY2hGdW5jIFRoZSBmdW5jdGlvbiB0byBpdGVyYXRlIG92ZXIgYSBjb2xsZWN0aW9uLlxuICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBiYXNlIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVCYXNlRWFjaChlYWNoRnVuYywgZnJvbVJpZ2h0KSB7XG4gIHJldHVybiBmdW5jdGlvbihjb2xsZWN0aW9uLCBpdGVyYXRlZSkge1xuICAgIHZhciBsZW5ndGggPSBjb2xsZWN0aW9uID8gZ2V0TGVuZ3RoKGNvbGxlY3Rpb24pIDogMDtcbiAgICBpZiAoIWlzTGVuZ3RoKGxlbmd0aCkpIHtcbiAgICAgIHJldHVybiBlYWNoRnVuYyhjb2xsZWN0aW9uLCBpdGVyYXRlZSk7XG4gICAgfVxuICAgIHZhciBpbmRleCA9IGZyb21SaWdodCA/IGxlbmd0aCA6IC0xLFxuICAgICAgICBpdGVyYWJsZSA9IHRvT2JqZWN0KGNvbGxlY3Rpb24pO1xuXG4gICAgd2hpbGUgKChmcm9tUmlnaHQgPyBpbmRleC0tIDogKytpbmRleCA8IGxlbmd0aCkpIHtcbiAgICAgIGlmIChpdGVyYXRlZShpdGVyYWJsZVtpbmRleF0sIGluZGV4LCBpdGVyYWJsZSkgPT09IGZhbHNlKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gY29sbGVjdGlvbjtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVCYXNlRWFjaDtcbiIsInZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vdG9PYmplY3QnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgYmFzZSBmdW5jdGlvbiBmb3IgYF8uZm9ySW5gIG9yIGBfLmZvckluUmlnaHRgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtmcm9tUmlnaHRdIFNwZWNpZnkgaXRlcmF0aW5nIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGJhc2UgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUJhc2VGb3IoZnJvbVJpZ2h0KSB7XG4gIHJldHVybiBmdW5jdGlvbihvYmplY3QsIGl0ZXJhdGVlLCBrZXlzRnVuYykge1xuICAgIHZhciBpdGVyYWJsZSA9IHRvT2JqZWN0KG9iamVjdCksXG4gICAgICAgIHByb3BzID0ga2V5c0Z1bmMob2JqZWN0KSxcbiAgICAgICAgbGVuZ3RoID0gcHJvcHMubGVuZ3RoLFxuICAgICAgICBpbmRleCA9IGZyb21SaWdodCA/IGxlbmd0aCA6IC0xO1xuXG4gICAgd2hpbGUgKChmcm9tUmlnaHQgPyBpbmRleC0tIDogKytpbmRleCA8IGxlbmd0aCkpIHtcbiAgICAgIHZhciBrZXkgPSBwcm9wc1tpbmRleF07XG4gICAgICBpZiAoaXRlcmF0ZWUoaXRlcmFibGVba2V5XSwga2V5LCBpdGVyYWJsZSkgPT09IGZhbHNlKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0O1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUJhc2VGb3I7XG4iLCIoZnVuY3Rpb24gKGdsb2JhbCl7XG52YXIgY3JlYXRlQ3RvcldyYXBwZXIgPSByZXF1aXJlKCcuL2NyZWF0ZUN0b3JXcmFwcGVyJyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgd3JhcHMgYGZ1bmNgIGFuZCBpbnZva2VzIGl0IHdpdGggdGhlIGB0aGlzYFxuICogYmluZGluZyBvZiBgdGhpc0FyZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGJpbmQuXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYm91bmQgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUJpbmRXcmFwcGVyKGZ1bmMsIHRoaXNBcmcpIHtcbiAgdmFyIEN0b3IgPSBjcmVhdGVDdG9yV3JhcHBlcihmdW5jKTtcblxuICBmdW5jdGlvbiB3cmFwcGVyKCkge1xuICAgIHZhciBmbiA9ICh0aGlzICYmIHRoaXMgIT09IGdsb2JhbCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikgPyBDdG9yIDogZnVuYztcbiAgICByZXR1cm4gZm4uYXBwbHkodGhpc0FyZywgYXJndW1lbnRzKTtcbiAgfVxuICByZXR1cm4gd3JhcHBlcjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVCaW5kV3JhcHBlcjtcblxufSkuY2FsbCh0aGlzLHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOiB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30pXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldDp1dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbTV2WkdWZmJXOWtkV3hsY3k5c2IyUmhjMmd0WTI5dGNHRjBMMmx1ZEdWeWJtRnNMMk55WldGMFpVSnBibVJYY21Gd2NHVnlMbXB6SWwwc0ltNWhiV1Z6SWpwYlhTd2liV0Z3Y0dsdVozTWlPaUk3UVVGQlFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJJaXdpWm1sc1pTSTZJbWRsYm1WeVlYUmxaQzVxY3lJc0luTnZkWEpqWlZKdmIzUWlPaUlpTENKemIzVnlZMlZ6UTI5dWRHVnVkQ0k2V3lKMllYSWdZM0psWVhSbFEzUnZjbGR5WVhCd1pYSWdQU0J5WlhGMWFYSmxLQ2N1TDJOeVpXRjBaVU4wYjNKWGNtRndjR1Z5SnlrN1hHNWNiaThxS2x4dUlDb2dRM0psWVhSbGN5QmhJR1oxYm1OMGFXOXVJSFJvWVhRZ2QzSmhjSE1nWUdaMWJtTmdJR0Z1WkNCcGJuWnZhMlZ6SUdsMElIZHBkR2dnZEdobElHQjBhR2x6WUZ4dUlDb2dZbWx1WkdsdVp5QnZaaUJnZEdocGMwRnlaMkF1WEc0Z0tseHVJQ29nUUhCeWFYWmhkR1ZjYmlBcUlFQndZWEpoYlNCN1JuVnVZM1JwYjI1OUlHWjFibU1nVkdobElHWjFibU4wYVc5dUlIUnZJR0pwYm1RdVhHNGdLaUJBY0dGeVlXMGdleXA5SUZ0MGFHbHpRWEpuWFNCVWFHVWdZSFJvYVhOZ0lHSnBibVJwYm1jZ2IyWWdZR1oxYm1OZ0xseHVJQ29nUUhKbGRIVnlibk1nZTBaMWJtTjBhVzl1ZlNCU1pYUjFjbTV6SUhSb1pTQnVaWGNnWW05MWJtUWdablZ1WTNScGIyNHVYRzRnS2k5Y2JtWjFibU4wYVc5dUlHTnlaV0YwWlVKcGJtUlhjbUZ3Y0dWeUtHWjFibU1zSUhSb2FYTkJjbWNwSUh0Y2JpQWdkbUZ5SUVOMGIzSWdQU0JqY21WaGRHVkRkRzl5VjNKaGNIQmxjaWhtZFc1aktUdGNibHh1SUNCbWRXNWpkR2x2YmlCM2NtRndjR1Z5S0NrZ2UxeHVJQ0FnSUhaaGNpQm1iaUE5SUNoMGFHbHpJQ1ltSUhSb2FYTWdJVDA5SUdkc2IySmhiQ0FtSmlCMGFHbHpJR2x1YzNSaGJtTmxiMllnZDNKaGNIQmxjaWtnUHlCRGRHOXlJRG9nWm5WdVl6dGNiaUFnSUNCeVpYUjFjbTRnWm00dVlYQndiSGtvZEdocGMwRnlaeXdnWVhKbmRXMWxiblJ6S1R0Y2JpQWdmVnh1SUNCeVpYUjFjbTRnZDNKaGNIQmxjanRjYm4xY2JseHViVzlrZFd4bExtVjRjRzl5ZEhNZ1BTQmpjbVZoZEdWQ2FXNWtWM0poY0hCbGNqdGNiaUpkZlE9PSIsInZhciBiYXNlQ3JlYXRlID0gcmVxdWlyZSgnLi9iYXNlQ3JlYXRlJyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0Jyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcHJvZHVjZXMgYW4gaW5zdGFuY2Ugb2YgYEN0b3JgIHJlZ2FyZGxlc3Mgb2ZcbiAqIHdoZXRoZXIgaXQgd2FzIGludm9rZWQgYXMgcGFydCBvZiBhIGBuZXdgIGV4cHJlc3Npb24gb3IgYnkgYGNhbGxgIG9yIGBhcHBseWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IEN0b3IgVGhlIGNvbnN0cnVjdG9yIHRvIHdyYXAuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB3cmFwcGVkIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVDdG9yV3JhcHBlcihDdG9yKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAvLyBVc2UgYSBgc3dpdGNoYCBzdGF0ZW1lbnQgdG8gd29yayB3aXRoIGNsYXNzIGNvbnN0cnVjdG9ycy5cbiAgICAvLyBTZWUgaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtZWNtYXNjcmlwdC1mdW5jdGlvbi1vYmplY3RzLWNhbGwtdGhpc2FyZ3VtZW50LWFyZ3VtZW50c2xpc3RcbiAgICAvLyBmb3IgbW9yZSBkZXRhaWxzLlxuICAgIHZhciBhcmdzID0gYXJndW1lbnRzO1xuICAgIHN3aXRjaCAoYXJncy5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMDogcmV0dXJuIG5ldyBDdG9yO1xuICAgICAgY2FzZSAxOiByZXR1cm4gbmV3IEN0b3IoYXJnc1swXSk7XG4gICAgICBjYXNlIDI6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdLCBhcmdzWzFdKTtcbiAgICAgIGNhc2UgMzogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgY2FzZSA0OiByZXR1cm4gbmV3IEN0b3IoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSwgYXJnc1szXSk7XG4gICAgICBjYXNlIDU6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdLCBhcmdzWzRdKTtcbiAgICAgIGNhc2UgNjogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10sIGFyZ3NbNF0sIGFyZ3NbNV0pO1xuICAgICAgY2FzZSA3OiByZXR1cm4gbmV3IEN0b3IoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSwgYXJnc1szXSwgYXJnc1s0XSwgYXJnc1s1XSwgYXJnc1s2XSk7XG4gICAgfVxuICAgIHZhciB0aGlzQmluZGluZyA9IGJhc2VDcmVhdGUoQ3Rvci5wcm90b3R5cGUpLFxuICAgICAgICByZXN1bHQgPSBDdG9yLmFwcGx5KHRoaXNCaW5kaW5nLCBhcmdzKTtcblxuICAgIC8vIE1pbWljIHRoZSBjb25zdHJ1Y3RvcidzIGByZXR1cm5gIGJlaGF2aW9yLlxuICAgIC8vIFNlZSBodHRwczovL2VzNS5naXRodWIuaW8vI3gxMy4yLjIgZm9yIG1vcmUgZGV0YWlscy5cbiAgICByZXR1cm4gaXNPYmplY3QocmVzdWx0KSA/IHJlc3VsdCA6IHRoaXNCaW5kaW5nO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUN0b3JXcmFwcGVyO1xuIiwidmFyIGJhc2VDYWxsYmFjayA9IHJlcXVpcmUoJy4vYmFzZUNhbGxiYWNrJyksXG4gICAgYmFzZUZpbmQgPSByZXF1aXJlKCcuL2Jhc2VGaW5kJyksXG4gICAgYmFzZUZpbmRJbmRleCA9IHJlcXVpcmUoJy4vYmFzZUZpbmRJbmRleCcpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgYF8uZmluZGAgb3IgYF8uZmluZExhc3RgIGZ1bmN0aW9uLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBlYWNoRnVuYyBUaGUgZnVuY3Rpb24gdG8gaXRlcmF0ZSBvdmVyIGEgY29sbGVjdGlvbi5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZmluZCBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlRmluZChlYWNoRnVuYywgZnJvbVJpZ2h0KSB7XG4gIHJldHVybiBmdW5jdGlvbihjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIHRoaXNBcmcpIHtcbiAgICBwcmVkaWNhdGUgPSBiYXNlQ2FsbGJhY2socHJlZGljYXRlLCB0aGlzQXJnLCAzKTtcbiAgICBpZiAoaXNBcnJheShjb2xsZWN0aW9uKSkge1xuICAgICAgdmFyIGluZGV4ID0gYmFzZUZpbmRJbmRleChjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIGZyb21SaWdodCk7XG4gICAgICByZXR1cm4gaW5kZXggPiAtMSA/IGNvbGxlY3Rpb25baW5kZXhdIDogdW5kZWZpbmVkO1xuICAgIH1cbiAgICByZXR1cm4gYmFzZUZpbmQoY29sbGVjdGlvbiwgcHJlZGljYXRlLCBlYWNoRnVuYyk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlRmluZDtcbiIsInZhciBiaW5kQ2FsbGJhY2sgPSByZXF1aXJlKCcuL2JpbmRDYWxsYmFjaycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gZm9yIGBfLmZvckVhY2hgIG9yIGBfLmZvckVhY2hSaWdodGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGFycmF5RnVuYyBUaGUgZnVuY3Rpb24gdG8gaXRlcmF0ZSBvdmVyIGFuIGFycmF5LlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZWFjaEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGl0ZXJhdGUgb3ZlciBhIGNvbGxlY3Rpb24uXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBlYWNoIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVGb3JFYWNoKGFycmF5RnVuYywgZWFjaEZ1bmMpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKGNvbGxlY3Rpb24sIGl0ZXJhdGVlLCB0aGlzQXJnKSB7XG4gICAgcmV0dXJuICh0eXBlb2YgaXRlcmF0ZWUgPT0gJ2Z1bmN0aW9uJyAmJiB0aGlzQXJnID09PSB1bmRlZmluZWQgJiYgaXNBcnJheShjb2xsZWN0aW9uKSlcbiAgICAgID8gYXJyYXlGdW5jKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKVxuICAgICAgOiBlYWNoRnVuYyhjb2xsZWN0aW9uLCBiaW5kQ2FsbGJhY2soaXRlcmF0ZWUsIHRoaXNBcmcsIDMpKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVGb3JFYWNoO1xuIiwiKGZ1bmN0aW9uIChnbG9iYWwpe1xudmFyIGFycmF5Q29weSA9IHJlcXVpcmUoJy4vYXJyYXlDb3B5JyksXG4gICAgY29tcG9zZUFyZ3MgPSByZXF1aXJlKCcuL2NvbXBvc2VBcmdzJyksXG4gICAgY29tcG9zZUFyZ3NSaWdodCA9IHJlcXVpcmUoJy4vY29tcG9zZUFyZ3NSaWdodCcpLFxuICAgIGNyZWF0ZUN0b3JXcmFwcGVyID0gcmVxdWlyZSgnLi9jcmVhdGVDdG9yV3JhcHBlcicpLFxuICAgIGlzTGF6aWFibGUgPSByZXF1aXJlKCcuL2lzTGF6aWFibGUnKSxcbiAgICByZW9yZGVyID0gcmVxdWlyZSgnLi9yZW9yZGVyJyksXG4gICAgcmVwbGFjZUhvbGRlcnMgPSByZXF1aXJlKCcuL3JlcGxhY2VIb2xkZXJzJyksXG4gICAgc2V0RGF0YSA9IHJlcXVpcmUoJy4vc2V0RGF0YScpO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB3cmFwcGVyIG1ldGFkYXRhLiAqL1xudmFyIEJJTkRfRkxBRyA9IDEsXG4gICAgQklORF9LRVlfRkxBRyA9IDIsXG4gICAgQ1VSUllfQk9VTkRfRkxBRyA9IDQsXG4gICAgQ1VSUllfRkxBRyA9IDgsXG4gICAgQ1VSUllfUklHSFRfRkxBRyA9IDE2LFxuICAgIFBBUlRJQUxfRkxBRyA9IDMyLFxuICAgIFBBUlRJQUxfUklHSFRfRkxBRyA9IDY0LFxuICAgIEFSWV9GTEFHID0gMTI4O1xuXG4vKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1heCA9IE1hdGgubWF4O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHdyYXBzIGBmdW5jYCBhbmQgaW52b2tlcyBpdCB3aXRoIG9wdGlvbmFsIGB0aGlzYFxuICogYmluZGluZyBvZiwgcGFydGlhbCBhcHBsaWNhdGlvbiwgYW5kIGN1cnJ5aW5nLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufHN0cmluZ30gZnVuYyBUaGUgZnVuY3Rpb24gb3IgbWV0aG9kIG5hbWUgdG8gcmVmZXJlbmNlLlxuICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgb2YgZmxhZ3MuIFNlZSBgY3JlYXRlV3JhcHBlcmAgZm9yIG1vcmUgZGV0YWlscy5cbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gKiBAcGFyYW0ge0FycmF5fSBbcGFydGlhbHNdIFRoZSBhcmd1bWVudHMgdG8gcHJlcGVuZCB0byB0aG9zZSBwcm92aWRlZCB0byB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNdIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gKiBAcGFyYW0ge0FycmF5fSBbcGFydGlhbHNSaWdodF0gVGhlIGFyZ3VtZW50cyB0byBhcHBlbmQgdG8gdGhvc2UgcHJvdmlkZWQgdG8gdGhlIG5ldyBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7QXJyYXl9IFtob2xkZXJzUmlnaHRdIFRoZSBgcGFydGlhbHNSaWdodGAgcGxhY2Vob2xkZXIgaW5kZXhlcy5cbiAqIEBwYXJhbSB7QXJyYXl9IFthcmdQb3NdIFRoZSBhcmd1bWVudCBwb3NpdGlvbnMgb2YgdGhlIG5ldyBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXJ5XSBUaGUgYXJpdHkgY2FwIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXJpdHldIFRoZSBhcml0eSBvZiBgZnVuY2AuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB3cmFwcGVkIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVIeWJyaWRXcmFwcGVyKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzLCBob2xkZXJzLCBwYXJ0aWFsc1JpZ2h0LCBob2xkZXJzUmlnaHQsIGFyZ1BvcywgYXJ5LCBhcml0eSkge1xuICB2YXIgaXNBcnkgPSBiaXRtYXNrICYgQVJZX0ZMQUcsXG4gICAgICBpc0JpbmQgPSBiaXRtYXNrICYgQklORF9GTEFHLFxuICAgICAgaXNCaW5kS2V5ID0gYml0bWFzayAmIEJJTkRfS0VZX0ZMQUcsXG4gICAgICBpc0N1cnJ5ID0gYml0bWFzayAmIENVUlJZX0ZMQUcsXG4gICAgICBpc0N1cnJ5Qm91bmQgPSBiaXRtYXNrICYgQ1VSUllfQk9VTkRfRkxBRyxcbiAgICAgIGlzQ3VycnlSaWdodCA9IGJpdG1hc2sgJiBDVVJSWV9SSUdIVF9GTEFHLFxuICAgICAgQ3RvciA9IGlzQmluZEtleSA/IHVuZGVmaW5lZCA6IGNyZWF0ZUN0b3JXcmFwcGVyKGZ1bmMpO1xuXG4gIGZ1bmN0aW9uIHdyYXBwZXIoKSB7XG4gICAgLy8gQXZvaWQgYGFyZ3VtZW50c2Agb2JqZWN0IHVzZSBkaXNxdWFsaWZ5aW5nIG9wdGltaXphdGlvbnMgYnlcbiAgICAvLyBjb252ZXJ0aW5nIGl0IHRvIGFuIGFycmF5IGJlZm9yZSBwcm92aWRpbmcgaXQgdG8gb3RoZXIgZnVuY3Rpb25zLlxuICAgIHZhciBsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoLFxuICAgICAgICBpbmRleCA9IGxlbmd0aCxcbiAgICAgICAgYXJncyA9IEFycmF5KGxlbmd0aCk7XG5cbiAgICB3aGlsZSAoaW5kZXgtLSkge1xuICAgICAgYXJnc1tpbmRleF0gPSBhcmd1bWVudHNbaW5kZXhdO1xuICAgIH1cbiAgICBpZiAocGFydGlhbHMpIHtcbiAgICAgIGFyZ3MgPSBjb21wb3NlQXJncyhhcmdzLCBwYXJ0aWFscywgaG9sZGVycyk7XG4gICAgfVxuICAgIGlmIChwYXJ0aWFsc1JpZ2h0KSB7XG4gICAgICBhcmdzID0gY29tcG9zZUFyZ3NSaWdodChhcmdzLCBwYXJ0aWFsc1JpZ2h0LCBob2xkZXJzUmlnaHQpO1xuICAgIH1cbiAgICBpZiAoaXNDdXJyeSB8fCBpc0N1cnJ5UmlnaHQpIHtcbiAgICAgIHZhciBwbGFjZWhvbGRlciA9IHdyYXBwZXIucGxhY2Vob2xkZXIsXG4gICAgICAgICAgYXJnc0hvbGRlcnMgPSByZXBsYWNlSG9sZGVycyhhcmdzLCBwbGFjZWhvbGRlcik7XG5cbiAgICAgIGxlbmd0aCAtPSBhcmdzSG9sZGVycy5sZW5ndGg7XG4gICAgICBpZiAobGVuZ3RoIDwgYXJpdHkpIHtcbiAgICAgICAgdmFyIG5ld0FyZ1BvcyA9IGFyZ1BvcyA/IGFycmF5Q29weShhcmdQb3MpIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgbmV3QXJpdHkgPSBuYXRpdmVNYXgoYXJpdHkgLSBsZW5ndGgsIDApLFxuICAgICAgICAgICAgbmV3c0hvbGRlcnMgPSBpc0N1cnJ5ID8gYXJnc0hvbGRlcnMgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBuZXdIb2xkZXJzUmlnaHQgPSBpc0N1cnJ5ID8gdW5kZWZpbmVkIDogYXJnc0hvbGRlcnMsXG4gICAgICAgICAgICBuZXdQYXJ0aWFscyA9IGlzQ3VycnkgPyBhcmdzIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgbmV3UGFydGlhbHNSaWdodCA9IGlzQ3VycnkgPyB1bmRlZmluZWQgOiBhcmdzO1xuXG4gICAgICAgIGJpdG1hc2sgfD0gKGlzQ3VycnkgPyBQQVJUSUFMX0ZMQUcgOiBQQVJUSUFMX1JJR0hUX0ZMQUcpO1xuICAgICAgICBiaXRtYXNrICY9IH4oaXNDdXJyeSA/IFBBUlRJQUxfUklHSFRfRkxBRyA6IFBBUlRJQUxfRkxBRyk7XG5cbiAgICAgICAgaWYgKCFpc0N1cnJ5Qm91bmQpIHtcbiAgICAgICAgICBiaXRtYXNrICY9IH4oQklORF9GTEFHIHwgQklORF9LRVlfRkxBRyk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIG5ld0RhdGEgPSBbZnVuYywgYml0bWFzaywgdGhpc0FyZywgbmV3UGFydGlhbHMsIG5ld3NIb2xkZXJzLCBuZXdQYXJ0aWFsc1JpZ2h0LCBuZXdIb2xkZXJzUmlnaHQsIG5ld0FyZ1BvcywgYXJ5LCBuZXdBcml0eV0sXG4gICAgICAgICAgICByZXN1bHQgPSBjcmVhdGVIeWJyaWRXcmFwcGVyLmFwcGx5KHVuZGVmaW5lZCwgbmV3RGF0YSk7XG5cbiAgICAgICAgaWYgKGlzTGF6aWFibGUoZnVuYykpIHtcbiAgICAgICAgICBzZXREYXRhKHJlc3VsdCwgbmV3RGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzdWx0LnBsYWNlaG9sZGVyID0gcGxhY2Vob2xkZXI7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgfVxuICAgIHZhciB0aGlzQmluZGluZyA9IGlzQmluZCA/IHRoaXNBcmcgOiB0aGlzLFxuICAgICAgICBmbiA9IGlzQmluZEtleSA/IHRoaXNCaW5kaW5nW2Z1bmNdIDogZnVuYztcblxuICAgIGlmIChhcmdQb3MpIHtcbiAgICAgIGFyZ3MgPSByZW9yZGVyKGFyZ3MsIGFyZ1Bvcyk7XG4gICAgfVxuICAgIGlmIChpc0FyeSAmJiBhcnkgPCBhcmdzLmxlbmd0aCkge1xuICAgICAgYXJncy5sZW5ndGggPSBhcnk7XG4gICAgfVxuICAgIGlmICh0aGlzICYmIHRoaXMgIT09IGdsb2JhbCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikge1xuICAgICAgZm4gPSBDdG9yIHx8IGNyZWF0ZUN0b3JXcmFwcGVyKGZ1bmMpO1xuICAgIH1cbiAgICByZXR1cm4gZm4uYXBwbHkodGhpc0JpbmRpbmcsIGFyZ3MpO1xuICB9XG4gIHJldHVybiB3cmFwcGVyO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUh5YnJpZFdyYXBwZXI7XG5cbn0pLmNhbGwodGhpcyx0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiID8gZ2xvYmFsIDogdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9KVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ6dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p6YjNWeVkyVnpJanBiSW01dlpHVmZiVzlrZFd4bGN5OXNiMlJoYzJndFkyOXRjR0YwTDJsdWRHVnlibUZzTDJOeVpXRjBaVWg1WW5KcFpGZHlZWEJ3WlhJdWFuTWlYU3dpYm1GdFpYTWlPbHRkTENKdFlYQndhVzVuY3lJNklqdEJRVUZCTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJJaXdpWm1sc1pTSTZJbWRsYm1WeVlYUmxaQzVxY3lJc0luTnZkWEpqWlZKdmIzUWlPaUlpTENKemIzVnlZMlZ6UTI5dWRHVnVkQ0k2V3lKMllYSWdZWEp5WVhsRGIzQjVJRDBnY21WeGRXbHlaU2duTGk5aGNuSmhlVU52Y0hrbktTeGNiaUFnSUNCamIyMXdiM05sUVhKbmN5QTlJSEpsY1hWcGNtVW9KeTR2WTI5dGNHOXpaVUZ5WjNNbktTeGNiaUFnSUNCamIyMXdiM05sUVhKbmMxSnBaMmgwSUQwZ2NtVnhkV2x5WlNnbkxpOWpiMjF3YjNObFFYSm5jMUpwWjJoMEp5a3NYRzRnSUNBZ1kzSmxZWFJsUTNSdmNsZHlZWEJ3WlhJZ1BTQnlaWEYxYVhKbEtDY3VMMk55WldGMFpVTjBiM0pYY21Gd2NHVnlKeWtzWEc0Z0lDQWdhWE5NWVhwcFlXSnNaU0E5SUhKbGNYVnBjbVVvSnk0dmFYTk1ZWHBwWVdKc1pTY3BMRnh1SUNBZ0lISmxiM0prWlhJZ1BTQnlaWEYxYVhKbEtDY3VMM0psYjNKa1pYSW5LU3hjYmlBZ0lDQnlaWEJzWVdObFNHOXNaR1Z5Y3lBOUlISmxjWFZwY21Vb0p5NHZjbVZ3YkdGalpVaHZiR1JsY25NbktTeGNiaUFnSUNCelpYUkVZWFJoSUQwZ2NtVnhkV2x5WlNnbkxpOXpaWFJFWVhSaEp5azdYRzVjYmk4cUtpQlZjMlZrSUhSdklHTnZiWEJ2YzJVZ1ltbDBiV0Z6YTNNZ1ptOXlJSGR5WVhCd1pYSWdiV1YwWVdSaGRHRXVJQ292WEc1MllYSWdRa2xPUkY5R1RFRkhJRDBnTVN4Y2JpQWdJQ0JDU1U1RVgwdEZXVjlHVEVGSElEMGdNaXhjYmlBZ0lDQkRWVkpTV1Y5Q1QxVk9SRjlHVEVGSElEMGdOQ3hjYmlBZ0lDQkRWVkpTV1Y5R1RFRkhJRDBnT0N4Y2JpQWdJQ0JEVlZKU1dWOVNTVWRJVkY5R1RFRkhJRDBnTVRZc1hHNGdJQ0FnVUVGU1ZFbEJURjlHVEVGSElEMGdNeklzWEc0Z0lDQWdVRUZTVkVsQlRGOVNTVWRJVkY5R1RFRkhJRDBnTmpRc1hHNGdJQ0FnUVZKWlgwWk1RVWNnUFNBeE1qZzdYRzVjYmk4cUlFNWhkR2wyWlNCdFpYUm9iMlFnY21WbVpYSmxibU5sY3lCbWIzSWdkR2h2YzJVZ2QybDBhQ0IwYUdVZ2MyRnRaU0J1WVcxbElHRnpJRzkwYUdWeUlHQnNiMlJoYzJoZ0lHMWxkR2h2WkhNdUlDb3ZYRzUyWVhJZ2JtRjBhWFpsVFdGNElEMGdUV0YwYUM1dFlYZzdYRzVjYmk4cUtseHVJQ29nUTNKbFlYUmxjeUJoSUdaMWJtTjBhVzl1SUhSb1lYUWdkM0poY0hNZ1lHWjFibU5nSUdGdVpDQnBiblp2YTJWeklHbDBJSGRwZEdnZ2IzQjBhVzl1WVd3Z1lIUm9hWE5nWEc0Z0tpQmlhVzVrYVc1bklHOW1MQ0J3WVhKMGFXRnNJR0Z3Y0d4cFkyRjBhVzl1TENCaGJtUWdZM1Z5Y25scGJtY3VYRzRnS2x4dUlDb2dRSEJ5YVhaaGRHVmNiaUFxSUVCd1lYSmhiU0I3Um5WdVkzUnBiMjU4YzNSeWFXNW5mU0JtZFc1aklGUm9aU0JtZFc1amRHbHZiaUJ2Y2lCdFpYUm9iMlFnYm1GdFpTQjBieUJ5WldabGNtVnVZMlV1WEc0Z0tpQkFjR0Z5WVcwZ2UyNTFiV0psY24wZ1ltbDBiV0Z6YXlCVWFHVWdZbWwwYldGemF5QnZaaUJtYkdGbmN5NGdVMlZsSUdCamNtVmhkR1ZYY21Gd2NHVnlZQ0JtYjNJZ2JXOXlaU0JrWlhSaGFXeHpMbHh1SUNvZ1FIQmhjbUZ0SUhzcWZTQmJkR2hwYzBGeVoxMGdWR2hsSUdCMGFHbHpZQ0JpYVc1a2FXNW5JRzltSUdCbWRXNWpZQzVjYmlBcUlFQndZWEpoYlNCN1FYSnlZWGw5SUZ0d1lYSjBhV0ZzYzEwZ1ZHaGxJR0Z5WjNWdFpXNTBjeUIwYnlCd2NtVndaVzVrSUhSdklIUm9iM05sSUhCeWIzWnBaR1ZrSUhSdklIUm9aU0J1WlhjZ1puVnVZM1JwYjI0dVhHNGdLaUJBY0dGeVlXMGdlMEZ5Y21GNWZTQmJhRzlzWkdWeWMxMGdWR2hsSUdCd1lYSjBhV0ZzYzJBZ2NHeGhZMlZvYjJ4a1pYSWdhVzVrWlhobGN5NWNiaUFxSUVCd1lYSmhiU0I3UVhKeVlYbDlJRnR3WVhKMGFXRnNjMUpwWjJoMFhTQlVhR1VnWVhKbmRXMWxiblJ6SUhSdklHRndjR1Z1WkNCMGJ5QjBhRzl6WlNCd2NtOTJhV1JsWkNCMGJ5QjBhR1VnYm1WM0lHWjFibU4wYVc5dUxseHVJQ29nUUhCaGNtRnRJSHRCY25KaGVYMGdXMmh2YkdSbGNuTlNhV2RvZEYwZ1ZHaGxJR0J3WVhKMGFXRnNjMUpwWjJoMFlDQndiR0ZqWldodmJHUmxjaUJwYm1SbGVHVnpMbHh1SUNvZ1FIQmhjbUZ0SUh0QmNuSmhlWDBnVzJGeVoxQnZjMTBnVkdobElHRnlaM1Z0Wlc1MElIQnZjMmwwYVc5dWN5QnZaaUIwYUdVZ2JtVjNJR1oxYm1OMGFXOXVMbHh1SUNvZ1FIQmhjbUZ0SUh0dWRXMWlaWEo5SUZ0aGNubGRJRlJvWlNCaGNtbDBlU0JqWVhBZ2IyWWdZR1oxYm1OZ0xseHVJQ29nUUhCaGNtRnRJSHR1ZFcxaVpYSjlJRnRoY21sMGVWMGdWR2hsSUdGeWFYUjVJRzltSUdCbWRXNWpZQzVjYmlBcUlFQnlaWFIxY201eklIdEdkVzVqZEdsdmJuMGdVbVYwZFhKdWN5QjBhR1VnYm1WM0lIZHlZWEJ3WldRZ1puVnVZM1JwYjI0dVhHNGdLaTljYm1aMWJtTjBhVzl1SUdOeVpXRjBaVWg1WW5KcFpGZHlZWEJ3WlhJb1puVnVZeXdnWW1sMGJXRnpheXdnZEdocGMwRnlaeXdnY0dGeWRHbGhiSE1zSUdodmJHUmxjbk1zSUhCaGNuUnBZV3h6VW1sbmFIUXNJR2h2YkdSbGNuTlNhV2RvZEN3Z1lYSm5VRzl6TENCaGNua3NJR0Z5YVhSNUtTQjdYRzRnSUhaaGNpQnBjMEZ5ZVNBOUlHSnBkRzFoYzJzZ0ppQkJVbGxmUmt4QlJ5eGNiaUFnSUNBZ0lHbHpRbWx1WkNBOUlHSnBkRzFoYzJzZ0ppQkNTVTVFWDBaTVFVY3NYRzRnSUNBZ0lDQnBjMEpwYm1STFpYa2dQU0JpYVhSdFlYTnJJQ1lnUWtsT1JGOUxSVmxmUmt4QlJ5eGNiaUFnSUNBZ0lHbHpRM1Z5Y25rZ1BTQmlhWFJ0WVhOcklDWWdRMVZTVWxsZlJreEJSeXhjYmlBZ0lDQWdJR2x6UTNWeWNubENiM1Z1WkNBOUlHSnBkRzFoYzJzZ0ppQkRWVkpTV1Y5Q1QxVk9SRjlHVEVGSExGeHVJQ0FnSUNBZ2FYTkRkWEp5ZVZKcFoyaDBJRDBnWW1sMGJXRnpheUFtSUVOVlVsSlpYMUpKUjBoVVgwWk1RVWNzWEc0Z0lDQWdJQ0JEZEc5eUlEMGdhWE5DYVc1a1MyVjVJRDhnZFc1a1pXWnBibVZrSURvZ1kzSmxZWFJsUTNSdmNsZHlZWEJ3WlhJb1puVnVZeWs3WEc1Y2JpQWdablZ1WTNScGIyNGdkM0poY0hCbGNpZ3BJSHRjYmlBZ0lDQXZMeUJCZG05cFpDQmdZWEpuZFcxbGJuUnpZQ0J2WW1wbFkzUWdkWE5sSUdScGMzRjFZV3hwWm5scGJtY2diM0IwYVcxcGVtRjBhVzl1Y3lCaWVWeHVJQ0FnSUM4dklHTnZiblpsY25ScGJtY2dhWFFnZEc4Z1lXNGdZWEp5WVhrZ1ltVm1iM0psSUhCeWIzWnBaR2x1WnlCcGRDQjBieUJ2ZEdobGNpQm1kVzVqZEdsdmJuTXVYRzRnSUNBZ2RtRnlJR3hsYm1kMGFDQTlJR0Z5WjNWdFpXNTBjeTVzWlc1bmRHZ3NYRzRnSUNBZ0lDQWdJR2x1WkdWNElEMGdiR1Z1WjNSb0xGeHVJQ0FnSUNBZ0lDQmhjbWR6SUQwZ1FYSnlZWGtvYkdWdVozUm9LVHRjYmx4dUlDQWdJSGRvYVd4bElDaHBibVJsZUMwdEtTQjdYRzRnSUNBZ0lDQmhjbWR6VzJsdVpHVjRYU0E5SUdGeVozVnRaVzUwYzF0cGJtUmxlRjA3WEc0Z0lDQWdmVnh1SUNBZ0lHbG1JQ2h3WVhKMGFXRnNjeWtnZTF4dUlDQWdJQ0FnWVhKbmN5QTlJR052YlhCdmMyVkJjbWR6S0dGeVozTXNJSEJoY25ScFlXeHpMQ0JvYjJ4a1pYSnpLVHRjYmlBZ0lDQjlYRzRnSUNBZ2FXWWdLSEJoY25ScFlXeHpVbWxuYUhRcElIdGNiaUFnSUNBZ0lHRnlaM01nUFNCamIyMXdiM05sUVhKbmMxSnBaMmgwS0dGeVozTXNJSEJoY25ScFlXeHpVbWxuYUhRc0lHaHZiR1JsY25OU2FXZG9kQ2s3WEc0Z0lDQWdmVnh1SUNBZ0lHbG1JQ2hwYzBOMWNuSjVJSHg4SUdselEzVnljbmxTYVdkb2RDa2dlMXh1SUNBZ0lDQWdkbUZ5SUhCc1lXTmxhRzlzWkdWeUlEMGdkM0poY0hCbGNpNXdiR0ZqWldodmJHUmxjaXhjYmlBZ0lDQWdJQ0FnSUNCaGNtZHpTRzlzWkdWeWN5QTlJSEpsY0d4aFkyVkliMnhrWlhKektHRnlaM01zSUhCc1lXTmxhRzlzWkdWeUtUdGNibHh1SUNBZ0lDQWdiR1Z1WjNSb0lDMDlJR0Z5WjNOSWIyeGtaWEp6TG14bGJtZDBhRHRjYmlBZ0lDQWdJR2xtSUNoc1pXNW5kR2dnUENCaGNtbDBlU2tnZTF4dUlDQWdJQ0FnSUNCMllYSWdibVYzUVhKblVHOXpJRDBnWVhKblVHOXpJRDhnWVhKeVlYbERiM0I1S0dGeVoxQnZjeWtnT2lCMWJtUmxabWx1WldRc1hHNGdJQ0FnSUNBZ0lDQWdJQ0J1WlhkQmNtbDBlU0E5SUc1aGRHbDJaVTFoZUNoaGNtbDBlU0F0SUd4bGJtZDBhQ3dnTUNrc1hHNGdJQ0FnSUNBZ0lDQWdJQ0J1WlhkelNHOXNaR1Z5Y3lBOUlHbHpRM1Z5Y25rZ1B5QmhjbWR6U0c5c1pHVnljeUE2SUhWdVpHVm1hVzVsWkN4Y2JpQWdJQ0FnSUNBZ0lDQWdJRzVsZDBodmJHUmxjbk5TYVdkb2RDQTlJR2x6UTNWeWNua2dQeUIxYm1SbFptbHVaV1FnT2lCaGNtZHpTRzlzWkdWeWN5eGNiaUFnSUNBZ0lDQWdJQ0FnSUc1bGQxQmhjblJwWVd4eklEMGdhWE5EZFhKeWVTQS9JR0Z5WjNNZ09pQjFibVJsWm1sdVpXUXNYRzRnSUNBZ0lDQWdJQ0FnSUNCdVpYZFFZWEowYVdGc2MxSnBaMmgwSUQwZ2FYTkRkWEp5ZVNBL0lIVnVaR1ZtYVc1bFpDQTZJR0Z5WjNNN1hHNWNiaUFnSUNBZ0lDQWdZbWwwYldGemF5QjhQU0FvYVhORGRYSnllU0EvSUZCQlVsUkpRVXhmUmt4QlJ5QTZJRkJCVWxSSlFVeGZVa2xIU0ZSZlJreEJSeWs3WEc0Z0lDQWdJQ0FnSUdKcGRHMWhjMnNnSmowZ2ZpaHBjME4xY25KNUlEOGdVRUZTVkVsQlRGOVNTVWRJVkY5R1RFRkhJRG9nVUVGU1ZFbEJURjlHVEVGSEtUdGNibHh1SUNBZ0lDQWdJQ0JwWmlBb0lXbHpRM1Z5Y25sQ2IzVnVaQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lHSnBkRzFoYzJzZ0pqMGdmaWhDU1U1RVgwWk1RVWNnZkNCQ1NVNUVYMHRGV1Y5R1RFRkhLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCMllYSWdibVYzUkdGMFlTQTlJRnRtZFc1akxDQmlhWFJ0WVhOckxDQjBhR2x6UVhKbkxDQnVaWGRRWVhKMGFXRnNjeXdnYm1WM2MwaHZiR1JsY25Nc0lHNWxkMUJoY25ScFlXeHpVbWxuYUhRc0lHNWxkMGh2YkdSbGNuTlNhV2RvZEN3Z2JtVjNRWEpuVUc5ekxDQmhjbmtzSUc1bGQwRnlhWFI1WFN4Y2JpQWdJQ0FnSUNBZ0lDQWdJSEpsYzNWc2RDQTlJR055WldGMFpVaDVZbkpwWkZkeVlYQndaWEl1WVhCd2JIa29kVzVrWldacGJtVmtMQ0J1WlhkRVlYUmhLVHRjYmx4dUlDQWdJQ0FnSUNCcFppQW9hWE5NWVhwcFlXSnNaU2htZFc1aktTa2dlMXh1SUNBZ0lDQWdJQ0FnSUhObGRFUmhkR0VvY21WemRXeDBMQ0J1WlhkRVlYUmhLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCeVpYTjFiSFF1Y0d4aFkyVm9iMnhrWlhJZ1BTQndiR0ZqWldodmJHUmxjanRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJSEpsYzNWc2REdGNiaUFnSUNBZ0lIMWNiaUFnSUNCOVhHNGdJQ0FnZG1GeUlIUm9hWE5DYVc1a2FXNW5JRDBnYVhOQ2FXNWtJRDhnZEdocGMwRnlaeUE2SUhSb2FYTXNYRzRnSUNBZ0lDQWdJR1p1SUQwZ2FYTkNhVzVrUzJWNUlEOGdkR2hwYzBKcGJtUnBibWRiWm5WdVkxMGdPaUJtZFc1ak8xeHVYRzRnSUNBZ2FXWWdLR0Z5WjFCdmN5a2dlMXh1SUNBZ0lDQWdZWEpuY3lBOUlISmxiM0prWlhJb1lYSm5jeXdnWVhKblVHOXpLVHRjYmlBZ0lDQjlYRzRnSUNBZ2FXWWdLR2x6UVhKNUlDWW1JR0Z5ZVNBOElHRnlaM011YkdWdVozUm9LU0I3WEc0Z0lDQWdJQ0JoY21kekxteGxibWQwYUNBOUlHRnllVHRjYmlBZ0lDQjlYRzRnSUNBZ2FXWWdLSFJvYVhNZ0ppWWdkR2hwY3lBaFBUMGdaMnh2WW1Gc0lDWW1JSFJvYVhNZ2FXNXpkR0Z1WTJWdlppQjNjbUZ3Y0dWeUtTQjdYRzRnSUNBZ0lDQm1iaUE5SUVOMGIzSWdmSHdnWTNKbFlYUmxRM1J2Y2xkeVlYQndaWElvWm5WdVl5azdYRzRnSUNBZ2ZWeHVJQ0FnSUhKbGRIVnliaUJtYmk1aGNIQnNlU2gwYUdselFtbHVaR2x1Wnl3Z1lYSm5jeWs3WEc0Z0lIMWNiaUFnY21WMGRYSnVJSGR5WVhCd1pYSTdYRzU5WEc1Y2JtMXZaSFZzWlM1bGVIQnZjblJ6SUQwZ1kzSmxZWFJsU0hsaWNtbGtWM0poY0hCbGNqdGNiaUpkZlE9PSIsIihmdW5jdGlvbiAoZ2xvYmFsKXtcbnZhciBjcmVhdGVDdG9yV3JhcHBlciA9IHJlcXVpcmUoJy4vY3JlYXRlQ3RvcldyYXBwZXInKTtcblxuLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3Igd3JhcHBlciBtZXRhZGF0YS4gKi9cbnZhciBCSU5EX0ZMQUcgPSAxO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHdyYXBzIGBmdW5jYCBhbmQgaW52b2tlcyBpdCB3aXRoIHRoZSBvcHRpb25hbCBgdGhpc2BcbiAqIGJpbmRpbmcgb2YgYHRoaXNBcmdgIGFuZCB0aGUgYHBhcnRpYWxzYCBwcmVwZW5kZWQgdG8gdGhvc2UgcHJvdmlkZWQgdG9cbiAqIHRoZSB3cmFwcGVyLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBwYXJ0aWFsbHkgYXBwbHkgYXJndW1lbnRzIHRvLlxuICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgb2YgZmxhZ3MuIFNlZSBgY3JlYXRlV3JhcHBlcmAgZm9yIG1vcmUgZGV0YWlscy5cbiAqIEBwYXJhbSB7Kn0gdGhpc0FyZyBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICogQHBhcmFtIHtBcnJheX0gcGFydGlhbHMgVGhlIGFyZ3VtZW50cyB0byBwcmVwZW5kIHRvIHRob3NlIHByb3ZpZGVkIHRvIHRoZSBuZXcgZnVuY3Rpb24uXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBib3VuZCBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlUGFydGlhbFdyYXBwZXIoZnVuYywgYml0bWFzaywgdGhpc0FyZywgcGFydGlhbHMpIHtcbiAgdmFyIGlzQmluZCA9IGJpdG1hc2sgJiBCSU5EX0ZMQUcsXG4gICAgICBDdG9yID0gY3JlYXRlQ3RvcldyYXBwZXIoZnVuYyk7XG5cbiAgZnVuY3Rpb24gd3JhcHBlcigpIHtcbiAgICAvLyBBdm9pZCBgYXJndW1lbnRzYCBvYmplY3QgdXNlIGRpc3F1YWxpZnlpbmcgb3B0aW1pemF0aW9ucyBieVxuICAgIC8vIGNvbnZlcnRpbmcgaXQgdG8gYW4gYXJyYXkgYmVmb3JlIHByb3ZpZGluZyBpdCBgZnVuY2AuXG4gICAgdmFyIGFyZ3NJbmRleCA9IC0xLFxuICAgICAgICBhcmdzTGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aCxcbiAgICAgICAgbGVmdEluZGV4ID0gLTEsXG4gICAgICAgIGxlZnRMZW5ndGggPSBwYXJ0aWFscy5sZW5ndGgsXG4gICAgICAgIGFyZ3MgPSBBcnJheShsZWZ0TGVuZ3RoICsgYXJnc0xlbmd0aCk7XG5cbiAgICB3aGlsZSAoKytsZWZ0SW5kZXggPCBsZWZ0TGVuZ3RoKSB7XG4gICAgICBhcmdzW2xlZnRJbmRleF0gPSBwYXJ0aWFsc1tsZWZ0SW5kZXhdO1xuICAgIH1cbiAgICB3aGlsZSAoYXJnc0xlbmd0aC0tKSB7XG4gICAgICBhcmdzW2xlZnRJbmRleCsrXSA9IGFyZ3VtZW50c1srK2FyZ3NJbmRleF07XG4gICAgfVxuICAgIHZhciBmbiA9ICh0aGlzICYmIHRoaXMgIT09IGdsb2JhbCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikgPyBDdG9yIDogZnVuYztcbiAgICByZXR1cm4gZm4uYXBwbHkoaXNCaW5kID8gdGhpc0FyZyA6IHRoaXMsIGFyZ3MpO1xuICB9XG4gIHJldHVybiB3cmFwcGVyO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZVBhcnRpYWxXcmFwcGVyO1xuXG59KS5jYWxsKHRoaXMsdHlwZW9mIGdsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIiA/IGdsb2JhbCA6IHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSlcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtjaGFyc2V0OnV0Zi04O2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKemIzVnlZMlZ6SWpwYkltNXZaR1ZmYlc5a2RXeGxjeTlzYjJSaGMyZ3RZMjl0Y0dGMEwybHVkR1Z5Ym1Gc0wyTnlaV0YwWlZCaGNuUnBZV3hYY21Gd2NHVnlMbXB6SWwwc0ltNWhiV1Z6SWpwYlhTd2liV0Z3Y0dsdVozTWlPaUk3UVVGQlFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQklpd2labWxzWlNJNkltZGxibVZ5WVhSbFpDNXFjeUlzSW5OdmRYSmpaVkp2YjNRaU9pSWlMQ0p6YjNWeVkyVnpRMjl1ZEdWdWRDSTZXeUoyWVhJZ1kzSmxZWFJsUTNSdmNsZHlZWEJ3WlhJZ1BTQnlaWEYxYVhKbEtDY3VMMk55WldGMFpVTjBiM0pYY21Gd2NHVnlKeWs3WEc1Y2JpOHFLaUJWYzJWa0lIUnZJR052YlhCdmMyVWdZbWwwYldGemEzTWdabTl5SUhkeVlYQndaWElnYldWMFlXUmhkR0V1SUNvdlhHNTJZWElnUWtsT1JGOUdURUZISUQwZ01UdGNibHh1THlvcVhHNGdLaUJEY21WaGRHVnpJR0VnWm5WdVkzUnBiMjRnZEdoaGRDQjNjbUZ3Y3lCZ1puVnVZMkFnWVc1a0lHbHVkbTlyWlhNZ2FYUWdkMmwwYUNCMGFHVWdiM0IwYVc5dVlXd2dZSFJvYVhOZ1hHNGdLaUJpYVc1a2FXNW5JRzltSUdCMGFHbHpRWEpuWUNCaGJtUWdkR2hsSUdCd1lYSjBhV0ZzYzJBZ2NISmxjR1Z1WkdWa0lIUnZJSFJvYjNObElIQnliM1pwWkdWa0lIUnZYRzRnS2lCMGFHVWdkM0poY0hCbGNpNWNiaUFxWEc0Z0tpQkFjSEpwZG1GMFpWeHVJQ29nUUhCaGNtRnRJSHRHZFc1amRHbHZibjBnWm5WdVl5QlVhR1VnWm5WdVkzUnBiMjRnZEc4Z2NHRnlkR2xoYkd4NUlHRndjR3g1SUdGeVozVnRaVzUwY3lCMGJ5NWNiaUFxSUVCd1lYSmhiU0I3Ym5WdFltVnlmU0JpYVhSdFlYTnJJRlJvWlNCaWFYUnRZWE5ySUc5bUlHWnNZV2R6TGlCVFpXVWdZR055WldGMFpWZHlZWEJ3WlhKZ0lHWnZjaUJ0YjNKbElHUmxkR0ZwYkhNdVhHNGdLaUJBY0dGeVlXMGdleXA5SUhSb2FYTkJjbWNnVkdobElHQjBhR2x6WUNCaWFXNWthVzVuSUc5bUlHQm1kVzVqWUM1Y2JpQXFJRUJ3WVhKaGJTQjdRWEp5WVhsOUlIQmhjblJwWVd4eklGUm9aU0JoY21kMWJXVnVkSE1nZEc4Z2NISmxjR1Z1WkNCMGJ5QjBhRzl6WlNCd2NtOTJhV1JsWkNCMGJ5QjBhR1VnYm1WM0lHWjFibU4wYVc5dUxseHVJQ29nUUhKbGRIVnlibk1nZTBaMWJtTjBhVzl1ZlNCU1pYUjFjbTV6SUhSb1pTQnVaWGNnWW05MWJtUWdablZ1WTNScGIyNHVYRzRnS2k5Y2JtWjFibU4wYVc5dUlHTnlaV0YwWlZCaGNuUnBZV3hYY21Gd2NHVnlLR1oxYm1Nc0lHSnBkRzFoYzJzc0lIUm9hWE5CY21jc0lIQmhjblJwWVd4ektTQjdYRzRnSUhaaGNpQnBjMEpwYm1RZ1BTQmlhWFJ0WVhOcklDWWdRa2xPUkY5R1RFRkhMRnh1SUNBZ0lDQWdRM1J2Y2lBOUlHTnlaV0YwWlVOMGIzSlhjbUZ3Y0dWeUtHWjFibU1wTzF4dVhHNGdJR1oxYm1OMGFXOXVJSGR5WVhCd1pYSW9LU0I3WEc0Z0lDQWdMeThnUVhadmFXUWdZR0Z5WjNWdFpXNTBjMkFnYjJKcVpXTjBJSFZ6WlNCa2FYTnhkV0ZzYVdaNWFXNW5JRzl3ZEdsdGFYcGhkR2x2Ym5NZ1lubGNiaUFnSUNBdkx5QmpiMjUyWlhKMGFXNW5JR2wwSUhSdklHRnVJR0Z5Y21GNUlHSmxabTl5WlNCd2NtOTJhV1JwYm1jZ2FYUWdZR1oxYm1OZ0xseHVJQ0FnSUhaaGNpQmhjbWR6U1c1a1pYZ2dQU0F0TVN4Y2JpQWdJQ0FnSUNBZ1lYSm5jMHhsYm1kMGFDQTlJR0Z5WjNWdFpXNTBjeTVzWlc1bmRHZ3NYRzRnSUNBZ0lDQWdJR3hsWm5SSmJtUmxlQ0E5SUMweExGeHVJQ0FnSUNBZ0lDQnNaV1owVEdWdVozUm9JRDBnY0dGeWRHbGhiSE11YkdWdVozUm9MRnh1SUNBZ0lDQWdJQ0JoY21keklEMGdRWEp5WVhrb2JHVm1kRXhsYm1kMGFDQXJJR0Z5WjNOTVpXNW5kR2dwTzF4dVhHNGdJQ0FnZDJocGJHVWdLQ3NyYkdWbWRFbHVaR1Y0SUR3Z2JHVm1kRXhsYm1kMGFDa2dlMXh1SUNBZ0lDQWdZWEpuYzF0c1pXWjBTVzVrWlhoZElEMGdjR0Z5ZEdsaGJITmJiR1ZtZEVsdVpHVjRYVHRjYmlBZ0lDQjlYRzRnSUNBZ2QyaHBiR1VnS0dGeVozTk1aVzVuZEdndExTa2dlMXh1SUNBZ0lDQWdZWEpuYzF0c1pXWjBTVzVrWlhncksxMGdQU0JoY21kMWJXVnVkSE5iS3l0aGNtZHpTVzVrWlhoZE8xeHVJQ0FnSUgxY2JpQWdJQ0IyWVhJZ1ptNGdQU0FvZEdocGN5QW1KaUIwYUdseklDRTlQU0JuYkc5aVlXd2dKaVlnZEdocGN5QnBibk4wWVc1alpXOW1JSGR5WVhCd1pYSXBJRDhnUTNSdmNpQTZJR1oxYm1NN1hHNGdJQ0FnY21WMGRYSnVJR1p1TG1Gd2NHeDVLR2x6UW1sdVpDQS9JSFJvYVhOQmNtY2dPaUIwYUdsekxDQmhjbWR6S1R0Y2JpQWdmVnh1SUNCeVpYUjFjbTRnZDNKaGNIQmxjanRjYm4xY2JseHViVzlrZFd4bExtVjRjRzl5ZEhNZ1BTQmpjbVZoZEdWUVlYSjBhV0ZzVjNKaGNIQmxjanRjYmlKZGZRPT0iLCJ2YXIgYmFzZVNldERhdGEgPSByZXF1aXJlKCcuL2Jhc2VTZXREYXRhJyksXG4gICAgY3JlYXRlQmluZFdyYXBwZXIgPSByZXF1aXJlKCcuL2NyZWF0ZUJpbmRXcmFwcGVyJyksXG4gICAgY3JlYXRlSHlicmlkV3JhcHBlciA9IHJlcXVpcmUoJy4vY3JlYXRlSHlicmlkV3JhcHBlcicpLFxuICAgIGNyZWF0ZVBhcnRpYWxXcmFwcGVyID0gcmVxdWlyZSgnLi9jcmVhdGVQYXJ0aWFsV3JhcHBlcicpLFxuICAgIGdldERhdGEgPSByZXF1aXJlKCcuL2dldERhdGEnKSxcbiAgICBtZXJnZURhdGEgPSByZXF1aXJlKCcuL21lcmdlRGF0YScpLFxuICAgIHNldERhdGEgPSByZXF1aXJlKCcuL3NldERhdGEnKTtcblxuLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3Igd3JhcHBlciBtZXRhZGF0YS4gKi9cbnZhciBCSU5EX0ZMQUcgPSAxLFxuICAgIEJJTkRfS0VZX0ZMQUcgPSAyLFxuICAgIFBBUlRJQUxfRkxBRyA9IDMyLFxuICAgIFBBUlRJQUxfUklHSFRfRkxBRyA9IDY0O1xuXG4vKiogVXNlZCBhcyB0aGUgYFR5cGVFcnJvcmAgbWVzc2FnZSBmb3IgXCJGdW5jdGlvbnNcIiBtZXRob2RzLiAqL1xudmFyIEZVTkNfRVJST1JfVEVYVCA9ICdFeHBlY3RlZCBhIGZ1bmN0aW9uJztcblxuLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heDtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCBlaXRoZXIgY3VycmllcyBvciBpbnZva2VzIGBmdW5jYCB3aXRoIG9wdGlvbmFsXG4gKiBgdGhpc2AgYmluZGluZyBhbmQgcGFydGlhbGx5IGFwcGxpZWQgYXJndW1lbnRzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufHN0cmluZ30gZnVuYyBUaGUgZnVuY3Rpb24gb3IgbWV0aG9kIG5hbWUgdG8gcmVmZXJlbmNlLlxuICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgb2YgZmxhZ3MuXG4gKiAgVGhlIGJpdG1hc2sgbWF5IGJlIGNvbXBvc2VkIG9mIHRoZSBmb2xsb3dpbmcgZmxhZ3M6XG4gKiAgICAgMSAtIGBfLmJpbmRgXG4gKiAgICAgMiAtIGBfLmJpbmRLZXlgXG4gKiAgICAgNCAtIGBfLmN1cnJ5YCBvciBgXy5jdXJyeVJpZ2h0YCBvZiBhIGJvdW5kIGZ1bmN0aW9uXG4gKiAgICAgOCAtIGBfLmN1cnJ5YFxuICogICAgMTYgLSBgXy5jdXJyeVJpZ2h0YFxuICogICAgMzIgLSBgXy5wYXJ0aWFsYFxuICogICAgNjQgLSBgXy5wYXJ0aWFsUmlnaHRgXG4gKiAgIDEyOCAtIGBfLnJlYXJnYFxuICogICAyNTYgLSBgXy5hcnlgXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICogQHBhcmFtIHtBcnJheX0gW3BhcnRpYWxzXSBUaGUgYXJndW1lbnRzIHRvIGJlIHBhcnRpYWxseSBhcHBsaWVkLlxuICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNdIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gKiBAcGFyYW0ge0FycmF5fSBbYXJnUG9zXSBUaGUgYXJndW1lbnQgcG9zaXRpb25zIG9mIHRoZSBuZXcgZnVuY3Rpb24uXG4gKiBAcGFyYW0ge251bWJlcn0gW2FyeV0gVGhlIGFyaXR5IGNhcCBvZiBgZnVuY2AuXG4gKiBAcGFyYW0ge251bWJlcn0gW2FyaXR5XSBUaGUgYXJpdHkgb2YgYGZ1bmNgLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgd3JhcHBlZCBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlV3JhcHBlcihmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBwYXJ0aWFscywgaG9sZGVycywgYXJnUG9zLCBhcnksIGFyaXR5KSB7XG4gIHZhciBpc0JpbmRLZXkgPSBiaXRtYXNrICYgQklORF9LRVlfRkxBRztcbiAgaWYgKCFpc0JpbmRLZXkgJiYgdHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRlVOQ19FUlJPUl9URVhUKTtcbiAgfVxuICB2YXIgbGVuZ3RoID0gcGFydGlhbHMgPyBwYXJ0aWFscy5sZW5ndGggOiAwO1xuICBpZiAoIWxlbmd0aCkge1xuICAgIGJpdG1hc2sgJj0gfihQQVJUSUFMX0ZMQUcgfCBQQVJUSUFMX1JJR0hUX0ZMQUcpO1xuICAgIHBhcnRpYWxzID0gaG9sZGVycyA9IHVuZGVmaW5lZDtcbiAgfVxuICBsZW5ndGggLT0gKGhvbGRlcnMgPyBob2xkZXJzLmxlbmd0aCA6IDApO1xuICBpZiAoYml0bWFzayAmIFBBUlRJQUxfUklHSFRfRkxBRykge1xuICAgIHZhciBwYXJ0aWFsc1JpZ2h0ID0gcGFydGlhbHMsXG4gICAgICAgIGhvbGRlcnNSaWdodCA9IGhvbGRlcnM7XG5cbiAgICBwYXJ0aWFscyA9IGhvbGRlcnMgPSB1bmRlZmluZWQ7XG4gIH1cbiAgdmFyIGRhdGEgPSBpc0JpbmRLZXkgPyB1bmRlZmluZWQgOiBnZXREYXRhKGZ1bmMpLFxuICAgICAgbmV3RGF0YSA9IFtmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBwYXJ0aWFscywgaG9sZGVycywgcGFydGlhbHNSaWdodCwgaG9sZGVyc1JpZ2h0LCBhcmdQb3MsIGFyeSwgYXJpdHldO1xuXG4gIGlmIChkYXRhKSB7XG4gICAgbWVyZ2VEYXRhKG5ld0RhdGEsIGRhdGEpO1xuICAgIGJpdG1hc2sgPSBuZXdEYXRhWzFdO1xuICAgIGFyaXR5ID0gbmV3RGF0YVs5XTtcbiAgfVxuICBuZXdEYXRhWzldID0gYXJpdHkgPT0gbnVsbFxuICAgID8gKGlzQmluZEtleSA/IDAgOiBmdW5jLmxlbmd0aClcbiAgICA6IChuYXRpdmVNYXgoYXJpdHkgLSBsZW5ndGgsIDApIHx8IDApO1xuXG4gIGlmIChiaXRtYXNrID09IEJJTkRfRkxBRykge1xuICAgIHZhciByZXN1bHQgPSBjcmVhdGVCaW5kV3JhcHBlcihuZXdEYXRhWzBdLCBuZXdEYXRhWzJdKTtcbiAgfSBlbHNlIGlmICgoYml0bWFzayA9PSBQQVJUSUFMX0ZMQUcgfHwgYml0bWFzayA9PSAoQklORF9GTEFHIHwgUEFSVElBTF9GTEFHKSkgJiYgIW5ld0RhdGFbNF0ubGVuZ3RoKSB7XG4gICAgcmVzdWx0ID0gY3JlYXRlUGFydGlhbFdyYXBwZXIuYXBwbHkodW5kZWZpbmVkLCBuZXdEYXRhKTtcbiAgfSBlbHNlIHtcbiAgICByZXN1bHQgPSBjcmVhdGVIeWJyaWRXcmFwcGVyLmFwcGx5KHVuZGVmaW5lZCwgbmV3RGF0YSk7XG4gIH1cbiAgdmFyIHNldHRlciA9IGRhdGEgPyBiYXNlU2V0RGF0YSA6IHNldERhdGE7XG4gIHJldHVybiBzZXR0ZXIocmVzdWx0LCBuZXdEYXRhKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVXcmFwcGVyO1xuIiwidmFyIGFycmF5U29tZSA9IHJlcXVpcmUoJy4vYXJyYXlTb21lJyk7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlSXNFcXVhbERlZXBgIGZvciBhcnJheXMgd2l0aCBzdXBwb3J0IGZvclxuICogcGFydGlhbCBkZWVwIGNvbXBhcmlzb25zLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7QXJyYXl9IG90aGVyIFRoZSBvdGhlciBhcnJheSB0byBjb21wYXJlLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaW5nIGFycmF5cy5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzTG9vc2VdIFNwZWNpZnkgcGVyZm9ybWluZyBwYXJ0aWFsIGNvbXBhcmlzb25zLlxuICogQHBhcmFtIHtBcnJheX0gW3N0YWNrQV0gVHJhY2tzIHRyYXZlcnNlZCBgdmFsdWVgIG9iamVjdHMuXG4gKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tCXSBUcmFja3MgdHJhdmVyc2VkIGBvdGhlcmAgb2JqZWN0cy5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgYXJyYXlzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGVxdWFsQXJyYXlzKGFycmF5LCBvdGhlciwgZXF1YWxGdW5jLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQikge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGFyckxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIG90aExlbmd0aCA9IG90aGVyLmxlbmd0aDtcblxuICBpZiAoYXJyTGVuZ3RoICE9IG90aExlbmd0aCAmJiAhKGlzTG9vc2UgJiYgb3RoTGVuZ3RoID4gYXJyTGVuZ3RoKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICAvLyBJZ25vcmUgbm9uLWluZGV4IHByb3BlcnRpZXMuXG4gIHdoaWxlICgrK2luZGV4IDwgYXJyTGVuZ3RoKSB7XG4gICAgdmFyIGFyclZhbHVlID0gYXJyYXlbaW5kZXhdLFxuICAgICAgICBvdGhWYWx1ZSA9IG90aGVyW2luZGV4XSxcbiAgICAgICAgcmVzdWx0ID0gY3VzdG9taXplciA/IGN1c3RvbWl6ZXIoaXNMb29zZSA/IG90aFZhbHVlIDogYXJyVmFsdWUsIGlzTG9vc2UgPyBhcnJWYWx1ZSA6IG90aFZhbHVlLCBpbmRleCkgOiB1bmRlZmluZWQ7XG5cbiAgICBpZiAocmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIC8vIFJlY3Vyc2l2ZWx5IGNvbXBhcmUgYXJyYXlzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuXG4gICAgaWYgKGlzTG9vc2UpIHtcbiAgICAgIGlmICghYXJyYXlTb21lKG90aGVyLCBmdW5jdGlvbihvdGhWYWx1ZSkge1xuICAgICAgICAgICAgcmV0dXJuIGFyclZhbHVlID09PSBvdGhWYWx1ZSB8fCBlcXVhbEZ1bmMoYXJyVmFsdWUsIG90aFZhbHVlLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQik7XG4gICAgICAgICAgfSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoIShhcnJWYWx1ZSA9PT0gb3RoVmFsdWUgfHwgZXF1YWxGdW5jKGFyclZhbHVlLCBvdGhWYWx1ZSwgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBlcXVhbEFycmF5cztcbiIsIi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgIGRhdGVUYWcgPSAnW29iamVjdCBEYXRlXScsXG4gICAgZXJyb3JUYWcgPSAnW29iamVjdCBFcnJvcl0nLFxuICAgIG51bWJlclRhZyA9ICdbb2JqZWN0IE51bWJlcl0nLFxuICAgIHJlZ2V4cFRhZyA9ICdbb2JqZWN0IFJlZ0V4cF0nLFxuICAgIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nO1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxEZWVwYCBmb3IgY29tcGFyaW5nIG9iamVjdHMgb2ZcbiAqIHRoZSBzYW1lIGB0b1N0cmluZ1RhZ2AuXG4gKlxuICogKipOb3RlOioqIFRoaXMgZnVuY3Rpb24gb25seSBzdXBwb3J0cyBjb21wYXJpbmcgdmFsdWVzIHdpdGggdGFncyBvZlxuICogYEJvb2xlYW5gLCBgRGF0ZWAsIGBFcnJvcmAsIGBOdW1iZXJgLCBgUmVnRXhwYCwgb3IgYFN0cmluZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjb21wYXJlLlxuICogQHBhcmFtIHtPYmplY3R9IG90aGVyIFRoZSBvdGhlciBvYmplY3QgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0YWcgVGhlIGB0b1N0cmluZ1RhZ2Agb2YgdGhlIG9iamVjdHMgdG8gY29tcGFyZS5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgb2JqZWN0cyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBlcXVhbEJ5VGFnKG9iamVjdCwgb3RoZXIsIHRhZykge1xuICBzd2l0Y2ggKHRhZykge1xuICAgIGNhc2UgYm9vbFRhZzpcbiAgICBjYXNlIGRhdGVUYWc6XG4gICAgICAvLyBDb2VyY2UgZGF0ZXMgYW5kIGJvb2xlYW5zIHRvIG51bWJlcnMsIGRhdGVzIHRvIG1pbGxpc2Vjb25kcyBhbmQgYm9vbGVhbnNcbiAgICAgIC8vIHRvIGAxYCBvciBgMGAgdHJlYXRpbmcgaW52YWxpZCBkYXRlcyBjb2VyY2VkIHRvIGBOYU5gIGFzIG5vdCBlcXVhbC5cbiAgICAgIHJldHVybiArb2JqZWN0ID09ICtvdGhlcjtcblxuICAgIGNhc2UgZXJyb3JUYWc6XG4gICAgICByZXR1cm4gb2JqZWN0Lm5hbWUgPT0gb3RoZXIubmFtZSAmJiBvYmplY3QubWVzc2FnZSA9PSBvdGhlci5tZXNzYWdlO1xuXG4gICAgY2FzZSBudW1iZXJUYWc6XG4gICAgICAvLyBUcmVhdCBgTmFOYCB2cy4gYE5hTmAgYXMgZXF1YWwuXG4gICAgICByZXR1cm4gKG9iamVjdCAhPSArb2JqZWN0KVxuICAgICAgICA/IG90aGVyICE9ICtvdGhlclxuICAgICAgICA6IG9iamVjdCA9PSArb3RoZXI7XG5cbiAgICBjYXNlIHJlZ2V4cFRhZzpcbiAgICBjYXNlIHN0cmluZ1RhZzpcbiAgICAgIC8vIENvZXJjZSByZWdleGVzIHRvIHN0cmluZ3MgYW5kIHRyZWF0IHN0cmluZ3MgcHJpbWl0aXZlcyBhbmQgc3RyaW5nXG4gICAgICAvLyBvYmplY3RzIGFzIGVxdWFsLiBTZWUgaHR0cHM6Ly9lczUuZ2l0aHViLmlvLyN4MTUuMTAuNi40IGZvciBtb3JlIGRldGFpbHMuXG4gICAgICByZXR1cm4gb2JqZWN0ID09IChvdGhlciArICcnKTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZXF1YWxCeVRhZztcbiIsInZhciBrZXlzID0gcmVxdWlyZSgnLi4vb2JqZWN0L2tleXMnKTtcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlSXNFcXVhbERlZXBgIGZvciBvYmplY3RzIHdpdGggc3VwcG9ydCBmb3JcbiAqIHBhcnRpYWwgZGVlcCBjb21wYXJpc29ucy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge09iamVjdH0gb3RoZXIgVGhlIG90aGVyIG9iamVjdCB0byBjb21wYXJlLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaW5nIHZhbHVlcy5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzTG9vc2VdIFNwZWNpZnkgcGVyZm9ybWluZyBwYXJ0aWFsIGNvbXBhcmlzb25zLlxuICogQHBhcmFtIHtBcnJheX0gW3N0YWNrQV0gVHJhY2tzIHRyYXZlcnNlZCBgdmFsdWVgIG9iamVjdHMuXG4gKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tCXSBUcmFja3MgdHJhdmVyc2VkIGBvdGhlcmAgb2JqZWN0cy5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgb2JqZWN0cyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBlcXVhbE9iamVjdHMob2JqZWN0LCBvdGhlciwgZXF1YWxGdW5jLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQikge1xuICB2YXIgb2JqUHJvcHMgPSBrZXlzKG9iamVjdCksXG4gICAgICBvYmpMZW5ndGggPSBvYmpQcm9wcy5sZW5ndGgsXG4gICAgICBvdGhQcm9wcyA9IGtleXMob3RoZXIpLFxuICAgICAgb3RoTGVuZ3RoID0gb3RoUHJvcHMubGVuZ3RoO1xuXG4gIGlmIChvYmpMZW5ndGggIT0gb3RoTGVuZ3RoICYmICFpc0xvb3NlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciBpbmRleCA9IG9iakxlbmd0aDtcbiAgd2hpbGUgKGluZGV4LS0pIHtcbiAgICB2YXIga2V5ID0gb2JqUHJvcHNbaW5kZXhdO1xuICAgIGlmICghKGlzTG9vc2UgPyBrZXkgaW4gb3RoZXIgOiBoYXNPd25Qcm9wZXJ0eS5jYWxsKG90aGVyLCBrZXkpKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICB2YXIgc2tpcEN0b3IgPSBpc0xvb3NlO1xuICB3aGlsZSAoKytpbmRleCA8IG9iakxlbmd0aCkge1xuICAgIGtleSA9IG9ialByb3BzW2luZGV4XTtcbiAgICB2YXIgb2JqVmFsdWUgPSBvYmplY3Rba2V5XSxcbiAgICAgICAgb3RoVmFsdWUgPSBvdGhlcltrZXldLFxuICAgICAgICByZXN1bHQgPSBjdXN0b21pemVyID8gY3VzdG9taXplcihpc0xvb3NlID8gb3RoVmFsdWUgOiBvYmpWYWx1ZSwgaXNMb29zZT8gb2JqVmFsdWUgOiBvdGhWYWx1ZSwga2V5KSA6IHVuZGVmaW5lZDtcblxuICAgIC8vIFJlY3Vyc2l2ZWx5IGNvbXBhcmUgb2JqZWN0cyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLlxuICAgIGlmICghKHJlc3VsdCA9PT0gdW5kZWZpbmVkID8gZXF1YWxGdW5jKG9ialZhbHVlLCBvdGhWYWx1ZSwgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpIDogcmVzdWx0KSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBza2lwQ3RvciB8fCAoc2tpcEN0b3IgPSBrZXkgPT0gJ2NvbnN0cnVjdG9yJyk7XG4gIH1cbiAgaWYgKCFza2lwQ3Rvcikge1xuICAgIHZhciBvYmpDdG9yID0gb2JqZWN0LmNvbnN0cnVjdG9yLFxuICAgICAgICBvdGhDdG9yID0gb3RoZXIuY29uc3RydWN0b3I7XG5cbiAgICAvLyBOb24gYE9iamVjdGAgb2JqZWN0IGluc3RhbmNlcyB3aXRoIGRpZmZlcmVudCBjb25zdHJ1Y3RvcnMgYXJlIG5vdCBlcXVhbC5cbiAgICBpZiAob2JqQ3RvciAhPSBvdGhDdG9yICYmXG4gICAgICAgICgnY29uc3RydWN0b3InIGluIG9iamVjdCAmJiAnY29uc3RydWN0b3InIGluIG90aGVyKSAmJlxuICAgICAgICAhKHR5cGVvZiBvYmpDdG9yID09ICdmdW5jdGlvbicgJiYgb2JqQ3RvciBpbnN0YW5jZW9mIG9iakN0b3IgJiZcbiAgICAgICAgICB0eXBlb2Ygb3RoQ3RvciA9PSAnZnVuY3Rpb24nICYmIG90aEN0b3IgaW5zdGFuY2VvZiBvdGhDdG9yKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBlcXVhbE9iamVjdHM7XG4iLCJ2YXIgbWV0YU1hcCA9IHJlcXVpcmUoJy4vbWV0YU1hcCcpLFxuICAgIG5vb3AgPSByZXF1aXJlKCcuLi91dGlsaXR5L25vb3AnKTtcblxuLyoqXG4gKiBHZXRzIG1ldGFkYXRhIGZvciBgZnVuY2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHF1ZXJ5LlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG1ldGFkYXRhIGZvciBgZnVuY2AuXG4gKi9cbnZhciBnZXREYXRhID0gIW1ldGFNYXAgPyBub29wIDogZnVuY3Rpb24oZnVuYykge1xuICByZXR1cm4gbWV0YU1hcC5nZXQoZnVuYyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGdldERhdGE7XG4iLCJ2YXIgcmVhbE5hbWVzID0gcmVxdWlyZSgnLi9yZWFsTmFtZXMnKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBuYW1lIG9mIGBmdW5jYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBmdW5jdGlvbiBuYW1lLlxuICovXG5mdW5jdGlvbiBnZXRGdW5jTmFtZShmdW5jKSB7XG4gIHZhciByZXN1bHQgPSAoZnVuYy5uYW1lICsgJycpLFxuICAgICAgYXJyYXkgPSByZWFsTmFtZXNbcmVzdWx0XSxcbiAgICAgIGxlbmd0aCA9IGFycmF5ID8gYXJyYXkubGVuZ3RoIDogMDtcblxuICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICB2YXIgZGF0YSA9IGFycmF5W2xlbmd0aF0sXG4gICAgICAgIG90aGVyRnVuYyA9IGRhdGEuZnVuYztcbiAgICBpZiAob3RoZXJGdW5jID09IG51bGwgfHwgb3RoZXJGdW5jID09IGZ1bmMpIHtcbiAgICAgIHJldHVybiBkYXRhLm5hbWU7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0RnVuY05hbWU7XG4iLCJ2YXIgYmFzZVByb3BlcnR5ID0gcmVxdWlyZSgnLi9iYXNlUHJvcGVydHknKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBcImxlbmd0aFwiIHByb3BlcnR5IHZhbHVlIG9mIGBvYmplY3RgLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gYXZvaWQgYSBbSklUIGJ1Z10oaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTE0Mjc5MilcbiAqIHRoYXQgYWZmZWN0cyBTYWZhcmkgb24gYXQgbGVhc3QgaU9TIDguMS04LjMgQVJNNjQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBcImxlbmd0aFwiIHZhbHVlLlxuICovXG52YXIgZ2V0TGVuZ3RoID0gYmFzZVByb3BlcnR5KCdsZW5ndGgnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBnZXRMZW5ndGg7XG4iLCJ2YXIgaXNTdHJpY3RDb21wYXJhYmxlID0gcmVxdWlyZSgnLi9pc1N0cmljdENvbXBhcmFibGUnKSxcbiAgICBwYWlycyA9IHJlcXVpcmUoJy4uL29iamVjdC9wYWlycycpO1xuXG4vKipcbiAqIEdldHMgdGhlIHByb3BlcnkgbmFtZXMsIHZhbHVlcywgYW5kIGNvbXBhcmUgZmxhZ3Mgb2YgYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbWF0Y2ggZGF0YSBvZiBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gZ2V0TWF0Y2hEYXRhKG9iamVjdCkge1xuICB2YXIgcmVzdWx0ID0gcGFpcnMob2JqZWN0KSxcbiAgICAgIGxlbmd0aCA9IHJlc3VsdC5sZW5ndGg7XG5cbiAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgcmVzdWx0W2xlbmd0aF1bMl0gPSBpc1N0cmljdENvbXBhcmFibGUocmVzdWx0W2xlbmd0aF1bMV0pO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0TWF0Y2hEYXRhO1xuIiwidmFyIGlzTmF0aXZlID0gcmVxdWlyZSgnLi4vbGFuZy9pc05hdGl2ZScpO1xuXG4vKipcbiAqIEdldHMgdGhlIG5hdGl2ZSBmdW5jdGlvbiBhdCBga2V5YCBvZiBgb2JqZWN0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBtZXRob2QgdG8gZ2V0LlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGZ1bmN0aW9uIGlmIGl0J3MgbmF0aXZlLCBlbHNlIGB1bmRlZmluZWRgLlxuICovXG5mdW5jdGlvbiBnZXROYXRpdmUob2JqZWN0LCBrZXkpIHtcbiAgdmFyIHZhbHVlID0gb2JqZWN0ID09IG51bGwgPyB1bmRlZmluZWQgOiBvYmplY3Rba2V5XTtcbiAgcmV0dXJuIGlzTmF0aXZlKHZhbHVlKSA/IHZhbHVlIDogdW5kZWZpbmVkO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldE5hdGl2ZTtcbiIsIi8qKlxuICogR2V0cyB0aGUgaW5kZXggYXQgd2hpY2ggdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgYE5hTmAgaXMgZm91bmQgaW4gYGFycmF5YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNlYXJjaC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBmcm9tSW5kZXggVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCBgTmFOYCwgZWxzZSBgLTFgLlxuICovXG5mdW5jdGlvbiBpbmRleE9mTmFOKGFycmF5LCBmcm9tSW5kZXgsIGZyb21SaWdodCkge1xuICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgaW5kZXggPSBmcm9tSW5kZXggKyAoZnJvbVJpZ2h0ID8gMCA6IC0xKTtcblxuICB3aGlsZSAoKGZyb21SaWdodCA/IGluZGV4LS0gOiArK2luZGV4IDwgbGVuZ3RoKSkge1xuICAgIHZhciBvdGhlciA9IGFycmF5W2luZGV4XTtcbiAgICBpZiAob3RoZXIgIT09IG90aGVyKSB7XG4gICAgICByZXR1cm4gaW5kZXg7XG4gICAgfVxuICB9XG4gIHJldHVybiAtMTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpbmRleE9mTmFOO1xuIiwiLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogSW5pdGlhbGl6ZXMgYW4gYXJyYXkgY2xvbmUuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBjbG9uZS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgaW5pdGlhbGl6ZWQgY2xvbmUuXG4gKi9cbmZ1bmN0aW9uIGluaXRDbG9uZUFycmF5KGFycmF5KSB7XG4gIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBuZXcgYXJyYXkuY29uc3RydWN0b3IobGVuZ3RoKTtcblxuICAvLyBBZGQgYXJyYXkgcHJvcGVydGllcyBhc3NpZ25lZCBieSBgUmVnRXhwI2V4ZWNgLlxuICBpZiAobGVuZ3RoICYmIHR5cGVvZiBhcnJheVswXSA9PSAnc3RyaW5nJyAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKGFycmF5LCAnaW5kZXgnKSkge1xuICAgIHJlc3VsdC5pbmRleCA9IGFycmF5LmluZGV4O1xuICAgIHJlc3VsdC5pbnB1dCA9IGFycmF5LmlucHV0O1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaW5pdENsb25lQXJyYXk7XG4iLCIoZnVuY3Rpb24gKGdsb2JhbCl7XG52YXIgYnVmZmVyQ2xvbmUgPSByZXF1aXJlKCcuL2J1ZmZlckNsb25lJyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgIGRhdGVUYWcgPSAnW29iamVjdCBEYXRlXScsXG4gICAgbnVtYmVyVGFnID0gJ1tvYmplY3QgTnVtYmVyXScsXG4gICAgcmVnZXhwVGFnID0gJ1tvYmplY3QgUmVnRXhwXScsXG4gICAgc3RyaW5nVGFnID0gJ1tvYmplY3QgU3RyaW5nXSc7XG5cbnZhciBhcnJheUJ1ZmZlclRhZyA9ICdbb2JqZWN0IEFycmF5QnVmZmVyXScsXG4gICAgZmxvYXQzMlRhZyA9ICdbb2JqZWN0IEZsb2F0MzJBcnJheV0nLFxuICAgIGZsb2F0NjRUYWcgPSAnW29iamVjdCBGbG9hdDY0QXJyYXldJyxcbiAgICBpbnQ4VGFnID0gJ1tvYmplY3QgSW50OEFycmF5XScsXG4gICAgaW50MTZUYWcgPSAnW29iamVjdCBJbnQxNkFycmF5XScsXG4gICAgaW50MzJUYWcgPSAnW29iamVjdCBJbnQzMkFycmF5XScsXG4gICAgdWludDhUYWcgPSAnW29iamVjdCBVaW50OEFycmF5XScsXG4gICAgdWludDhDbGFtcGVkVGFnID0gJ1tvYmplY3QgVWludDhDbGFtcGVkQXJyYXldJyxcbiAgICB1aW50MTZUYWcgPSAnW29iamVjdCBVaW50MTZBcnJheV0nLFxuICAgIHVpbnQzMlRhZyA9ICdbb2JqZWN0IFVpbnQzMkFycmF5XSc7XG5cbi8qKiBVc2VkIHRvIG1hdGNoIGBSZWdFeHBgIGZsYWdzIGZyb20gdGhlaXIgY29lcmNlZCBzdHJpbmcgdmFsdWVzLiAqL1xudmFyIHJlRmxhZ3MgPSAvXFx3KiQvO1xuXG4vKiogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIFVpbnQ4QXJyYXkgPSBnbG9iYWwuVWludDhBcnJheTtcblxuLyoqIFVzZWQgdG8gbG9va3VwIGEgdHlwZSBhcnJheSBjb25zdHJ1Y3RvcnMgYnkgYHRvU3RyaW5nVGFnYC4gKi9cbnZhciBjdG9yQnlUYWcgPSB7fTtcbmN0b3JCeVRhZ1tmbG9hdDMyVGFnXSA9IGdsb2JhbC5GbG9hdDMyQXJyYXk7XG5jdG9yQnlUYWdbZmxvYXQ2NFRhZ10gPSBnbG9iYWwuRmxvYXQ2NEFycmF5O1xuY3RvckJ5VGFnW2ludDhUYWddID0gZ2xvYmFsLkludDhBcnJheTtcbmN0b3JCeVRhZ1tpbnQxNlRhZ10gPSBnbG9iYWwuSW50MTZBcnJheTtcbmN0b3JCeVRhZ1tpbnQzMlRhZ10gPSBnbG9iYWwuSW50MzJBcnJheTtcbmN0b3JCeVRhZ1t1aW50OFRhZ10gPSBVaW50OEFycmF5O1xuY3RvckJ5VGFnW3VpbnQ4Q2xhbXBlZFRhZ10gPSBnbG9iYWwuVWludDhDbGFtcGVkQXJyYXk7XG5jdG9yQnlUYWdbdWludDE2VGFnXSA9IGdsb2JhbC5VaW50MTZBcnJheTtcbmN0b3JCeVRhZ1t1aW50MzJUYWddID0gZ2xvYmFsLlVpbnQzMkFycmF5O1xuXG4vKipcbiAqIEluaXRpYWxpemVzIGFuIG9iamVjdCBjbG9uZSBiYXNlZCBvbiBpdHMgYHRvU3RyaW5nVGFnYC5cbiAqXG4gKiAqKk5vdGU6KiogVGhpcyBmdW5jdGlvbiBvbmx5IHN1cHBvcnRzIGNsb25pbmcgdmFsdWVzIHdpdGggdGFncyBvZlxuICogYEJvb2xlYW5gLCBgRGF0ZWAsIGBFcnJvcmAsIGBOdW1iZXJgLCBgUmVnRXhwYCwgb3IgYFN0cmluZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjbG9uZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0YWcgVGhlIGB0b1N0cmluZ1RhZ2Agb2YgdGhlIG9iamVjdCB0byBjbG9uZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzRGVlcF0gU3BlY2lmeSBhIGRlZXAgY2xvbmUuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBpbml0aWFsaXplZCBjbG9uZS5cbiAqL1xuZnVuY3Rpb24gaW5pdENsb25lQnlUYWcob2JqZWN0LCB0YWcsIGlzRGVlcCkge1xuICB2YXIgQ3RvciA9IG9iamVjdC5jb25zdHJ1Y3RvcjtcbiAgc3dpdGNoICh0YWcpIHtcbiAgICBjYXNlIGFycmF5QnVmZmVyVGFnOlxuICAgICAgcmV0dXJuIGJ1ZmZlckNsb25lKG9iamVjdCk7XG5cbiAgICBjYXNlIGJvb2xUYWc6XG4gICAgY2FzZSBkYXRlVGFnOlxuICAgICAgcmV0dXJuIG5ldyBDdG9yKCtvYmplY3QpO1xuXG4gICAgY2FzZSBmbG9hdDMyVGFnOiBjYXNlIGZsb2F0NjRUYWc6XG4gICAgY2FzZSBpbnQ4VGFnOiBjYXNlIGludDE2VGFnOiBjYXNlIGludDMyVGFnOlxuICAgIGNhc2UgdWludDhUYWc6IGNhc2UgdWludDhDbGFtcGVkVGFnOiBjYXNlIHVpbnQxNlRhZzogY2FzZSB1aW50MzJUYWc6XG4gICAgICAvLyBTYWZhcmkgNSBtb2JpbGUgaW5jb3JyZWN0bHkgaGFzIGBPYmplY3RgIGFzIHRoZSBjb25zdHJ1Y3RvciBvZiB0eXBlZCBhcnJheXMuXG4gICAgICBpZiAoQ3RvciBpbnN0YW5jZW9mIEN0b3IpIHtcbiAgICAgICAgQ3RvciA9IGN0b3JCeVRhZ1t0YWddO1xuICAgICAgfVxuICAgICAgdmFyIGJ1ZmZlciA9IG9iamVjdC5idWZmZXI7XG4gICAgICByZXR1cm4gbmV3IEN0b3IoaXNEZWVwID8gYnVmZmVyQ2xvbmUoYnVmZmVyKSA6IGJ1ZmZlciwgb2JqZWN0LmJ5dGVPZmZzZXQsIG9iamVjdC5sZW5ndGgpO1xuXG4gICAgY2FzZSBudW1iZXJUYWc6XG4gICAgY2FzZSBzdHJpbmdUYWc6XG4gICAgICByZXR1cm4gbmV3IEN0b3Iob2JqZWN0KTtcblxuICAgIGNhc2UgcmVnZXhwVGFnOlxuICAgICAgdmFyIHJlc3VsdCA9IG5ldyBDdG9yKG9iamVjdC5zb3VyY2UsIHJlRmxhZ3MuZXhlYyhvYmplY3QpKTtcbiAgICAgIHJlc3VsdC5sYXN0SW5kZXggPSBvYmplY3QubGFzdEluZGV4O1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaW5pdENsb25lQnlUYWc7XG5cbn0pLmNhbGwodGhpcyx0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiID8gZ2xvYmFsIDogdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9KVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ6dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p6YjNWeVkyVnpJanBiSW01dlpHVmZiVzlrZFd4bGN5OXNiMlJoYzJndFkyOXRjR0YwTDJsdWRHVnlibUZzTDJsdWFYUkRiRzl1WlVKNVZHRm5MbXB6SWwwc0ltNWhiV1Z6SWpwYlhTd2liV0Z3Y0dsdVozTWlPaUk3UVVGQlFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CSWl3aVptbHNaU0k2SW1kbGJtVnlZWFJsWkM1cWN5SXNJbk52ZFhKalpWSnZiM1FpT2lJaUxDSnpiM1Z5WTJWelEyOXVkR1Z1ZENJNld5SjJZWElnWW5WbVptVnlRMnh2Ym1VZ1BTQnlaWEYxYVhKbEtDY3VMMkoxWm1abGNrTnNiMjVsSnlrN1hHNWNiaThxS2lCZ1QySnFaV04wSTNSdlUzUnlhVzVuWUNCeVpYTjFiSFFnY21WbVpYSmxibU5sY3k0Z0tpOWNiblpoY2lCaWIyOXNWR0ZuSUQwZ0oxdHZZbXBsWTNRZ1FtOXZiR1ZoYmwwbkxGeHVJQ0FnSUdSaGRHVlVZV2NnUFNBblcyOWlhbVZqZENCRVlYUmxYU2NzWEc0Z0lDQWdiblZ0WW1WeVZHRm5JRDBnSjF0dlltcGxZM1FnVG5WdFltVnlYU2NzWEc0Z0lDQWdjbVZuWlhod1ZHRm5JRDBnSjF0dlltcGxZM1FnVW1WblJYaHdYU2NzWEc0Z0lDQWdjM1J5YVc1blZHRm5JRDBnSjF0dlltcGxZM1FnVTNSeWFXNW5YU2M3WEc1Y2JuWmhjaUJoY25KaGVVSjFabVpsY2xSaFp5QTlJQ2RiYjJKcVpXTjBJRUZ5Y21GNVFuVm1abVZ5WFNjc1hHNGdJQ0FnWm14dllYUXpNbFJoWnlBOUlDZGJiMkpxWldOMElFWnNiMkYwTXpKQmNuSmhlVjBuTEZ4dUlDQWdJR1pzYjJGME5qUlVZV2NnUFNBblcyOWlhbVZqZENCR2JHOWhkRFkwUVhKeVlYbGRKeXhjYmlBZ0lDQnBiblE0VkdGbklEMGdKMXR2WW1wbFkzUWdTVzUwT0VGeWNtRjVYU2NzWEc0Z0lDQWdhVzUwTVRaVVlXY2dQU0FuVzI5aWFtVmpkQ0JKYm5ReE5rRnljbUY1WFNjc1hHNGdJQ0FnYVc1ME16SlVZV2NnUFNBblcyOWlhbVZqZENCSmJuUXpNa0Z5Y21GNVhTY3NYRzRnSUNBZ2RXbHVkRGhVWVdjZ1BTQW5XMjlpYW1WamRDQlZhVzUwT0VGeWNtRjVYU2NzWEc0Z0lDQWdkV2x1ZERoRGJHRnRjR1ZrVkdGbklEMGdKMXR2WW1wbFkzUWdWV2x1ZERoRGJHRnRjR1ZrUVhKeVlYbGRKeXhjYmlBZ0lDQjFhVzUwTVRaVVlXY2dQU0FuVzI5aWFtVmpkQ0JWYVc1ME1UWkJjbkpoZVYwbkxGeHVJQ0FnSUhWcGJuUXpNbFJoWnlBOUlDZGJiMkpxWldOMElGVnBiblF6TWtGeWNtRjVYU2M3WEc1Y2JpOHFLaUJWYzJWa0lIUnZJRzFoZEdOb0lHQlNaV2RGZUhCZ0lHWnNZV2R6SUdaeWIyMGdkR2hsYVhJZ1kyOWxjbU5sWkNCemRISnBibWNnZG1Gc2RXVnpMaUFxTDF4dWRtRnlJSEpsUm14aFozTWdQU0F2WEZ4M0tpUXZPMXh1WEc0dktpb2dUbUYwYVhabElHMWxkR2h2WkNCeVpXWmxjbVZ1WTJWekxpQXFMMXh1ZG1GeUlGVnBiblE0UVhKeVlYa2dQU0JuYkc5aVlXd3VWV2x1ZERoQmNuSmhlVHRjYmx4dUx5b3FJRlZ6WldRZ2RHOGdiRzl2YTNWd0lHRWdkSGx3WlNCaGNuSmhlU0JqYjI1emRISjFZM1J2Y25NZ1lua2dZSFJ2VTNSeWFXNW5WR0ZuWUM0Z0tpOWNiblpoY2lCamRHOXlRbmxVWVdjZ1BTQjdmVHRjYm1OMGIzSkNlVlJoWjF0bWJHOWhkRE15VkdGblhTQTlJR2RzYjJKaGJDNUdiRzloZERNeVFYSnlZWGs3WEc1amRHOXlRbmxVWVdkYlpteHZZWFEyTkZSaFoxMGdQU0JuYkc5aVlXd3VSbXh2WVhRMk5FRnljbUY1TzF4dVkzUnZja0o1VkdGblcybHVkRGhVWVdkZElEMGdaMnh2WW1Gc0xrbHVkRGhCY25KaGVUdGNibU4wYjNKQ2VWUmhaMXRwYm5ReE5sUmhaMTBnUFNCbmJHOWlZV3d1U1c1ME1UWkJjbkpoZVR0Y2JtTjBiM0pDZVZSaFoxdHBiblF6TWxSaFoxMGdQU0JuYkc5aVlXd3VTVzUwTXpKQmNuSmhlVHRjYm1OMGIzSkNlVlJoWjF0MWFXNTBPRlJoWjEwZ1BTQlZhVzUwT0VGeWNtRjVPMXh1WTNSdmNrSjVWR0ZuVzNWcGJuUTRRMnhoYlhCbFpGUmhaMTBnUFNCbmJHOWlZV3d1VldsdWREaERiR0Z0Y0dWa1FYSnlZWGs3WEc1amRHOXlRbmxVWVdkYmRXbHVkREUyVkdGblhTQTlJR2RzYjJKaGJDNVZhVzUwTVRaQmNuSmhlVHRjYm1OMGIzSkNlVlJoWjF0MWFXNTBNekpVWVdkZElEMGdaMnh2WW1Gc0xsVnBiblF6TWtGeWNtRjVPMXh1WEc0dktpcGNiaUFxSUVsdWFYUnBZV3hwZW1WeklHRnVJRzlpYW1WamRDQmpiRzl1WlNCaVlYTmxaQ0J2YmlCcGRITWdZSFJ2VTNSeWFXNW5WR0ZuWUM1Y2JpQXFYRzRnS2lBcUtrNXZkR1U2S2lvZ1ZHaHBjeUJtZFc1amRHbHZiaUJ2Ym14NUlITjFjSEJ2Y25SeklHTnNiMjVwYm1jZ2RtRnNkV1Z6SUhkcGRHZ2dkR0ZuY3lCdlpseHVJQ29nWUVKdmIyeGxZVzVnTENCZ1JHRjBaV0FzSUdCRmNuSnZjbUFzSUdCT2RXMWlaWEpnTENCZ1VtVm5SWGh3WUN3Z2IzSWdZRk4wY21sdVoyQXVYRzRnS2x4dUlDb2dRSEJ5YVhaaGRHVmNiaUFxSUVCd1lYSmhiU0I3VDJKcVpXTjBmU0J2WW1wbFkzUWdWR2hsSUc5aWFtVmpkQ0IwYnlCamJHOXVaUzVjYmlBcUlFQndZWEpoYlNCN2MzUnlhVzVuZlNCMFlXY2dWR2hsSUdCMGIxTjBjbWx1WjFSaFoyQWdiMllnZEdobElHOWlhbVZqZENCMGJ5QmpiRzl1WlM1Y2JpQXFJRUJ3WVhKaGJTQjdZbTl2YkdWaGJuMGdXMmx6UkdWbGNGMGdVM0JsWTJsbWVTQmhJR1JsWlhBZ1kyeHZibVV1WEc0Z0tpQkFjbVYwZFhKdWN5QjdUMkpxWldOMGZTQlNaWFIxY201eklIUm9aU0JwYm1sMGFXRnNhWHBsWkNCamJHOXVaUzVjYmlBcUwxeHVablZ1WTNScGIyNGdhVzVwZEVOc2IyNWxRbmxVWVdjb2IySnFaV04wTENCMFlXY3NJR2x6UkdWbGNDa2dlMXh1SUNCMllYSWdRM1J2Y2lBOUlHOWlhbVZqZEM1amIyNXpkSEoxWTNSdmNqdGNiaUFnYzNkcGRHTm9JQ2gwWVdjcElIdGNiaUFnSUNCallYTmxJR0Z5Y21GNVFuVm1abVZ5VkdGbk9seHVJQ0FnSUNBZ2NtVjBkWEp1SUdKMVptWmxja05zYjI1bEtHOWlhbVZqZENrN1hHNWNiaUFnSUNCallYTmxJR0p2YjJ4VVlXYzZYRzRnSUNBZ1kyRnpaU0JrWVhSbFZHRm5PbHh1SUNBZ0lDQWdjbVYwZFhKdUlHNWxkeUJEZEc5eUtDdHZZbXBsWTNRcE8xeHVYRzRnSUNBZ1kyRnpaU0JtYkc5aGRETXlWR0ZuT2lCallYTmxJR1pzYjJGME5qUlVZV2M2WEc0Z0lDQWdZMkZ6WlNCcGJuUTRWR0ZuT2lCallYTmxJR2x1ZERFMlZHRm5PaUJqWVhObElHbHVkRE15VkdGbk9seHVJQ0FnSUdOaGMyVWdkV2x1ZERoVVlXYzZJR05oYzJVZ2RXbHVkRGhEYkdGdGNHVmtWR0ZuT2lCallYTmxJSFZwYm5ReE5sUmhaem9nWTJGelpTQjFhVzUwTXpKVVlXYzZYRzRnSUNBZ0lDQXZMeUJUWVdaaGNta2dOU0J0YjJKcGJHVWdhVzVqYjNKeVpXTjBiSGtnYUdGeklHQlBZbXBsWTNSZ0lHRnpJSFJvWlNCamIyNXpkSEoxWTNSdmNpQnZaaUIwZVhCbFpDQmhjbkpoZVhNdVhHNGdJQ0FnSUNCcFppQW9RM1J2Y2lCcGJuTjBZVzVqWlc5bUlFTjBiM0lwSUh0Y2JpQWdJQ0FnSUNBZ1EzUnZjaUE5SUdOMGIzSkNlVlJoWjF0MFlXZGRPMXh1SUNBZ0lDQWdmVnh1SUNBZ0lDQWdkbUZ5SUdKMVptWmxjaUE5SUc5aWFtVmpkQzVpZFdabVpYSTdYRzRnSUNBZ0lDQnlaWFIxY200Z2JtVjNJRU4wYjNJb2FYTkVaV1Z3SUQ4Z1luVm1abVZ5UTJ4dmJtVW9ZblZtWm1WeUtTQTZJR0oxWm1abGNpd2diMkpxWldOMExtSjVkR1ZQWm1aelpYUXNJRzlpYW1WamRDNXNaVzVuZEdncE8xeHVYRzRnSUNBZ1kyRnpaU0J1ZFcxaVpYSlVZV2M2WEc0Z0lDQWdZMkZ6WlNCemRISnBibWRVWVdjNlhHNGdJQ0FnSUNCeVpYUjFjbTRnYm1WM0lFTjBiM0lvYjJKcVpXTjBLVHRjYmx4dUlDQWdJR05oYzJVZ2NtVm5aWGh3VkdGbk9seHVJQ0FnSUNBZ2RtRnlJSEpsYzNWc2RDQTlJRzVsZHlCRGRHOXlLRzlpYW1WamRDNXpiM1Z5WTJVc0lISmxSbXhoWjNNdVpYaGxZeWh2WW1wbFkzUXBLVHRjYmlBZ0lDQWdJSEpsYzNWc2RDNXNZWE4wU1c1a1pYZ2dQU0J2WW1wbFkzUXViR0Z6ZEVsdVpHVjRPMXh1SUNCOVhHNGdJSEpsZEhWeWJpQnlaWE4xYkhRN1hHNTlYRzVjYm0xdlpIVnNaUzVsZUhCdmNuUnpJRDBnYVc1cGRFTnNiMjVsUW5sVVlXYzdYRzRpWFgwPSIsIi8qKlxuICogSW5pdGlhbGl6ZXMgYW4gb2JqZWN0IGNsb25lLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY2xvbmUuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBpbml0aWFsaXplZCBjbG9uZS5cbiAqL1xuZnVuY3Rpb24gaW5pdENsb25lT2JqZWN0KG9iamVjdCkge1xuICB2YXIgQ3RvciA9IG9iamVjdC5jb25zdHJ1Y3RvcjtcbiAgaWYgKCEodHlwZW9mIEN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiBDdG9yIGluc3RhbmNlb2YgQ3RvcikpIHtcbiAgICBDdG9yID0gT2JqZWN0O1xuICB9XG4gIHJldHVybiBuZXcgQ3Rvcjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpbml0Q2xvbmVPYmplY3Q7XG4iLCJ2YXIgZ2V0TGVuZ3RoID0gcmVxdWlyZSgnLi9nZXRMZW5ndGgnKSxcbiAgICBpc0xlbmd0aCA9IHJlcXVpcmUoJy4vaXNMZW5ndGgnKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhcnJheS1saWtlLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFycmF5LWxpa2UsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNBcnJheUxpa2UodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlICE9IG51bGwgJiYgaXNMZW5ndGgoZ2V0TGVuZ3RoKHZhbHVlKSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNBcnJheUxpa2U7XG4iLCIvKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgaG9zdCBvYmplY3QgaW4gSUUgPCA5LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgaG9zdCBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAqL1xudmFyIGlzSG9zdE9iamVjdCA9IChmdW5jdGlvbigpIHtcbiAgdHJ5IHtcbiAgICBPYmplY3QoeyAndG9TdHJpbmcnOiAwIH0gKyAnJyk7XG4gIH0gY2F0Y2goZSkge1xuICAgIHJldHVybiBmdW5jdGlvbigpIHsgcmV0dXJuIGZhbHNlOyB9O1xuICB9XG4gIHJldHVybiBmdW5jdGlvbih2YWx1ZSkge1xuICAgIC8vIElFIDwgOSBwcmVzZW50cyBtYW55IGhvc3Qgb2JqZWN0cyBhcyBgT2JqZWN0YCBvYmplY3RzIHRoYXQgY2FuIGNvZXJjZVxuICAgIC8vIHRvIHN0cmluZ3MgZGVzcGl0ZSBoYXZpbmcgaW1wcm9wZXJseSBkZWZpbmVkIGB0b1N0cmluZ2AgbWV0aG9kcy5cbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlLnRvU3RyaW5nICE9ICdmdW5jdGlvbicgJiYgdHlwZW9mICh2YWx1ZSArICcnKSA9PSAnc3RyaW5nJztcbiAgfTtcbn0oKSk7XG5cbm1vZHVsZS5leHBvcnRzID0gaXNIb3N0T2JqZWN0O1xuIiwiLyoqIFVzZWQgdG8gZGV0ZWN0IHVuc2lnbmVkIGludGVnZXIgdmFsdWVzLiAqL1xudmFyIHJlSXNVaW50ID0gL15cXGQrJC87XG5cbi8qKlxuICogVXNlZCBhcyB0aGUgW21heGltdW0gbGVuZ3RoXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1udW1iZXIubWF4X3NhZmVfaW50ZWdlcilcbiAqIG9mIGFuIGFycmF5LWxpa2UgdmFsdWUuXG4gKi9cbnZhciBNQVhfU0FGRV9JTlRFR0VSID0gOTAwNzE5OTI1NDc0MDk5MTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGFycmF5LWxpa2UgaW5kZXguXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGg9TUFYX1NBRkVfSU5URUdFUl0gVGhlIHVwcGVyIGJvdW5kcyBvZiBhIHZhbGlkIGluZGV4LlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB2YWxpZCBpbmRleCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc0luZGV4KHZhbHVlLCBsZW5ndGgpIHtcbiAgdmFsdWUgPSAodHlwZW9mIHZhbHVlID09ICdudW1iZXInIHx8IHJlSXNVaW50LnRlc3QodmFsdWUpKSA/ICt2YWx1ZSA6IC0xO1xuICBsZW5ndGggPSBsZW5ndGggPT0gbnVsbCA/IE1BWF9TQUZFX0lOVEVHRVIgOiBsZW5ndGg7XG4gIHJldHVybiB2YWx1ZSA+IC0xICYmIHZhbHVlICUgMSA9PSAwICYmIHZhbHVlIDwgbGVuZ3RoO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzSW5kZXg7XG4iLCJ2YXIgaXNBcnJheUxpa2UgPSByZXF1aXJlKCcuL2lzQXJyYXlMaWtlJyksXG4gICAgaXNJbmRleCA9IHJlcXVpcmUoJy4vaXNJbmRleCcpLFxuICAgIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vbGFuZy9pc09iamVjdCcpO1xuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgcHJvdmlkZWQgYXJndW1lbnRzIGFyZSBmcm9tIGFuIGl0ZXJhdGVlIGNhbGwuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHBvdGVudGlhbCBpdGVyYXRlZSB2YWx1ZSBhcmd1bWVudC5cbiAqIEBwYXJhbSB7Kn0gaW5kZXggVGhlIHBvdGVudGlhbCBpdGVyYXRlZSBpbmRleCBvciBrZXkgYXJndW1lbnQuXG4gKiBAcGFyYW0geyp9IG9iamVjdCBUaGUgcG90ZW50aWFsIGl0ZXJhdGVlIG9iamVjdCBhcmd1bWVudC5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgYXJndW1lbnRzIGFyZSBmcm9tIGFuIGl0ZXJhdGVlIGNhbGwsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNJdGVyYXRlZUNhbGwodmFsdWUsIGluZGV4LCBvYmplY3QpIHtcbiAgaWYgKCFpc09iamVjdChvYmplY3QpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciB0eXBlID0gdHlwZW9mIGluZGV4O1xuICBpZiAodHlwZSA9PSAnbnVtYmVyJ1xuICAgICAgPyAoaXNBcnJheUxpa2Uob2JqZWN0KSAmJiBpc0luZGV4KGluZGV4LCBvYmplY3QubGVuZ3RoKSlcbiAgICAgIDogKHR5cGUgPT0gJ3N0cmluZycgJiYgaW5kZXggaW4gb2JqZWN0KSkge1xuICAgIHZhciBvdGhlciA9IG9iamVjdFtpbmRleF07XG4gICAgcmV0dXJuIHZhbHVlID09PSB2YWx1ZSA/ICh2YWx1ZSA9PT0gb3RoZXIpIDogKG90aGVyICE9PSBvdGhlcik7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzSXRlcmF0ZWVDYWxsO1xuIiwidmFyIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKSxcbiAgICB0b09iamVjdCA9IHJlcXVpcmUoJy4vdG9PYmplY3QnKTtcblxuLyoqIFVzZWQgdG8gbWF0Y2ggcHJvcGVydHkgbmFtZXMgd2l0aGluIHByb3BlcnR5IHBhdGhzLiAqL1xudmFyIHJlSXNEZWVwUHJvcCA9IC9cXC58XFxbKD86W15bXFxdXSp8KFtcIiddKSg/Oig/IVxcMSlbXlxcblxcXFxdfFxcXFwuKSo/XFwxKVxcXS8sXG4gICAgcmVJc1BsYWluUHJvcCA9IC9eXFx3KiQvO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgcHJvcGVydHkgbmFtZSBhbmQgbm90IGEgcHJvcGVydHkgcGF0aC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcGFyYW0ge09iamVjdH0gW29iamVjdF0gVGhlIG9iamVjdCB0byBxdWVyeSBrZXlzIG9uLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBwcm9wZXJ0eSBuYW1lLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzS2V5KHZhbHVlLCBvYmplY3QpIHtcbiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG4gIGlmICgodHlwZSA9PSAnc3RyaW5nJyAmJiByZUlzUGxhaW5Qcm9wLnRlc3QodmFsdWUpKSB8fCB0eXBlID09ICdudW1iZXInKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciByZXN1bHQgPSAhcmVJc0RlZXBQcm9wLnRlc3QodmFsdWUpO1xuICByZXR1cm4gcmVzdWx0IHx8IChvYmplY3QgIT0gbnVsbCAmJiB2YWx1ZSBpbiB0b09iamVjdChvYmplY3QpKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0tleTtcbiIsInZhciBMYXp5V3JhcHBlciA9IHJlcXVpcmUoJy4vTGF6eVdyYXBwZXInKSxcbiAgICBnZXREYXRhID0gcmVxdWlyZSgnLi9nZXREYXRhJyksXG4gICAgZ2V0RnVuY05hbWUgPSByZXF1aXJlKCcuL2dldEZ1bmNOYW1lJyksXG4gICAgbG9kYXNoID0gcmVxdWlyZSgnLi4vY2hhaW4vbG9kYXNoJyk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGBmdW5jYCBoYXMgYSBsYXp5IGNvdW50ZXJwYXJ0LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgZnVuY2AgaGFzIGEgbGF6eSBjb3VudGVycGFydCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc0xhemlhYmxlKGZ1bmMpIHtcbiAgdmFyIGZ1bmNOYW1lID0gZ2V0RnVuY05hbWUoZnVuYyksXG4gICAgICBvdGhlciA9IGxvZGFzaFtmdW5jTmFtZV07XG5cbiAgaWYgKHR5cGVvZiBvdGhlciAhPSAnZnVuY3Rpb24nIHx8ICEoZnVuY05hbWUgaW4gTGF6eVdyYXBwZXIucHJvdG90eXBlKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoZnVuYyA9PT0gb3RoZXIpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICB2YXIgZGF0YSA9IGdldERhdGEob3RoZXIpO1xuICByZXR1cm4gISFkYXRhICYmIGZ1bmMgPT09IGRhdGFbMF07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNMYXppYWJsZTtcbiIsIi8qKlxuICogVXNlZCBhcyB0aGUgW21heGltdW0gbGVuZ3RoXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1udW1iZXIubWF4X3NhZmVfaW50ZWdlcilcbiAqIG9mIGFuIGFycmF5LWxpa2UgdmFsdWUuXG4gKi9cbnZhciBNQVhfU0FGRV9JTlRFR0VSID0gOTAwNzE5OTI1NDc0MDk5MTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGFycmF5LWxpa2UgbGVuZ3RoLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIGZ1bmN0aW9uIGlzIGJhc2VkIG9uIFtgVG9MZW5ndGhgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy10b2xlbmd0aCkuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB2YWxpZCBsZW5ndGgsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNMZW5ndGgodmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJyAmJiB2YWx1ZSA+IC0xICYmIHZhbHVlICUgMSA9PSAwICYmIHZhbHVlIDw9IE1BWF9TQUZFX0lOVEVHRVI7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNMZW5ndGg7XG4iLCIvKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIG9iamVjdC1saWtlLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIG9iamVjdC1saWtlLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzT2JqZWN0TGlrZSh2YWx1ZSkge1xuICByZXR1cm4gISF2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNPYmplY3RMaWtlO1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vbGFuZy9pc09iamVjdCcpO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIHN1aXRhYmxlIGZvciBzdHJpY3QgZXF1YWxpdHkgY29tcGFyaXNvbnMsIGkuZS4gYD09PWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaWYgc3VpdGFibGUgZm9yIHN0cmljdFxuICogIGVxdWFsaXR5IGNvbXBhcmlzb25zLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzU3RyaWN0Q29tcGFyYWJsZSh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgPT09IHZhbHVlICYmICFpc09iamVjdCh2YWx1ZSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNTdHJpY3RDb21wYXJhYmxlO1xuIiwidmFyIGFycmF5Q29weSA9IHJlcXVpcmUoJy4vYXJyYXlDb3B5JyksXG4gICAgY29tcG9zZUFyZ3MgPSByZXF1aXJlKCcuL2NvbXBvc2VBcmdzJyksXG4gICAgY29tcG9zZUFyZ3NSaWdodCA9IHJlcXVpcmUoJy4vY29tcG9zZUFyZ3NSaWdodCcpLFxuICAgIHJlcGxhY2VIb2xkZXJzID0gcmVxdWlyZSgnLi9yZXBsYWNlSG9sZGVycycpO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB3cmFwcGVyIG1ldGFkYXRhLiAqL1xudmFyIEJJTkRfRkxBRyA9IDEsXG4gICAgQ1VSUllfQk9VTkRfRkxBRyA9IDQsXG4gICAgQ1VSUllfRkxBRyA9IDgsXG4gICAgQVJZX0ZMQUcgPSAxMjgsXG4gICAgUkVBUkdfRkxBRyA9IDI1NjtcblxuLyoqIFVzZWQgYXMgdGhlIGludGVybmFsIGFyZ3VtZW50IHBsYWNlaG9sZGVyLiAqL1xudmFyIFBMQUNFSE9MREVSID0gJ19fbG9kYXNoX3BsYWNlaG9sZGVyX18nO1xuXG4vKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1pbiA9IE1hdGgubWluO1xuXG4vKipcbiAqIE1lcmdlcyB0aGUgZnVuY3Rpb24gbWV0YWRhdGEgb2YgYHNvdXJjZWAgaW50byBgZGF0YWAuXG4gKlxuICogTWVyZ2luZyBtZXRhZGF0YSByZWR1Y2VzIHRoZSBudW1iZXIgb2Ygd3JhcHBlcnMgcmVxdWlyZWQgdG8gaW52b2tlIGEgZnVuY3Rpb24uXG4gKiBUaGlzIGlzIHBvc3NpYmxlIGJlY2F1c2UgbWV0aG9kcyBsaWtlIGBfLmJpbmRgLCBgXy5jdXJyeWAsIGFuZCBgXy5wYXJ0aWFsYFxuICogbWF5IGJlIGFwcGxpZWQgcmVnYXJkbGVzcyBvZiBleGVjdXRpb24gb3JkZXIuIE1ldGhvZHMgbGlrZSBgXy5hcnlgIGFuZCBgXy5yZWFyZ2BcbiAqIGF1Z21lbnQgZnVuY3Rpb24gYXJndW1lbnRzLCBtYWtpbmcgdGhlIG9yZGVyIGluIHdoaWNoIHRoZXkgYXJlIGV4ZWN1dGVkIGltcG9ydGFudCxcbiAqIHByZXZlbnRpbmcgdGhlIG1lcmdpbmcgb2YgbWV0YWRhdGEuIEhvd2V2ZXIsIHdlIG1ha2UgYW4gZXhjZXB0aW9uIGZvciBhIHNhZmVcbiAqIGNvbW1vbiBjYXNlIHdoZXJlIGN1cnJpZWQgZnVuY3Rpb25zIGhhdmUgYF8uYXJ5YCBhbmQgb3IgYF8ucmVhcmdgIGFwcGxpZWQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGRhdGEgVGhlIGRlc3RpbmF0aW9uIG1ldGFkYXRhLlxuICogQHBhcmFtIHtBcnJheX0gc291cmNlIFRoZSBzb3VyY2UgbWV0YWRhdGEuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGRhdGFgLlxuICovXG5mdW5jdGlvbiBtZXJnZURhdGEoZGF0YSwgc291cmNlKSB7XG4gIHZhciBiaXRtYXNrID0gZGF0YVsxXSxcbiAgICAgIHNyY0JpdG1hc2sgPSBzb3VyY2VbMV0sXG4gICAgICBuZXdCaXRtYXNrID0gYml0bWFzayB8IHNyY0JpdG1hc2ssXG4gICAgICBpc0NvbW1vbiA9IG5ld0JpdG1hc2sgPCBBUllfRkxBRztcblxuICB2YXIgaXNDb21ibyA9XG4gICAgKHNyY0JpdG1hc2sgPT0gQVJZX0ZMQUcgJiYgYml0bWFzayA9PSBDVVJSWV9GTEFHKSB8fFxuICAgIChzcmNCaXRtYXNrID09IEFSWV9GTEFHICYmIGJpdG1hc2sgPT0gUkVBUkdfRkxBRyAmJiBkYXRhWzddLmxlbmd0aCA8PSBzb3VyY2VbOF0pIHx8XG4gICAgKHNyY0JpdG1hc2sgPT0gKEFSWV9GTEFHIHwgUkVBUkdfRkxBRykgJiYgYml0bWFzayA9PSBDVVJSWV9GTEFHKTtcblxuICAvLyBFeGl0IGVhcmx5IGlmIG1ldGFkYXRhIGNhbid0IGJlIG1lcmdlZC5cbiAgaWYgKCEoaXNDb21tb24gfHwgaXNDb21ibykpIHtcbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuICAvLyBVc2Ugc291cmNlIGB0aGlzQXJnYCBpZiBhdmFpbGFibGUuXG4gIGlmIChzcmNCaXRtYXNrICYgQklORF9GTEFHKSB7XG4gICAgZGF0YVsyXSA9IHNvdXJjZVsyXTtcbiAgICAvLyBTZXQgd2hlbiBjdXJyeWluZyBhIGJvdW5kIGZ1bmN0aW9uLlxuICAgIG5ld0JpdG1hc2sgfD0gKGJpdG1hc2sgJiBCSU5EX0ZMQUcpID8gMCA6IENVUlJZX0JPVU5EX0ZMQUc7XG4gIH1cbiAgLy8gQ29tcG9zZSBwYXJ0aWFsIGFyZ3VtZW50cy5cbiAgdmFyIHZhbHVlID0gc291cmNlWzNdO1xuICBpZiAodmFsdWUpIHtcbiAgICB2YXIgcGFydGlhbHMgPSBkYXRhWzNdO1xuICAgIGRhdGFbM10gPSBwYXJ0aWFscyA/IGNvbXBvc2VBcmdzKHBhcnRpYWxzLCB2YWx1ZSwgc291cmNlWzRdKSA6IGFycmF5Q29weSh2YWx1ZSk7XG4gICAgZGF0YVs0XSA9IHBhcnRpYWxzID8gcmVwbGFjZUhvbGRlcnMoZGF0YVszXSwgUExBQ0VIT0xERVIpIDogYXJyYXlDb3B5KHNvdXJjZVs0XSk7XG4gIH1cbiAgLy8gQ29tcG9zZSBwYXJ0aWFsIHJpZ2h0IGFyZ3VtZW50cy5cbiAgdmFsdWUgPSBzb3VyY2VbNV07XG4gIGlmICh2YWx1ZSkge1xuICAgIHBhcnRpYWxzID0gZGF0YVs1XTtcbiAgICBkYXRhWzVdID0gcGFydGlhbHMgPyBjb21wb3NlQXJnc1JpZ2h0KHBhcnRpYWxzLCB2YWx1ZSwgc291cmNlWzZdKSA6IGFycmF5Q29weSh2YWx1ZSk7XG4gICAgZGF0YVs2XSA9IHBhcnRpYWxzID8gcmVwbGFjZUhvbGRlcnMoZGF0YVs1XSwgUExBQ0VIT0xERVIpIDogYXJyYXlDb3B5KHNvdXJjZVs2XSk7XG4gIH1cbiAgLy8gVXNlIHNvdXJjZSBgYXJnUG9zYCBpZiBhdmFpbGFibGUuXG4gIHZhbHVlID0gc291cmNlWzddO1xuICBpZiAodmFsdWUpIHtcbiAgICBkYXRhWzddID0gYXJyYXlDb3B5KHZhbHVlKTtcbiAgfVxuICAvLyBVc2Ugc291cmNlIGBhcnlgIGlmIGl0J3Mgc21hbGxlci5cbiAgaWYgKHNyY0JpdG1hc2sgJiBBUllfRkxBRykge1xuICAgIGRhdGFbOF0gPSBkYXRhWzhdID09IG51bGwgPyBzb3VyY2VbOF0gOiBuYXRpdmVNaW4oZGF0YVs4XSwgc291cmNlWzhdKTtcbiAgfVxuICAvLyBVc2Ugc291cmNlIGBhcml0eWAgaWYgb25lIGlzIG5vdCBwcm92aWRlZC5cbiAgaWYgKGRhdGFbOV0gPT0gbnVsbCkge1xuICAgIGRhdGFbOV0gPSBzb3VyY2VbOV07XG4gIH1cbiAgLy8gVXNlIHNvdXJjZSBgZnVuY2AgYW5kIG1lcmdlIGJpdG1hc2tzLlxuICBkYXRhWzBdID0gc291cmNlWzBdO1xuICBkYXRhWzFdID0gbmV3Qml0bWFzaztcblxuICByZXR1cm4gZGF0YTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBtZXJnZURhdGE7XG4iLCIoZnVuY3Rpb24gKGdsb2JhbCl7XG52YXIgZ2V0TmF0aXZlID0gcmVxdWlyZSgnLi9nZXROYXRpdmUnKTtcblxuLyoqIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBXZWFrTWFwID0gZ2V0TmF0aXZlKGdsb2JhbCwgJ1dlYWtNYXAnKTtcblxuLyoqIFVzZWQgdG8gc3RvcmUgZnVuY3Rpb24gbWV0YWRhdGEuICovXG52YXIgbWV0YU1hcCA9IFdlYWtNYXAgJiYgbmV3IFdlYWtNYXA7XG5cbm1vZHVsZS5leHBvcnRzID0gbWV0YU1hcDtcblxufSkuY2FsbCh0aGlzLHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOiB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30pXG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhOmFwcGxpY2F0aW9uL2pzb247Y2hhcnNldDp1dGYtODtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJJbTV2WkdWZmJXOWtkV3hsY3k5c2IyUmhjMmd0WTI5dGNHRjBMMmx1ZEdWeWJtRnNMMjFsZEdGTllYQXVhbk1pWFN3aWJtRnRaWE1pT2x0ZExDSnRZWEJ3YVc1bmN5STZJanRCUVVGQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQklpd2labWxzWlNJNkltZGxibVZ5WVhSbFpDNXFjeUlzSW5OdmRYSmpaVkp2YjNRaU9pSWlMQ0p6YjNWeVkyVnpRMjl1ZEdWdWRDSTZXeUoyWVhJZ1oyVjBUbUYwYVhabElEMGdjbVZ4ZFdseVpTZ25MaTluWlhST1lYUnBkbVVuS1R0Y2JseHVMeW9xSUU1aGRHbDJaU0J0WlhSb2IyUWdjbVZtWlhKbGJtTmxjeTRnS2k5Y2JuWmhjaUJYWldGclRXRndJRDBnWjJWMFRtRjBhWFpsS0dkc2IySmhiQ3dnSjFkbFlXdE5ZWEFuS1R0Y2JseHVMeW9xSUZWelpXUWdkRzhnYzNSdmNtVWdablZ1WTNScGIyNGdiV1YwWVdSaGRHRXVJQ292WEc1MllYSWdiV1YwWVUxaGNDQTlJRmRsWVd0TllYQWdKaVlnYm1WM0lGZGxZV3ROWVhBN1hHNWNibTF2WkhWc1pTNWxlSEJ2Y25SeklEMGdiV1YwWVUxaGNEdGNiaUpkZlE9PSIsIi8qKiBVc2VkIHRvIGxvb2t1cCB1bm1pbmlmaWVkIGZ1bmN0aW9uIG5hbWVzLiAqL1xudmFyIHJlYWxOYW1lcyA9IHt9O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJlYWxOYW1lcztcbiIsInZhciBhcnJheUNvcHkgPSByZXF1aXJlKCcuL2FycmF5Q29weScpLFxuICAgIGlzSW5kZXggPSByZXF1aXJlKCcuL2lzSW5kZXgnKTtcblxuLyogTmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNaW4gPSBNYXRoLm1pbjtcblxuLyoqXG4gKiBSZW9yZGVyIGBhcnJheWAgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpZWQgaW5kZXhlcyB3aGVyZSB0aGUgZWxlbWVudCBhdFxuICogdGhlIGZpcnN0IGluZGV4IGlzIGFzc2lnbmVkIGFzIHRoZSBmaXJzdCBlbGVtZW50LCB0aGUgZWxlbWVudCBhdFxuICogdGhlIHNlY29uZCBpbmRleCBpcyBhc3NpZ25lZCBhcyB0aGUgc2Vjb25kIGVsZW1lbnQsIGFuZCBzbyBvbi5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHJlb3JkZXIuXG4gKiBAcGFyYW0ge0FycmF5fSBpbmRleGVzIFRoZSBhcnJhbmdlZCBhcnJheSBpbmRleGVzLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIHJlb3JkZXIoYXJyYXksIGluZGV4ZXMpIHtcbiAgdmFyIGFyckxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIGxlbmd0aCA9IG5hdGl2ZU1pbihpbmRleGVzLmxlbmd0aCwgYXJyTGVuZ3RoKSxcbiAgICAgIG9sZEFycmF5ID0gYXJyYXlDb3B5KGFycmF5KTtcblxuICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICB2YXIgaW5kZXggPSBpbmRleGVzW2xlbmd0aF07XG4gICAgYXJyYXlbbGVuZ3RoXSA9IGlzSW5kZXgoaW5kZXgsIGFyckxlbmd0aCkgPyBvbGRBcnJheVtpbmRleF0gOiB1bmRlZmluZWQ7XG4gIH1cbiAgcmV0dXJuIGFycmF5O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHJlb3JkZXI7XG4iLCIvKiogVXNlZCBhcyB0aGUgaW50ZXJuYWwgYXJndW1lbnQgcGxhY2Vob2xkZXIuICovXG52YXIgUExBQ0VIT0xERVIgPSAnX19sb2Rhc2hfcGxhY2Vob2xkZXJfXyc7XG5cbi8qKlxuICogUmVwbGFjZXMgYWxsIGBwbGFjZWhvbGRlcmAgZWxlbWVudHMgaW4gYGFycmF5YCB3aXRoIGFuIGludGVybmFsIHBsYWNlaG9sZGVyXG4gKiBhbmQgcmV0dXJucyBhbiBhcnJheSBvZiB0aGVpciBpbmRleGVzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gbW9kaWZ5LlxuICogQHBhcmFtIHsqfSBwbGFjZWhvbGRlciBUaGUgcGxhY2Vob2xkZXIgdG8gcmVwbGFjZS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gKi9cbmZ1bmN0aW9uIHJlcGxhY2VIb2xkZXJzKGFycmF5LCBwbGFjZWhvbGRlcikge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIHJlc0luZGV4ID0gLTEsXG4gICAgICByZXN1bHQgPSBbXTtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIGlmIChhcnJheVtpbmRleF0gPT09IHBsYWNlaG9sZGVyKSB7XG4gICAgICBhcnJheVtpbmRleF0gPSBQTEFDRUhPTERFUjtcbiAgICAgIHJlc3VsdFsrK3Jlc0luZGV4XSA9IGluZGV4O1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHJlcGxhY2VIb2xkZXJzO1xuIiwidmFyIGJhc2VTZXREYXRhID0gcmVxdWlyZSgnLi9iYXNlU2V0RGF0YScpLFxuICAgIG5vdyA9IHJlcXVpcmUoJy4uL2RhdGUvbm93Jyk7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCB3aGVuIGEgZnVuY3Rpb24gYmVjb21lcyBob3QuICovXG52YXIgSE9UX0NPVU5UID0gMTUwLFxuICAgIEhPVF9TUEFOID0gMTY7XG5cbi8qKlxuICogU2V0cyBtZXRhZGF0YSBmb3IgYGZ1bmNgLlxuICpcbiAqICoqTm90ZToqKiBJZiB0aGlzIGZ1bmN0aW9uIGJlY29tZXMgaG90LCBpLmUuIGlzIGludm9rZWQgYSBsb3QgaW4gYSBzaG9ydFxuICogcGVyaW9kIG9mIHRpbWUsIGl0IHdpbGwgdHJpcCBpdHMgYnJlYWtlciBhbmQgdHJhbnNpdGlvbiB0byBhbiBpZGVudGl0eSBmdW5jdGlvblxuICogdG8gYXZvaWQgZ2FyYmFnZSBjb2xsZWN0aW9uIHBhdXNlcyBpbiBWOC4gU2VlIFtWOCBpc3N1ZSAyMDcwXShodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MjA3MClcbiAqIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFzc29jaWF0ZSBtZXRhZGF0YSB3aXRoLlxuICogQHBhcmFtIHsqfSBkYXRhIFRoZSBtZXRhZGF0YS5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyBgZnVuY2AuXG4gKi9cbnZhciBzZXREYXRhID0gKGZ1bmN0aW9uKCkge1xuICB2YXIgY291bnQgPSAwLFxuICAgICAgbGFzdENhbGxlZCA9IDA7XG5cbiAgcmV0dXJuIGZ1bmN0aW9uKGtleSwgdmFsdWUpIHtcbiAgICB2YXIgc3RhbXAgPSBub3coKSxcbiAgICAgICAgcmVtYWluaW5nID0gSE9UX1NQQU4gLSAoc3RhbXAgLSBsYXN0Q2FsbGVkKTtcblxuICAgIGxhc3RDYWxsZWQgPSBzdGFtcDtcbiAgICBpZiAocmVtYWluaW5nID4gMCkge1xuICAgICAgaWYgKCsrY291bnQgPj0gSE9UX0NPVU5UKSB7XG4gICAgICAgIHJldHVybiBrZXk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvdW50ID0gMDtcbiAgICB9XG4gICAgcmV0dXJuIGJhc2VTZXREYXRhKGtleSwgdmFsdWUpO1xuICB9O1xufSgpKTtcblxubW9kdWxlLmV4cG9ydHMgPSBzZXREYXRhO1xuIiwidmFyIGlzQXJndW1lbnRzID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FyZ3VtZW50cycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKSxcbiAgICBpc0luZGV4ID0gcmVxdWlyZSgnLi9pc0luZGV4JyksXG4gICAgaXNMZW5ndGggPSByZXF1aXJlKCcuL2lzTGVuZ3RoJyksXG4gICAgaXNTdHJpbmcgPSByZXF1aXJlKCcuLi9sYW5nL2lzU3RyaW5nJyksXG4gICAga2V5c0luID0gcmVxdWlyZSgnLi4vb2JqZWN0L2tleXNJbicpO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBBIGZhbGxiYWNrIGltcGxlbWVudGF0aW9uIG9mIGBPYmplY3Qua2V5c2Agd2hpY2ggY3JlYXRlcyBhbiBhcnJheSBvZiB0aGVcbiAqIG93biBlbnVtZXJhYmxlIHByb3BlcnR5IG5hbWVzIG9mIGBvYmplY3RgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICovXG5mdW5jdGlvbiBzaGltS2V5cyhvYmplY3QpIHtcbiAgdmFyIHByb3BzID0ga2V5c0luKG9iamVjdCksXG4gICAgICBwcm9wc0xlbmd0aCA9IHByb3BzLmxlbmd0aCxcbiAgICAgIGxlbmd0aCA9IHByb3BzTGVuZ3RoICYmIG9iamVjdC5sZW5ndGg7XG5cbiAgdmFyIGFsbG93SW5kZXhlcyA9ICEhbGVuZ3RoICYmIGlzTGVuZ3RoKGxlbmd0aCkgJiZcbiAgICAoaXNBcnJheShvYmplY3QpIHx8IGlzQXJndW1lbnRzKG9iamVjdCkgfHwgaXNTdHJpbmcob2JqZWN0KSk7XG5cbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICByZXN1bHQgPSBbXTtcblxuICB3aGlsZSAoKytpbmRleCA8IHByb3BzTGVuZ3RoKSB7XG4gICAgdmFyIGtleSA9IHByb3BzW2luZGV4XTtcbiAgICBpZiAoKGFsbG93SW5kZXhlcyAmJiBpc0luZGV4KGtleSwgbGVuZ3RoKSkgfHwgaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSkpIHtcbiAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gc2hpbUtleXM7XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0JyksXG4gICAgaXNTdHJpbmcgPSByZXF1aXJlKCcuLi9sYW5nL2lzU3RyaW5nJyksXG4gICAgc3VwcG9ydCA9IHJlcXVpcmUoJy4uL3N1cHBvcnQnKTtcblxuLyoqXG4gKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGFuIG9iamVjdCBpZiBpdCdzIG5vdCBvbmUuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHByb2Nlc3MuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBvYmplY3QuXG4gKi9cbmZ1bmN0aW9uIHRvT2JqZWN0KHZhbHVlKSB7XG4gIGlmIChzdXBwb3J0LnVuaW5kZXhlZENoYXJzICYmIGlzU3RyaW5nKHZhbHVlKSkge1xuICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSB2YWx1ZS5sZW5ndGgsXG4gICAgICAgIHJlc3VsdCA9IE9iamVjdCh2YWx1ZSk7XG5cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgcmVzdWx0W2luZGV4XSA9IHZhbHVlLmNoYXJBdChpbmRleCk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgcmV0dXJuIGlzT2JqZWN0KHZhbHVlKSA/IHZhbHVlIDogT2JqZWN0KHZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB0b09iamVjdDtcbiIsInZhciBiYXNlVG9TdHJpbmcgPSByZXF1aXJlKCcuL2Jhc2VUb1N0cmluZycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKTtcblxuLyoqIFVzZWQgdG8gbWF0Y2ggcHJvcGVydHkgbmFtZXMgd2l0aGluIHByb3BlcnR5IHBhdGhzLiAqL1xudmFyIHJlUHJvcE5hbWUgPSAvW14uW1xcXV0rfFxcWyg/OigtP1xcZCsoPzpcXC5cXGQrKT8pfChbXCInXSkoKD86KD8hXFwyKVteXFxuXFxcXF18XFxcXC4pKj8pXFwyKVxcXS9nO1xuXG4vKiogVXNlZCB0byBtYXRjaCBiYWNrc2xhc2hlcyBpbiBwcm9wZXJ0eSBwYXRocy4gKi9cbnZhciByZUVzY2FwZUNoYXIgPSAvXFxcXChcXFxcKT8vZztcblxuLyoqXG4gKiBDb252ZXJ0cyBgdmFsdWVgIHRvIHByb3BlcnR5IHBhdGggYXJyYXkgaWYgaXQncyBub3Qgb25lLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwcm9jZXNzLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBwcm9wZXJ0eSBwYXRoIGFycmF5LlxuICovXG5mdW5jdGlvbiB0b1BhdGgodmFsdWUpIHtcbiAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgYmFzZVRvU3RyaW5nKHZhbHVlKS5yZXBsYWNlKHJlUHJvcE5hbWUsIGZ1bmN0aW9uKG1hdGNoLCBudW1iZXIsIHF1b3RlLCBzdHJpbmcpIHtcbiAgICByZXN1bHQucHVzaChxdW90ZSA/IHN0cmluZy5yZXBsYWNlKHJlRXNjYXBlQ2hhciwgJyQxJykgOiAobnVtYmVyIHx8IG1hdGNoKSk7XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHRvUGF0aDtcbiIsInZhciBMYXp5V3JhcHBlciA9IHJlcXVpcmUoJy4vTGF6eVdyYXBwZXInKSxcbiAgICBMb2Rhc2hXcmFwcGVyID0gcmVxdWlyZSgnLi9Mb2Rhc2hXcmFwcGVyJyksXG4gICAgYXJyYXlDb3B5ID0gcmVxdWlyZSgnLi9hcnJheUNvcHknKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgY2xvbmUgb2YgYHdyYXBwZXJgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gd3JhcHBlciBUaGUgd3JhcHBlciB0byBjbG9uZS5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNsb25lZCB3cmFwcGVyLlxuICovXG5mdW5jdGlvbiB3cmFwcGVyQ2xvbmUod3JhcHBlcikge1xuICByZXR1cm4gd3JhcHBlciBpbnN0YW5jZW9mIExhenlXcmFwcGVyXG4gICAgPyB3cmFwcGVyLmNsb25lKClcbiAgICA6IG5ldyBMb2Rhc2hXcmFwcGVyKHdyYXBwZXIuX193cmFwcGVkX18sIHdyYXBwZXIuX19jaGFpbl9fLCBhcnJheUNvcHkod3JhcHBlci5fX2FjdGlvbnNfXykpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHdyYXBwZXJDbG9uZTtcbiIsInZhciBiYXNlQ2xvbmUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlQ2xvbmUnKSxcbiAgICBiaW5kQ2FsbGJhY2sgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iaW5kQ2FsbGJhY2snKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZGVlcCBjbG9uZSBvZiBgdmFsdWVgLiBJZiBgY3VzdG9taXplcmAgaXMgcHJvdmlkZWQgaXQncyBpbnZva2VkXG4gKiB0byBwcm9kdWNlIHRoZSBjbG9uZWQgdmFsdWVzLiBJZiBgY3VzdG9taXplcmAgcmV0dXJucyBgdW5kZWZpbmVkYCBjbG9uaW5nXG4gKiBpcyBoYW5kbGVkIGJ5IHRoZSBtZXRob2QgaW5zdGVhZC4gVGhlIGBjdXN0b21pemVyYCBpcyBib3VuZCB0byBgdGhpc0FyZ2BcbiAqIGFuZCBpbnZva2VkIHdpdGggdXAgdG8gdGhyZWUgYXJndW1lbnQ7ICh2YWx1ZSBbLCBpbmRleHxrZXksIG9iamVjdF0pLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBsb29zZWx5IGJhc2VkIG9uIHRoZVxuICogW3N0cnVjdHVyZWQgY2xvbmUgYWxnb3JpdGhtXShodHRwOi8vd3d3LnczLm9yZy9UUi9odG1sNS9pbmZyYXN0cnVjdHVyZS5odG1sI2ludGVybmFsLXN0cnVjdHVyZWQtY2xvbmluZy1hbGdvcml0aG0pLlxuICogVGhlIGVudW1lcmFibGUgcHJvcGVydGllcyBvZiBgYXJndW1lbnRzYCBvYmplY3RzIGFuZCBvYmplY3RzIGNyZWF0ZWQgYnlcbiAqIGNvbnN0cnVjdG9ycyBvdGhlciB0aGFuIGBPYmplY3RgIGFyZSBjbG9uZWQgdG8gcGxhaW4gYE9iamVjdGAgb2JqZWN0cy4gQW5cbiAqIGVtcHR5IG9iamVjdCBpcyByZXR1cm5lZCBmb3IgdW5jbG9uZWFibGUgdmFsdWVzIHN1Y2ggYXMgZnVuY3Rpb25zLCBET00gbm9kZXMsXG4gKiBNYXBzLCBTZXRzLCBhbmQgV2Vha01hcHMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBkZWVwIGNsb25lLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY2xvbmluZyB2YWx1ZXMuXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGN1c3RvbWl6ZXJgLlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGRlZXAgY2xvbmVkIHZhbHVlLlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgdXNlcnMgPSBbXG4gKiAgIHsgJ3VzZXInOiAnYmFybmV5JyB9LFxuICogICB7ICd1c2VyJzogJ2ZyZWQnIH1cbiAqIF07XG4gKlxuICogdmFyIGRlZXAgPSBfLmNsb25lRGVlcCh1c2Vycyk7XG4gKiBkZWVwWzBdID09PSB1c2Vyc1swXTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogLy8gdXNpbmcgYSBjdXN0b21pemVyIGNhbGxiYWNrXG4gKiB2YXIgZWwgPSBfLmNsb25lRGVlcChkb2N1bWVudC5ib2R5LCBmdW5jdGlvbih2YWx1ZSkge1xuICogICBpZiAoXy5pc0VsZW1lbnQodmFsdWUpKSB7XG4gKiAgICAgcmV0dXJuIHZhbHVlLmNsb25lTm9kZSh0cnVlKTtcbiAqICAgfVxuICogfSk7XG4gKlxuICogZWwgPT09IGRvY3VtZW50LmJvZHlcbiAqIC8vID0+IGZhbHNlXG4gKiBlbC5ub2RlTmFtZVxuICogLy8gPT4gQk9EWVxuICogZWwuY2hpbGROb2Rlcy5sZW5ndGg7XG4gKiAvLyA9PiAyMFxuICovXG5mdW5jdGlvbiBjbG9uZURlZXAodmFsdWUsIGN1c3RvbWl6ZXIsIHRoaXNBcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBjdXN0b21pemVyID09ICdmdW5jdGlvbidcbiAgICA/IGJhc2VDbG9uZSh2YWx1ZSwgdHJ1ZSwgYmluZENhbGxiYWNrKGN1c3RvbWl6ZXIsIHRoaXNBcmcsIDMpKVxuICAgIDogYmFzZUNsb25lKHZhbHVlLCB0cnVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjbG9uZURlZXA7XG4iLCJ2YXIgaXNBcnJheUxpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0FycmF5TGlrZScpLFxuICAgIGlzT2JqZWN0TGlrZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzT2JqZWN0TGlrZScpO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBwcm9wZXJ0eUlzRW51bWVyYWJsZSA9IG9iamVjdFByb3RvLnByb3BlcnR5SXNFbnVtZXJhYmxlO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYW4gYGFyZ3VtZW50c2Agb2JqZWN0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBjb3JyZWN0bHkgY2xhc3NpZmllZCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzQXJndW1lbnRzKGZ1bmN0aW9uKCkgeyByZXR1cm4gYXJndW1lbnRzOyB9KCkpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNBcmd1bWVudHMoWzEsIDIsIDNdKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzQXJndW1lbnRzKHZhbHVlKSB7XG4gIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGlzQXJyYXlMaWtlKHZhbHVlKSAmJlxuICAgIGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsICdjYWxsZWUnKSAmJiAhcHJvcGVydHlJc0VudW1lcmFibGUuY2FsbCh2YWx1ZSwgJ2NhbGxlZScpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzQXJndW1lbnRzO1xuIiwidmFyIGdldE5hdGl2ZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2dldE5hdGl2ZScpLFxuICAgIGlzTGVuZ3RoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNMZW5ndGgnKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc09iamVjdExpa2UnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGFycmF5VGFnID0gJ1tvYmplY3QgQXJyYXldJztcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9ialRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlSXNBcnJheSA9IGdldE5hdGl2ZShBcnJheSwgJ2lzQXJyYXknKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGFuIGBBcnJheWAgb2JqZWN0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBjb3JyZWN0bHkgY2xhc3NpZmllZCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzQXJyYXkoWzEsIDIsIDNdKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzQXJyYXkoZnVuY3Rpb24oKSB7IHJldHVybiBhcmd1bWVudHM7IH0oKSk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG52YXIgaXNBcnJheSA9IG5hdGl2ZUlzQXJyYXkgfHwgZnVuY3Rpb24odmFsdWUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaXNMZW5ndGgodmFsdWUubGVuZ3RoKSAmJiBvYmpUb1N0cmluZy5jYWxsKHZhbHVlKSA9PSBhcnJheVRhZztcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gaXNBcnJheTtcbiIsInZhciBpc0FyZ3VtZW50cyA9IHJlcXVpcmUoJy4vaXNBcmd1bWVudHMnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi9pc0FycmF5JyksXG4gICAgaXNBcnJheUxpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0FycmF5TGlrZScpLFxuICAgIGlzRnVuY3Rpb24gPSByZXF1aXJlKCcuL2lzRnVuY3Rpb24nKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc09iamVjdExpa2UnKSxcbiAgICBpc1N0cmluZyA9IHJlcXVpcmUoJy4vaXNTdHJpbmcnKSxcbiAgICBrZXlzID0gcmVxdWlyZSgnLi4vb2JqZWN0L2tleXMnKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBlbXB0eS4gQSB2YWx1ZSBpcyBjb25zaWRlcmVkIGVtcHR5IHVubGVzcyBpdCdzIGFuXG4gKiBgYXJndW1lbnRzYCBvYmplY3QsIGFycmF5LCBzdHJpbmcsIG9yIGpRdWVyeS1saWtlIGNvbGxlY3Rpb24gd2l0aCBhIGxlbmd0aFxuICogZ3JlYXRlciB0aGFuIGAwYCBvciBhbiBvYmplY3Qgd2l0aCBvd24gZW51bWVyYWJsZSBwcm9wZXJ0aWVzLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSB2YWx1ZSBUaGUgdmFsdWUgdG8gaW5zcGVjdC5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGVtcHR5LCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNFbXB0eShudWxsKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzRW1wdHkodHJ1ZSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0VtcHR5KDEpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNFbXB0eShbMSwgMiwgM10pO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzRW1wdHkoeyAnYSc6IDEgfSk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc0VtcHR5KHZhbHVlKSB7XG4gIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKGlzQXJyYXlMaWtlKHZhbHVlKSAmJiAoaXNBcnJheSh2YWx1ZSkgfHwgaXNTdHJpbmcodmFsdWUpIHx8IGlzQXJndW1lbnRzKHZhbHVlKSB8fFxuICAgICAgKGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaXNGdW5jdGlvbih2YWx1ZS5zcGxpY2UpKSkpIHtcbiAgICByZXR1cm4gIXZhbHVlLmxlbmd0aDtcbiAgfVxuICByZXR1cm4gIWtleXModmFsdWUpLmxlbmd0aDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0VtcHR5O1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9pc09iamVjdCcpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgZnVuY1RhZyA9ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG5cbi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKipcbiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgW2B0b1N0cmluZ1RhZ2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW9iamVjdC5wcm90b3R5cGUudG9zdHJpbmcpXG4gKiBvZiB2YWx1ZXMuXG4gKi9cbnZhciBvYmpUb1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgRnVuY3Rpb25gIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgY29ycmVjdGx5IGNsYXNzaWZpZWQsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc0Z1bmN0aW9uKF8pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNGdW5jdGlvbigvYWJjLyk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKHZhbHVlKSB7XG4gIC8vIFRoZSB1c2Ugb2YgYE9iamVjdCN0b1N0cmluZ2AgYXZvaWRzIGlzc3VlcyB3aXRoIHRoZSBgdHlwZW9mYCBvcGVyYXRvclxuICAvLyBpbiBvbGRlciB2ZXJzaW9ucyBvZiBDaHJvbWUgYW5kIFNhZmFyaSB3aGljaCByZXR1cm4gJ2Z1bmN0aW9uJyBmb3IgcmVnZXhlc1xuICAvLyBhbmQgU2FmYXJpIDggd2hpY2ggcmV0dXJucyAnb2JqZWN0JyBmb3IgdHlwZWQgYXJyYXkgY29uc3RydWN0b3JzLlxuICByZXR1cm4gaXNPYmplY3QodmFsdWUpICYmIG9ialRvU3RyaW5nLmNhbGwodmFsdWUpID09IGZ1bmNUYWc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNGdW5jdGlvbjtcbiIsInZhciBpc0Z1bmN0aW9uID0gcmVxdWlyZSgnLi9pc0Z1bmN0aW9uJyksXG4gICAgaXNIb3N0T2JqZWN0ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNIb3N0T2JqZWN0JyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNPYmplY3RMaWtlJyk7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBob3N0IGNvbnN0cnVjdG9ycyAoU2FmYXJpID4gNSkuICovXG52YXIgcmVJc0hvc3RDdG9yID0gL15cXFtvYmplY3QgLis/Q29uc3RydWN0b3JcXF0kLztcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIHJlc29sdmUgdGhlIGRlY29tcGlsZWQgc291cmNlIG9mIGZ1bmN0aW9ucy4gKi9cbnZhciBmblRvU3RyaW5nID0gRnVuY3Rpb24ucHJvdG90eXBlLnRvU3RyaW5nO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKiogVXNlZCB0byBkZXRlY3QgaWYgYSBtZXRob2QgaXMgbmF0aXZlLiAqL1xudmFyIHJlSXNOYXRpdmUgPSBSZWdFeHAoJ14nICtcbiAgZm5Ub1N0cmluZy5jYWxsKGhhc093blByb3BlcnR5KS5yZXBsYWNlKC9bXFxcXF4kLiorPygpW1xcXXt9fF0vZywgJ1xcXFwkJicpXG4gIC5yZXBsYWNlKC9oYXNPd25Qcm9wZXJ0eXwoZnVuY3Rpb24pLio/KD89XFxcXFxcKCl8IGZvciAuKz8oPz1cXFxcXFxdKS9nLCAnJDEuKj8nKSArICckJ1xuKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIG5hdGl2ZSBmdW5jdGlvbi5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBuYXRpdmUgZnVuY3Rpb24sIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc05hdGl2ZShBcnJheS5wcm90b3R5cGUucHVzaCk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc05hdGl2ZShfKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzTmF0aXZlKHZhbHVlKSB7XG4gIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkge1xuICAgIHJldHVybiByZUlzTmF0aXZlLnRlc3QoZm5Ub1N0cmluZy5jYWxsKHZhbHVlKSk7XG4gIH1cbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgKGlzSG9zdE9iamVjdCh2YWx1ZSkgPyByZUlzTmF0aXZlIDogcmVJc0hvc3RDdG9yKS50ZXN0KHZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc05hdGl2ZTtcbiIsIi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgdGhlIFtsYW5ndWFnZSB0eXBlXShodHRwczovL2VzNS5naXRodWIuaW8vI3g4KSBvZiBgT2JqZWN0YC5cbiAqIChlLmcuIGFycmF5cywgZnVuY3Rpb25zLCBvYmplY3RzLCByZWdleGVzLCBgbmV3IE51bWJlcigwKWAsIGFuZCBgbmV3IFN0cmluZygnJylgKVxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc09iamVjdCh7fSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdChbMSwgMiwgM10pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3QoMSk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc09iamVjdCh2YWx1ZSkge1xuICAvLyBBdm9pZCBhIFY4IEpJVCBidWcgaW4gQ2hyb21lIDE5LTIwLlxuICAvLyBTZWUgaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC92OC9pc3N1ZXMvZGV0YWlsP2lkPTIyOTEgZm9yIG1vcmUgZGV0YWlscy5cbiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG4gIHJldHVybiAhIXZhbHVlICYmICh0eXBlID09ICdvYmplY3QnIHx8IHR5cGUgPT0gJ2Z1bmN0aW9uJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNPYmplY3Q7XG4iLCJ2YXIgYmFzZUZvckluID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZUZvckluJyksXG4gICAgaXNBcmd1bWVudHMgPSByZXF1aXJlKCcuL2lzQXJndW1lbnRzJyksXG4gICAgaXNIb3N0T2JqZWN0ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNIb3N0T2JqZWN0JyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNPYmplY3RMaWtlJyksXG4gICAgc3VwcG9ydCA9IHJlcXVpcmUoJy4uL3N1cHBvcnQnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqVG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHBsYWluIG9iamVjdCwgdGhhdCBpcywgYW4gb2JqZWN0IGNyZWF0ZWQgYnkgdGhlXG4gKiBgT2JqZWN0YCBjb25zdHJ1Y3RvciBvciBvbmUgd2l0aCBhIGBbW1Byb3RvdHlwZV1dYCBvZiBgbnVsbGAuXG4gKlxuICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGFzc3VtZXMgb2JqZWN0cyBjcmVhdGVkIGJ5IHRoZSBgT2JqZWN0YCBjb25zdHJ1Y3RvclxuICogaGF2ZSBubyBpbmhlcml0ZWQgZW51bWVyYWJsZSBwcm9wZXJ0aWVzLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHBsYWluIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBmdW5jdGlvbiBGb28oKSB7XG4gKiAgIHRoaXMuYSA9IDE7XG4gKiB9XG4gKlxuICogXy5pc1BsYWluT2JqZWN0KG5ldyBGb28pO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzUGxhaW5PYmplY3QoWzEsIDIsIDNdKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc1BsYWluT2JqZWN0KHsgJ3gnOiAwLCAneSc6IDAgfSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc1BsYWluT2JqZWN0KE9iamVjdC5jcmVhdGUobnVsbCkpO1xuICogLy8gPT4gdHJ1ZVxuICovXG5mdW5jdGlvbiBpc1BsYWluT2JqZWN0KHZhbHVlKSB7XG4gIHZhciBDdG9yO1xuXG4gIC8vIEV4aXQgZWFybHkgZm9yIG5vbiBgT2JqZWN0YCBvYmplY3RzLlxuICBpZiAoIShpc09iamVjdExpa2UodmFsdWUpICYmIG9ialRvU3RyaW5nLmNhbGwodmFsdWUpID09IG9iamVjdFRhZyAmJiAhaXNIb3N0T2JqZWN0KHZhbHVlKSAmJiAhaXNBcmd1bWVudHModmFsdWUpKSB8fFxuICAgICAgKCFoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbHVlLCAnY29uc3RydWN0b3InKSAmJiAoQ3RvciA9IHZhbHVlLmNvbnN0cnVjdG9yLCB0eXBlb2YgQ3RvciA9PSAnZnVuY3Rpb24nICYmICEoQ3RvciBpbnN0YW5jZW9mIEN0b3IpKSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy8gSUUgPCA5IGl0ZXJhdGVzIGluaGVyaXRlZCBwcm9wZXJ0aWVzIGJlZm9yZSBvd24gcHJvcGVydGllcy4gSWYgdGhlIGZpcnN0XG4gIC8vIGl0ZXJhdGVkIHByb3BlcnR5IGlzIGFuIG9iamVjdCdzIG93biBwcm9wZXJ0eSB0aGVuIHRoZXJlIGFyZSBubyBpbmhlcml0ZWRcbiAgLy8gZW51bWVyYWJsZSBwcm9wZXJ0aWVzLlxuICB2YXIgcmVzdWx0O1xuICBpZiAoc3VwcG9ydC5vd25MYXN0KSB7XG4gICAgYmFzZUZvckluKHZhbHVlLCBmdW5jdGlvbihzdWJWYWx1ZSwga2V5LCBvYmplY3QpIHtcbiAgICAgIHJlc3VsdCA9IGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQgIT09IGZhbHNlO1xuICB9XG4gIC8vIEluIG1vc3QgZW52aXJvbm1lbnRzIGFuIG9iamVjdCdzIG93biBwcm9wZXJ0aWVzIGFyZSBpdGVyYXRlZCBiZWZvcmVcbiAgLy8gaXRzIGluaGVyaXRlZCBwcm9wZXJ0aWVzLiBJZiB0aGUgbGFzdCBpdGVyYXRlZCBwcm9wZXJ0eSBpcyBhbiBvYmplY3Qnc1xuICAvLyBvd24gcHJvcGVydHkgdGhlbiB0aGVyZSBhcmUgbm8gaW5oZXJpdGVkIGVudW1lcmFibGUgcHJvcGVydGllcy5cbiAgYmFzZUZvckluKHZhbHVlLCBmdW5jdGlvbihzdWJWYWx1ZSwga2V5KSB7XG4gICAgcmVzdWx0ID0ga2V5O1xuICB9KTtcbiAgcmV0dXJuIHJlc3VsdCA9PT0gdW5kZWZpbmVkIHx8IGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsIHJlc3VsdCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNQbGFpbk9iamVjdDtcbiIsInZhciBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc09iamVjdExpa2UnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqVG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYFN0cmluZ2AgcHJpbWl0aXZlIG9yIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgY29ycmVjdGx5IGNsYXNzaWZpZWQsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc1N0cmluZygnYWJjJyk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc1N0cmluZygxKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzU3RyaW5nKHZhbHVlKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycgfHwgKGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgb2JqVG9TdHJpbmcuY2FsbCh2YWx1ZSkgPT0gc3RyaW5nVGFnKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1N0cmluZztcbiIsInZhciBpc0xlbmd0aCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzTGVuZ3RoJyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNPYmplY3RMaWtlJyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBhcmdzVGFnID0gJ1tvYmplY3QgQXJndW1lbnRzXScsXG4gICAgYXJyYXlUYWcgPSAnW29iamVjdCBBcnJheV0nLFxuICAgIGJvb2xUYWcgPSAnW29iamVjdCBCb29sZWFuXScsXG4gICAgZGF0ZVRhZyA9ICdbb2JqZWN0IERhdGVdJyxcbiAgICBlcnJvclRhZyA9ICdbb2JqZWN0IEVycm9yXScsXG4gICAgZnVuY1RhZyA9ICdbb2JqZWN0IEZ1bmN0aW9uXScsXG4gICAgbWFwVGFnID0gJ1tvYmplY3QgTWFwXScsXG4gICAgbnVtYmVyVGFnID0gJ1tvYmplY3QgTnVtYmVyXScsXG4gICAgb2JqZWN0VGFnID0gJ1tvYmplY3QgT2JqZWN0XScsXG4gICAgcmVnZXhwVGFnID0gJ1tvYmplY3QgUmVnRXhwXScsXG4gICAgc2V0VGFnID0gJ1tvYmplY3QgU2V0XScsXG4gICAgc3RyaW5nVGFnID0gJ1tvYmplY3QgU3RyaW5nXScsXG4gICAgd2Vha01hcFRhZyA9ICdbb2JqZWN0IFdlYWtNYXBdJztcblxudmFyIGFycmF5QnVmZmVyVGFnID0gJ1tvYmplY3QgQXJyYXlCdWZmZXJdJyxcbiAgICBmbG9hdDMyVGFnID0gJ1tvYmplY3QgRmxvYXQzMkFycmF5XScsXG4gICAgZmxvYXQ2NFRhZyA9ICdbb2JqZWN0IEZsb2F0NjRBcnJheV0nLFxuICAgIGludDhUYWcgPSAnW29iamVjdCBJbnQ4QXJyYXldJyxcbiAgICBpbnQxNlRhZyA9ICdbb2JqZWN0IEludDE2QXJyYXldJyxcbiAgICBpbnQzMlRhZyA9ICdbb2JqZWN0IEludDMyQXJyYXldJyxcbiAgICB1aW50OFRhZyA9ICdbb2JqZWN0IFVpbnQ4QXJyYXldJyxcbiAgICB1aW50OENsYW1wZWRUYWcgPSAnW29iamVjdCBVaW50OENsYW1wZWRBcnJheV0nLFxuICAgIHVpbnQxNlRhZyA9ICdbb2JqZWN0IFVpbnQxNkFycmF5XScsXG4gICAgdWludDMyVGFnID0gJ1tvYmplY3QgVWludDMyQXJyYXldJztcblxuLyoqIFVzZWQgdG8gaWRlbnRpZnkgYHRvU3RyaW5nVGFnYCB2YWx1ZXMgb2YgdHlwZWQgYXJyYXlzLiAqL1xudmFyIHR5cGVkQXJyYXlUYWdzID0ge307XG50eXBlZEFycmF5VGFnc1tmbG9hdDMyVGFnXSA9IHR5cGVkQXJyYXlUYWdzW2Zsb2F0NjRUYWddID1cbnR5cGVkQXJyYXlUYWdzW2ludDhUYWddID0gdHlwZWRBcnJheVRhZ3NbaW50MTZUYWddID1cbnR5cGVkQXJyYXlUYWdzW2ludDMyVGFnXSA9IHR5cGVkQXJyYXlUYWdzW3VpbnQ4VGFnXSA9XG50eXBlZEFycmF5VGFnc1t1aW50OENsYW1wZWRUYWddID0gdHlwZWRBcnJheVRhZ3NbdWludDE2VGFnXSA9XG50eXBlZEFycmF5VGFnc1t1aW50MzJUYWddID0gdHJ1ZTtcbnR5cGVkQXJyYXlUYWdzW2FyZ3NUYWddID0gdHlwZWRBcnJheVRhZ3NbYXJyYXlUYWddID1cbnR5cGVkQXJyYXlUYWdzW2FycmF5QnVmZmVyVGFnXSA9IHR5cGVkQXJyYXlUYWdzW2Jvb2xUYWddID1cbnR5cGVkQXJyYXlUYWdzW2RhdGVUYWddID0gdHlwZWRBcnJheVRhZ3NbZXJyb3JUYWddID1cbnR5cGVkQXJyYXlUYWdzW2Z1bmNUYWddID0gdHlwZWRBcnJheVRhZ3NbbWFwVGFnXSA9XG50eXBlZEFycmF5VGFnc1tudW1iZXJUYWddID0gdHlwZWRBcnJheVRhZ3Nbb2JqZWN0VGFnXSA9XG50eXBlZEFycmF5VGFnc1tyZWdleHBUYWddID0gdHlwZWRBcnJheVRhZ3Nbc2V0VGFnXSA9XG50eXBlZEFycmF5VGFnc1tzdHJpbmdUYWddID0gdHlwZWRBcnJheVRhZ3Nbd2Vha01hcFRhZ10gPSBmYWxzZTtcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9ialRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIHR5cGVkIGFycmF5LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBjb3JyZWN0bHkgY2xhc3NpZmllZCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzVHlwZWRBcnJheShuZXcgVWludDhBcnJheSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc1R5cGVkQXJyYXkoW10pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNUeXBlZEFycmF5KHZhbHVlKSB7XG4gIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGlzTGVuZ3RoKHZhbHVlLmxlbmd0aCkgJiYgISF0eXBlZEFycmF5VGFnc1tvYmpUb1N0cmluZy5jYWxsKHZhbHVlKV07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNUeXBlZEFycmF5O1xuIiwiLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBgdW5kZWZpbmVkYC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYHVuZGVmaW5lZGAsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc1VuZGVmaW5lZCh2b2lkIDApO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNVbmRlZmluZWQobnVsbCk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc1VuZGVmaW5lZCh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgPT09IHVuZGVmaW5lZDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1VuZGVmaW5lZDtcbiIsInZhciBnZXROYXRpdmUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9nZXROYXRpdmUnKSxcbiAgICBpc0FycmF5TGlrZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzQXJyYXlMaWtlJyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0JyksXG4gICAgc2hpbUtleXMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9zaGltS2V5cycpLFxuICAgIHN1cHBvcnQgPSByZXF1aXJlKCcuLi9zdXBwb3J0Jyk7XG5cbi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlS2V5cyA9IGdldE5hdGl2ZShPYmplY3QsICdrZXlzJyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgb2YgYG9iamVjdGAuXG4gKlxuICogKipOb3RlOioqIE5vbi1vYmplY3QgdmFsdWVzIGFyZSBjb2VyY2VkIHRvIG9iamVjdHMuIFNlZSB0aGVcbiAqIFtFUyBzcGVjXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3Qua2V5cylcbiAqIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBPYmplY3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gKiBAZXhhbXBsZVxuICpcbiAqIGZ1bmN0aW9uIEZvbygpIHtcbiAqICAgdGhpcy5hID0gMTtcbiAqICAgdGhpcy5iID0gMjtcbiAqIH1cbiAqXG4gKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICpcbiAqIF8ua2V5cyhuZXcgRm9vKTtcbiAqIC8vID0+IFsnYScsICdiJ10gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAqXG4gKiBfLmtleXMoJ2hpJyk7XG4gKiAvLyA9PiBbJzAnLCAnMSddXG4gKi9cbnZhciBrZXlzID0gIW5hdGl2ZUtleXMgPyBzaGltS2V5cyA6IGZ1bmN0aW9uKG9iamVjdCkge1xuICB2YXIgQ3RvciA9IG9iamVjdCA9PSBudWxsID8gdW5kZWZpbmVkIDogb2JqZWN0LmNvbnN0cnVjdG9yO1xuICBpZiAoKHR5cGVvZiBDdG9yID09ICdmdW5jdGlvbicgJiYgQ3Rvci5wcm90b3R5cGUgPT09IG9iamVjdCkgfHxcbiAgICAgICh0eXBlb2Ygb2JqZWN0ID09ICdmdW5jdGlvbicgPyBzdXBwb3J0LmVudW1Qcm90b3R5cGVzIDogaXNBcnJheUxpa2Uob2JqZWN0KSkpIHtcbiAgICByZXR1cm4gc2hpbUtleXMob2JqZWN0KTtcbiAgfVxuICByZXR1cm4gaXNPYmplY3Qob2JqZWN0KSA/IG5hdGl2ZUtleXMob2JqZWN0KSA6IFtdO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBrZXlzO1xuIiwidmFyIGFycmF5RWFjaCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2FycmF5RWFjaCcpLFxuICAgIGlzQXJndW1lbnRzID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FyZ3VtZW50cycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKSxcbiAgICBpc0Z1bmN0aW9uID0gcmVxdWlyZSgnLi4vbGFuZy9pc0Z1bmN0aW9uJyksXG4gICAgaXNJbmRleCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzSW5kZXgnKSxcbiAgICBpc0xlbmd0aCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzTGVuZ3RoJyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0JyksXG4gICAgaXNTdHJpbmcgPSByZXF1aXJlKCcuLi9sYW5nL2lzU3RyaW5nJyksXG4gICAgc3VwcG9ydCA9IHJlcXVpcmUoJy4uL3N1cHBvcnQnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGFycmF5VGFnID0gJ1tvYmplY3QgQXJyYXldJyxcbiAgICBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgIGRhdGVUYWcgPSAnW29iamVjdCBEYXRlXScsXG4gICAgZXJyb3JUYWcgPSAnW29iamVjdCBFcnJvcl0nLFxuICAgIGZ1bmNUYWcgPSAnW29iamVjdCBGdW5jdGlvbl0nLFxuICAgIG51bWJlclRhZyA9ICdbb2JqZWN0IE51bWJlcl0nLFxuICAgIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nLFxuICAgIHJlZ2V4cFRhZyA9ICdbb2JqZWN0IFJlZ0V4cF0nLFxuICAgIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nO1xuXG4vKiogVXNlZCB0byBmaXggdGhlIEpTY3JpcHQgYFtbRG9udEVudW1dXWAgYnVnLiAqL1xudmFyIHNoYWRvd1Byb3BzID0gW1xuICAnY29uc3RydWN0b3InLCAnaGFzT3duUHJvcGVydHknLCAnaXNQcm90b3R5cGVPZicsICdwcm9wZXJ0eUlzRW51bWVyYWJsZScsXG4gICd0b0xvY2FsZVN0cmluZycsICd0b1N0cmluZycsICd2YWx1ZU9mJ1xuXTtcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBlcnJvclByb3RvID0gRXJyb3IucHJvdG90eXBlLFxuICAgIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZSxcbiAgICBzdHJpbmdQcm90byA9IFN0cmluZy5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9ialRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qKiBVc2VkIHRvIGF2b2lkIGl0ZXJhdGluZyBvdmVyIG5vbi1lbnVtZXJhYmxlIHByb3BlcnRpZXMgaW4gSUUgPCA5LiAqL1xudmFyIG5vbkVudW1Qcm9wcyA9IHt9O1xubm9uRW51bVByb3BzW2FycmF5VGFnXSA9IG5vbkVudW1Qcm9wc1tkYXRlVGFnXSA9IG5vbkVudW1Qcm9wc1tudW1iZXJUYWddID0geyAnY29uc3RydWN0b3InOiB0cnVlLCAndG9Mb2NhbGVTdHJpbmcnOiB0cnVlLCAndG9TdHJpbmcnOiB0cnVlLCAndmFsdWVPZic6IHRydWUgfTtcbm5vbkVudW1Qcm9wc1tib29sVGFnXSA9IG5vbkVudW1Qcm9wc1tzdHJpbmdUYWddID0geyAnY29uc3RydWN0b3InOiB0cnVlLCAndG9TdHJpbmcnOiB0cnVlLCAndmFsdWVPZic6IHRydWUgfTtcbm5vbkVudW1Qcm9wc1tlcnJvclRhZ10gPSBub25FbnVtUHJvcHNbZnVuY1RhZ10gPSBub25FbnVtUHJvcHNbcmVnZXhwVGFnXSA9IHsgJ2NvbnN0cnVjdG9yJzogdHJ1ZSwgJ3RvU3RyaW5nJzogdHJ1ZSB9O1xubm9uRW51bVByb3BzW29iamVjdFRhZ10gPSB7ICdjb25zdHJ1Y3Rvcic6IHRydWUgfTtcblxuYXJyYXlFYWNoKHNoYWRvd1Byb3BzLCBmdW5jdGlvbihrZXkpIHtcbiAgZm9yICh2YXIgdGFnIGluIG5vbkVudW1Qcm9wcykge1xuICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKG5vbkVudW1Qcm9wcywgdGFnKSkge1xuICAgICAgdmFyIHByb3BzID0gbm9uRW51bVByb3BzW3RhZ107XG4gICAgICBwcm9wc1trZXldID0gaGFzT3duUHJvcGVydHkuY2FsbChwcm9wcywga2V5KTtcbiAgICB9XG4gIH1cbn0pO1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIG93biBhbmQgaW5oZXJpdGVkIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgb2YgYG9iamVjdGAuXG4gKlxuICogKipOb3RlOioqIE5vbi1vYmplY3QgdmFsdWVzIGFyZSBjb2VyY2VkIHRvIG9iamVjdHMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBPYmplY3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gKiBAZXhhbXBsZVxuICpcbiAqIGZ1bmN0aW9uIEZvbygpIHtcbiAqICAgdGhpcy5hID0gMTtcbiAqICAgdGhpcy5iID0gMjtcbiAqIH1cbiAqXG4gKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICpcbiAqIF8ua2V5c0luKG5ldyBGb28pO1xuICogLy8gPT4gWydhJywgJ2InLCAnYyddIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gKi9cbmZ1bmN0aW9uIGtleXNJbihvYmplY3QpIHtcbiAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG4gIGlmICghaXNPYmplY3Qob2JqZWN0KSkge1xuICAgIG9iamVjdCA9IE9iamVjdChvYmplY3QpO1xuICB9XG4gIHZhciBsZW5ndGggPSBvYmplY3QubGVuZ3RoO1xuXG4gIGxlbmd0aCA9IChsZW5ndGggJiYgaXNMZW5ndGgobGVuZ3RoKSAmJlxuICAgIChpc0FycmF5KG9iamVjdCkgfHwgaXNBcmd1bWVudHMob2JqZWN0KSB8fCBpc1N0cmluZyhvYmplY3QpKSAmJiBsZW5ndGgpIHx8IDA7XG5cbiAgdmFyIEN0b3IgPSBvYmplY3QuY29uc3RydWN0b3IsXG4gICAgICBpbmRleCA9IC0xLFxuICAgICAgcHJvdG8gPSAoaXNGdW5jdGlvbihDdG9yKSAmJiBDdG9yLnByb3RvdHlwZSkgfHwgb2JqZWN0UHJvdG8sXG4gICAgICBpc1Byb3RvID0gcHJvdG8gPT09IG9iamVjdCxcbiAgICAgIHJlc3VsdCA9IEFycmF5KGxlbmd0aCksXG4gICAgICBza2lwSW5kZXhlcyA9IGxlbmd0aCA+IDAsXG4gICAgICBza2lwRXJyb3JQcm9wcyA9IHN1cHBvcnQuZW51bUVycm9yUHJvcHMgJiYgKG9iamVjdCA9PT0gZXJyb3JQcm90byB8fCBvYmplY3QgaW5zdGFuY2VvZiBFcnJvciksXG4gICAgICBza2lwUHJvdG8gPSBzdXBwb3J0LmVudW1Qcm90b3R5cGVzICYmIGlzRnVuY3Rpb24ob2JqZWN0KTtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHJlc3VsdFtpbmRleF0gPSAoaW5kZXggKyAnJyk7XG4gIH1cbiAgLy8gbG9kYXNoIHNraXBzIHRoZSBgY29uc3RydWN0b3JgIHByb3BlcnR5IHdoZW4gaXQgaW5mZXJzIGl0J3MgaXRlcmF0aW5nXG4gIC8vIG92ZXIgYSBgcHJvdG90eXBlYCBvYmplY3QgYmVjYXVzZSBJRSA8IDkgY2FuJ3Qgc2V0IHRoZSBgW1tFbnVtZXJhYmxlXV1gXG4gIC8vIGF0dHJpYnV0ZSBvZiBhbiBleGlzdGluZyBwcm9wZXJ0eSBhbmQgdGhlIGBjb25zdHJ1Y3RvcmAgcHJvcGVydHkgb2YgYVxuICAvLyBwcm90b3R5cGUgZGVmYXVsdHMgdG8gbm9uLWVudW1lcmFibGUuXG4gIGZvciAodmFyIGtleSBpbiBvYmplY3QpIHtcbiAgICBpZiAoIShza2lwUHJvdG8gJiYga2V5ID09ICdwcm90b3R5cGUnKSAmJlxuICAgICAgICAhKHNraXBFcnJvclByb3BzICYmIChrZXkgPT0gJ21lc3NhZ2UnIHx8IGtleSA9PSAnbmFtZScpKSAmJlxuICAgICAgICAhKHNraXBJbmRleGVzICYmIGlzSW5kZXgoa2V5LCBsZW5ndGgpKSAmJlxuICAgICAgICAhKGtleSA9PSAnY29uc3RydWN0b3InICYmIChpc1Byb3RvIHx8ICFoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSkpKSB7XG4gICAgICByZXN1bHQucHVzaChrZXkpO1xuICAgIH1cbiAgfVxuICBpZiAoc3VwcG9ydC5ub25FbnVtU2hhZG93cyAmJiBvYmplY3QgIT09IG9iamVjdFByb3RvKSB7XG4gICAgdmFyIHRhZyA9IG9iamVjdCA9PT0gc3RyaW5nUHJvdG8gPyBzdHJpbmdUYWcgOiAob2JqZWN0ID09PSBlcnJvclByb3RvID8gZXJyb3JUYWcgOiBvYmpUb1N0cmluZy5jYWxsKG9iamVjdCkpLFxuICAgICAgICBub25FbnVtcyA9IG5vbkVudW1Qcm9wc1t0YWddIHx8IG5vbkVudW1Qcm9wc1tvYmplY3RUYWddO1xuXG4gICAgaWYgKHRhZyA9PSBvYmplY3RUYWcpIHtcbiAgICAgIHByb3RvID0gb2JqZWN0UHJvdG87XG4gICAgfVxuICAgIGxlbmd0aCA9IHNoYWRvd1Byb3BzLmxlbmd0aDtcbiAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgIGtleSA9IHNoYWRvd1Byb3BzW2xlbmd0aF07XG4gICAgICB2YXIgbm9uRW51bSA9IG5vbkVudW1zW2tleV07XG4gICAgICBpZiAoIShpc1Byb3RvICYmIG5vbkVudW0pICYmXG4gICAgICAgICAgKG5vbkVudW0gPyBoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSA6IG9iamVjdFtrZXldICE9PSBwcm90b1trZXldKSkge1xuICAgICAgICByZXN1bHQucHVzaChrZXkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGtleXNJbjtcbiIsInZhciBrZXlzID0gcmVxdWlyZSgnLi9rZXlzJyksXG4gICAgdG9PYmplY3QgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC90b09iamVjdCcpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSB0d28gZGltZW5zaW9uYWwgYXJyYXkgb2YgdGhlIGtleS12YWx1ZSBwYWlycyBmb3IgYG9iamVjdGAsXG4gKiBlLmcuIGBbW2tleTEsIHZhbHVlMV0sIFtrZXkyLCB2YWx1ZTJdXWAuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBPYmplY3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGtleS12YWx1ZSBwYWlycy5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5wYWlycyh7ICdiYXJuZXknOiAzNiwgJ2ZyZWQnOiA0MCB9KTtcbiAqIC8vID0+IFtbJ2Jhcm5leScsIDM2XSwgWydmcmVkJywgNDBdXSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICovXG5mdW5jdGlvbiBwYWlycyhvYmplY3QpIHtcbiAgb2JqZWN0ID0gdG9PYmplY3Qob2JqZWN0KTtcblxuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIHByb3BzID0ga2V5cyhvYmplY3QpLFxuICAgICAgbGVuZ3RoID0gcHJvcHMubGVuZ3RoLFxuICAgICAgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKTtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHZhciBrZXkgPSBwcm9wc1tpbmRleF07XG4gICAgcmVzdWx0W2luZGV4XSA9IFtrZXksIG9iamVjdFtrZXldXTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHBhaXJzO1xuIiwidmFyIGJhc2VWYWx1ZXMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlVmFsdWVzJyksXG4gICAga2V5cyA9IHJlcXVpcmUoJy4va2V5cycpO1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIG93biBlbnVtZXJhYmxlIHByb3BlcnR5IHZhbHVlcyBvZiBgb2JqZWN0YC5cbiAqXG4gKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IE9iamVjdFxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSB2YWx1ZXMuXG4gKiBAZXhhbXBsZVxuICpcbiAqIGZ1bmN0aW9uIEZvbygpIHtcbiAqICAgdGhpcy5hID0gMTtcbiAqICAgdGhpcy5iID0gMjtcbiAqIH1cbiAqXG4gKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICpcbiAqIF8udmFsdWVzKG5ldyBGb28pO1xuICogLy8gPT4gWzEsIDJdIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gKlxuICogXy52YWx1ZXMoJ2hpJyk7XG4gKiAvLyA9PiBbJ2gnLCAnaSddXG4gKi9cbmZ1bmN0aW9uIHZhbHVlcyhvYmplY3QpIHtcbiAgcmV0dXJuIGJhc2VWYWx1ZXMob2JqZWN0LCBrZXlzKG9iamVjdCkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHZhbHVlcztcbiIsIi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgYXJyYXlQcm90byA9IEFycmF5LnByb3RvdHlwZSxcbiAgICBlcnJvclByb3RvID0gRXJyb3IucHJvdG90eXBlLFxuICAgIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBwcm9wZXJ0eUlzRW51bWVyYWJsZSA9IG9iamVjdFByb3RvLnByb3BlcnR5SXNFbnVtZXJhYmxlLFxuICAgIHNwbGljZSA9IGFycmF5UHJvdG8uc3BsaWNlO1xuXG4vKipcbiAqIEFuIG9iamVjdCBlbnZpcm9ubWVudCBmZWF0dXJlIGZsYWdzLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAdHlwZSBPYmplY3RcbiAqL1xudmFyIHN1cHBvcnQgPSB7fTtcblxuKGZ1bmN0aW9uKHgpIHtcbiAgdmFyIEN0b3IgPSBmdW5jdGlvbigpIHsgdGhpcy54ID0geDsgfSxcbiAgICAgIG9iamVjdCA9IHsgJzAnOiB4LCAnbGVuZ3RoJzogeCB9LFxuICAgICAgcHJvcHMgPSBbXTtcblxuICBDdG9yLnByb3RvdHlwZSA9IHsgJ3ZhbHVlT2YnOiB4LCAneSc6IHggfTtcbiAgZm9yICh2YXIga2V5IGluIG5ldyBDdG9yKSB7IHByb3BzLnB1c2goa2V5KTsgfVxuXG4gIC8qKlxuICAgKiBEZXRlY3QgaWYgYG5hbWVgIG9yIGBtZXNzYWdlYCBwcm9wZXJ0aWVzIG9mIGBFcnJvci5wcm90b3R5cGVgIGFyZVxuICAgKiBlbnVtZXJhYmxlIGJ5IGRlZmF1bHQgKElFIDwgOSwgU2FmYXJpIDwgNS4xKS5cbiAgICpcbiAgICogQG1lbWJlck9mIF8uc3VwcG9ydFxuICAgKiBAdHlwZSBib29sZWFuXG4gICAqL1xuICBzdXBwb3J0LmVudW1FcnJvclByb3BzID0gcHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChlcnJvclByb3RvLCAnbWVzc2FnZScpIHx8XG4gICAgcHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChlcnJvclByb3RvLCAnbmFtZScpO1xuXG4gIC8qKlxuICAgKiBEZXRlY3QgaWYgYHByb3RvdHlwZWAgcHJvcGVydGllcyBhcmUgZW51bWVyYWJsZSBieSBkZWZhdWx0LlxuICAgKlxuICAgKiBGaXJlZm94IDwgMy42LCBPcGVyYSA+IDkuNTAgLSBPcGVyYSA8IDExLjYwLCBhbmQgU2FmYXJpIDwgNS4xXG4gICAqIChpZiB0aGUgcHJvdG90eXBlIG9yIGEgcHJvcGVydHkgb24gdGhlIHByb3RvdHlwZSBoYXMgYmVlbiBzZXQpXG4gICAqIGluY29ycmVjdGx5IHNldCB0aGUgYFtbRW51bWVyYWJsZV1dYCB2YWx1ZSBvZiBhIGZ1bmN0aW9uJ3MgYHByb3RvdHlwZWBcbiAgICogcHJvcGVydHkgdG8gYHRydWVgLlxuICAgKlxuICAgKiBAbWVtYmVyT2YgXy5zdXBwb3J0XG4gICAqIEB0eXBlIGJvb2xlYW5cbiAgICovXG4gIHN1cHBvcnQuZW51bVByb3RvdHlwZXMgPSBwcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKEN0b3IsICdwcm90b3R5cGUnKTtcblxuICAvKipcbiAgICogRGV0ZWN0IGlmIHByb3BlcnRpZXMgc2hhZG93aW5nIHRob3NlIG9uIGBPYmplY3QucHJvdG90eXBlYCBhcmUgbm9uLWVudW1lcmFibGUuXG4gICAqXG4gICAqIEluIElFIDwgOSBhbiBvYmplY3QncyBvd24gcHJvcGVydGllcywgc2hhZG93aW5nIG5vbi1lbnVtZXJhYmxlIG9uZXMsXG4gICAqIGFyZSBtYWRlIG5vbi1lbnVtZXJhYmxlIGFzIHdlbGwgKGEuay5hIHRoZSBKU2NyaXB0IGBbW0RvbnRFbnVtXV1gIGJ1ZykuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBfLnN1cHBvcnRcbiAgICogQHR5cGUgYm9vbGVhblxuICAgKi9cbiAgc3VwcG9ydC5ub25FbnVtU2hhZG93cyA9ICEvdmFsdWVPZi8udGVzdChwcm9wcyk7XG5cbiAgLyoqXG4gICAqIERldGVjdCBpZiBvd24gcHJvcGVydGllcyBhcmUgaXRlcmF0ZWQgYWZ0ZXIgaW5oZXJpdGVkIHByb3BlcnRpZXMgKElFIDwgOSkuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBfLnN1cHBvcnRcbiAgICogQHR5cGUgYm9vbGVhblxuICAgKi9cbiAgc3VwcG9ydC5vd25MYXN0ID0gcHJvcHNbMF0gIT0gJ3gnO1xuXG4gIC8qKlxuICAgKiBEZXRlY3QgaWYgYEFycmF5I3NoaWZ0YCBhbmQgYEFycmF5I3NwbGljZWAgYXVnbWVudCBhcnJheS1saWtlIG9iamVjdHNcbiAgICogY29ycmVjdGx5LlxuICAgKlxuICAgKiBGaXJlZm94IDwgMTAsIGNvbXBhdGliaWxpdHkgbW9kZXMgb2YgSUUgOCwgYW5kIElFIDwgOSBoYXZlIGJ1Z2d5IEFycmF5XG4gICAqIGBzaGlmdCgpYCBhbmQgYHNwbGljZSgpYCBmdW5jdGlvbnMgdGhhdCBmYWlsIHRvIHJlbW92ZSB0aGUgbGFzdCBlbGVtZW50LFxuICAgKiBgdmFsdWVbMF1gLCBvZiBhcnJheS1saWtlIG9iamVjdHMgZXZlbiB0aG91Z2ggdGhlIFwibGVuZ3RoXCIgcHJvcGVydHkgaXNcbiAgICogc2V0IHRvIGAwYC4gVGhlIGBzaGlmdCgpYCBtZXRob2QgaXMgYnVnZ3kgaW4gY29tcGF0aWJpbGl0eSBtb2RlcyBvZiBJRSA4LFxuICAgKiB3aGlsZSBgc3BsaWNlKClgIGlzIGJ1Z2d5IHJlZ2FyZGxlc3Mgb2YgbW9kZSBpbiBJRSA8IDkuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBfLnN1cHBvcnRcbiAgICogQHR5cGUgYm9vbGVhblxuICAgKi9cbiAgc3VwcG9ydC5zcGxpY2VPYmplY3RzID0gKHNwbGljZS5jYWxsKG9iamVjdCwgMCwgMSksICFvYmplY3RbMF0pO1xuXG4gIC8qKlxuICAgKiBEZXRlY3QgbGFjayBvZiBzdXBwb3J0IGZvciBhY2Nlc3Npbmcgc3RyaW5nIGNoYXJhY3RlcnMgYnkgaW5kZXguXG4gICAqXG4gICAqIElFIDwgOCBjYW4ndCBhY2Nlc3MgY2hhcmFjdGVycyBieSBpbmRleC4gSUUgOCBjYW4gb25seSBhY2Nlc3MgY2hhcmFjdGVyc1xuICAgKiBieSBpbmRleCBvbiBzdHJpbmcgbGl0ZXJhbHMsIG5vdCBzdHJpbmcgb2JqZWN0cy5cbiAgICpcbiAgICogQG1lbWJlck9mIF8uc3VwcG9ydFxuICAgKiBAdHlwZSBib29sZWFuXG4gICAqL1xuICBzdXBwb3J0LnVuaW5kZXhlZENoYXJzID0gKCd4J1swXSArIE9iamVjdCgneCcpWzBdKSAhPSAneHgnO1xufSgxLCAwKSk7XG5cbm1vZHVsZS5leHBvcnRzID0gc3VwcG9ydDtcbiIsIi8qKlxuICogVGhpcyBtZXRob2QgcmV0dXJucyB0aGUgZmlyc3QgYXJndW1lbnQgcHJvdmlkZWQgdG8gaXQuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBVdGlsaXR5XG4gKiBAcGFyYW0geyp9IHZhbHVlIEFueSB2YWx1ZS5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIGB2YWx1ZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBvYmplY3QgPSB7ICd1c2VyJzogJ2ZyZWQnIH07XG4gKlxuICogXy5pZGVudGl0eShvYmplY3QpID09PSBvYmplY3Q7XG4gKiAvLyA9PiB0cnVlXG4gKi9cbmZ1bmN0aW9uIGlkZW50aXR5KHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpZGVudGl0eTtcbiIsIi8qKlxuICogQSBuby1vcGVyYXRpb24gZnVuY3Rpb24gdGhhdCByZXR1cm5zIGB1bmRlZmluZWRgIHJlZ2FyZGxlc3Mgb2YgdGhlXG4gKiBhcmd1bWVudHMgaXQgcmVjZWl2ZXMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBVdGlsaXR5XG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBvYmplY3QgPSB7ICd1c2VyJzogJ2ZyZWQnIH07XG4gKlxuICogXy5ub29wKG9iamVjdCkgPT09IHVuZGVmaW5lZDtcbiAqIC8vID0+IHRydWVcbiAqL1xuZnVuY3Rpb24gbm9vcCgpIHtcbiAgLy8gTm8gb3BlcmF0aW9uIHBlcmZvcm1lZC5cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBub29wO1xuIiwidmFyIGJhc2VQcm9wZXJ0eSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2Jhc2VQcm9wZXJ0eScpLFxuICAgIGJhc2VQcm9wZXJ0eURlZXAgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlUHJvcGVydHlEZWVwJyksXG4gICAgaXNLZXkgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0tleScpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlIGF0IGBwYXRoYCBvbiBhXG4gKiBnaXZlbiBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBVdGlsaXR5XG4gKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBvYmplY3RzID0gW1xuICogICB7ICdhJzogeyAnYic6IHsgJ2MnOiAyIH0gfSB9LFxuICogICB7ICdhJzogeyAnYic6IHsgJ2MnOiAxIH0gfSB9XG4gKiBdO1xuICpcbiAqIF8ubWFwKG9iamVjdHMsIF8ucHJvcGVydHkoJ2EuYi5jJykpO1xuICogLy8gPT4gWzIsIDFdXG4gKlxuICogXy5wbHVjayhfLnNvcnRCeShvYmplY3RzLCBfLnByb3BlcnR5KFsnYScsICdiJywgJ2MnXSkpLCAnYS5iLmMnKTtcbiAqIC8vID0+IFsxLCAyXVxuICovXG5mdW5jdGlvbiBwcm9wZXJ0eShwYXRoKSB7XG4gIHJldHVybiBpc0tleShwYXRoKSA/IGJhc2VQcm9wZXJ0eShwYXRoKSA6IGJhc2VQcm9wZXJ0eURlZXAocGF0aCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gcHJvcGVydHk7XG4iLCIoZnVuY3Rpb24gKHByb2Nlc3Mpe1xuLy8gdmltOnRzPTQ6c3RzPTQ6c3c9NDpcbi8qIVxuICpcbiAqIENvcHlyaWdodCAyMDA5LTIwMTIgS3JpcyBLb3dhbCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIE1JVFxuICogbGljZW5zZSBmb3VuZCBhdCBodHRwOi8vZ2l0aHViLmNvbS9rcmlza293YWwvcS9yYXcvbWFzdGVyL0xJQ0VOU0VcbiAqXG4gKiBXaXRoIHBhcnRzIGJ5IFR5bGVyIENsb3NlXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDA5IFR5bGVyIENsb3NlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgTUlUIFggbGljZW5zZSBmb3VuZFxuICogYXQgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9taXQtbGljZW5zZS5odG1sXG4gKiBGb3JrZWQgYXQgcmVmX3NlbmQuanMgdmVyc2lvbjogMjAwOS0wNS0xMVxuICpcbiAqIFdpdGggcGFydHMgYnkgTWFyayBNaWxsZXJcbiAqIENvcHlyaWdodCAoQykgMjAxMSBHb29nbGUgSW5jLlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4oZnVuY3Rpb24gKGRlZmluaXRpb24pIHtcbiAgICBcInVzZSBzdHJpY3RcIjtcblxuICAgIC8vIFRoaXMgZmlsZSB3aWxsIGZ1bmN0aW9uIHByb3Blcmx5IGFzIGEgPHNjcmlwdD4gdGFnLCBvciBhIG1vZHVsZVxuICAgIC8vIHVzaW5nIENvbW1vbkpTIGFuZCBOb2RlSlMgb3IgUmVxdWlyZUpTIG1vZHVsZSBmb3JtYXRzLiAgSW5cbiAgICAvLyBDb21tb24vTm9kZS9SZXF1aXJlSlMsIHRoZSBtb2R1bGUgZXhwb3J0cyB0aGUgUSBBUEkgYW5kIHdoZW5cbiAgICAvLyBleGVjdXRlZCBhcyBhIHNpbXBsZSA8c2NyaXB0PiwgaXQgY3JlYXRlcyBhIFEgZ2xvYmFsIGluc3RlYWQuXG5cbiAgICAvLyBNb250YWdlIFJlcXVpcmVcbiAgICBpZiAodHlwZW9mIGJvb3RzdHJhcCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGJvb3RzdHJhcChcInByb21pc2VcIiwgZGVmaW5pdGlvbik7XG5cbiAgICAvLyBDb21tb25KU1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG1vZHVsZSA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGRlZmluaXRpb24oKTtcblxuICAgIC8vIFJlcXVpcmVKU1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcbiAgICAgICAgZGVmaW5lKGRlZmluaXRpb24pO1xuXG4gICAgLy8gU0VTIChTZWN1cmUgRWNtYVNjcmlwdClcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBzZXMgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgaWYgKCFzZXMub2soKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2VzLm1ha2VRID0gZGVmaW5pdGlvbjtcbiAgICAgICAgfVxuXG4gICAgLy8gPHNjcmlwdD5cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgfHwgdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgLy8gUHJlZmVyIHdpbmRvdyBvdmVyIHNlbGYgZm9yIGFkZC1vbiBzY3JpcHRzLiBVc2Ugc2VsZiBmb3JcbiAgICAgICAgLy8gbm9uLXdpbmRvd2VkIGNvbnRleHRzLlxuICAgICAgICB2YXIgZ2xvYmFsID0gdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHNlbGY7XG5cbiAgICAgICAgLy8gR2V0IHRoZSBgd2luZG93YCBvYmplY3QsIHNhdmUgdGhlIHByZXZpb3VzIFEgZ2xvYmFsXG4gICAgICAgIC8vIGFuZCBpbml0aWFsaXplIFEgYXMgYSBnbG9iYWwuXG4gICAgICAgIHZhciBwcmV2aW91c1EgPSBnbG9iYWwuUTtcbiAgICAgICAgZ2xvYmFsLlEgPSBkZWZpbml0aW9uKCk7XG5cbiAgICAgICAgLy8gQWRkIGEgbm9Db25mbGljdCBmdW5jdGlvbiBzbyBRIGNhbiBiZSByZW1vdmVkIGZyb20gdGhlXG4gICAgICAgIC8vIGdsb2JhbCBuYW1lc3BhY2UuXG4gICAgICAgIGdsb2JhbC5RLm5vQ29uZmxpY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBnbG9iYWwuUSA9IHByZXZpb3VzUTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9O1xuXG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBlbnZpcm9ubWVudCB3YXMgbm90IGFudGljaXBhdGVkIGJ5IFEuIFBsZWFzZSBmaWxlIGEgYnVnLlwiKTtcbiAgICB9XG5cbn0pKGZ1bmN0aW9uICgpIHtcblwidXNlIHN0cmljdFwiO1xuXG52YXIgaGFzU3RhY2tzID0gZmFsc2U7XG50cnkge1xuICAgIHRocm93IG5ldyBFcnJvcigpO1xufSBjYXRjaCAoZSkge1xuICAgIGhhc1N0YWNrcyA9ICEhZS5zdGFjaztcbn1cblxuLy8gQWxsIGNvZGUgYWZ0ZXIgdGhpcyBwb2ludCB3aWxsIGJlIGZpbHRlcmVkIGZyb20gc3RhY2sgdHJhY2VzIHJlcG9ydGVkXG4vLyBieSBRLlxudmFyIHFTdGFydGluZ0xpbmUgPSBjYXB0dXJlTGluZSgpO1xudmFyIHFGaWxlTmFtZTtcblxuLy8gc2hpbXNcblxuLy8gdXNlZCBmb3IgZmFsbGJhY2sgaW4gXCJhbGxSZXNvbHZlZFwiXG52YXIgbm9vcCA9IGZ1bmN0aW9uICgpIHt9O1xuXG4vLyBVc2UgdGhlIGZhc3Rlc3QgcG9zc2libGUgbWVhbnMgdG8gZXhlY3V0ZSBhIHRhc2sgaW4gYSBmdXR1cmUgdHVyblxuLy8gb2YgdGhlIGV2ZW50IGxvb3AuXG52YXIgbmV4dFRpY2sgPShmdW5jdGlvbiAoKSB7XG4gICAgLy8gbGlua2VkIGxpc3Qgb2YgdGFza3MgKHNpbmdsZSwgd2l0aCBoZWFkIG5vZGUpXG4gICAgdmFyIGhlYWQgPSB7dGFzazogdm9pZCAwLCBuZXh0OiBudWxsfTtcbiAgICB2YXIgdGFpbCA9IGhlYWQ7XG4gICAgdmFyIGZsdXNoaW5nID0gZmFsc2U7XG4gICAgdmFyIHJlcXVlc3RUaWNrID0gdm9pZCAwO1xuICAgIHZhciBpc05vZGVKUyA9IGZhbHNlO1xuICAgIC8vIHF1ZXVlIGZvciBsYXRlIHRhc2tzLCB1c2VkIGJ5IHVuaGFuZGxlZCByZWplY3Rpb24gdHJhY2tpbmdcbiAgICB2YXIgbGF0ZXJRdWV1ZSA9IFtdO1xuXG4gICAgZnVuY3Rpb24gZmx1c2goKSB7XG4gICAgICAgIC8qIGpzaGludCBsb29wZnVuYzogdHJ1ZSAqL1xuICAgICAgICB2YXIgdGFzaywgZG9tYWluO1xuXG4gICAgICAgIHdoaWxlIChoZWFkLm5leHQpIHtcbiAgICAgICAgICAgIGhlYWQgPSBoZWFkLm5leHQ7XG4gICAgICAgICAgICB0YXNrID0gaGVhZC50YXNrO1xuICAgICAgICAgICAgaGVhZC50YXNrID0gdm9pZCAwO1xuICAgICAgICAgICAgZG9tYWluID0gaGVhZC5kb21haW47XG5cbiAgICAgICAgICAgIGlmIChkb21haW4pIHtcbiAgICAgICAgICAgICAgICBoZWFkLmRvbWFpbiA9IHZvaWQgMDtcbiAgICAgICAgICAgICAgICBkb21haW4uZW50ZXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJ1blNpbmdsZSh0YXNrLCBkb21haW4pO1xuXG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKGxhdGVyUXVldWUubGVuZ3RoKSB7XG4gICAgICAgICAgICB0YXNrID0gbGF0ZXJRdWV1ZS5wb3AoKTtcbiAgICAgICAgICAgIHJ1blNpbmdsZSh0YXNrKTtcbiAgICAgICAgfVxuICAgICAgICBmbHVzaGluZyA9IGZhbHNlO1xuICAgIH1cbiAgICAvLyBydW5zIGEgc2luZ2xlIGZ1bmN0aW9uIGluIHRoZSBhc3luYyBxdWV1ZVxuICAgIGZ1bmN0aW9uIHJ1blNpbmdsZSh0YXNrLCBkb21haW4pIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRhc2soKTtcblxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBpZiAoaXNOb2RlSlMpIHtcbiAgICAgICAgICAgICAgICAvLyBJbiBub2RlLCB1bmNhdWdodCBleGNlcHRpb25zIGFyZSBjb25zaWRlcmVkIGZhdGFsIGVycm9ycy5cbiAgICAgICAgICAgICAgICAvLyBSZS10aHJvdyB0aGVtIHN5bmNocm9ub3VzbHkgdG8gaW50ZXJydXB0IGZsdXNoaW5nIVxuXG4gICAgICAgICAgICAgICAgLy8gRW5zdXJlIGNvbnRpbnVhdGlvbiBpZiB0aGUgdW5jYXVnaHQgZXhjZXB0aW9uIGlzIHN1cHByZXNzZWRcbiAgICAgICAgICAgICAgICAvLyBsaXN0ZW5pbmcgXCJ1bmNhdWdodEV4Y2VwdGlvblwiIGV2ZW50cyAoYXMgZG9tYWlucyBkb2VzKS5cbiAgICAgICAgICAgICAgICAvLyBDb250aW51ZSBpbiBuZXh0IGV2ZW50IHRvIGF2b2lkIHRpY2sgcmVjdXJzaW9uLlxuICAgICAgICAgICAgICAgIGlmIChkb21haW4pIHtcbiAgICAgICAgICAgICAgICAgICAgZG9tYWluLmV4aXQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dChmbHVzaCwgMCk7XG4gICAgICAgICAgICAgICAgaWYgKGRvbWFpbikge1xuICAgICAgICAgICAgICAgICAgICBkb21haW4uZW50ZXIoKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aHJvdyBlO1xuXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIEluIGJyb3dzZXJzLCB1bmNhdWdodCBleGNlcHRpb25zIGFyZSBub3QgZmF0YWwuXG4gICAgICAgICAgICAgICAgLy8gUmUtdGhyb3cgdGhlbSBhc3luY2hyb25vdXNseSB0byBhdm9pZCBzbG93LWRvd25zLlxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICAgICAgICAgIH0sIDApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGRvbWFpbikge1xuICAgICAgICAgICAgZG9tYWluLmV4aXQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5leHRUaWNrID0gZnVuY3Rpb24gKHRhc2spIHtcbiAgICAgICAgdGFpbCA9IHRhaWwubmV4dCA9IHtcbiAgICAgICAgICAgIHRhc2s6IHRhc2ssXG4gICAgICAgICAgICBkb21haW46IGlzTm9kZUpTICYmIHByb2Nlc3MuZG9tYWluLFxuICAgICAgICAgICAgbmV4dDogbnVsbFxuICAgICAgICB9O1xuXG4gICAgICAgIGlmICghZmx1c2hpbmcpIHtcbiAgICAgICAgICAgIGZsdXNoaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIHJlcXVlc3RUaWNrKCk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgIHByb2Nlc3MudG9TdHJpbmcoKSA9PT0gXCJbb2JqZWN0IHByb2Nlc3NdXCIgJiYgcHJvY2Vzcy5uZXh0VGljaykge1xuICAgICAgICAvLyBFbnN1cmUgUSBpcyBpbiBhIHJlYWwgTm9kZSBlbnZpcm9ubWVudCwgd2l0aCBhIGBwcm9jZXNzLm5leHRUaWNrYC5cbiAgICAgICAgLy8gVG8gc2VlIHRocm91Z2ggZmFrZSBOb2RlIGVudmlyb25tZW50czpcbiAgICAgICAgLy8gKiBNb2NoYSB0ZXN0IHJ1bm5lciAtIGV4cG9zZXMgYSBgcHJvY2Vzc2AgZ2xvYmFsIHdpdGhvdXQgYSBgbmV4dFRpY2tgXG4gICAgICAgIC8vICogQnJvd3NlcmlmeSAtIGV4cG9zZXMgYSBgcHJvY2Vzcy5uZXhUaWNrYCBmdW5jdGlvbiB0aGF0IHVzZXNcbiAgICAgICAgLy8gICBgc2V0VGltZW91dGAuIEluIHRoaXMgY2FzZSBgc2V0SW1tZWRpYXRlYCBpcyBwcmVmZXJyZWQgYmVjYXVzZVxuICAgICAgICAvLyAgICBpdCBpcyBmYXN0ZXIuIEJyb3dzZXJpZnkncyBgcHJvY2Vzcy50b1N0cmluZygpYCB5aWVsZHNcbiAgICAgICAgLy8gICBcIltvYmplY3QgT2JqZWN0XVwiLCB3aGlsZSBpbiBhIHJlYWwgTm9kZSBlbnZpcm9ubWVudFxuICAgICAgICAvLyAgIGBwcm9jZXNzLm5leHRUaWNrKClgIHlpZWxkcyBcIltvYmplY3QgcHJvY2Vzc11cIi5cbiAgICAgICAgaXNOb2RlSlMgPSB0cnVlO1xuXG4gICAgICAgIHJlcXVlc3RUaWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcHJvY2Vzcy5uZXh0VGljayhmbHVzaCk7XG4gICAgICAgIH07XG5cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBzZXRJbW1lZGlhdGUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAvLyBJbiBJRTEwLCBOb2RlLmpzIDAuOSssIG9yIGh0dHBzOi8vZ2l0aHViLmNvbS9Ob2JsZUpTL3NldEltbWVkaWF0ZVxuICAgICAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgcmVxdWVzdFRpY2sgPSBzZXRJbW1lZGlhdGUuYmluZCh3aW5kb3csIGZsdXNoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlcXVlc3RUaWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHNldEltbWVkaWF0ZShmbHVzaCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBNZXNzYWdlQ2hhbm5lbCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAvLyBtb2Rlcm4gYnJvd3NlcnNcbiAgICAgICAgLy8gaHR0cDovL3d3dy5ub25ibG9ja2luZy5pby8yMDExLzA2L3dpbmRvd25leHR0aWNrLmh0bWxcbiAgICAgICAgdmFyIGNoYW5uZWwgPSBuZXcgTWVzc2FnZUNoYW5uZWwoKTtcbiAgICAgICAgLy8gQXQgbGVhc3QgU2FmYXJpIFZlcnNpb24gNi4wLjUgKDg1MzYuMzAuMSkgaW50ZXJtaXR0ZW50bHkgY2Fubm90IGNyZWF0ZVxuICAgICAgICAvLyB3b3JraW5nIG1lc3NhZ2UgcG9ydHMgdGhlIGZpcnN0IHRpbWUgYSBwYWdlIGxvYWRzLlxuICAgICAgICBjaGFubmVsLnBvcnQxLm9ubWVzc2FnZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJlcXVlc3RUaWNrID0gcmVxdWVzdFBvcnRUaWNrO1xuICAgICAgICAgICAgY2hhbm5lbC5wb3J0MS5vbm1lc3NhZ2UgPSBmbHVzaDtcbiAgICAgICAgICAgIGZsdXNoKCk7XG4gICAgICAgIH07XG4gICAgICAgIHZhciByZXF1ZXN0UG9ydFRpY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAvLyBPcGVyYSByZXF1aXJlcyB1cyB0byBwcm92aWRlIGEgbWVzc2FnZSBwYXlsb2FkLCByZWdhcmRsZXNzIG9mXG4gICAgICAgICAgICAvLyB3aGV0aGVyIHdlIHVzZSBpdC5cbiAgICAgICAgICAgIGNoYW5uZWwucG9ydDIucG9zdE1lc3NhZ2UoMCk7XG4gICAgICAgIH07XG4gICAgICAgIHJlcXVlc3RUaWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgc2V0VGltZW91dChmbHVzaCwgMCk7XG4gICAgICAgICAgICByZXF1ZXN0UG9ydFRpY2soKTtcbiAgICAgICAgfTtcblxuICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIG9sZCBicm93c2Vyc1xuICAgICAgICByZXF1ZXN0VGljayA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoZmx1c2gsIDApO1xuICAgICAgICB9O1xuICAgIH1cbiAgICAvLyBydW5zIGEgdGFzayBhZnRlciBhbGwgb3RoZXIgdGFza3MgaGF2ZSBiZWVuIHJ1blxuICAgIC8vIHRoaXMgaXMgdXNlZnVsIGZvciB1bmhhbmRsZWQgcmVqZWN0aW9uIHRyYWNraW5nIHRoYXQgbmVlZHMgdG8gaGFwcGVuXG4gICAgLy8gYWZ0ZXIgYWxsIGB0aGVuYGQgdGFza3MgaGF2ZSBiZWVuIHJ1bi5cbiAgICBuZXh0VGljay5ydW5BZnRlciA9IGZ1bmN0aW9uICh0YXNrKSB7XG4gICAgICAgIGxhdGVyUXVldWUucHVzaCh0YXNrKTtcbiAgICAgICAgaWYgKCFmbHVzaGluZykge1xuICAgICAgICAgICAgZmx1c2hpbmcgPSB0cnVlO1xuICAgICAgICAgICAgcmVxdWVzdFRpY2soKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgcmV0dXJuIG5leHRUaWNrO1xufSkoKTtcblxuLy8gQXR0ZW1wdCB0byBtYWtlIGdlbmVyaWNzIHNhZmUgaW4gdGhlIGZhY2Ugb2YgZG93bnN0cmVhbVxuLy8gbW9kaWZpY2F0aW9ucy5cbi8vIFRoZXJlIGlzIG5vIHNpdHVhdGlvbiB3aGVyZSB0aGlzIGlzIG5lY2Vzc2FyeS5cbi8vIElmIHlvdSBuZWVkIGEgc2VjdXJpdHkgZ3VhcmFudGVlLCB0aGVzZSBwcmltb3JkaWFscyBuZWVkIHRvIGJlXG4vLyBkZWVwbHkgZnJvemVuIGFueXdheSwgYW5kIGlmIHlvdSBkb27igJl0IG5lZWQgYSBzZWN1cml0eSBndWFyYW50ZWUsXG4vLyB0aGlzIGlzIGp1c3QgcGxhaW4gcGFyYW5vaWQuXG4vLyBIb3dldmVyLCB0aGlzICoqbWlnaHQqKiBoYXZlIHRoZSBuaWNlIHNpZGUtZWZmZWN0IG9mIHJlZHVjaW5nIHRoZSBzaXplIG9mXG4vLyB0aGUgbWluaWZpZWQgY29kZSBieSByZWR1Y2luZyB4LmNhbGwoKSB0byBtZXJlbHkgeCgpXG4vLyBTZWUgTWFyayBNaWxsZXLigJlzIGV4cGxhbmF0aW9uIG9mIHdoYXQgdGhpcyBkb2VzLlxuLy8gaHR0cDovL3dpa2kuZWNtYXNjcmlwdC5vcmcvZG9rdS5waHA/aWQ9Y29udmVudGlvbnM6c2FmZV9tZXRhX3Byb2dyYW1taW5nXG52YXIgY2FsbCA9IEZ1bmN0aW9uLmNhbGw7XG5mdW5jdGlvbiB1bmN1cnJ5VGhpcyhmKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIGNhbGwuYXBwbHkoZiwgYXJndW1lbnRzKTtcbiAgICB9O1xufVxuLy8gVGhpcyBpcyBlcXVpdmFsZW50LCBidXQgc2xvd2VyOlxuLy8gdW5jdXJyeVRoaXMgPSBGdW5jdGlvbl9iaW5kLmJpbmQoRnVuY3Rpb25fYmluZC5jYWxsKTtcbi8vIGh0dHA6Ly9qc3BlcmYuY29tL3VuY3Vycnl0aGlzXG5cbnZhciBhcnJheV9zbGljZSA9IHVuY3VycnlUaGlzKEFycmF5LnByb3RvdHlwZS5zbGljZSk7XG5cbnZhciBhcnJheV9yZWR1Y2UgPSB1bmN1cnJ5VGhpcyhcbiAgICBBcnJheS5wcm90b3R5cGUucmVkdWNlIHx8IGZ1bmN0aW9uIChjYWxsYmFjaywgYmFzaXMpIHtcbiAgICAgICAgdmFyIGluZGV4ID0gMCxcbiAgICAgICAgICAgIGxlbmd0aCA9IHRoaXMubGVuZ3RoO1xuICAgICAgICAvLyBjb25jZXJuaW5nIHRoZSBpbml0aWFsIHZhbHVlLCBpZiBvbmUgaXMgbm90IHByb3ZpZGVkXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICAvLyBzZWVrIHRvIHRoZSBmaXJzdCB2YWx1ZSBpbiB0aGUgYXJyYXksIGFjY291bnRpbmdcbiAgICAgICAgICAgIC8vIGZvciB0aGUgcG9zc2liaWxpdHkgdGhhdCBpcyBpcyBhIHNwYXJzZSBhcnJheVxuICAgICAgICAgICAgZG8ge1xuICAgICAgICAgICAgICAgIGlmIChpbmRleCBpbiB0aGlzKSB7XG4gICAgICAgICAgICAgICAgICAgIGJhc2lzID0gdGhpc1tpbmRleCsrXTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICgrK2luZGV4ID49IGxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSB3aGlsZSAoMSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gcmVkdWNlXG4gICAgICAgIGZvciAoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICAgICAgLy8gYWNjb3VudCBmb3IgdGhlIHBvc3NpYmlsaXR5IHRoYXQgdGhlIGFycmF5IGlzIHNwYXJzZVxuICAgICAgICAgICAgaWYgKGluZGV4IGluIHRoaXMpIHtcbiAgICAgICAgICAgICAgICBiYXNpcyA9IGNhbGxiYWNrKGJhc2lzLCB0aGlzW2luZGV4XSwgaW5kZXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBiYXNpcztcbiAgICB9XG4pO1xuXG52YXIgYXJyYXlfaW5kZXhPZiA9IHVuY3VycnlUaGlzKFxuICAgIEFycmF5LnByb3RvdHlwZS5pbmRleE9mIHx8IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAvLyBub3QgYSB2ZXJ5IGdvb2Qgc2hpbSwgYnV0IGdvb2QgZW5vdWdoIGZvciBvdXIgb25lIHVzZSBvZiBpdFxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICh0aGlzW2ldID09PSB2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiAtMTtcbiAgICB9XG4pO1xuXG52YXIgYXJyYXlfbWFwID0gdW5jdXJyeVRoaXMoXG4gICAgQXJyYXkucHJvdG90eXBlLm1hcCB8fCBmdW5jdGlvbiAoY2FsbGJhY2ssIHRoaXNwKSB7XG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgdmFyIGNvbGxlY3QgPSBbXTtcbiAgICAgICAgYXJyYXlfcmVkdWNlKHNlbGYsIGZ1bmN0aW9uICh1bmRlZmluZWQsIHZhbHVlLCBpbmRleCkge1xuICAgICAgICAgICAgY29sbGVjdC5wdXNoKGNhbGxiYWNrLmNhbGwodGhpc3AsIHZhbHVlLCBpbmRleCwgc2VsZikpO1xuICAgICAgICB9LCB2b2lkIDApO1xuICAgICAgICByZXR1cm4gY29sbGVjdDtcbiAgICB9XG4pO1xuXG52YXIgb2JqZWN0X2NyZWF0ZSA9IE9iamVjdC5jcmVhdGUgfHwgZnVuY3Rpb24gKHByb3RvdHlwZSkge1xuICAgIGZ1bmN0aW9uIFR5cGUoKSB7IH1cbiAgICBUeXBlLnByb3RvdHlwZSA9IHByb3RvdHlwZTtcbiAgICByZXR1cm4gbmV3IFR5cGUoKTtcbn07XG5cbnZhciBvYmplY3RfaGFzT3duUHJvcGVydHkgPSB1bmN1cnJ5VGhpcyhPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5KTtcblxudmFyIG9iamVjdF9rZXlzID0gT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24gKG9iamVjdCkge1xuICAgIHZhciBrZXlzID0gW107XG4gICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgICAgICBpZiAob2JqZWN0X2hhc093blByb3BlcnR5KG9iamVjdCwga2V5KSkge1xuICAgICAgICAgICAga2V5cy5wdXNoKGtleSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGtleXM7XG59O1xuXG52YXIgb2JqZWN0X3RvU3RyaW5nID0gdW5jdXJyeVRoaXMoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZyk7XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09PSBPYmplY3QodmFsdWUpO1xufVxuXG4vLyBnZW5lcmF0b3IgcmVsYXRlZCBzaGltc1xuXG4vLyBGSVhNRTogUmVtb3ZlIHRoaXMgZnVuY3Rpb24gb25jZSBFUzYgZ2VuZXJhdG9ycyBhcmUgaW4gU3BpZGVyTW9ua2V5LlxuZnVuY3Rpb24gaXNTdG9wSXRlcmF0aW9uKGV4Y2VwdGlvbikge1xuICAgIHJldHVybiAoXG4gICAgICAgIG9iamVjdF90b1N0cmluZyhleGNlcHRpb24pID09PSBcIltvYmplY3QgU3RvcEl0ZXJhdGlvbl1cIiB8fFxuICAgICAgICBleGNlcHRpb24gaW5zdGFuY2VvZiBRUmV0dXJuVmFsdWVcbiAgICApO1xufVxuXG4vLyBGSVhNRTogUmVtb3ZlIHRoaXMgaGVscGVyIGFuZCBRLnJldHVybiBvbmNlIEVTNiBnZW5lcmF0b3JzIGFyZSBpblxuLy8gU3BpZGVyTW9ua2V5LlxudmFyIFFSZXR1cm5WYWx1ZTtcbmlmICh0eXBlb2YgUmV0dXJuVmFsdWUgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICBRUmV0dXJuVmFsdWUgPSBSZXR1cm5WYWx1ZTtcbn0gZWxzZSB7XG4gICAgUVJldHVyblZhbHVlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB9O1xufVxuXG4vLyBsb25nIHN0YWNrIHRyYWNlc1xuXG52YXIgU1RBQ0tfSlVNUF9TRVBBUkFUT1IgPSBcIkZyb20gcHJldmlvdXMgZXZlbnQ6XCI7XG5cbmZ1bmN0aW9uIG1ha2VTdGFja1RyYWNlTG9uZyhlcnJvciwgcHJvbWlzZSkge1xuICAgIC8vIElmIHBvc3NpYmxlLCB0cmFuc2Zvcm0gdGhlIGVycm9yIHN0YWNrIHRyYWNlIGJ5IHJlbW92aW5nIE5vZGUgYW5kIFFcbiAgICAvLyBjcnVmdCwgdGhlbiBjb25jYXRlbmF0aW5nIHdpdGggdGhlIHN0YWNrIHRyYWNlIG9mIGBwcm9taXNlYC4gU2VlICM1Ny5cbiAgICBpZiAoaGFzU3RhY2tzICYmXG4gICAgICAgIHByb21pc2Uuc3RhY2sgJiZcbiAgICAgICAgdHlwZW9mIGVycm9yID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgIGVycm9yICE9PSBudWxsICYmXG4gICAgICAgIGVycm9yLnN0YWNrICYmXG4gICAgICAgIGVycm9yLnN0YWNrLmluZGV4T2YoU1RBQ0tfSlVNUF9TRVBBUkFUT1IpID09PSAtMVxuICAgICkge1xuICAgICAgICB2YXIgc3RhY2tzID0gW107XG4gICAgICAgIGZvciAodmFyIHAgPSBwcm9taXNlOyAhIXA7IHAgPSBwLnNvdXJjZSkge1xuICAgICAgICAgICAgaWYgKHAuc3RhY2spIHtcbiAgICAgICAgICAgICAgICBzdGFja3MudW5zaGlmdChwLnN0YWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBzdGFja3MudW5zaGlmdChlcnJvci5zdGFjayk7XG5cbiAgICAgICAgdmFyIGNvbmNhdGVkU3RhY2tzID0gc3RhY2tzLmpvaW4oXCJcXG5cIiArIFNUQUNLX0pVTVBfU0VQQVJBVE9SICsgXCJcXG5cIik7XG4gICAgICAgIGVycm9yLnN0YWNrID0gZmlsdGVyU3RhY2tTdHJpbmcoY29uY2F0ZWRTdGFja3MpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZmlsdGVyU3RhY2tTdHJpbmcoc3RhY2tTdHJpbmcpIHtcbiAgICB2YXIgbGluZXMgPSBzdGFja1N0cmluZy5zcGxpdChcIlxcblwiKTtcbiAgICB2YXIgZGVzaXJlZExpbmVzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgbGluZSA9IGxpbmVzW2ldO1xuXG4gICAgICAgIGlmICghaXNJbnRlcm5hbEZyYW1lKGxpbmUpICYmICFpc05vZGVGcmFtZShsaW5lKSAmJiBsaW5lKSB7XG4gICAgICAgICAgICBkZXNpcmVkTGluZXMucHVzaChsaW5lKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZGVzaXJlZExpbmVzLmpvaW4oXCJcXG5cIik7XG59XG5cbmZ1bmN0aW9uIGlzTm9kZUZyYW1lKHN0YWNrTGluZSkge1xuICAgIHJldHVybiBzdGFja0xpbmUuaW5kZXhPZihcIihtb2R1bGUuanM6XCIpICE9PSAtMSB8fFxuICAgICAgICAgICBzdGFja0xpbmUuaW5kZXhPZihcIihub2RlLmpzOlwiKSAhPT0gLTE7XG59XG5cbmZ1bmN0aW9uIGdldEZpbGVOYW1lQW5kTGluZU51bWJlcihzdGFja0xpbmUpIHtcbiAgICAvLyBOYW1lZCBmdW5jdGlvbnM6IFwiYXQgZnVuY3Rpb25OYW1lIChmaWxlbmFtZTpsaW5lTnVtYmVyOmNvbHVtbk51bWJlcilcIlxuICAgIC8vIEluIElFMTAgZnVuY3Rpb24gbmFtZSBjYW4gaGF2ZSBzcGFjZXMgKFwiQW5vbnltb3VzIGZ1bmN0aW9uXCIpIE9fb1xuICAgIHZhciBhdHRlbXB0MSA9IC9hdCAuKyBcXCgoLispOihcXGQrKTooPzpcXGQrKVxcKSQvLmV4ZWMoc3RhY2tMaW5lKTtcbiAgICBpZiAoYXR0ZW1wdDEpIHtcbiAgICAgICAgcmV0dXJuIFthdHRlbXB0MVsxXSwgTnVtYmVyKGF0dGVtcHQxWzJdKV07XG4gICAgfVxuXG4gICAgLy8gQW5vbnltb3VzIGZ1bmN0aW9uczogXCJhdCBmaWxlbmFtZTpsaW5lTnVtYmVyOmNvbHVtbk51bWJlclwiXG4gICAgdmFyIGF0dGVtcHQyID0gL2F0IChbXiBdKyk6KFxcZCspOig/OlxcZCspJC8uZXhlYyhzdGFja0xpbmUpO1xuICAgIGlmIChhdHRlbXB0Mikge1xuICAgICAgICByZXR1cm4gW2F0dGVtcHQyWzFdLCBOdW1iZXIoYXR0ZW1wdDJbMl0pXTtcbiAgICB9XG5cbiAgICAvLyBGaXJlZm94IHN0eWxlOiBcImZ1bmN0aW9uQGZpbGVuYW1lOmxpbmVOdW1iZXIgb3IgQGZpbGVuYW1lOmxpbmVOdW1iZXJcIlxuICAgIHZhciBhdHRlbXB0MyA9IC8uKkAoLispOihcXGQrKSQvLmV4ZWMoc3RhY2tMaW5lKTtcbiAgICBpZiAoYXR0ZW1wdDMpIHtcbiAgICAgICAgcmV0dXJuIFthdHRlbXB0M1sxXSwgTnVtYmVyKGF0dGVtcHQzWzJdKV07XG4gICAgfVxufVxuXG5mdW5jdGlvbiBpc0ludGVybmFsRnJhbWUoc3RhY2tMaW5lKSB7XG4gICAgdmFyIGZpbGVOYW1lQW5kTGluZU51bWJlciA9IGdldEZpbGVOYW1lQW5kTGluZU51bWJlcihzdGFja0xpbmUpO1xuXG4gICAgaWYgKCFmaWxlTmFtZUFuZExpbmVOdW1iZXIpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHZhciBmaWxlTmFtZSA9IGZpbGVOYW1lQW5kTGluZU51bWJlclswXTtcbiAgICB2YXIgbGluZU51bWJlciA9IGZpbGVOYW1lQW5kTGluZU51bWJlclsxXTtcblxuICAgIHJldHVybiBmaWxlTmFtZSA9PT0gcUZpbGVOYW1lICYmXG4gICAgICAgIGxpbmVOdW1iZXIgPj0gcVN0YXJ0aW5nTGluZSAmJlxuICAgICAgICBsaW5lTnVtYmVyIDw9IHFFbmRpbmdMaW5lO1xufVxuXG4vLyBkaXNjb3ZlciBvd24gZmlsZSBuYW1lIGFuZCBsaW5lIG51bWJlciByYW5nZSBmb3IgZmlsdGVyaW5nIHN0YWNrXG4vLyB0cmFjZXNcbmZ1bmN0aW9uIGNhcHR1cmVMaW5lKCkge1xuICAgIGlmICghaGFzU3RhY2tzKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHZhciBsaW5lcyA9IGUuc3RhY2suc3BsaXQoXCJcXG5cIik7XG4gICAgICAgIHZhciBmaXJzdExpbmUgPSBsaW5lc1swXS5pbmRleE9mKFwiQFwiKSA+IDAgPyBsaW5lc1sxXSA6IGxpbmVzWzJdO1xuICAgICAgICB2YXIgZmlsZU5hbWVBbmRMaW5lTnVtYmVyID0gZ2V0RmlsZU5hbWVBbmRMaW5lTnVtYmVyKGZpcnN0TGluZSk7XG4gICAgICAgIGlmICghZmlsZU5hbWVBbmRMaW5lTnVtYmVyKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBxRmlsZU5hbWUgPSBmaWxlTmFtZUFuZExpbmVOdW1iZXJbMF07XG4gICAgICAgIHJldHVybiBmaWxlTmFtZUFuZExpbmVOdW1iZXJbMV07XG4gICAgfVxufVxuXG5mdW5jdGlvbiBkZXByZWNhdGUoY2FsbGJhY2ssIG5hbWUsIGFsdGVybmF0aXZlKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjb25zb2xlICE9PSBcInVuZGVmaW5lZFwiICYmXG4gICAgICAgICAgICB0eXBlb2YgY29uc29sZS53YXJuID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihuYW1lICsgXCIgaXMgZGVwcmVjYXRlZCwgdXNlIFwiICsgYWx0ZXJuYXRpdmUgK1xuICAgICAgICAgICAgICAgICAgICAgICAgIFwiIGluc3RlYWQuXCIsIG5ldyBFcnJvcihcIlwiKS5zdGFjayk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KGNhbGxiYWNrLCBhcmd1bWVudHMpO1xuICAgIH07XG59XG5cbi8vIGVuZCBvZiBzaGltc1xuLy8gYmVnaW5uaW5nIG9mIHJlYWwgd29ya1xuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBwcm9taXNlIGZvciBhbiBpbW1lZGlhdGUgcmVmZXJlbmNlLCBwYXNzZXMgcHJvbWlzZXMgdGhyb3VnaCwgb3JcbiAqIGNvZXJjZXMgcHJvbWlzZXMgZnJvbSBkaWZmZXJlbnQgc3lzdGVtcy5cbiAqIEBwYXJhbSB2YWx1ZSBpbW1lZGlhdGUgcmVmZXJlbmNlIG9yIHByb21pc2VcbiAqL1xuZnVuY3Rpb24gUSh2YWx1ZSkge1xuICAgIC8vIElmIHRoZSBvYmplY3QgaXMgYWxyZWFkeSBhIFByb21pc2UsIHJldHVybiBpdCBkaXJlY3RseS4gIFRoaXMgZW5hYmxlc1xuICAgIC8vIHRoZSByZXNvbHZlIGZ1bmN0aW9uIHRvIGJvdGggYmUgdXNlZCB0byBjcmVhdGVkIHJlZmVyZW5jZXMgZnJvbSBvYmplY3RzLFxuICAgIC8vIGJ1dCB0byB0b2xlcmFibHkgY29lcmNlIG5vbi1wcm9taXNlcyB0byBwcm9taXNlcy5cbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG5cbiAgICAvLyBhc3NpbWlsYXRlIHRoZW5hYmxlc1xuICAgIGlmIChpc1Byb21pc2VBbGlrZSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIGNvZXJjZSh2YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZ1bGZpbGwodmFsdWUpO1xuICAgIH1cbn1cblEucmVzb2x2ZSA9IFE7XG5cbi8qKlxuICogUGVyZm9ybXMgYSB0YXNrIGluIGEgZnV0dXJlIHR1cm4gb2YgdGhlIGV2ZW50IGxvb3AuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSB0YXNrXG4gKi9cblEubmV4dFRpY2sgPSBuZXh0VGljaztcblxuLyoqXG4gKiBDb250cm9scyB3aGV0aGVyIG9yIG5vdCBsb25nIHN0YWNrIHRyYWNlcyB3aWxsIGJlIG9uXG4gKi9cblEubG9uZ1N0YWNrU3VwcG9ydCA9IGZhbHNlO1xuXG4vLyBlbmFibGUgbG9uZyBzdGFja3MgaWYgUV9ERUJVRyBpcyBzZXRcbmlmICh0eXBlb2YgcHJvY2VzcyA9PT0gXCJvYmplY3RcIiAmJiBwcm9jZXNzICYmIHByb2Nlc3MuZW52ICYmIHByb2Nlc3MuZW52LlFfREVCVUcpIHtcbiAgICBRLmxvbmdTdGFja1N1cHBvcnQgPSB0cnVlO1xufVxuXG4vKipcbiAqIENvbnN0cnVjdHMgYSB7cHJvbWlzZSwgcmVzb2x2ZSwgcmVqZWN0fSBvYmplY3QuXG4gKlxuICogYHJlc29sdmVgIGlzIGEgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggYSBtb3JlIHJlc29sdmVkIHZhbHVlIGZvciB0aGVcbiAqIHByb21pc2UuIFRvIGZ1bGZpbGwgdGhlIHByb21pc2UsIGludm9rZSBgcmVzb2x2ZWAgd2l0aCBhbnkgdmFsdWUgdGhhdCBpc1xuICogbm90IGEgdGhlbmFibGUuIFRvIHJlamVjdCB0aGUgcHJvbWlzZSwgaW52b2tlIGByZXNvbHZlYCB3aXRoIGEgcmVqZWN0ZWRcbiAqIHRoZW5hYmxlLCBvciBpbnZva2UgYHJlamVjdGAgd2l0aCB0aGUgcmVhc29uIGRpcmVjdGx5LiBUbyByZXNvbHZlIHRoZVxuICogcHJvbWlzZSB0byBhbm90aGVyIHRoZW5hYmxlLCB0aHVzIHB1dHRpbmcgaXQgaW4gdGhlIHNhbWUgc3RhdGUsIGludm9rZVxuICogYHJlc29sdmVgIHdpdGggdGhhdCBvdGhlciB0aGVuYWJsZS5cbiAqL1xuUS5kZWZlciA9IGRlZmVyO1xuZnVuY3Rpb24gZGVmZXIoKSB7XG4gICAgLy8gaWYgXCJtZXNzYWdlc1wiIGlzIGFuIFwiQXJyYXlcIiwgdGhhdCBpbmRpY2F0ZXMgdGhhdCB0aGUgcHJvbWlzZSBoYXMgbm90IHlldFxuICAgIC8vIGJlZW4gcmVzb2x2ZWQuICBJZiBpdCBpcyBcInVuZGVmaW5lZFwiLCBpdCBoYXMgYmVlbiByZXNvbHZlZC4gIEVhY2hcbiAgICAvLyBlbGVtZW50IG9mIHRoZSBtZXNzYWdlcyBhcnJheSBpcyBpdHNlbGYgYW4gYXJyYXkgb2YgY29tcGxldGUgYXJndW1lbnRzIHRvXG4gICAgLy8gZm9yd2FyZCB0byB0aGUgcmVzb2x2ZWQgcHJvbWlzZS4gIFdlIGNvZXJjZSB0aGUgcmVzb2x1dGlvbiB2YWx1ZSB0byBhXG4gICAgLy8gcHJvbWlzZSB1c2luZyB0aGUgYHJlc29sdmVgIGZ1bmN0aW9uIGJlY2F1c2UgaXQgaGFuZGxlcyBib3RoIGZ1bGx5XG4gICAgLy8gbm9uLXRoZW5hYmxlIHZhbHVlcyBhbmQgb3RoZXIgdGhlbmFibGVzIGdyYWNlZnVsbHkuXG4gICAgdmFyIG1lc3NhZ2VzID0gW10sIHByb2dyZXNzTGlzdGVuZXJzID0gW10sIHJlc29sdmVkUHJvbWlzZTtcblxuICAgIHZhciBkZWZlcnJlZCA9IG9iamVjdF9jcmVhdGUoZGVmZXIucHJvdG90eXBlKTtcbiAgICB2YXIgcHJvbWlzZSA9IG9iamVjdF9jcmVhdGUoUHJvbWlzZS5wcm90b3R5cGUpO1xuXG4gICAgcHJvbWlzZS5wcm9taXNlRGlzcGF0Y2ggPSBmdW5jdGlvbiAocmVzb2x2ZSwgb3AsIG9wZXJhbmRzKSB7XG4gICAgICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICAgICAgaWYgKG1lc3NhZ2VzKSB7XG4gICAgICAgICAgICBtZXNzYWdlcy5wdXNoKGFyZ3MpO1xuICAgICAgICAgICAgaWYgKG9wID09PSBcIndoZW5cIiAmJiBvcGVyYW5kc1sxXSkgeyAvLyBwcm9ncmVzcyBvcGVyYW5kXG4gICAgICAgICAgICAgICAgcHJvZ3Jlc3NMaXN0ZW5lcnMucHVzaChvcGVyYW5kc1sxXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBRLm5leHRUaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlZFByb21pc2UucHJvbWlzZURpc3BhdGNoLmFwcGx5KHJlc29sdmVkUHJvbWlzZSwgYXJncyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICAvLyBYWFggZGVwcmVjYXRlZFxuICAgIHByb21pc2UudmFsdWVPZiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKG1lc3NhZ2VzKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbmVhcmVyVmFsdWUgPSBuZWFyZXIocmVzb2x2ZWRQcm9taXNlKTtcbiAgICAgICAgaWYgKGlzUHJvbWlzZShuZWFyZXJWYWx1ZSkpIHtcbiAgICAgICAgICAgIHJlc29sdmVkUHJvbWlzZSA9IG5lYXJlclZhbHVlOyAvLyBzaG9ydGVuIGNoYWluXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5lYXJlclZhbHVlO1xuICAgIH07XG5cbiAgICBwcm9taXNlLmluc3BlY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghcmVzb2x2ZWRQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm4geyBzdGF0ZTogXCJwZW5kaW5nXCIgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzb2x2ZWRQcm9taXNlLmluc3BlY3QoKTtcbiAgICB9O1xuXG4gICAgaWYgKFEubG9uZ1N0YWNrU3VwcG9ydCAmJiBoYXNTdGFja3MpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvLyBOT1RFOiBkb24ndCB0cnkgdG8gdXNlIGBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZWAgb3IgdHJhbnNmZXIgdGhlXG4gICAgICAgICAgICAvLyBhY2Nlc3NvciBhcm91bmQ7IHRoYXQgY2F1c2VzIG1lbW9yeSBsZWFrcyBhcyBwZXIgR0gtMTExLiBKdXN0XG4gICAgICAgICAgICAvLyByZWlmeSB0aGUgc3RhY2sgdHJhY2UgYXMgYSBzdHJpbmcgQVNBUC5cbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyBBdCB0aGUgc2FtZSB0aW1lLCBjdXQgb2ZmIHRoZSBmaXJzdCBsaW5lOyBpdCdzIGFsd2F5cyBqdXN0XG4gICAgICAgICAgICAvLyBcIltvYmplY3QgUHJvbWlzZV1cXG5cIiwgYXMgcGVyIHRoZSBgdG9TdHJpbmdgLlxuICAgICAgICAgICAgcHJvbWlzZS5zdGFjayA9IGUuc3RhY2suc3Vic3RyaW5nKGUuc3RhY2suaW5kZXhPZihcIlxcblwiKSArIDEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gTk9URTogd2UgZG8gdGhlIGNoZWNrcyBmb3IgYHJlc29sdmVkUHJvbWlzZWAgaW4gZWFjaCBtZXRob2QsIGluc3RlYWQgb2ZcbiAgICAvLyBjb25zb2xpZGF0aW5nIHRoZW0gaW50byBgYmVjb21lYCwgc2luY2Ugb3RoZXJ3aXNlIHdlJ2QgY3JlYXRlIG5ld1xuICAgIC8vIHByb21pc2VzIHdpdGggdGhlIGxpbmVzIGBiZWNvbWUod2hhdGV2ZXIodmFsdWUpKWAuIFNlZSBlLmcuIEdILTI1Mi5cblxuICAgIGZ1bmN0aW9uIGJlY29tZShuZXdQcm9taXNlKSB7XG4gICAgICAgIHJlc29sdmVkUHJvbWlzZSA9IG5ld1Byb21pc2U7XG4gICAgICAgIHByb21pc2Uuc291cmNlID0gbmV3UHJvbWlzZTtcblxuICAgICAgICBhcnJheV9yZWR1Y2UobWVzc2FnZXMsIGZ1bmN0aW9uICh1bmRlZmluZWQsIG1lc3NhZ2UpIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIG5ld1Byb21pc2UucHJvbWlzZURpc3BhdGNoLmFwcGx5KG5ld1Byb21pc2UsIG1lc3NhZ2UpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0sIHZvaWQgMCk7XG5cbiAgICAgICAgbWVzc2FnZXMgPSB2b2lkIDA7XG4gICAgICAgIHByb2dyZXNzTGlzdGVuZXJzID0gdm9pZCAwO1xuICAgIH1cblxuICAgIGRlZmVycmVkLnByb21pc2UgPSBwcm9taXNlO1xuICAgIGRlZmVycmVkLnJlc29sdmUgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgaWYgKHJlc29sdmVkUHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgYmVjb21lKFEodmFsdWUpKTtcbiAgICB9O1xuXG4gICAgZGVmZXJyZWQuZnVsZmlsbCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICBpZiAocmVzb2x2ZWRQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBiZWNvbWUoZnVsZmlsbCh2YWx1ZSkpO1xuICAgIH07XG4gICAgZGVmZXJyZWQucmVqZWN0ID0gZnVuY3Rpb24gKHJlYXNvbikge1xuICAgICAgICBpZiAocmVzb2x2ZWRQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBiZWNvbWUocmVqZWN0KHJlYXNvbikpO1xuICAgIH07XG4gICAgZGVmZXJyZWQubm90aWZ5ID0gZnVuY3Rpb24gKHByb2dyZXNzKSB7XG4gICAgICAgIGlmIChyZXNvbHZlZFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGFycmF5X3JlZHVjZShwcm9ncmVzc0xpc3RlbmVycywgZnVuY3Rpb24gKHVuZGVmaW5lZCwgcHJvZ3Jlc3NMaXN0ZW5lcikge1xuICAgICAgICAgICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcHJvZ3Jlc3NMaXN0ZW5lcihwcm9ncmVzcyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSwgdm9pZCAwKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIGRlZmVycmVkO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBOb2RlLXN0eWxlIGNhbGxiYWNrIHRoYXQgd2lsbCByZXNvbHZlIG9yIHJlamVjdCB0aGUgZGVmZXJyZWRcbiAqIHByb21pc2UuXG4gKiBAcmV0dXJucyBhIG5vZGViYWNrXG4gKi9cbmRlZmVyLnByb3RvdHlwZS5tYWtlTm9kZVJlc29sdmVyID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICByZXR1cm4gZnVuY3Rpb24gKGVycm9yLCB2YWx1ZSkge1xuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgIHNlbGYucmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMikge1xuICAgICAgICAgICAgc2VsZi5yZXNvbHZlKGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2VsZi5yZXNvbHZlKHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuXG4vKipcbiAqIEBwYXJhbSByZXNvbHZlciB7RnVuY3Rpb259IGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIG5vdGhpbmcgYW5kIGFjY2VwdHNcbiAqIHRoZSByZXNvbHZlLCByZWplY3QsIGFuZCBub3RpZnkgZnVuY3Rpb25zIGZvciBhIGRlZmVycmVkLlxuICogQHJldHVybnMgYSBwcm9taXNlIHRoYXQgbWF5IGJlIHJlc29sdmVkIHdpdGggdGhlIGdpdmVuIHJlc29sdmUgYW5kIHJlamVjdFxuICogZnVuY3Rpb25zLCBvciByZWplY3RlZCBieSBhIHRocm93biBleGNlcHRpb24gaW4gcmVzb2x2ZXJcbiAqL1xuUS5Qcm9taXNlID0gcHJvbWlzZTsgLy8gRVM2XG5RLnByb21pc2UgPSBwcm9taXNlO1xuZnVuY3Rpb24gcHJvbWlzZShyZXNvbHZlcikge1xuICAgIGlmICh0eXBlb2YgcmVzb2x2ZXIgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwicmVzb2x2ZXIgbXVzdCBiZSBhIGZ1bmN0aW9uLlwiKTtcbiAgICB9XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICB0cnkge1xuICAgICAgICByZXNvbHZlcihkZWZlcnJlZC5yZXNvbHZlLCBkZWZlcnJlZC5yZWplY3QsIGRlZmVycmVkLm5vdGlmeSk7XG4gICAgfSBjYXRjaCAocmVhc29uKSB7XG4gICAgICAgIGRlZmVycmVkLnJlamVjdChyZWFzb24pO1xuICAgIH1cbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn1cblxucHJvbWlzZS5yYWNlID0gcmFjZTsgLy8gRVM2XG5wcm9taXNlLmFsbCA9IGFsbDsgLy8gRVM2XG5wcm9taXNlLnJlamVjdCA9IHJlamVjdDsgLy8gRVM2XG5wcm9taXNlLnJlc29sdmUgPSBROyAvLyBFUzZcblxuLy8gWFhYIGV4cGVyaW1lbnRhbC4gIFRoaXMgbWV0aG9kIGlzIGEgd2F5IHRvIGRlbm90ZSB0aGF0IGEgbG9jYWwgdmFsdWUgaXNcbi8vIHNlcmlhbGl6YWJsZSBhbmQgc2hvdWxkIGJlIGltbWVkaWF0ZWx5IGRpc3BhdGNoZWQgdG8gYSByZW1vdGUgdXBvbiByZXF1ZXN0LFxuLy8gaW5zdGVhZCBvZiBwYXNzaW5nIGEgcmVmZXJlbmNlLlxuUS5wYXNzQnlDb3B5ID0gZnVuY3Rpb24gKG9iamVjdCkge1xuICAgIC8vZnJlZXplKG9iamVjdCk7XG4gICAgLy9wYXNzQnlDb3BpZXMuc2V0KG9iamVjdCwgdHJ1ZSk7XG4gICAgcmV0dXJuIG9iamVjdDtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnBhc3NCeUNvcHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgLy9mcmVlemUob2JqZWN0KTtcbiAgICAvL3Bhc3NCeUNvcGllcy5zZXQob2JqZWN0LCB0cnVlKTtcbiAgICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogSWYgdHdvIHByb21pc2VzIGV2ZW50dWFsbHkgZnVsZmlsbCB0byB0aGUgc2FtZSB2YWx1ZSwgcHJvbWlzZXMgdGhhdCB2YWx1ZSxcbiAqIGJ1dCBvdGhlcndpc2UgcmVqZWN0cy5cbiAqIEBwYXJhbSB4IHtBbnkqfVxuICogQHBhcmFtIHkge0FueSp9XG4gKiBAcmV0dXJucyB7QW55Kn0gYSBwcm9taXNlIGZvciB4IGFuZCB5IGlmIHRoZXkgYXJlIHRoZSBzYW1lLCBidXQgYSByZWplY3Rpb25cbiAqIG90aGVyd2lzZS5cbiAqXG4gKi9cblEuam9pbiA9IGZ1bmN0aW9uICh4LCB5KSB7XG4gICAgcmV0dXJuIFEoeCkuam9pbih5KTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmpvaW4gPSBmdW5jdGlvbiAodGhhdCkge1xuICAgIHJldHVybiBRKFt0aGlzLCB0aGF0XSkuc3ByZWFkKGZ1bmN0aW9uICh4LCB5KSB7XG4gICAgICAgIGlmICh4ID09PSB5KSB7XG4gICAgICAgICAgICAvLyBUT0RPOiBcIj09PVwiIHNob3VsZCBiZSBPYmplY3QuaXMgb3IgZXF1aXZcbiAgICAgICAgICAgIHJldHVybiB4O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2FuJ3Qgam9pbjogbm90IHRoZSBzYW1lOiBcIiArIHggKyBcIiBcIiArIHkpO1xuICAgICAgICB9XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgZmlyc3Qgb2YgYW4gYXJyYXkgb2YgcHJvbWlzZXMgdG8gYmVjb21lIHNldHRsZWQuXG4gKiBAcGFyYW0gYW5zd2VycyB7QXJyYXlbQW55Kl19IHByb21pc2VzIHRvIHJhY2VcbiAqIEByZXR1cm5zIHtBbnkqfSB0aGUgZmlyc3QgcHJvbWlzZSB0byBiZSBzZXR0bGVkXG4gKi9cblEucmFjZSA9IHJhY2U7XG5mdW5jdGlvbiByYWNlKGFuc3dlclBzKSB7XG4gICAgcmV0dXJuIHByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICAvLyBTd2l0Y2ggdG8gdGhpcyBvbmNlIHdlIGNhbiBhc3N1bWUgYXQgbGVhc3QgRVM1XG4gICAgICAgIC8vIGFuc3dlclBzLmZvckVhY2goZnVuY3Rpb24gKGFuc3dlclApIHtcbiAgICAgICAgLy8gICAgIFEoYW5zd2VyUCkudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAvLyB9KTtcbiAgICAgICAgLy8gVXNlIHRoaXMgaW4gdGhlIG1lYW50aW1lXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBhbnN3ZXJQcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgUShhbnN3ZXJQc1tpXSkudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICB9XG4gICAgfSk7XG59XG5cblByb21pc2UucHJvdG90eXBlLnJhY2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbihRLnJhY2UpO1xufTtcblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgUHJvbWlzZSB3aXRoIGEgcHJvbWlzZSBkZXNjcmlwdG9yIG9iamVjdCBhbmQgb3B0aW9uYWwgZmFsbGJhY2tcbiAqIGZ1bmN0aW9uLiAgVGhlIGRlc2NyaXB0b3IgY29udGFpbnMgbWV0aG9kcyBsaWtlIHdoZW4ocmVqZWN0ZWQpLCBnZXQobmFtZSksXG4gKiBzZXQobmFtZSwgdmFsdWUpLCBwb3N0KG5hbWUsIGFyZ3MpLCBhbmQgZGVsZXRlKG5hbWUpLCB3aGljaCBhbGxcbiAqIHJldHVybiBlaXRoZXIgYSB2YWx1ZSwgYSBwcm9taXNlIGZvciBhIHZhbHVlLCBvciBhIHJlamVjdGlvbi4gIFRoZSBmYWxsYmFja1xuICogYWNjZXB0cyB0aGUgb3BlcmF0aW9uIG5hbWUsIGEgcmVzb2x2ZXIsIGFuZCBhbnkgZnVydGhlciBhcmd1bWVudHMgdGhhdCB3b3VsZFxuICogaGF2ZSBiZWVuIGZvcndhcmRlZCB0byB0aGUgYXBwcm9wcmlhdGUgbWV0aG9kIGFib3ZlIGhhZCBhIG1ldGhvZCBiZWVuXG4gKiBwcm92aWRlZCB3aXRoIHRoZSBwcm9wZXIgbmFtZS4gIFRoZSBBUEkgbWFrZXMgbm8gZ3VhcmFudGVlcyBhYm91dCB0aGUgbmF0dXJlXG4gKiBvZiB0aGUgcmV0dXJuZWQgb2JqZWN0LCBhcGFydCBmcm9tIHRoYXQgaXQgaXMgdXNhYmxlIHdoZXJlZXZlciBwcm9taXNlcyBhcmVcbiAqIGJvdWdodCBhbmQgc29sZC5cbiAqL1xuUS5tYWtlUHJvbWlzZSA9IFByb21pc2U7XG5mdW5jdGlvbiBQcm9taXNlKGRlc2NyaXB0b3IsIGZhbGxiYWNrLCBpbnNwZWN0KSB7XG4gICAgaWYgKGZhbGxiYWNrID09PSB2b2lkIDApIHtcbiAgICAgICAgZmFsbGJhY2sgPSBmdW5jdGlvbiAob3ApIHtcbiAgICAgICAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKFxuICAgICAgICAgICAgICAgIFwiUHJvbWlzZSBkb2VzIG5vdCBzdXBwb3J0IG9wZXJhdGlvbjogXCIgKyBvcFxuICAgICAgICAgICAgKSk7XG4gICAgICAgIH07XG4gICAgfVxuICAgIGlmIChpbnNwZWN0ID09PSB2b2lkIDApIHtcbiAgICAgICAgaW5zcGVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB7c3RhdGU6IFwidW5rbm93blwifTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICB2YXIgcHJvbWlzZSA9IG9iamVjdF9jcmVhdGUoUHJvbWlzZS5wcm90b3R5cGUpO1xuXG4gICAgcHJvbWlzZS5wcm9taXNlRGlzcGF0Y2ggPSBmdW5jdGlvbiAocmVzb2x2ZSwgb3AsIGFyZ3MpIHtcbiAgICAgICAgdmFyIHJlc3VsdDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmIChkZXNjcmlwdG9yW29wXSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGRlc2NyaXB0b3Jbb3BdLmFwcGx5KHByb21pc2UsIGFyZ3MpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBmYWxsYmFjay5jYWxsKHByb21pc2UsIG9wLCBhcmdzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICByZXN1bHQgPSByZWplY3QoZXhjZXB0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVzb2x2ZSkge1xuICAgICAgICAgICAgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHByb21pc2UuaW5zcGVjdCA9IGluc3BlY3Q7XG5cbiAgICAvLyBYWFggZGVwcmVjYXRlZCBgdmFsdWVPZmAgYW5kIGBleGNlcHRpb25gIHN1cHBvcnRcbiAgICBpZiAoaW5zcGVjdCkge1xuICAgICAgICB2YXIgaW5zcGVjdGVkID0gaW5zcGVjdCgpO1xuICAgICAgICBpZiAoaW5zcGVjdGVkLnN0YXRlID09PSBcInJlamVjdGVkXCIpIHtcbiAgICAgICAgICAgIHByb21pc2UuZXhjZXB0aW9uID0gaW5zcGVjdGVkLnJlYXNvbjtcbiAgICAgICAgfVxuXG4gICAgICAgIHByb21pc2UudmFsdWVPZiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBpbnNwZWN0ZWQgPSBpbnNwZWN0KCk7XG4gICAgICAgICAgICBpZiAoaW5zcGVjdGVkLnN0YXRlID09PSBcInBlbmRpbmdcIiB8fFxuICAgICAgICAgICAgICAgIGluc3BlY3RlZC5zdGF0ZSA9PT0gXCJyZWplY3RlZFwiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gaW5zcGVjdGVkLnZhbHVlO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiBwcm9taXNlO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gXCJbb2JqZWN0IFByb21pc2VdXCI7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS50aGVuID0gZnVuY3Rpb24gKGZ1bGZpbGxlZCwgcmVqZWN0ZWQsIHByb2dyZXNzZWQpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICB2YXIgZG9uZSA9IGZhbHNlOyAgIC8vIGVuc3VyZSB0aGUgdW50cnVzdGVkIHByb21pc2UgbWFrZXMgYXQgbW9zdCBhXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBzaW5nbGUgY2FsbCB0byBvbmUgb2YgdGhlIGNhbGxiYWNrc1xuXG4gICAgZnVuY3Rpb24gX2Z1bGZpbGxlZCh2YWx1ZSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiBmdWxmaWxsZWQgPT09IFwiZnVuY3Rpb25cIiA/IGZ1bGZpbGxlZCh2YWx1ZSkgOiB2YWx1ZTtcbiAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVqZWN0KGV4Y2VwdGlvbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfcmVqZWN0ZWQoZXhjZXB0aW9uKSB7XG4gICAgICAgIGlmICh0eXBlb2YgcmVqZWN0ZWQgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgbWFrZVN0YWNrVHJhY2VMb25nKGV4Y2VwdGlvbiwgc2VsZik7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3RlZChleGNlcHRpb24pO1xuICAgICAgICAgICAgfSBjYXRjaCAobmV3RXhjZXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChuZXdFeGNlcHRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZWplY3QoZXhjZXB0aW9uKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBfcHJvZ3Jlc3NlZCh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdHlwZW9mIHByb2dyZXNzZWQgPT09IFwiZnVuY3Rpb25cIiA/IHByb2dyZXNzZWQodmFsdWUpIDogdmFsdWU7XG4gICAgfVxuXG4gICAgUS5uZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNlbGYucHJvbWlzZURpc3BhdGNoKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkb25lID0gdHJ1ZTtcblxuICAgICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZShfZnVsZmlsbGVkKHZhbHVlKSk7XG4gICAgICAgIH0sIFwid2hlblwiLCBbZnVuY3Rpb24gKGV4Y2VwdGlvbikge1xuICAgICAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkb25lID0gdHJ1ZTtcblxuICAgICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZShfcmVqZWN0ZWQoZXhjZXB0aW9uKSk7XG4gICAgICAgIH1dKTtcbiAgICB9KTtcblxuICAgIC8vIFByb2dyZXNzIHByb3BhZ2F0b3IgbmVlZCB0byBiZSBhdHRhY2hlZCBpbiB0aGUgY3VycmVudCB0aWNrLlxuICAgIHNlbGYucHJvbWlzZURpc3BhdGNoKHZvaWQgMCwgXCJ3aGVuXCIsIFt2b2lkIDAsIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgbmV3VmFsdWU7XG4gICAgICAgIHZhciB0aHJldyA9IGZhbHNlO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbmV3VmFsdWUgPSBfcHJvZ3Jlc3NlZCh2YWx1ZSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHRocmV3ID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmIChRLm9uZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBRLm9uZXJyb3IoZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRocmV3KSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5ub3RpZnkobmV3VmFsdWUpO1xuICAgICAgICB9XG4gICAgfV0pO1xuXG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG5RLnRhcCA9IGZ1bmN0aW9uIChwcm9taXNlLCBjYWxsYmFjaykge1xuICAgIHJldHVybiBRKHByb21pc2UpLnRhcChjYWxsYmFjayk7XG59O1xuXG4vKipcbiAqIFdvcmtzIGFsbW9zdCBsaWtlIFwiZmluYWxseVwiLCBidXQgbm90IGNhbGxlZCBmb3IgcmVqZWN0aW9ucy5cbiAqIE9yaWdpbmFsIHJlc29sdXRpb24gdmFsdWUgaXMgcGFzc2VkIHRocm91Z2ggY2FsbGJhY2sgdW5hZmZlY3RlZC5cbiAqIENhbGxiYWNrIG1heSByZXR1cm4gYSBwcm9taXNlIHRoYXQgd2lsbCBiZSBhd2FpdGVkIGZvci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gKiBAcmV0dXJucyB7US5Qcm9taXNlfVxuICogQGV4YW1wbGVcbiAqIGRvU29tZXRoaW5nKClcbiAqICAgLnRoZW4oLi4uKVxuICogICAudGFwKGNvbnNvbGUubG9nKVxuICogICAudGhlbiguLi4pO1xuICovXG5Qcm9taXNlLnByb3RvdHlwZS50YXAgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICBjYWxsYmFjayA9IFEoY2FsbGJhY2spO1xuXG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmZjYWxsKHZhbHVlKS50aGVuUmVzb2x2ZSh2YWx1ZSk7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhbiBvYnNlcnZlciBvbiBhIHByb21pc2UuXG4gKlxuICogR3VhcmFudGVlczpcbiAqXG4gKiAxLiB0aGF0IGZ1bGZpbGxlZCBhbmQgcmVqZWN0ZWQgd2lsbCBiZSBjYWxsZWQgb25seSBvbmNlLlxuICogMi4gdGhhdCBlaXRoZXIgdGhlIGZ1bGZpbGxlZCBjYWxsYmFjayBvciB0aGUgcmVqZWN0ZWQgY2FsbGJhY2sgd2lsbCBiZVxuICogICAgY2FsbGVkLCBidXQgbm90IGJvdGguXG4gKiAzLiB0aGF0IGZ1bGZpbGxlZCBhbmQgcmVqZWN0ZWQgd2lsbCBub3QgYmUgY2FsbGVkIGluIHRoaXMgdHVybi5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgICAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgdG8gb2JzZXJ2ZVxuICogQHBhcmFtIGZ1bGZpbGxlZCAgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdpdGggdGhlIGZ1bGZpbGxlZCB2YWx1ZVxuICogQHBhcmFtIHJlamVjdGVkICAgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdpdGggdGhlIHJlamVjdGlvbiBleGNlcHRpb25cbiAqIEBwYXJhbSBwcm9ncmVzc2VkIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCBvbiBhbnkgcHJvZ3Jlc3Mgbm90aWZpY2F0aW9uc1xuICogQHJldHVybiBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlIGZyb20gdGhlIGludm9rZWQgY2FsbGJhY2tcbiAqL1xuUS53aGVuID0gd2hlbjtcbmZ1bmN0aW9uIHdoZW4odmFsdWUsIGZ1bGZpbGxlZCwgcmVqZWN0ZWQsIHByb2dyZXNzZWQpIHtcbiAgICByZXR1cm4gUSh2YWx1ZSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzc2VkKTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUudGhlblJlc29sdmUgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHZhbHVlOyB9KTtcbn07XG5cblEudGhlblJlc29sdmUgPSBmdW5jdGlvbiAocHJvbWlzZSwgdmFsdWUpIHtcbiAgICByZXR1cm4gUShwcm9taXNlKS50aGVuUmVzb2x2ZSh2YWx1ZSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS50aGVuUmVqZWN0ID0gZnVuY3Rpb24gKHJlYXNvbikge1xuICAgIHJldHVybiB0aGlzLnRoZW4oZnVuY3Rpb24gKCkgeyB0aHJvdyByZWFzb247IH0pO1xufTtcblxuUS50aGVuUmVqZWN0ID0gZnVuY3Rpb24gKHByb21pc2UsIHJlYXNvbikge1xuICAgIHJldHVybiBRKHByb21pc2UpLnRoZW5SZWplY3QocmVhc29uKTtcbn07XG5cbi8qKlxuICogSWYgYW4gb2JqZWN0IGlzIG5vdCBhIHByb21pc2UsIGl0IGlzIGFzIFwibmVhclwiIGFzIHBvc3NpYmxlLlxuICogSWYgYSBwcm9taXNlIGlzIHJlamVjdGVkLCBpdCBpcyBhcyBcIm5lYXJcIiBhcyBwb3NzaWJsZSB0b28uXG4gKiBJZiBpdOKAmXMgYSBmdWxmaWxsZWQgcHJvbWlzZSwgdGhlIGZ1bGZpbGxtZW50IHZhbHVlIGlzIG5lYXJlci5cbiAqIElmIGl04oCZcyBhIGRlZmVycmVkIHByb21pc2UgYW5kIHRoZSBkZWZlcnJlZCBoYXMgYmVlbiByZXNvbHZlZCwgdGhlXG4gKiByZXNvbHV0aW9uIGlzIFwibmVhcmVyXCIuXG4gKiBAcGFyYW0gb2JqZWN0XG4gKiBAcmV0dXJucyBtb3N0IHJlc29sdmVkIChuZWFyZXN0KSBmb3JtIG9mIHRoZSBvYmplY3RcbiAqL1xuXG4vLyBYWFggc2hvdWxkIHdlIHJlLWRvIHRoaXM/XG5RLm5lYXJlciA9IG5lYXJlcjtcbmZ1bmN0aW9uIG5lYXJlcih2YWx1ZSkge1xuICAgIGlmIChpc1Byb21pc2UodmFsdWUpKSB7XG4gICAgICAgIHZhciBpbnNwZWN0ZWQgPSB2YWx1ZS5pbnNwZWN0KCk7XG4gICAgICAgIGlmIChpbnNwZWN0ZWQuc3RhdGUgPT09IFwiZnVsZmlsbGVkXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBpbnNwZWN0ZWQudmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xufVxuXG4vKipcbiAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIG9iamVjdCBpcyBhIHByb21pc2UuXG4gKiBPdGhlcndpc2UgaXQgaXMgYSBmdWxmaWxsZWQgdmFsdWUuXG4gKi9cblEuaXNQcm9taXNlID0gaXNQcm9taXNlO1xuZnVuY3Rpb24gaXNQcm9taXNlKG9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3QgaW5zdGFuY2VvZiBQcm9taXNlO1xufVxuXG5RLmlzUHJvbWlzZUFsaWtlID0gaXNQcm9taXNlQWxpa2U7XG5mdW5jdGlvbiBpc1Byb21pc2VBbGlrZShvYmplY3QpIHtcbiAgICByZXR1cm4gaXNPYmplY3Qob2JqZWN0KSAmJiB0eXBlb2Ygb2JqZWN0LnRoZW4gPT09IFwiZnVuY3Rpb25cIjtcbn1cblxuLyoqXG4gKiBAcmV0dXJucyB3aGV0aGVyIHRoZSBnaXZlbiBvYmplY3QgaXMgYSBwZW5kaW5nIHByb21pc2UsIG1lYW5pbmcgbm90XG4gKiBmdWxmaWxsZWQgb3IgcmVqZWN0ZWQuXG4gKi9cblEuaXNQZW5kaW5nID0gaXNQZW5kaW5nO1xuZnVuY3Rpb24gaXNQZW5kaW5nKG9iamVjdCkge1xuICAgIHJldHVybiBpc1Byb21pc2Uob2JqZWN0KSAmJiBvYmplY3QuaW5zcGVjdCgpLnN0YXRlID09PSBcInBlbmRpbmdcIjtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuaXNQZW5kaW5nID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmluc3BlY3QoKS5zdGF0ZSA9PT0gXCJwZW5kaW5nXCI7XG59O1xuXG4vKipcbiAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIG9iamVjdCBpcyBhIHZhbHVlIG9yIGZ1bGZpbGxlZFxuICogcHJvbWlzZS5cbiAqL1xuUS5pc0Z1bGZpbGxlZCA9IGlzRnVsZmlsbGVkO1xuZnVuY3Rpb24gaXNGdWxmaWxsZWQob2JqZWN0KSB7XG4gICAgcmV0dXJuICFpc1Byb21pc2Uob2JqZWN0KSB8fCBvYmplY3QuaW5zcGVjdCgpLnN0YXRlID09PSBcImZ1bGZpbGxlZFwiO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5pc0Z1bGZpbGxlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5pbnNwZWN0KCkuc3RhdGUgPT09IFwiZnVsZmlsbGVkXCI7XG59O1xuXG4vKipcbiAqIEByZXR1cm5zIHdoZXRoZXIgdGhlIGdpdmVuIG9iamVjdCBpcyBhIHJlamVjdGVkIHByb21pc2UuXG4gKi9cblEuaXNSZWplY3RlZCA9IGlzUmVqZWN0ZWQ7XG5mdW5jdGlvbiBpc1JlamVjdGVkKG9iamVjdCkge1xuICAgIHJldHVybiBpc1Byb21pc2Uob2JqZWN0KSAmJiBvYmplY3QuaW5zcGVjdCgpLnN0YXRlID09PSBcInJlamVjdGVkXCI7XG59XG5cblByb21pc2UucHJvdG90eXBlLmlzUmVqZWN0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuaW5zcGVjdCgpLnN0YXRlID09PSBcInJlamVjdGVkXCI7XG59O1xuXG4vLy8vIEJFR0lOIFVOSEFORExFRCBSRUpFQ1RJT04gVFJBQ0tJTkdcblxuLy8gVGhpcyBwcm9taXNlIGxpYnJhcnkgY29uc3VtZXMgZXhjZXB0aW9ucyB0aHJvd24gaW4gaGFuZGxlcnMgc28gdGhleSBjYW4gYmVcbi8vIGhhbmRsZWQgYnkgYSBzdWJzZXF1ZW50IHByb21pc2UuICBUaGUgZXhjZXB0aW9ucyBnZXQgYWRkZWQgdG8gdGhpcyBhcnJheSB3aGVuXG4vLyB0aGV5IGFyZSBjcmVhdGVkLCBhbmQgcmVtb3ZlZCB3aGVuIHRoZXkgYXJlIGhhbmRsZWQuICBOb3RlIHRoYXQgaW4gRVM2IG9yXG4vLyBzaGltbWVkIGVudmlyb25tZW50cywgdGhpcyB3b3VsZCBuYXR1cmFsbHkgYmUgYSBgU2V0YC5cbnZhciB1bmhhbmRsZWRSZWFzb25zID0gW107XG52YXIgdW5oYW5kbGVkUmVqZWN0aW9ucyA9IFtdO1xudmFyIHJlcG9ydGVkVW5oYW5kbGVkUmVqZWN0aW9ucyA9IFtdO1xudmFyIHRyYWNrVW5oYW5kbGVkUmVqZWN0aW9ucyA9IHRydWU7XG5cbmZ1bmN0aW9uIHJlc2V0VW5oYW5kbGVkUmVqZWN0aW9ucygpIHtcbiAgICB1bmhhbmRsZWRSZWFzb25zLmxlbmd0aCA9IDA7XG4gICAgdW5oYW5kbGVkUmVqZWN0aW9ucy5sZW5ndGggPSAwO1xuXG4gICAgaWYgKCF0cmFja1VuaGFuZGxlZFJlamVjdGlvbnMpIHtcbiAgICAgICAgdHJhY2tVbmhhbmRsZWRSZWplY3Rpb25zID0gdHJ1ZTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHRyYWNrUmVqZWN0aW9uKHByb21pc2UsIHJlYXNvbikge1xuICAgIGlmICghdHJhY2tVbmhhbmRsZWRSZWplY3Rpb25zKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBwcm9jZXNzLmVtaXQgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICBRLm5leHRUaWNrLnJ1bkFmdGVyKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChhcnJheV9pbmRleE9mKHVuaGFuZGxlZFJlamVjdGlvbnMsIHByb21pc2UpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIHByb2Nlc3MuZW1pdChcInVuaGFuZGxlZFJlamVjdGlvblwiLCByZWFzb24sIHByb21pc2UpO1xuICAgICAgICAgICAgICAgIHJlcG9ydGVkVW5oYW5kbGVkUmVqZWN0aW9ucy5wdXNoKHByb21pc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICB1bmhhbmRsZWRSZWplY3Rpb25zLnB1c2gocHJvbWlzZSk7XG4gICAgaWYgKHJlYXNvbiAmJiB0eXBlb2YgcmVhc29uLnN0YWNrICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgIHVuaGFuZGxlZFJlYXNvbnMucHVzaChyZWFzb24uc3RhY2spO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHVuaGFuZGxlZFJlYXNvbnMucHVzaChcIihubyBzdGFjaykgXCIgKyByZWFzb24pO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gdW50cmFja1JlamVjdGlvbihwcm9taXNlKSB7XG4gICAgaWYgKCF0cmFja1VuaGFuZGxlZFJlamVjdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBhdCA9IGFycmF5X2luZGV4T2YodW5oYW5kbGVkUmVqZWN0aW9ucywgcHJvbWlzZSk7XG4gICAgaWYgKGF0ICE9PSAtMSkge1xuICAgICAgICBpZiAodHlwZW9mIHByb2Nlc3MgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHByb2Nlc3MuZW1pdCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICBRLm5leHRUaWNrLnJ1bkFmdGVyKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgYXRSZXBvcnQgPSBhcnJheV9pbmRleE9mKHJlcG9ydGVkVW5oYW5kbGVkUmVqZWN0aW9ucywgcHJvbWlzZSk7XG4gICAgICAgICAgICAgICAgaWYgKGF0UmVwb3J0ICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICBwcm9jZXNzLmVtaXQoXCJyZWplY3Rpb25IYW5kbGVkXCIsIHVuaGFuZGxlZFJlYXNvbnNbYXRdLCBwcm9taXNlKTtcbiAgICAgICAgICAgICAgICAgICAgcmVwb3J0ZWRVbmhhbmRsZWRSZWplY3Rpb25zLnNwbGljZShhdFJlcG9ydCwgMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdW5oYW5kbGVkUmVqZWN0aW9ucy5zcGxpY2UoYXQsIDEpO1xuICAgICAgICB1bmhhbmRsZWRSZWFzb25zLnNwbGljZShhdCwgMSk7XG4gICAgfVxufVxuXG5RLnJlc2V0VW5oYW5kbGVkUmVqZWN0aW9ucyA9IHJlc2V0VW5oYW5kbGVkUmVqZWN0aW9ucztcblxuUS5nZXRVbmhhbmRsZWRSZWFzb25zID0gZnVuY3Rpb24gKCkge1xuICAgIC8vIE1ha2UgYSBjb3B5IHNvIHRoYXQgY29uc3VtZXJzIGNhbid0IGludGVyZmVyZSB3aXRoIG91ciBpbnRlcm5hbCBzdGF0ZS5cbiAgICByZXR1cm4gdW5oYW5kbGVkUmVhc29ucy5zbGljZSgpO1xufTtcblxuUS5zdG9wVW5oYW5kbGVkUmVqZWN0aW9uVHJhY2tpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmVzZXRVbmhhbmRsZWRSZWplY3Rpb25zKCk7XG4gICAgdHJhY2tVbmhhbmRsZWRSZWplY3Rpb25zID0gZmFsc2U7XG59O1xuXG5yZXNldFVuaGFuZGxlZFJlamVjdGlvbnMoKTtcblxuLy8vLyBFTkQgVU5IQU5ETEVEIFJFSkVDVElPTiBUUkFDS0lOR1xuXG4vKipcbiAqIENvbnN0cnVjdHMgYSByZWplY3RlZCBwcm9taXNlLlxuICogQHBhcmFtIHJlYXNvbiB2YWx1ZSBkZXNjcmliaW5nIHRoZSBmYWlsdXJlXG4gKi9cblEucmVqZWN0ID0gcmVqZWN0O1xuZnVuY3Rpb24gcmVqZWN0KHJlYXNvbikge1xuICAgIHZhciByZWplY3Rpb24gPSBQcm9taXNlKHtcbiAgICAgICAgXCJ3aGVuXCI6IGZ1bmN0aW9uIChyZWplY3RlZCkge1xuICAgICAgICAgICAgLy8gbm90ZSB0aGF0IHRoZSBlcnJvciBoYXMgYmVlbiBoYW5kbGVkXG4gICAgICAgICAgICBpZiAocmVqZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICB1bnRyYWNrUmVqZWN0aW9uKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJlamVjdGVkID8gcmVqZWN0ZWQocmVhc29uKSA6IHRoaXM7XG4gICAgICAgIH1cbiAgICB9LCBmdW5jdGlvbiBmYWxsYmFjaygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSwgZnVuY3Rpb24gaW5zcGVjdCgpIHtcbiAgICAgICAgcmV0dXJuIHsgc3RhdGU6IFwicmVqZWN0ZWRcIiwgcmVhc29uOiByZWFzb24gfTtcbiAgICB9KTtcblxuICAgIC8vIE5vdGUgdGhhdCB0aGUgcmVhc29uIGhhcyBub3QgYmVlbiBoYW5kbGVkLlxuICAgIHRyYWNrUmVqZWN0aW9uKHJlamVjdGlvbiwgcmVhc29uKTtcblxuICAgIHJldHVybiByZWplY3Rpb247XG59XG5cbi8qKlxuICogQ29uc3RydWN0cyBhIGZ1bGZpbGxlZCBwcm9taXNlIGZvciBhbiBpbW1lZGlhdGUgcmVmZXJlbmNlLlxuICogQHBhcmFtIHZhbHVlIGltbWVkaWF0ZSByZWZlcmVuY2VcbiAqL1xuUS5mdWxmaWxsID0gZnVsZmlsbDtcbmZ1bmN0aW9uIGZ1bGZpbGwodmFsdWUpIHtcbiAgICByZXR1cm4gUHJvbWlzZSh7XG4gICAgICAgIFwid2hlblwiOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH0sXG4gICAgICAgIFwiZ2V0XCI6IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWVbbmFtZV07XG4gICAgICAgIH0sXG4gICAgICAgIFwic2V0XCI6IGZ1bmN0aW9uIChuYW1lLCByaHMpIHtcbiAgICAgICAgICAgIHZhbHVlW25hbWVdID0gcmhzO1xuICAgICAgICB9LFxuICAgICAgICBcImRlbGV0ZVwiOiBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICAgICAgZGVsZXRlIHZhbHVlW25hbWVdO1xuICAgICAgICB9LFxuICAgICAgICBcInBvc3RcIjogZnVuY3Rpb24gKG5hbWUsIGFyZ3MpIHtcbiAgICAgICAgICAgIC8vIE1hcmsgTWlsbGVyIHByb3Bvc2VzIHRoYXQgcG9zdCB3aXRoIG5vIG5hbWUgc2hvdWxkIGFwcGx5IGFcbiAgICAgICAgICAgIC8vIHByb21pc2VkIGZ1bmN0aW9uLlxuICAgICAgICAgICAgaWYgKG5hbWUgPT09IG51bGwgfHwgbmFtZSA9PT0gdm9pZCAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlLmFwcGx5KHZvaWQgMCwgYXJncyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZVtuYW1lXS5hcHBseSh2YWx1ZSwgYXJncyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIFwiYXBwbHlcIjogZnVuY3Rpb24gKHRoaXNwLCBhcmdzKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWUuYXBwbHkodGhpc3AsIGFyZ3MpO1xuICAgICAgICB9LFxuICAgICAgICBcImtleXNcIjogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIG9iamVjdF9rZXlzKHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH0sIHZvaWQgMCwgZnVuY3Rpb24gaW5zcGVjdCgpIHtcbiAgICAgICAgcmV0dXJuIHsgc3RhdGU6IFwiZnVsZmlsbGVkXCIsIHZhbHVlOiB2YWx1ZSB9O1xuICAgIH0pO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIHRoZW5hYmxlcyB0byBRIHByb21pc2VzLlxuICogQHBhcmFtIHByb21pc2UgdGhlbmFibGUgcHJvbWlzZVxuICogQHJldHVybnMgYSBRIHByb21pc2VcbiAqL1xuZnVuY3Rpb24gY29lcmNlKHByb21pc2UpIHtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcHJvbWlzZS50aGVuKGRlZmVycmVkLnJlc29sdmUsIGRlZmVycmVkLnJlamVjdCwgZGVmZXJyZWQubm90aWZ5KTtcbiAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5yZWplY3QoZXhjZXB0aW9uKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xufVxuXG4vKipcbiAqIEFubm90YXRlcyBhbiBvYmplY3Qgc3VjaCB0aGF0IGl0IHdpbGwgbmV2ZXIgYmVcbiAqIHRyYW5zZmVycmVkIGF3YXkgZnJvbSB0aGlzIHByb2Nlc3Mgb3ZlciBhbnkgcHJvbWlzZVxuICogY29tbXVuaWNhdGlvbiBjaGFubmVsLlxuICogQHBhcmFtIG9iamVjdFxuICogQHJldHVybnMgcHJvbWlzZSBhIHdyYXBwaW5nIG9mIHRoYXQgb2JqZWN0IHRoYXRcbiAqIGFkZGl0aW9uYWxseSByZXNwb25kcyB0byB0aGUgXCJpc0RlZlwiIG1lc3NhZ2VcbiAqIHdpdGhvdXQgYSByZWplY3Rpb24uXG4gKi9cblEubWFzdGVyID0gbWFzdGVyO1xuZnVuY3Rpb24gbWFzdGVyKG9iamVjdCkge1xuICAgIHJldHVybiBQcm9taXNlKHtcbiAgICAgICAgXCJpc0RlZlwiOiBmdW5jdGlvbiAoKSB7fVxuICAgIH0sIGZ1bmN0aW9uIGZhbGxiYWNrKG9wLCBhcmdzKSB7XG4gICAgICAgIHJldHVybiBkaXNwYXRjaChvYmplY3QsIG9wLCBhcmdzKTtcbiAgICB9LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBRKG9iamVjdCkuaW5zcGVjdCgpO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIFNwcmVhZHMgdGhlIHZhbHVlcyBvZiBhIHByb21pc2VkIGFycmF5IG9mIGFyZ3VtZW50cyBpbnRvIHRoZVxuICogZnVsZmlsbG1lbnQgY2FsbGJhY2suXG4gKiBAcGFyYW0gZnVsZmlsbGVkIGNhbGxiYWNrIHRoYXQgcmVjZWl2ZXMgdmFyaWFkaWMgYXJndW1lbnRzIGZyb20gdGhlXG4gKiBwcm9taXNlZCBhcnJheVxuICogQHBhcmFtIHJlamVjdGVkIGNhbGxiYWNrIHRoYXQgcmVjZWl2ZXMgdGhlIGV4Y2VwdGlvbiBpZiB0aGUgcHJvbWlzZVxuICogaXMgcmVqZWN0ZWQuXG4gKiBAcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWUgb3IgdGhyb3duIGV4Y2VwdGlvbiBvZlxuICogZWl0aGVyIGNhbGxiYWNrLlxuICovXG5RLnNwcmVhZCA9IHNwcmVhZDtcbmZ1bmN0aW9uIHNwcmVhZCh2YWx1ZSwgZnVsZmlsbGVkLCByZWplY3RlZCkge1xuICAgIHJldHVybiBRKHZhbHVlKS5zcHJlYWQoZnVsZmlsbGVkLCByZWplY3RlZCk7XG59XG5cblByb21pc2UucHJvdG90eXBlLnNwcmVhZCA9IGZ1bmN0aW9uIChmdWxmaWxsZWQsIHJlamVjdGVkKSB7XG4gICAgcmV0dXJuIHRoaXMuYWxsKCkudGhlbihmdW5jdGlvbiAoYXJyYXkpIHtcbiAgICAgICAgcmV0dXJuIGZ1bGZpbGxlZC5hcHBseSh2b2lkIDAsIGFycmF5KTtcbiAgICB9LCByZWplY3RlZCk7XG59O1xuXG4vKipcbiAqIFRoZSBhc3luYyBmdW5jdGlvbiBpcyBhIGRlY29yYXRvciBmb3IgZ2VuZXJhdG9yIGZ1bmN0aW9ucywgdHVybmluZ1xuICogdGhlbSBpbnRvIGFzeW5jaHJvbm91cyBnZW5lcmF0b3JzLiAgQWx0aG91Z2ggZ2VuZXJhdG9ycyBhcmUgb25seSBwYXJ0XG4gKiBvZiB0aGUgbmV3ZXN0IEVDTUFTY3JpcHQgNiBkcmFmdHMsIHRoaXMgY29kZSBkb2VzIG5vdCBjYXVzZSBzeW50YXhcbiAqIGVycm9ycyBpbiBvbGRlciBlbmdpbmVzLiAgVGhpcyBjb2RlIHNob3VsZCBjb250aW51ZSB0byB3b3JrIGFuZCB3aWxsXG4gKiBpbiBmYWN0IGltcHJvdmUgb3ZlciB0aW1lIGFzIHRoZSBsYW5ndWFnZSBpbXByb3Zlcy5cbiAqXG4gKiBFUzYgZ2VuZXJhdG9ycyBhcmUgY3VycmVudGx5IHBhcnQgb2YgVjggdmVyc2lvbiAzLjE5IHdpdGggdGhlXG4gKiAtLWhhcm1vbnktZ2VuZXJhdG9ycyBydW50aW1lIGZsYWcgZW5hYmxlZC4gIFNwaWRlck1vbmtleSBoYXMgaGFkIHRoZW1cbiAqIGZvciBsb25nZXIsIGJ1dCB1bmRlciBhbiBvbGRlciBQeXRob24taW5zcGlyZWQgZm9ybS4gIFRoaXMgZnVuY3Rpb25cbiAqIHdvcmtzIG9uIGJvdGgga2luZHMgb2YgZ2VuZXJhdG9ycy5cbiAqXG4gKiBEZWNvcmF0ZXMgYSBnZW5lcmF0b3IgZnVuY3Rpb24gc3VjaCB0aGF0OlxuICogIC0gaXQgbWF5IHlpZWxkIHByb21pc2VzXG4gKiAgLSBleGVjdXRpb24gd2lsbCBjb250aW51ZSB3aGVuIHRoYXQgcHJvbWlzZSBpcyBmdWxmaWxsZWRcbiAqICAtIHRoZSB2YWx1ZSBvZiB0aGUgeWllbGQgZXhwcmVzc2lvbiB3aWxsIGJlIHRoZSBmdWxmaWxsZWQgdmFsdWVcbiAqICAtIGl0IHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlICh3aGVuIHRoZSBnZW5lcmF0b3JcbiAqICAgIHN0b3BzIGl0ZXJhdGluZylcbiAqICAtIHRoZSBkZWNvcmF0ZWQgZnVuY3Rpb24gcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWVcbiAqICAgIG9mIHRoZSBnZW5lcmF0b3Igb3IgdGhlIGZpcnN0IHJlamVjdGVkIHByb21pc2UgYW1vbmcgdGhvc2VcbiAqICAgIHlpZWxkZWQuXG4gKiAgLSBpZiBhbiBlcnJvciBpcyB0aHJvd24gaW4gdGhlIGdlbmVyYXRvciwgaXQgcHJvcGFnYXRlcyB0aHJvdWdoXG4gKiAgICBldmVyeSBmb2xsb3dpbmcgeWllbGQgdW50aWwgaXQgaXMgY2F1Z2h0LCBvciB1bnRpbCBpdCBlc2NhcGVzXG4gKiAgICB0aGUgZ2VuZXJhdG9yIGZ1bmN0aW9uIGFsdG9nZXRoZXIsIGFuZCBpcyB0cmFuc2xhdGVkIGludG8gYVxuICogICAgcmVqZWN0aW9uIGZvciB0aGUgcHJvbWlzZSByZXR1cm5lZCBieSB0aGUgZGVjb3JhdGVkIGdlbmVyYXRvci5cbiAqL1xuUS5hc3luYyA9IGFzeW5jO1xuZnVuY3Rpb24gYXN5bmMobWFrZUdlbmVyYXRvcikge1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIHdoZW4gdmVyYiBpcyBcInNlbmRcIiwgYXJnIGlzIGEgdmFsdWVcbiAgICAgICAgLy8gd2hlbiB2ZXJiIGlzIFwidGhyb3dcIiwgYXJnIGlzIGFuIGV4Y2VwdGlvblxuICAgICAgICBmdW5jdGlvbiBjb250aW51ZXIodmVyYiwgYXJnKSB7XG4gICAgICAgICAgICB2YXIgcmVzdWx0O1xuXG4gICAgICAgICAgICAvLyBVbnRpbCBWOCAzLjE5IC8gQ2hyb21pdW0gMjkgaXMgcmVsZWFzZWQsIFNwaWRlck1vbmtleSBpcyB0aGUgb25seVxuICAgICAgICAgICAgLy8gZW5naW5lIHRoYXQgaGFzIGEgZGVwbG95ZWQgYmFzZSBvZiBicm93c2VycyB0aGF0IHN1cHBvcnQgZ2VuZXJhdG9ycy5cbiAgICAgICAgICAgIC8vIEhvd2V2ZXIsIFNNJ3MgZ2VuZXJhdG9ycyB1c2UgdGhlIFB5dGhvbi1pbnNwaXJlZCBzZW1hbnRpY3Mgb2ZcbiAgICAgICAgICAgIC8vIG91dGRhdGVkIEVTNiBkcmFmdHMuICBXZSB3b3VsZCBsaWtlIHRvIHN1cHBvcnQgRVM2LCBidXQgd2UnZCBhbHNvXG4gICAgICAgICAgICAvLyBsaWtlIHRvIG1ha2UgaXQgcG9zc2libGUgdG8gdXNlIGdlbmVyYXRvcnMgaW4gZGVwbG95ZWQgYnJvd3NlcnMsIHNvXG4gICAgICAgICAgICAvLyB3ZSBhbHNvIHN1cHBvcnQgUHl0aG9uLXN0eWxlIGdlbmVyYXRvcnMuICBBdCBzb21lIHBvaW50IHdlIGNhbiByZW1vdmVcbiAgICAgICAgICAgIC8vIHRoaXMgYmxvY2suXG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgU3RvcEl0ZXJhdGlvbiA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgICAgIC8vIEVTNiBHZW5lcmF0b3JzXG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gZ2VuZXJhdG9yW3ZlcmJdKGFyZyk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXhjZXB0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5kb25lKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBRKHJlc3VsdC52YWx1ZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHdoZW4ocmVzdWx0LnZhbHVlLCBjYWxsYmFjaywgZXJyYmFjayk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBTcGlkZXJNb25rZXkgR2VuZXJhdG9yc1xuICAgICAgICAgICAgICAgIC8vIEZJWE1FOiBSZW1vdmUgdGhpcyBjYXNlIHdoZW4gU00gZG9lcyBFUzYgZ2VuZXJhdG9ycy5cbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBnZW5lcmF0b3JbdmVyYl0oYXJnKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzU3RvcEl0ZXJhdGlvbihleGNlcHRpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gUShleGNlcHRpb24udmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChleGNlcHRpb24pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB3aGVuKHJlc3VsdCwgY2FsbGJhY2ssIGVycmJhY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHZhciBnZW5lcmF0b3IgPSBtYWtlR2VuZXJhdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIHZhciBjYWxsYmFjayA9IGNvbnRpbnVlci5iaW5kKGNvbnRpbnVlciwgXCJuZXh0XCIpO1xuICAgICAgICB2YXIgZXJyYmFjayA9IGNvbnRpbnVlci5iaW5kKGNvbnRpbnVlciwgXCJ0aHJvd1wiKTtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gICAgfTtcbn1cblxuLyoqXG4gKiBUaGUgc3Bhd24gZnVuY3Rpb24gaXMgYSBzbWFsbCB3cmFwcGVyIGFyb3VuZCBhc3luYyB0aGF0IGltbWVkaWF0ZWx5XG4gKiBjYWxscyB0aGUgZ2VuZXJhdG9yIGFuZCBhbHNvIGVuZHMgdGhlIHByb21pc2UgY2hhaW4sIHNvIHRoYXQgYW55XG4gKiB1bmhhbmRsZWQgZXJyb3JzIGFyZSB0aHJvd24gaW5zdGVhZCBvZiBmb3J3YXJkZWQgdG8gdGhlIGVycm9yXG4gKiBoYW5kbGVyLiBUaGlzIGlzIHVzZWZ1bCBiZWNhdXNlIGl0J3MgZXh0cmVtZWx5IGNvbW1vbiB0byBydW5cbiAqIGdlbmVyYXRvcnMgYXQgdGhlIHRvcC1sZXZlbCB0byB3b3JrIHdpdGggbGlicmFyaWVzLlxuICovXG5RLnNwYXduID0gc3Bhd247XG5mdW5jdGlvbiBzcGF3bihtYWtlR2VuZXJhdG9yKSB7XG4gICAgUS5kb25lKFEuYXN5bmMobWFrZUdlbmVyYXRvcikoKSk7XG59XG5cbi8vIEZJWE1FOiBSZW1vdmUgdGhpcyBpbnRlcmZhY2Ugb25jZSBFUzYgZ2VuZXJhdG9ycyBhcmUgaW4gU3BpZGVyTW9ua2V5LlxuLyoqXG4gKiBUaHJvd3MgYSBSZXR1cm5WYWx1ZSBleGNlcHRpb24gdG8gc3RvcCBhbiBhc3luY2hyb25vdXMgZ2VuZXJhdG9yLlxuICpcbiAqIFRoaXMgaW50ZXJmYWNlIGlzIGEgc3RvcC1nYXAgbWVhc3VyZSB0byBzdXBwb3J0IGdlbmVyYXRvciByZXR1cm5cbiAqIHZhbHVlcyBpbiBvbGRlciBGaXJlZm94L1NwaWRlck1vbmtleS4gIEluIGJyb3dzZXJzIHRoYXQgc3VwcG9ydCBFUzZcbiAqIGdlbmVyYXRvcnMgbGlrZSBDaHJvbWl1bSAyOSwganVzdCB1c2UgXCJyZXR1cm5cIiBpbiB5b3VyIGdlbmVyYXRvclxuICogZnVuY3Rpb25zLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSB0aGUgcmV0dXJuIHZhbHVlIGZvciB0aGUgc3Vycm91bmRpbmcgZ2VuZXJhdG9yXG4gKiBAdGhyb3dzIFJldHVyblZhbHVlIGV4Y2VwdGlvbiB3aXRoIHRoZSB2YWx1ZS5cbiAqIEBleGFtcGxlXG4gKiAvLyBFUzYgc3R5bGVcbiAqIFEuYXN5bmMoZnVuY3Rpb24qICgpIHtcbiAqICAgICAgdmFyIGZvbyA9IHlpZWxkIGdldEZvb1Byb21pc2UoKTtcbiAqICAgICAgdmFyIGJhciA9IHlpZWxkIGdldEJhclByb21pc2UoKTtcbiAqICAgICAgcmV0dXJuIGZvbyArIGJhcjtcbiAqIH0pXG4gKiAvLyBPbGRlciBTcGlkZXJNb25rZXkgc3R5bGVcbiAqIFEuYXN5bmMoZnVuY3Rpb24gKCkge1xuICogICAgICB2YXIgZm9vID0geWllbGQgZ2V0Rm9vUHJvbWlzZSgpO1xuICogICAgICB2YXIgYmFyID0geWllbGQgZ2V0QmFyUHJvbWlzZSgpO1xuICogICAgICBRLnJldHVybihmb28gKyBiYXIpO1xuICogfSlcbiAqL1xuUVtcInJldHVyblwiXSA9IF9yZXR1cm47XG5mdW5jdGlvbiBfcmV0dXJuKHZhbHVlKSB7XG4gICAgdGhyb3cgbmV3IFFSZXR1cm5WYWx1ZSh2YWx1ZSk7XG59XG5cbi8qKlxuICogVGhlIHByb21pc2VkIGZ1bmN0aW9uIGRlY29yYXRvciBlbnN1cmVzIHRoYXQgYW55IHByb21pc2UgYXJndW1lbnRzXG4gKiBhcmUgc2V0dGxlZCBhbmQgcGFzc2VkIGFzIHZhbHVlcyAoYHRoaXNgIGlzIGFsc28gc2V0dGxlZCBhbmQgcGFzc2VkXG4gKiBhcyBhIHZhbHVlKS4gIEl0IHdpbGwgYWxzbyBlbnN1cmUgdGhhdCB0aGUgcmVzdWx0IG9mIGEgZnVuY3Rpb24gaXNcbiAqIGFsd2F5cyBhIHByb21pc2UuXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBhZGQgPSBRLnByb21pc2VkKGZ1bmN0aW9uIChhLCBiKSB7XG4gKiAgICAgcmV0dXJuIGEgKyBiO1xuICogfSk7XG4gKiBhZGQoUShhKSwgUShCKSk7XG4gKlxuICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIHRvIGRlY29yYXRlXG4gKiBAcmV0dXJucyB7ZnVuY3Rpb259IGEgZnVuY3Rpb24gdGhhdCBoYXMgYmVlbiBkZWNvcmF0ZWQuXG4gKi9cblEucHJvbWlzZWQgPSBwcm9taXNlZDtcbmZ1bmN0aW9uIHByb21pc2VkKGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHNwcmVhZChbdGhpcywgYWxsKGFyZ3VtZW50cyldLCBmdW5jdGlvbiAoc2VsZiwgYXJncykge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KHNlbGYsIGFyZ3MpO1xuICAgICAgICB9KTtcbiAgICB9O1xufVxuXG4vKipcbiAqIHNlbmRzIGEgbWVzc2FnZSB0byBhIHZhbHVlIGluIGEgZnV0dXJlIHR1cm5cbiAqIEBwYXJhbSBvYmplY3QqIHRoZSByZWNpcGllbnRcbiAqIEBwYXJhbSBvcCB0aGUgbmFtZSBvZiB0aGUgbWVzc2FnZSBvcGVyYXRpb24sIGUuZy4sIFwid2hlblwiLFxuICogQHBhcmFtIGFyZ3MgZnVydGhlciBhcmd1bWVudHMgdG8gYmUgZm9yd2FyZGVkIHRvIHRoZSBvcGVyYXRpb25cbiAqIEByZXR1cm5zIHJlc3VsdCB7UHJvbWlzZX0gYSBwcm9taXNlIGZvciB0aGUgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb25cbiAqL1xuUS5kaXNwYXRjaCA9IGRpc3BhdGNoO1xuZnVuY3Rpb24gZGlzcGF0Y2gob2JqZWN0LCBvcCwgYXJncykge1xuICAgIHJldHVybiBRKG9iamVjdCkuZGlzcGF0Y2gob3AsIGFyZ3MpO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5kaXNwYXRjaCA9IGZ1bmN0aW9uIChvcCwgYXJncykge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICBzZWxmLnByb21pc2VEaXNwYXRjaChkZWZlcnJlZC5yZXNvbHZlLCBvcCwgYXJncyk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG4vKipcbiAqIEdldHMgdGhlIHZhbHVlIG9mIGEgcHJvcGVydHkgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgb2JqZWN0XG4gKiBAcGFyYW0gbmFtZSAgICAgIG5hbWUgb2YgcHJvcGVydHkgdG8gZ2V0XG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSBwcm9wZXJ0eSB2YWx1ZVxuICovXG5RLmdldCA9IGZ1bmN0aW9uIChvYmplY3QsIGtleSkge1xuICAgIHJldHVybiBRKG9iamVjdCkuZGlzcGF0Y2goXCJnZXRcIiwgW2tleV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKGtleSkge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwiZ2V0XCIsIFtrZXldKTtcbn07XG5cbi8qKlxuICogU2V0cyB0aGUgdmFsdWUgb2YgYSBwcm9wZXJ0eSBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIG9iamVjdCBvYmplY3RcbiAqIEBwYXJhbSBuYW1lICAgICAgbmFtZSBvZiBwcm9wZXJ0eSB0byBzZXRcbiAqIEBwYXJhbSB2YWx1ZSAgICAgbmV3IHZhbHVlIG9mIHByb3BlcnR5XG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWVcbiAqL1xuUS5zZXQgPSBmdW5jdGlvbiAob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcInNldFwiLCBba2V5LCB2YWx1ZV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcInNldFwiLCBba2V5LCB2YWx1ZV0pO1xufTtcblxuLyoqXG4gKiBEZWxldGVzIGEgcHJvcGVydHkgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgb2JqZWN0XG4gKiBAcGFyYW0gbmFtZSAgICAgIG5hbWUgb2YgcHJvcGVydHkgdG8gZGVsZXRlXG4gKiBAcmV0dXJuIHByb21pc2UgZm9yIHRoZSByZXR1cm4gdmFsdWVcbiAqL1xuUS5kZWwgPSAvLyBYWFggbGVnYWN5XG5RW1wiZGVsZXRlXCJdID0gZnVuY3Rpb24gKG9iamVjdCwga2V5KSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcImRlbGV0ZVwiLCBba2V5XSk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5kZWwgPSAvLyBYWFggbGVnYWN5XG5Qcm9taXNlLnByb3RvdHlwZVtcImRlbGV0ZVwiXSA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcImRlbGV0ZVwiLCBba2V5XSk7XG59O1xuXG4vKipcbiAqIEludm9rZXMgYSBtZXRob2QgaW4gYSBmdXR1cmUgdHVybi5cbiAqIEBwYXJhbSBvYmplY3QgICAgcHJvbWlzZSBvciBpbW1lZGlhdGUgcmVmZXJlbmNlIGZvciB0YXJnZXQgb2JqZWN0XG4gKiBAcGFyYW0gbmFtZSAgICAgIG5hbWUgb2YgbWV0aG9kIHRvIGludm9rZVxuICogQHBhcmFtIHZhbHVlICAgICBhIHZhbHVlIHRvIHBvc3QsIHR5cGljYWxseSBhbiBhcnJheSBvZlxuICogICAgICAgICAgICAgICAgICBpbnZvY2F0aW9uIGFyZ3VtZW50cyBmb3IgcHJvbWlzZXMgdGhhdFxuICogICAgICAgICAgICAgICAgICBhcmUgdWx0aW1hdGVseSBiYWNrZWQgd2l0aCBgcmVzb2x2ZWAgdmFsdWVzLFxuICogICAgICAgICAgICAgICAgICBhcyBvcHBvc2VkIHRvIHRob3NlIGJhY2tlZCB3aXRoIFVSTHNcbiAqICAgICAgICAgICAgICAgICAgd2hlcmVpbiB0aGUgcG9zdGVkIHZhbHVlIGNhbiBiZSBhbnlcbiAqICAgICAgICAgICAgICAgICAgSlNPTiBzZXJpYWxpemFibGUgb2JqZWN0LlxuICogQHJldHVybiBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlXG4gKi9cbi8vIGJvdW5kIGxvY2FsbHkgYmVjYXVzZSBpdCBpcyB1c2VkIGJ5IG90aGVyIG1ldGhvZHNcblEubWFwcGx5ID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblEucG9zdCA9IGZ1bmN0aW9uIChvYmplY3QsIG5hbWUsIGFyZ3MpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJnc10pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubWFwcGx5ID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblByb21pc2UucHJvdG90eXBlLnBvc3QgPSBmdW5jdGlvbiAobmFtZSwgYXJncykge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJnc10pO1xufTtcblxuLyoqXG4gKiBJbnZva2VzIGEgbWV0aG9kIGluIGEgZnV0dXJlIHR1cm4uXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IG9iamVjdFxuICogQHBhcmFtIG5hbWUgICAgICBuYW1lIG9mIG1ldGhvZCB0byBpbnZva2VcbiAqIEBwYXJhbSAuLi5hcmdzICAgYXJyYXkgb2YgaW52b2NhdGlvbiBhcmd1bWVudHNcbiAqIEByZXR1cm4gcHJvbWlzZSBmb3IgdGhlIHJldHVybiB2YWx1ZVxuICovXG5RLnNlbmQgPSAvLyBYWFggTWFyayBNaWxsZXIncyBwcm9wb3NlZCBwYXJsYW5jZVxuUS5tY2FsbCA9IC8vIFhYWCBBcyBwcm9wb3NlZCBieSBcIlJlZHNhbmRyb1wiXG5RLmludm9rZSA9IGZ1bmN0aW9uIChvYmplY3QsIG5hbWUgLyouLi5hcmdzKi8pIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAyKV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuc2VuZCA9IC8vIFhYWCBNYXJrIE1pbGxlcidzIHByb3Bvc2VkIHBhcmxhbmNlXG5Qcm9taXNlLnByb3RvdHlwZS5tY2FsbCA9IC8vIFhYWCBBcyBwcm9wb3NlZCBieSBcIlJlZHNhbmRyb1wiXG5Qcm9taXNlLnByb3RvdHlwZS5pbnZva2UgPSBmdW5jdGlvbiAobmFtZSAvKi4uLmFyZ3MqLykge1xuICAgIHJldHVybiB0aGlzLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKV0pO1xufTtcblxuLyoqXG4gKiBBcHBsaWVzIHRoZSBwcm9taXNlZCBmdW5jdGlvbiBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIHRhcmdldCBmdW5jdGlvblxuICogQHBhcmFtIGFyZ3MgICAgICBhcnJheSBvZiBhcHBsaWNhdGlvbiBhcmd1bWVudHNcbiAqL1xuUS5mYXBwbHkgPSBmdW5jdGlvbiAob2JqZWN0LCBhcmdzKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcImFwcGx5XCIsIFt2b2lkIDAsIGFyZ3NdKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmZhcHBseSA9IGZ1bmN0aW9uIChhcmdzKSB7XG4gICAgcmV0dXJuIHRoaXMuZGlzcGF0Y2goXCJhcHBseVwiLCBbdm9pZCAwLCBhcmdzXSk7XG59O1xuXG4vKipcbiAqIENhbGxzIHRoZSBwcm9taXNlZCBmdW5jdGlvbiBpbiBhIGZ1dHVyZSB0dXJuLlxuICogQHBhcmFtIG9iamVjdCAgICBwcm9taXNlIG9yIGltbWVkaWF0ZSByZWZlcmVuY2UgZm9yIHRhcmdldCBmdW5jdGlvblxuICogQHBhcmFtIC4uLmFyZ3MgICBhcnJheSBvZiBhcHBsaWNhdGlvbiBhcmd1bWVudHNcbiAqL1xuUVtcInRyeVwiXSA9XG5RLmZjYWxsID0gZnVuY3Rpb24gKG9iamVjdCAvKiAuLi5hcmdzKi8pIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRpc3BhdGNoKFwiYXBwbHlcIiwgW3ZvaWQgMCwgYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKV0pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZmNhbGwgPSBmdW5jdGlvbiAoLyouLi5hcmdzKi8pIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcImFwcGx5XCIsIFt2b2lkIDAsIGFycmF5X3NsaWNlKGFyZ3VtZW50cyldKTtcbn07XG5cbi8qKlxuICogQmluZHMgdGhlIHByb21pc2VkIGZ1bmN0aW9uLCB0cmFuc2Zvcm1pbmcgcmV0dXJuIHZhbHVlcyBpbnRvIGEgZnVsZmlsbGVkXG4gKiBwcm9taXNlIGFuZCB0aHJvd24gZXJyb3JzIGludG8gYSByZWplY3RlZCBvbmUuXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IGZ1bmN0aW9uXG4gKiBAcGFyYW0gLi4uYXJncyAgIGFycmF5IG9mIGFwcGxpY2F0aW9uIGFyZ3VtZW50c1xuICovXG5RLmZiaW5kID0gZnVuY3Rpb24gKG9iamVjdCAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBwcm9taXNlID0gUShvYmplY3QpO1xuICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzLCAxKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gZmJvdW5kKCkge1xuICAgICAgICByZXR1cm4gcHJvbWlzZS5kaXNwYXRjaChcImFwcGx5XCIsIFtcbiAgICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgICBhcmdzLmNvbmNhdChhcnJheV9zbGljZShhcmd1bWVudHMpKVxuICAgICAgICBdKTtcbiAgICB9O1xufTtcblByb21pc2UucHJvdG90eXBlLmZiaW5kID0gZnVuY3Rpb24gKC8qLi4uYXJncyovKSB7XG4gICAgdmFyIHByb21pc2UgPSB0aGlzO1xuICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gZmJvdW5kKCkge1xuICAgICAgICByZXR1cm4gcHJvbWlzZS5kaXNwYXRjaChcImFwcGx5XCIsIFtcbiAgICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgICBhcmdzLmNvbmNhdChhcnJheV9zbGljZShhcmd1bWVudHMpKVxuICAgICAgICBdKTtcbiAgICB9O1xufTtcblxuLyoqXG4gKiBSZXF1ZXN0cyB0aGUgbmFtZXMgb2YgdGhlIG93bmVkIHByb3BlcnRpZXMgb2YgYSBwcm9taXNlZFxuICogb2JqZWN0IGluIGEgZnV0dXJlIHR1cm4uXG4gKiBAcGFyYW0gb2JqZWN0ICAgIHByb21pc2Ugb3IgaW1tZWRpYXRlIHJlZmVyZW5jZSBmb3IgdGFyZ2V0IG9iamVjdFxuICogQHJldHVybiBwcm9taXNlIGZvciB0aGUga2V5cyBvZiB0aGUgZXZlbnR1YWxseSBzZXR0bGVkIG9iamVjdFxuICovXG5RLmtleXMgPSBmdW5jdGlvbiAob2JqZWN0KSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kaXNwYXRjaChcImtleXNcIiwgW10pO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUua2V5cyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwYXRjaChcImtleXNcIiwgW10pO1xufTtcblxuLyoqXG4gKiBUdXJucyBhbiBhcnJheSBvZiBwcm9taXNlcyBpbnRvIGEgcHJvbWlzZSBmb3IgYW4gYXJyYXkuICBJZiBhbnkgb2ZcbiAqIHRoZSBwcm9taXNlcyBnZXRzIHJlamVjdGVkLCB0aGUgd2hvbGUgYXJyYXkgaXMgcmVqZWN0ZWQgaW1tZWRpYXRlbHkuXG4gKiBAcGFyYW0ge0FycmF5Kn0gYW4gYXJyYXkgKG9yIHByb21pc2UgZm9yIGFuIGFycmF5KSBvZiB2YWx1ZXMgKG9yXG4gKiBwcm9taXNlcyBmb3IgdmFsdWVzKVxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciBhbiBhcnJheSBvZiB0aGUgY29ycmVzcG9uZGluZyB2YWx1ZXNcbiAqL1xuLy8gQnkgTWFyayBNaWxsZXJcbi8vIGh0dHA6Ly93aWtpLmVjbWFzY3JpcHQub3JnL2Rva3UucGhwP2lkPXN0cmF3bWFuOmNvbmN1cnJlbmN5JnJldj0xMzA4Nzc2NTIxI2FsbGZ1bGZpbGxlZFxuUS5hbGwgPSBhbGw7XG5mdW5jdGlvbiBhbGwocHJvbWlzZXMpIHtcbiAgICByZXR1cm4gd2hlbihwcm9taXNlcywgZnVuY3Rpb24gKHByb21pc2VzKSB7XG4gICAgICAgIHZhciBwZW5kaW5nQ291bnQgPSAwO1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBhcnJheV9yZWR1Y2UocHJvbWlzZXMsIGZ1bmN0aW9uICh1bmRlZmluZWQsIHByb21pc2UsIGluZGV4KSB7XG4gICAgICAgICAgICB2YXIgc25hcHNob3Q7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgaXNQcm9taXNlKHByb21pc2UpICYmXG4gICAgICAgICAgICAgICAgKHNuYXBzaG90ID0gcHJvbWlzZS5pbnNwZWN0KCkpLnN0YXRlID09PSBcImZ1bGZpbGxlZFwiXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICBwcm9taXNlc1tpbmRleF0gPSBzbmFwc2hvdC52YWx1ZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgKytwZW5kaW5nQ291bnQ7XG4gICAgICAgICAgICAgICAgd2hlbihcbiAgICAgICAgICAgICAgICAgICAgcHJvbWlzZSxcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9taXNlc1tpbmRleF0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgtLXBlbmRpbmdDb3VudCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUocHJvbWlzZXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBkZWZlcnJlZC5yZWplY3QsXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIChwcm9ncmVzcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVmZXJyZWQubm90aWZ5KHsgaW5kZXg6IGluZGV4LCB2YWx1ZTogcHJvZ3Jlc3MgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCB2b2lkIDApO1xuICAgICAgICBpZiAocGVuZGluZ0NvdW50ID09PSAwKSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHByb21pc2VzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9KTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuYWxsID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBhbGwodGhpcyk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGZpcnN0IHJlc29sdmVkIHByb21pc2Ugb2YgYW4gYXJyYXkuIFByaW9yIHJlamVjdGVkIHByb21pc2VzIGFyZVxuICogaWdub3JlZC4gIFJlamVjdHMgb25seSBpZiBhbGwgcHJvbWlzZXMgYXJlIHJlamVjdGVkLlxuICogQHBhcmFtIHtBcnJheSp9IGFuIGFycmF5IGNvbnRhaW5pbmcgdmFsdWVzIG9yIHByb21pc2VzIGZvciB2YWx1ZXNcbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmdWxmaWxsZWQgd2l0aCB0aGUgdmFsdWUgb2YgdGhlIGZpcnN0IHJlc29sdmVkIHByb21pc2UsXG4gKiBvciBhIHJlamVjdGVkIHByb21pc2UgaWYgYWxsIHByb21pc2VzIGFyZSByZWplY3RlZC5cbiAqL1xuUS5hbnkgPSBhbnk7XG5cbmZ1bmN0aW9uIGFueShwcm9taXNlcykge1xuICAgIGlmIChwcm9taXNlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIFEucmVzb2x2ZSgpO1xuICAgIH1cblxuICAgIHZhciBkZWZlcnJlZCA9IFEuZGVmZXIoKTtcbiAgICB2YXIgcGVuZGluZ0NvdW50ID0gMDtcbiAgICBhcnJheV9yZWR1Y2UocHJvbWlzZXMsIGZ1bmN0aW9uIChwcmV2LCBjdXJyZW50LCBpbmRleCkge1xuICAgICAgICB2YXIgcHJvbWlzZSA9IHByb21pc2VzW2luZGV4XTtcblxuICAgICAgICBwZW5kaW5nQ291bnQrKztcblxuICAgICAgICB3aGVuKHByb21pc2UsIG9uRnVsZmlsbGVkLCBvblJlamVjdGVkLCBvblByb2dyZXNzKTtcbiAgICAgICAgZnVuY3Rpb24gb25GdWxmaWxsZWQocmVzdWx0KSB7XG4gICAgICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gb25SZWplY3RlZCgpIHtcbiAgICAgICAgICAgIHBlbmRpbmdDb3VudC0tO1xuICAgICAgICAgICAgaWYgKHBlbmRpbmdDb3VudCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIGRlZmVycmVkLnJlamVjdChuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIFwiQ2FuJ3QgZ2V0IGZ1bGZpbGxtZW50IHZhbHVlIGZyb20gYW55IHByb21pc2UsIGFsbCBcIiArXG4gICAgICAgICAgICAgICAgICAgIFwicHJvbWlzZXMgd2VyZSByZWplY3RlZC5cIlxuICAgICAgICAgICAgICAgICkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZ1bmN0aW9uIG9uUHJvZ3Jlc3MocHJvZ3Jlc3MpIHtcbiAgICAgICAgICAgIGRlZmVycmVkLm5vdGlmeSh7XG4gICAgICAgICAgICAgICAgaW5kZXg6IGluZGV4LFxuICAgICAgICAgICAgICAgIHZhbHVlOiBwcm9ncmVzc1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9LCB1bmRlZmluZWQpO1xuXG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59XG5cblByb21pc2UucHJvdG90eXBlLmFueSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gYW55KHRoaXMpO1xufTtcblxuLyoqXG4gKiBXYWl0cyBmb3IgYWxsIHByb21pc2VzIHRvIGJlIHNldHRsZWQsIGVpdGhlciBmdWxmaWxsZWQgb3JcbiAqIHJlamVjdGVkLiAgVGhpcyBpcyBkaXN0aW5jdCBmcm9tIGBhbGxgIHNpbmNlIHRoYXQgd291bGQgc3RvcFxuICogd2FpdGluZyBhdCB0aGUgZmlyc3QgcmVqZWN0aW9uLiAgVGhlIHByb21pc2UgcmV0dXJuZWQgYnlcbiAqIGBhbGxSZXNvbHZlZGAgd2lsbCBuZXZlciBiZSByZWplY3RlZC5cbiAqIEBwYXJhbSBwcm9taXNlcyBhIHByb21pc2UgZm9yIGFuIGFycmF5IChvciBhbiBhcnJheSkgb2YgcHJvbWlzZXNcbiAqIChvciB2YWx1ZXMpXG4gKiBAcmV0dXJuIGEgcHJvbWlzZSBmb3IgYW4gYXJyYXkgb2YgcHJvbWlzZXNcbiAqL1xuUS5hbGxSZXNvbHZlZCA9IGRlcHJlY2F0ZShhbGxSZXNvbHZlZCwgXCJhbGxSZXNvbHZlZFwiLCBcImFsbFNldHRsZWRcIik7XG5mdW5jdGlvbiBhbGxSZXNvbHZlZChwcm9taXNlcykge1xuICAgIHJldHVybiB3aGVuKHByb21pc2VzLCBmdW5jdGlvbiAocHJvbWlzZXMpIHtcbiAgICAgICAgcHJvbWlzZXMgPSBhcnJheV9tYXAocHJvbWlzZXMsIFEpO1xuICAgICAgICByZXR1cm4gd2hlbihhbGwoYXJyYXlfbWFwKHByb21pc2VzLCBmdW5jdGlvbiAocHJvbWlzZSkge1xuICAgICAgICAgICAgcmV0dXJuIHdoZW4ocHJvbWlzZSwgbm9vcCwgbm9vcCk7XG4gICAgICAgIH0pKSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHByb21pc2VzO1xuICAgICAgICB9KTtcbiAgICB9KTtcbn1cblxuUHJvbWlzZS5wcm90b3R5cGUuYWxsUmVzb2x2ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGFsbFJlc29sdmVkKHRoaXMpO1xufTtcblxuLyoqXG4gKiBAc2VlIFByb21pc2UjYWxsU2V0dGxlZFxuICovXG5RLmFsbFNldHRsZWQgPSBhbGxTZXR0bGVkO1xuZnVuY3Rpb24gYWxsU2V0dGxlZChwcm9taXNlcykge1xuICAgIHJldHVybiBRKHByb21pc2VzKS5hbGxTZXR0bGVkKCk7XG59XG5cbi8qKlxuICogVHVybnMgYW4gYXJyYXkgb2YgcHJvbWlzZXMgaW50byBhIHByb21pc2UgZm9yIGFuIGFycmF5IG9mIHRoZWlyIHN0YXRlcyAoYXNcbiAqIHJldHVybmVkIGJ5IGBpbnNwZWN0YCkgd2hlbiB0aGV5IGhhdmUgYWxsIHNldHRsZWQuXG4gKiBAcGFyYW0ge0FycmF5W0FueSpdfSB2YWx1ZXMgYW4gYXJyYXkgKG9yIHByb21pc2UgZm9yIGFuIGFycmF5KSBvZiB2YWx1ZXMgKG9yXG4gKiBwcm9taXNlcyBmb3IgdmFsdWVzKVxuICogQHJldHVybnMge0FycmF5W1N0YXRlXX0gYW4gYXJyYXkgb2Ygc3RhdGVzIGZvciB0aGUgcmVzcGVjdGl2ZSB2YWx1ZXMuXG4gKi9cblByb21pc2UucHJvdG90eXBlLmFsbFNldHRsZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAocHJvbWlzZXMpIHtcbiAgICAgICAgcmV0dXJuIGFsbChhcnJheV9tYXAocHJvbWlzZXMsIGZ1bmN0aW9uIChwcm9taXNlKSB7XG4gICAgICAgICAgICBwcm9taXNlID0gUShwcm9taXNlKTtcbiAgICAgICAgICAgIGZ1bmN0aW9uIHJlZ2FyZGxlc3MoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2UuaW5zcGVjdCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHByb21pc2UudGhlbihyZWdhcmRsZXNzLCByZWdhcmRsZXNzKTtcbiAgICAgICAgfSkpO1xuICAgIH0pO1xufTtcblxuLyoqXG4gKiBDYXB0dXJlcyB0aGUgZmFpbHVyZSBvZiBhIHByb21pc2UsIGdpdmluZyBhbiBvcG9ydHVuaXR5IHRvIHJlY292ZXJcbiAqIHdpdGggYSBjYWxsYmFjay4gIElmIHRoZSBnaXZlbiBwcm9taXNlIGlzIGZ1bGZpbGxlZCwgdGhlIHJldHVybmVkXG4gKiBwcm9taXNlIGlzIGZ1bGZpbGxlZC5cbiAqIEBwYXJhbSB7QW55Kn0gcHJvbWlzZSBmb3Igc29tZXRoaW5nXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayB0byBmdWxmaWxsIHRoZSByZXR1cm5lZCBwcm9taXNlIGlmIHRoZVxuICogZ2l2ZW4gcHJvbWlzZSBpcyByZWplY3RlZFxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBjYWxsYmFja1xuICovXG5RLmZhaWwgPSAvLyBYWFggbGVnYWN5XG5RW1wiY2F0Y2hcIl0gPSBmdW5jdGlvbiAob2JqZWN0LCByZWplY3RlZCkge1xuICAgIHJldHVybiBRKG9iamVjdCkudGhlbih2b2lkIDAsIHJlamVjdGVkKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmZhaWwgPSAvLyBYWFggbGVnYWN5XG5Qcm9taXNlLnByb3RvdHlwZVtcImNhdGNoXCJdID0gZnVuY3Rpb24gKHJlamVjdGVkKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbih2b2lkIDAsIHJlamVjdGVkKTtcbn07XG5cbi8qKlxuICogQXR0YWNoZXMgYSBsaXN0ZW5lciB0aGF0IGNhbiByZXNwb25kIHRvIHByb2dyZXNzIG5vdGlmaWNhdGlvbnMgZnJvbSBhXG4gKiBwcm9taXNlJ3Mgb3JpZ2luYXRpbmcgZGVmZXJyZWQuIFRoaXMgbGlzdGVuZXIgcmVjZWl2ZXMgdGhlIGV4YWN0IGFyZ3VtZW50c1xuICogcGFzc2VkIHRvIGBgZGVmZXJyZWQubm90aWZ5YGAuXG4gKiBAcGFyYW0ge0FueSp9IHByb21pc2UgZm9yIHNvbWV0aGluZ1xuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgdG8gcmVjZWl2ZSBhbnkgcHJvZ3Jlc3Mgbm90aWZpY2F0aW9uc1xuICogQHJldHVybnMgdGhlIGdpdmVuIHByb21pc2UsIHVuY2hhbmdlZFxuICovXG5RLnByb2dyZXNzID0gcHJvZ3Jlc3M7XG5mdW5jdGlvbiBwcm9ncmVzcyhvYmplY3QsIHByb2dyZXNzZWQpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLnRoZW4odm9pZCAwLCB2b2lkIDAsIHByb2dyZXNzZWQpO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5wcm9ncmVzcyA9IGZ1bmN0aW9uIChwcm9ncmVzc2VkKSB7XG4gICAgcmV0dXJuIHRoaXMudGhlbih2b2lkIDAsIHZvaWQgMCwgcHJvZ3Jlc3NlZCk7XG59O1xuXG4vKipcbiAqIFByb3ZpZGVzIGFuIG9wcG9ydHVuaXR5IHRvIG9ic2VydmUgdGhlIHNldHRsaW5nIG9mIGEgcHJvbWlzZSxcbiAqIHJlZ2FyZGxlc3Mgb2Ygd2hldGhlciB0aGUgcHJvbWlzZSBpcyBmdWxmaWxsZWQgb3IgcmVqZWN0ZWQuICBGb3J3YXJkc1xuICogdGhlIHJlc29sdXRpb24gdG8gdGhlIHJldHVybmVkIHByb21pc2Ugd2hlbiB0aGUgY2FsbGJhY2sgaXMgZG9uZS5cbiAqIFRoZSBjYWxsYmFjayBjYW4gcmV0dXJuIGEgcHJvbWlzZSB0byBkZWZlciBjb21wbGV0aW9uLlxuICogQHBhcmFtIHtBbnkqfSBwcm9taXNlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayB0byBvYnNlcnZlIHRoZSByZXNvbHV0aW9uIG9mIHRoZSBnaXZlblxuICogcHJvbWlzZSwgdGFrZXMgbm8gYXJndW1lbnRzLlxuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmVzb2x1dGlvbiBvZiB0aGUgZ2l2ZW4gcHJvbWlzZSB3aGVuXG4gKiBgYGZpbmBgIGlzIGRvbmUuXG4gKi9cblEuZmluID0gLy8gWFhYIGxlZ2FjeVxuUVtcImZpbmFsbHlcIl0gPSBmdW5jdGlvbiAob2JqZWN0LCBjYWxsYmFjaykge1xuICAgIHJldHVybiBRKG9iamVjdClbXCJmaW5hbGx5XCJdKGNhbGxiYWNrKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmZpbiA9IC8vIFhYWCBsZWdhY3lcblByb21pc2UucHJvdG90eXBlW1wiZmluYWxseVwiXSA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrID0gUShjYWxsYmFjayk7XG4gICAgcmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmZjYWxsKCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH0pO1xuICAgIH0sIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgICAgLy8gVE9ETyBhdHRlbXB0IHRvIHJlY3ljbGUgdGhlIHJlamVjdGlvbiB3aXRoIFwidGhpc1wiLlxuICAgICAgICByZXR1cm4gY2FsbGJhY2suZmNhbGwoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRocm93IHJlYXNvbjtcbiAgICAgICAgfSk7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFRlcm1pbmF0ZXMgYSBjaGFpbiBvZiBwcm9taXNlcywgZm9yY2luZyByZWplY3Rpb25zIHRvIGJlXG4gKiB0aHJvd24gYXMgZXhjZXB0aW9ucy5cbiAqIEBwYXJhbSB7QW55Kn0gcHJvbWlzZSBhdCB0aGUgZW5kIG9mIGEgY2hhaW4gb2YgcHJvbWlzZXNcbiAqIEByZXR1cm5zIG5vdGhpbmdcbiAqL1xuUS5kb25lID0gZnVuY3Rpb24gKG9iamVjdCwgZnVsZmlsbGVkLCByZWplY3RlZCwgcHJvZ3Jlc3MpIHtcbiAgICByZXR1cm4gUShvYmplY3QpLmRvbmUoZnVsZmlsbGVkLCByZWplY3RlZCwgcHJvZ3Jlc3MpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUuZG9uZSA9IGZ1bmN0aW9uIChmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzcykge1xuICAgIHZhciBvblVuaGFuZGxlZEVycm9yID0gZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgIC8vIGZvcndhcmQgdG8gYSBmdXR1cmUgdHVybiBzbyB0aGF0IGBgd2hlbmBgXG4gICAgICAgIC8vIGRvZXMgbm90IGNhdGNoIGl0IGFuZCB0dXJuIGl0IGludG8gYSByZWplY3Rpb24uXG4gICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbWFrZVN0YWNrVHJhY2VMb25nKGVycm9yLCBwcm9taXNlKTtcbiAgICAgICAgICAgIGlmIChRLm9uZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBRLm9uZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIC8vIEF2b2lkIHVubmVjZXNzYXJ5IGBuZXh0VGlja2BpbmcgdmlhIGFuIHVubmVjZXNzYXJ5IGB3aGVuYC5cbiAgICB2YXIgcHJvbWlzZSA9IGZ1bGZpbGxlZCB8fCByZWplY3RlZCB8fCBwcm9ncmVzcyA/XG4gICAgICAgIHRoaXMudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkLCBwcm9ncmVzcykgOlxuICAgICAgICB0aGlzO1xuXG4gICAgaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmIHByb2Nlc3MgJiYgcHJvY2Vzcy5kb21haW4pIHtcbiAgICAgICAgb25VbmhhbmRsZWRFcnJvciA9IHByb2Nlc3MuZG9tYWluLmJpbmQob25VbmhhbmRsZWRFcnJvcik7XG4gICAgfVxuXG4gICAgcHJvbWlzZS50aGVuKHZvaWQgMCwgb25VbmhhbmRsZWRFcnJvcik7XG59O1xuXG4vKipcbiAqIENhdXNlcyBhIHByb21pc2UgdG8gYmUgcmVqZWN0ZWQgaWYgaXQgZG9lcyBub3QgZ2V0IGZ1bGZpbGxlZCBiZWZvcmVcbiAqIHNvbWUgbWlsbGlzZWNvbmRzIHRpbWUgb3V0LlxuICogQHBhcmFtIHtBbnkqfSBwcm9taXNlXG4gKiBAcGFyYW0ge051bWJlcn0gbWlsbGlzZWNvbmRzIHRpbWVvdXRcbiAqIEBwYXJhbSB7QW55Kn0gY3VzdG9tIGVycm9yIG1lc3NhZ2Ugb3IgRXJyb3Igb2JqZWN0IChvcHRpb25hbClcbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIHJlc29sdXRpb24gb2YgdGhlIGdpdmVuIHByb21pc2UgaWYgaXQgaXNcbiAqIGZ1bGZpbGxlZCBiZWZvcmUgdGhlIHRpbWVvdXQsIG90aGVyd2lzZSByZWplY3RlZC5cbiAqL1xuUS50aW1lb3V0ID0gZnVuY3Rpb24gKG9iamVjdCwgbXMsIGVycm9yKSB7XG4gICAgcmV0dXJuIFEob2JqZWN0KS50aW1lb3V0KG1zLCBlcnJvcik7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS50aW1lb3V0ID0gZnVuY3Rpb24gKG1zLCBlcnJvcikge1xuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgdmFyIHRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoIWVycm9yIHx8IFwic3RyaW5nXCIgPT09IHR5cGVvZiBlcnJvcikge1xuICAgICAgICAgICAgZXJyb3IgPSBuZXcgRXJyb3IoZXJyb3IgfHwgXCJUaW1lZCBvdXQgYWZ0ZXIgXCIgKyBtcyArIFwiIG1zXCIpO1xuICAgICAgICAgICAgZXJyb3IuY29kZSA9IFwiRVRJTUVET1VUXCI7XG4gICAgICAgIH1cbiAgICAgICAgZGVmZXJyZWQucmVqZWN0KGVycm9yKTtcbiAgICB9LCBtcyk7XG5cbiAgICB0aGlzLnRoZW4oZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICAgICAgICBkZWZlcnJlZC5yZXNvbHZlKHZhbHVlKTtcbiAgICB9LCBmdW5jdGlvbiAoZXhjZXB0aW9uKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuICAgICAgICBkZWZlcnJlZC5yZWplY3QoZXhjZXB0aW9uKTtcbiAgICB9LCBkZWZlcnJlZC5ub3RpZnkpO1xuXG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG4vKipcbiAqIFJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgZ2l2ZW4gdmFsdWUgKG9yIHByb21pc2VkIHZhbHVlKSwgc29tZVxuICogbWlsbGlzZWNvbmRzIGFmdGVyIGl0IHJlc29sdmVkLiBQYXNzZXMgcmVqZWN0aW9ucyBpbW1lZGlhdGVseS5cbiAqIEBwYXJhbSB7QW55Kn0gcHJvbWlzZVxuICogQHBhcmFtIHtOdW1iZXJ9IG1pbGxpc2Vjb25kc1xuICogQHJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgcmVzb2x1dGlvbiBvZiB0aGUgZ2l2ZW4gcHJvbWlzZSBhZnRlciBtaWxsaXNlY29uZHNcbiAqIHRpbWUgaGFzIGVsYXBzZWQgc2luY2UgdGhlIHJlc29sdXRpb24gb2YgdGhlIGdpdmVuIHByb21pc2UuXG4gKiBJZiB0aGUgZ2l2ZW4gcHJvbWlzZSByZWplY3RzLCB0aGF0IGlzIHBhc3NlZCBpbW1lZGlhdGVseS5cbiAqL1xuUS5kZWxheSA9IGZ1bmN0aW9uIChvYmplY3QsIHRpbWVvdXQpIHtcbiAgICBpZiAodGltZW91dCA9PT0gdm9pZCAwKSB7XG4gICAgICAgIHRpbWVvdXQgPSBvYmplY3Q7XG4gICAgICAgIG9iamVjdCA9IHZvaWQgMDtcbiAgICB9XG4gICAgcmV0dXJuIFEob2JqZWN0KS5kZWxheSh0aW1lb3V0KTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLmRlbGF5ID0gZnVuY3Rpb24gKHRpbWVvdXQpIHtcbiAgICByZXR1cm4gdGhpcy50aGVuKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUodmFsdWUpO1xuICAgICAgICB9LCB0aW1lb3V0KTtcbiAgICAgICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG4gICAgfSk7XG59O1xuXG4vKipcbiAqIFBhc3NlcyBhIGNvbnRpbnVhdGlvbiB0byBhIE5vZGUgZnVuY3Rpb24sIHdoaWNoIGlzIGNhbGxlZCB3aXRoIHRoZSBnaXZlblxuICogYXJndW1lbnRzIHByb3ZpZGVkIGFzIGFuIGFycmF5LCBhbmQgcmV0dXJucyBhIHByb21pc2UuXG4gKlxuICogICAgICBRLm5mYXBwbHkoRlMucmVhZEZpbGUsIFtfX2ZpbGVuYW1lXSlcbiAqICAgICAgLnRoZW4oZnVuY3Rpb24gKGNvbnRlbnQpIHtcbiAqICAgICAgfSlcbiAqXG4gKi9cblEubmZhcHBseSA9IGZ1bmN0aW9uIChjYWxsYmFjaywgYXJncykge1xuICAgIHJldHVybiBRKGNhbGxiYWNrKS5uZmFwcGx5KGFyZ3MpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmZhcHBseSA9IGZ1bmN0aW9uIChhcmdzKSB7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICB2YXIgbm9kZUFyZ3MgPSBhcnJheV9zbGljZShhcmdzKTtcbiAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgdGhpcy5mYXBwbHkobm9kZUFyZ3MpLmZhaWwoZGVmZXJyZWQucmVqZWN0KTtcbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cbi8qKlxuICogUGFzc2VzIGEgY29udGludWF0aW9uIHRvIGEgTm9kZSBmdW5jdGlvbiwgd2hpY2ggaXMgY2FsbGVkIHdpdGggdGhlIGdpdmVuXG4gKiBhcmd1bWVudHMgcHJvdmlkZWQgaW5kaXZpZHVhbGx5LCBhbmQgcmV0dXJucyBhIHByb21pc2UuXG4gKiBAZXhhbXBsZVxuICogUS5uZmNhbGwoRlMucmVhZEZpbGUsIF9fZmlsZW5hbWUpXG4gKiAudGhlbihmdW5jdGlvbiAoY29udGVudCkge1xuICogfSlcbiAqXG4gKi9cblEubmZjYWxsID0gZnVuY3Rpb24gKGNhbGxiYWNrIC8qLi4uYXJncyovKSB7XG4gICAgdmFyIGFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMsIDEpO1xuICAgIHJldHVybiBRKGNhbGxiYWNrKS5uZmFwcGx5KGFyZ3MpO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmZjYWxsID0gZnVuY3Rpb24gKC8qLi4uYXJncyovKSB7XG4gICAgdmFyIG5vZGVBcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIG5vZGVBcmdzLnB1c2goZGVmZXJyZWQubWFrZU5vZGVSZXNvbHZlcigpKTtcbiAgICB0aGlzLmZhcHBseShub2RlQXJncykuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xufTtcblxuLyoqXG4gKiBXcmFwcyBhIE5vZGVKUyBjb250aW51YXRpb24gcGFzc2luZyBmdW5jdGlvbiBhbmQgcmV0dXJucyBhbiBlcXVpdmFsZW50XG4gKiB2ZXJzaW9uIHRoYXQgcmV0dXJucyBhIHByb21pc2UuXG4gKiBAZXhhbXBsZVxuICogUS5uZmJpbmQoRlMucmVhZEZpbGUsIF9fZmlsZW5hbWUpKFwidXRmLThcIilcbiAqIC50aGVuKGNvbnNvbGUubG9nKVxuICogLmRvbmUoKVxuICovXG5RLm5mYmluZCA9XG5RLmRlbm9kZWlmeSA9IGZ1bmN0aW9uIChjYWxsYmFjayAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBiYXNlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMSk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG5vZGVBcmdzID0gYmFzZUFyZ3MuY29uY2F0KGFycmF5X3NsaWNlKGFyZ3VtZW50cykpO1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgICAgIFEoY2FsbGJhY2spLmZhcHBseShub2RlQXJncykuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmZiaW5kID1cblByb21pc2UucHJvdG90eXBlLmRlbm9kZWlmeSA9IGZ1bmN0aW9uICgvKi4uLmFyZ3MqLykge1xuICAgIHZhciBhcmdzID0gYXJyYXlfc2xpY2UoYXJndW1lbnRzKTtcbiAgICBhcmdzLnVuc2hpZnQodGhpcyk7XG4gICAgcmV0dXJuIFEuZGVub2RlaWZ5LmFwcGx5KHZvaWQgMCwgYXJncyk7XG59O1xuXG5RLm5iaW5kID0gZnVuY3Rpb24gKGNhbGxiYWNrLCB0aGlzcCAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBiYXNlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMik7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG5vZGVBcmdzID0gYmFzZUFyZ3MuY29uY2F0KGFycmF5X3NsaWNlKGFyZ3VtZW50cykpO1xuICAgICAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgICAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgICAgIGZ1bmN0aW9uIGJvdW5kKCkge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KHRoaXNwLCBhcmd1bWVudHMpO1xuICAgICAgICB9XG4gICAgICAgIFEoYm91bmQpLmZhcHBseShub2RlQXJncykuZmFpbChkZWZlcnJlZC5yZWplY3QpO1xuICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9O1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGUubmJpbmQgPSBmdW5jdGlvbiAoLyp0aGlzcCwgLi4uYXJncyovKSB7XG4gICAgdmFyIGFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMsIDApO1xuICAgIGFyZ3MudW5zaGlmdCh0aGlzKTtcbiAgICByZXR1cm4gUS5uYmluZC5hcHBseSh2b2lkIDAsIGFyZ3MpO1xufTtcblxuLyoqXG4gKiBDYWxscyBhIG1ldGhvZCBvZiBhIE5vZGUtc3R5bGUgb2JqZWN0IHRoYXQgYWNjZXB0cyBhIE5vZGUtc3R5bGVcbiAqIGNhbGxiYWNrIHdpdGggYSBnaXZlbiBhcnJheSBvZiBhcmd1bWVudHMsIHBsdXMgYSBwcm92aWRlZCBjYWxsYmFjay5cbiAqIEBwYXJhbSBvYmplY3QgYW4gb2JqZWN0IHRoYXQgaGFzIHRoZSBuYW1lZCBtZXRob2RcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIG5hbWUgb2YgdGhlIG1ldGhvZCBvZiBvYmplY3RcbiAqIEBwYXJhbSB7QXJyYXl9IGFyZ3MgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIG1ldGhvZDsgdGhlIGNhbGxiYWNrXG4gKiB3aWxsIGJlIHByb3ZpZGVkIGJ5IFEgYW5kIGFwcGVuZGVkIHRvIHRoZXNlIGFyZ3VtZW50cy5cbiAqIEByZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIHZhbHVlIG9yIGVycm9yXG4gKi9cblEubm1hcHBseSA9IC8vIFhYWCBBcyBwcm9wb3NlZCBieSBcIlJlZHNhbmRyb1wiXG5RLm5wb3N0ID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSwgYXJncykge1xuICAgIHJldHVybiBRKG9iamVjdCkubnBvc3QobmFtZSwgYXJncyk7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5ubWFwcGx5ID0gLy8gWFhYIEFzIHByb3Bvc2VkIGJ5IFwiUmVkc2FuZHJvXCJcblByb21pc2UucHJvdG90eXBlLm5wb3N0ID0gZnVuY3Rpb24gKG5hbWUsIGFyZ3MpIHtcbiAgICB2YXIgbm9kZUFyZ3MgPSBhcnJheV9zbGljZShhcmdzIHx8IFtdKTtcbiAgICB2YXIgZGVmZXJyZWQgPSBkZWZlcigpO1xuICAgIG5vZGVBcmdzLnB1c2goZGVmZXJyZWQubWFrZU5vZGVSZXNvbHZlcigpKTtcbiAgICB0aGlzLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgbm9kZUFyZ3NdKS5mYWlsKGRlZmVycmVkLnJlamVjdCk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG4vKipcbiAqIENhbGxzIGEgbWV0aG9kIG9mIGEgTm9kZS1zdHlsZSBvYmplY3QgdGhhdCBhY2NlcHRzIGEgTm9kZS1zdHlsZVxuICogY2FsbGJhY2ssIGZvcndhcmRpbmcgdGhlIGdpdmVuIHZhcmlhZGljIGFyZ3VtZW50cywgcGx1cyBhIHByb3ZpZGVkXG4gKiBjYWxsYmFjayBhcmd1bWVudC5cbiAqIEBwYXJhbSBvYmplY3QgYW4gb2JqZWN0IHRoYXQgaGFzIHRoZSBuYW1lZCBtZXRob2RcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIG5hbWUgb2YgdGhlIG1ldGhvZCBvZiBvYmplY3RcbiAqIEBwYXJhbSAuLi5hcmdzIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBtZXRob2Q7IHRoZSBjYWxsYmFjayB3aWxsXG4gKiBiZSBwcm92aWRlZCBieSBRIGFuZCBhcHBlbmRlZCB0byB0aGVzZSBhcmd1bWVudHMuXG4gKiBAcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSB2YWx1ZSBvciBlcnJvclxuICovXG5RLm5zZW5kID0gLy8gWFhYIEJhc2VkIG9uIE1hcmsgTWlsbGVyJ3MgcHJvcG9zZWQgXCJzZW5kXCJcblEubm1jYWxsID0gLy8gWFhYIEJhc2VkIG9uIFwiUmVkc2FuZHJvJ3NcIiBwcm9wb3NhbFxuUS5uaW52b2tlID0gZnVuY3Rpb24gKG9iamVjdCwgbmFtZSAvKi4uLmFyZ3MqLykge1xuICAgIHZhciBub2RlQXJncyA9IGFycmF5X3NsaWNlKGFyZ3VtZW50cywgMik7XG4gICAgdmFyIGRlZmVycmVkID0gZGVmZXIoKTtcbiAgICBub2RlQXJncy5wdXNoKGRlZmVycmVkLm1ha2VOb2RlUmVzb2x2ZXIoKSk7XG4gICAgUShvYmplY3QpLmRpc3BhdGNoKFwicG9zdFwiLCBbbmFtZSwgbm9kZUFyZ3NdKS5mYWlsKGRlZmVycmVkLnJlamVjdCk7XG4gICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG59O1xuXG5Qcm9taXNlLnByb3RvdHlwZS5uc2VuZCA9IC8vIFhYWCBCYXNlZCBvbiBNYXJrIE1pbGxlcidzIHByb3Bvc2VkIFwic2VuZFwiXG5Qcm9taXNlLnByb3RvdHlwZS5ubWNhbGwgPSAvLyBYWFggQmFzZWQgb24gXCJSZWRzYW5kcm8nc1wiIHByb3Bvc2FsXG5Qcm9taXNlLnByb3RvdHlwZS5uaW52b2tlID0gZnVuY3Rpb24gKG5hbWUgLyouLi5hcmdzKi8pIHtcbiAgICB2YXIgbm9kZUFyZ3MgPSBhcnJheV9zbGljZShhcmd1bWVudHMsIDEpO1xuICAgIHZhciBkZWZlcnJlZCA9IGRlZmVyKCk7XG4gICAgbm9kZUFyZ3MucHVzaChkZWZlcnJlZC5tYWtlTm9kZVJlc29sdmVyKCkpO1xuICAgIHRoaXMuZGlzcGF0Y2goXCJwb3N0XCIsIFtuYW1lLCBub2RlQXJnc10pLmZhaWwoZGVmZXJyZWQucmVqZWN0KTtcbiAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbn07XG5cbi8qKlxuICogSWYgYSBmdW5jdGlvbiB3b3VsZCBsaWtlIHRvIHN1cHBvcnQgYm90aCBOb2RlIGNvbnRpbnVhdGlvbi1wYXNzaW5nLXN0eWxlIGFuZFxuICogcHJvbWlzZS1yZXR1cm5pbmctc3R5bGUsIGl0IGNhbiBlbmQgaXRzIGludGVybmFsIHByb21pc2UgY2hhaW4gd2l0aFxuICogYG5vZGVpZnkobm9kZWJhY2spYCwgZm9yd2FyZGluZyB0aGUgb3B0aW9uYWwgbm9kZWJhY2sgYXJndW1lbnQuICBJZiB0aGUgdXNlclxuICogZWxlY3RzIHRvIHVzZSBhIG5vZGViYWNrLCB0aGUgcmVzdWx0IHdpbGwgYmUgc2VudCB0aGVyZS4gIElmIHRoZXkgZG8gbm90XG4gKiBwYXNzIGEgbm9kZWJhY2ssIHRoZXkgd2lsbCByZWNlaXZlIHRoZSByZXN1bHQgcHJvbWlzZS5cbiAqIEBwYXJhbSBvYmplY3QgYSByZXN1bHQgKG9yIGEgcHJvbWlzZSBmb3IgYSByZXN1bHQpXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBub2RlYmFjayBhIE5vZGUuanMtc3R5bGUgY2FsbGJhY2tcbiAqIEByZXR1cm5zIGVpdGhlciB0aGUgcHJvbWlzZSBvciBub3RoaW5nXG4gKi9cblEubm9kZWlmeSA9IG5vZGVpZnk7XG5mdW5jdGlvbiBub2RlaWZ5KG9iamVjdCwgbm9kZWJhY2spIHtcbiAgICByZXR1cm4gUShvYmplY3QpLm5vZGVpZnkobm9kZWJhY2spO1xufVxuXG5Qcm9taXNlLnByb3RvdHlwZS5ub2RlaWZ5ID0gZnVuY3Rpb24gKG5vZGViYWNrKSB7XG4gICAgaWYgKG5vZGViYWNrKSB7XG4gICAgICAgIHRoaXMudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIG5vZGViYWNrKG51bGwsIHZhbHVlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LCBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgICAgIFEubmV4dFRpY2soZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIG5vZGViYWNrKGVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59O1xuXG5RLm5vQ29uZmxpY3QgPSBmdW5jdGlvbigpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJRLm5vQ29uZmxpY3Qgb25seSB3b3JrcyB3aGVuIFEgaXMgdXNlZCBhcyBhIGdsb2JhbFwiKTtcbn07XG5cbi8vIEFsbCBjb2RlIGJlZm9yZSB0aGlzIHBvaW50IHdpbGwgYmUgZmlsdGVyZWQgZnJvbSBzdGFjayB0cmFjZXMuXG52YXIgcUVuZGluZ0xpbmUgPSBjYXB0dXJlTGluZSgpO1xuXG5yZXR1cm4gUTtcblxufSk7XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKCdfcHJvY2VzcycpKVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ6dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p6YjNWeVkyVnpJanBiSW01dlpHVmZiVzlrZFd4bGN5OXhMM0V1YW5NaVhTd2libUZ0WlhNaU9sdGRMQ0p0WVhCd2FXNW5jeUk2SWp0QlFVRkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFUdEJRVU5CTzBGQlEwRTdRVUZEUVR0QlFVTkJPMEZCUTBFN1FVRkRRVHRCUVVOQk8wRkJRMEU3UVVGRFFTSXNJbVpwYkdVaU9pSm5aVzVsY21GMFpXUXVhbk1pTENKemIzVnlZMlZTYjI5MElqb2lJaXdpYzI5MWNtTmxjME52Ym5SbGJuUWlPbHNpTHk4Z2RtbHRPblJ6UFRRNmMzUnpQVFE2YzNjOU5EcGNiaThxSVZ4dUlDcGNiaUFxSUVOdmNIbHlhV2RvZENBeU1EQTVMVEl3TVRJZ1MzSnBjeUJMYjNkaGJDQjFibVJsY2lCMGFHVWdkR1Z5YlhNZ2IyWWdkR2hsSUUxSlZGeHVJQ29nYkdsalpXNXpaU0JtYjNWdVpDQmhkQ0JvZEhSd09pOHZaMmwwYUhWaUxtTnZiUzlyY21semEyOTNZV3d2Y1M5eVlYY3ZiV0Z6ZEdWeUwweEpRMFZPVTBWY2JpQXFYRzRnS2lCWGFYUm9JSEJoY25SeklHSjVJRlI1YkdWeUlFTnNiM05sWEc0Z0tpQkRiM0I1Y21sbmFIUWdNakF3TnkweU1EQTVJRlI1YkdWeUlFTnNiM05sSUhWdVpHVnlJSFJvWlNCMFpYSnRjeUJ2WmlCMGFHVWdUVWxVSUZnZ2JHbGpaVzV6WlNCbWIzVnVaRnh1SUNvZ1lYUWdhSFIwY0RvdkwzZDNkeTV2Y0dWdWMyOTFjbU5sTG05eVp5OXNhV05sYm5ObGN5OXRhWFF0YkdsalpXNXpaUzVvZEcxc1hHNGdLaUJHYjNKclpXUWdZWFFnY21WbVgzTmxibVF1YW5NZ2RtVnljMmx2YmpvZ01qQXdPUzB3TlMweE1WeHVJQ3BjYmlBcUlGZHBkR2dnY0dGeWRITWdZbmtnVFdGeWF5Qk5hV3hzWlhKY2JpQXFJRU52Y0hseWFXZG9kQ0FvUXlrZ01qQXhNU0JIYjI5bmJHVWdTVzVqTGx4dUlDcGNiaUFxSUV4cFkyVnVjMlZrSUhWdVpHVnlJSFJvWlNCQmNHRmphR1VnVEdsalpXNXpaU3dnVm1WeWMybHZiaUF5TGpBZ0tIUm9aU0JjSWt4cFkyVnVjMlZjSWlrN1hHNGdLaUI1YjNVZ2JXRjVJRzV2ZENCMWMyVWdkR2hwY3lCbWFXeGxJR1Y0WTJWd2RDQnBiaUJqYjIxd2JHbGhibU5sSUhkcGRHZ2dkR2hsSUV4cFkyVnVjMlV1WEc0Z0tpQlpiM1VnYldGNUlHOWlkR0ZwYmlCaElHTnZjSGtnYjJZZ2RHaGxJRXhwWTJWdWMyVWdZWFJjYmlBcVhHNGdLaUJvZEhSd09pOHZkM2QzTG1Gd1lXTm9aUzV2Y21jdmJHbGpaVzV6WlhNdlRFbERSVTVUUlMweUxqQmNiaUFxWEc0Z0tpQlZibXhsYzNNZ2NtVnhkV2x5WldRZ1lua2dZWEJ3YkdsallXSnNaU0JzWVhjZ2IzSWdZV2R5WldWa0lIUnZJR2x1SUhkeWFYUnBibWNzSUhOdlpuUjNZWEpsWEc0Z0tpQmthWE4wY21saWRYUmxaQ0IxYm1SbGNpQjBhR1VnVEdsalpXNXpaU0JwY3lCa2FYTjBjbWxpZFhSbFpDQnZiaUJoYmlCY0lrRlRJRWxUWENJZ1FrRlRTVk1zWEc0Z0tpQlhTVlJJVDFWVUlGZEJVbEpCVGxSSlJWTWdUMUlnUTA5T1JFbFVTVTlPVXlCUFJpQkJUbGtnUzBsT1JDd2daV2wwYUdWeUlHVjRjSEpsYzNNZ2IzSWdhVzF3YkdsbFpDNWNiaUFxSUZObFpTQjBhR1VnVEdsalpXNXpaU0JtYjNJZ2RHaGxJSE53WldOcFptbGpJR3hoYm1kMVlXZGxJR2R2ZG1WeWJtbHVaeUJ3WlhKdGFYTnphVzl1Y3lCaGJtUmNiaUFxSUd4cGJXbDBZWFJwYjI1eklIVnVaR1Z5SUhSb1pTQk1hV05sYm5ObExseHVJQ3BjYmlBcUwxeHVYRzRvWm5WdVkzUnBiMjRnS0dSbFptbHVhWFJwYjI0cElIdGNiaUFnSUNCY0luVnpaU0J6ZEhKcFkzUmNJanRjYmx4dUlDQWdJQzh2SUZSb2FYTWdabWxzWlNCM2FXeHNJR1oxYm1OMGFXOXVJSEJ5YjNCbGNteDVJR0Z6SUdFZ1BITmpjbWx3ZEQ0Z2RHRm5MQ0J2Y2lCaElHMXZaSFZzWlZ4dUlDQWdJQzh2SUhWemFXNW5JRU52YlcxdmJrcFRJR0Z1WkNCT2IyUmxTbE1nYjNJZ1VtVnhkV2x5WlVwVElHMXZaSFZzWlNCbWIzSnRZWFJ6TGlBZ1NXNWNiaUFnSUNBdkx5QkRiMjF0YjI0dlRtOWtaUzlTWlhGMWFYSmxTbE1zSUhSb1pTQnRiMlIxYkdVZ1pYaHdiM0owY3lCMGFHVWdVU0JCVUVrZ1lXNWtJSGRvWlc1Y2JpQWdJQ0F2THlCbGVHVmpkWFJsWkNCaGN5QmhJSE5wYlhCc1pTQThjMk55YVhCMFBpd2dhWFFnWTNKbFlYUmxjeUJoSUZFZ1oyeHZZbUZzSUdsdWMzUmxZV1F1WEc1Y2JpQWdJQ0F2THlCTmIyNTBZV2RsSUZKbGNYVnBjbVZjYmlBZ0lDQnBaaUFvZEhsd1pXOW1JR0p2YjNSemRISmhjQ0E5UFQwZ1hDSm1kVzVqZEdsdmJsd2lLU0I3WEc0Z0lDQWdJQ0FnSUdKdmIzUnpkSEpoY0NoY0luQnliMjFwYzJWY0lpd2daR1ZtYVc1cGRHbHZiaWs3WEc1Y2JpQWdJQ0F2THlCRGIyMXRiMjVLVTF4dUlDQWdJSDBnWld4elpTQnBaaUFvZEhsd1pXOW1JR1Y0Y0c5eWRITWdQVDA5SUZ3aWIySnFaV04wWENJZ0ppWWdkSGx3Wlc5bUlHMXZaSFZzWlNBOVBUMGdYQ0p2WW1wbFkzUmNJaWtnZTF4dUlDQWdJQ0FnSUNCdGIyUjFiR1V1Wlhod2IzSjBjeUE5SUdSbFptbHVhWFJwYjI0b0tUdGNibHh1SUNBZ0lDOHZJRkpsY1hWcGNtVktVMXh1SUNBZ0lIMGdaV3h6WlNCcFppQW9kSGx3Wlc5bUlHUmxabWx1WlNBOVBUMGdYQ0ptZFc1amRHbHZibHdpSUNZbUlHUmxabWx1WlM1aGJXUXBJSHRjYmlBZ0lDQWdJQ0FnWkdWbWFXNWxLR1JsWm1sdWFYUnBiMjRwTzF4dVhHNGdJQ0FnTHk4Z1UwVlRJQ2hUWldOMWNtVWdSV050WVZOamNtbHdkQ2xjYmlBZ0lDQjlJR1ZzYzJVZ2FXWWdLSFI1Y0dWdlppQnpaWE1nSVQwOUlGd2lkVzVrWldacGJtVmtYQ0lwSUh0Y2JpQWdJQ0FnSUNBZ2FXWWdLQ0Z6WlhNdWIyc29LU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjbVYwZFhKdU8xeHVJQ0FnSUNBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnYzJWekxtMWhhMlZSSUQwZ1pHVm1hVzVwZEdsdmJqdGNiaUFnSUNBZ0lDQWdmVnh1WEc0Z0lDQWdMeThnUEhOamNtbHdkRDVjYmlBZ0lDQjlJR1ZzYzJVZ2FXWWdLSFI1Y0dWdlppQjNhVzVrYjNjZ0lUMDlJRndpZFc1a1pXWnBibVZrWENJZ2ZId2dkSGx3Wlc5bUlITmxiR1lnSVQwOUlGd2lkVzVrWldacGJtVmtYQ0lwSUh0Y2JpQWdJQ0FnSUNBZ0x5OGdVSEpsWm1WeUlIZHBibVJ2ZHlCdmRtVnlJSE5sYkdZZ1ptOXlJR0ZrWkMxdmJpQnpZM0pwY0hSekxpQlZjMlVnYzJWc1ppQm1iM0pjYmlBZ0lDQWdJQ0FnTHk4Z2JtOXVMWGRwYm1SdmQyVmtJR052Ym5SbGVIUnpMbHh1SUNBZ0lDQWdJQ0IyWVhJZ1oyeHZZbUZzSUQwZ2RIbHdaVzltSUhkcGJtUnZkeUFoUFQwZ1hDSjFibVJsWm1sdVpXUmNJaUEvSUhkcGJtUnZkeUE2SUhObGJHWTdYRzVjYmlBZ0lDQWdJQ0FnTHk4Z1IyVjBJSFJvWlNCZ2QybHVaRzkzWUNCdlltcGxZM1FzSUhOaGRtVWdkR2hsSUhCeVpYWnBiM1Z6SUZFZ1oyeHZZbUZzWEc0Z0lDQWdJQ0FnSUM4dklHRnVaQ0JwYm1sMGFXRnNhWHBsSUZFZ1lYTWdZU0JuYkc5aVlXd3VYRzRnSUNBZ0lDQWdJSFpoY2lCd2NtVjJhVzkxYzFFZ1BTQm5iRzlpWVd3dVVUdGNiaUFnSUNBZ0lDQWdaMnh2WW1Gc0xsRWdQU0JrWldacGJtbDBhVzl1S0NrN1hHNWNiaUFnSUNBZ0lDQWdMeThnUVdSa0lHRWdibTlEYjI1bWJHbGpkQ0JtZFc1amRHbHZiaUJ6YnlCUklHTmhiaUJpWlNCeVpXMXZkbVZrSUdaeWIyMGdkR2hsWEc0Z0lDQWdJQ0FnSUM4dklHZHNiMkpoYkNCdVlXMWxjM0JoWTJVdVhHNGdJQ0FnSUNBZ0lHZHNiMkpoYkM1UkxtNXZRMjl1Wm14cFkzUWdQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0JuYkc5aVlXd3VVU0E5SUhCeVpYWnBiM1Z6VVR0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQjBhR2x6TzF4dUlDQWdJQ0FnSUNCOU8xeHVYRzRnSUNBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0FnSUNBZ2RHaHliM2NnYm1WM0lFVnljbTl5S0Z3aVZHaHBjeUJsYm5acGNtOXViV1Z1ZENCM1lYTWdibTkwSUdGdWRHbGphWEJoZEdWa0lHSjVJRkV1SUZCc1pXRnpaU0JtYVd4bElHRWdZblZuTGx3aUtUdGNiaUFnSUNCOVhHNWNibjBwS0daMWJtTjBhVzl1SUNncElIdGNibHdpZFhObElITjBjbWxqZEZ3aU8xeHVYRzUyWVhJZ2FHRnpVM1JoWTJ0eklEMGdabUZzYzJVN1hHNTBjbmtnZTF4dUlDQWdJSFJvY205M0lHNWxkeUJGY25KdmNpZ3BPMXh1ZlNCallYUmphQ0FvWlNrZ2UxeHVJQ0FnSUdoaGMxTjBZV05yY3lBOUlDRWhaUzV6ZEdGamF6dGNibjFjYmx4dUx5OGdRV3hzSUdOdlpHVWdZV1owWlhJZ2RHaHBjeUJ3YjJsdWRDQjNhV3hzSUdKbElHWnBiSFJsY21Wa0lHWnliMjBnYzNSaFkyc2dkSEpoWTJWeklISmxjRzl5ZEdWa1hHNHZMeUJpZVNCUkxseHVkbUZ5SUhGVGRHRnlkR2x1WjB4cGJtVWdQU0JqWVhCMGRYSmxUR2x1WlNncE8xeHVkbUZ5SUhGR2FXeGxUbUZ0WlR0Y2JseHVMeThnYzJocGJYTmNibHh1THk4Z2RYTmxaQ0JtYjNJZ1ptRnNiR0poWTJzZ2FXNGdYQ0poYkd4U1pYTnZiSFpsWkZ3aVhHNTJZWElnYm05dmNDQTlJR1oxYm1OMGFXOXVJQ2dwSUh0OU8xeHVYRzR2THlCVmMyVWdkR2hsSUdaaGMzUmxjM1FnY0c5emMybGliR1VnYldWaGJuTWdkRzhnWlhobFkzVjBaU0JoSUhSaGMyc2dhVzRnWVNCbWRYUjFjbVVnZEhWeWJseHVMeThnYjJZZ2RHaGxJR1YyWlc1MElHeHZiM0F1WEc1MllYSWdibVY0ZEZScFkyc2dQU2htZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnTHk4Z2JHbHVhMlZrSUd4cGMzUWdiMllnZEdGemEzTWdLSE5wYm1kc1pTd2dkMmwwYUNCb1pXRmtJRzV2WkdVcFhHNGdJQ0FnZG1GeUlHaGxZV1FnUFNCN2RHRnphem9nZG05cFpDQXdMQ0J1WlhoME9pQnVkV3hzZlR0Y2JpQWdJQ0IyWVhJZ2RHRnBiQ0E5SUdobFlXUTdYRzRnSUNBZ2RtRnlJR1pzZFhOb2FXNW5JRDBnWm1Gc2MyVTdYRzRnSUNBZ2RtRnlJSEpsY1hWbGMzUlVhV05ySUQwZ2RtOXBaQ0F3TzF4dUlDQWdJSFpoY2lCcGMwNXZaR1ZLVXlBOUlHWmhiSE5sTzF4dUlDQWdJQzh2SUhGMVpYVmxJR1p2Y2lCc1lYUmxJSFJoYzJ0ekxDQjFjMlZrSUdKNUlIVnVhR0Z1Wkd4bFpDQnlaV3BsWTNScGIyNGdkSEpoWTJ0cGJtZGNiaUFnSUNCMllYSWdiR0YwWlhKUmRXVjFaU0E5SUZ0ZE8xeHVYRzRnSUNBZ1puVnVZM1JwYjI0Z1pteDFjMmdvS1NCN1hHNGdJQ0FnSUNBZ0lDOHFJR3B6YUdsdWRDQnNiMjl3Wm5WdVl6b2dkSEoxWlNBcUwxeHVJQ0FnSUNBZ0lDQjJZWElnZEdGemF5d2daRzl0WVdsdU8xeHVYRzRnSUNBZ0lDQWdJSGRvYVd4bElDaG9aV0ZrTG01bGVIUXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lHaGxZV1FnUFNCb1pXRmtMbTVsZUhRN1hHNGdJQ0FnSUNBZ0lDQWdJQ0IwWVhOcklEMGdhR1ZoWkM1MFlYTnJPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2FHVmhaQzUwWVhOcklEMGdkbTlwWkNBd08xeHVJQ0FnSUNBZ0lDQWdJQ0FnWkc5dFlXbHVJRDBnYUdWaFpDNWtiMjFoYVc0N1hHNWNiaUFnSUNBZ0lDQWdJQ0FnSUdsbUlDaGtiMjFoYVc0cElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQm9aV0ZrTG1SdmJXRnBiaUE5SUhadmFXUWdNRHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JrYjIxaGFXNHVaVzUwWlhJb0tUdGNiaUFnSUNBZ0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ0lDQWdJSEoxYmxOcGJtZHNaU2gwWVhOckxDQmtiMjFoYVc0cE8xeHVYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnZDJocGJHVWdLR3hoZEdWeVVYVmxkV1V1YkdWdVozUm9LU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjBZWE5ySUQwZ2JHRjBaWEpSZFdWMVpTNXdiM0FvS1R0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEoxYmxOcGJtZHNaU2gwWVhOcktUdGNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0JtYkhWemFHbHVaeUE5SUdaaGJITmxPMXh1SUNBZ0lIMWNiaUFnSUNBdkx5QnlkVzV6SUdFZ2MybHVaMnhsSUdaMWJtTjBhVzl1SUdsdUlIUm9aU0JoYzNsdVl5QnhkV1YxWlZ4dUlDQWdJR1oxYm1OMGFXOXVJSEoxYmxOcGJtZHNaU2gwWVhOckxDQmtiMjFoYVc0cElIdGNiaUFnSUNBZ0lDQWdkSEo1SUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSFJoYzJzb0tUdGNibHh1SUNBZ0lDQWdJQ0I5SUdOaGRHTm9JQ2hsS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0JwWmlBb2FYTk9iMlJsU2xNcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQXZMeUJKYmlCdWIyUmxMQ0IxYm1OaGRXZG9kQ0JsZUdObGNIUnBiMjV6SUdGeVpTQmpiMjV6YVdSbGNtVmtJR1poZEdGc0lHVnljbTl5Y3k1Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBdkx5QlNaUzEwYUhKdmR5QjBhR1Z0SUhONWJtTm9jbTl1YjNWemJIa2dkRzhnYVc1MFpYSnlkWEIwSUdac2RYTm9hVzVuSVZ4dVhHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0x5OGdSVzV6ZFhKbElHTnZiblJwYm5WaGRHbHZiaUJwWmlCMGFHVWdkVzVqWVhWbmFIUWdaWGhqWlhCMGFXOXVJR2x6SUhOMWNIQnlaWE56WldSY2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBdkx5QnNhWE4wWlc1cGJtY2dYQ0oxYm1OaGRXZG9kRVY0WTJWd2RHbHZibHdpSUdWMlpXNTBjeUFvWVhNZ1pHOXRZV2x1Y3lCa2IyVnpLUzVjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0F2THlCRGIyNTBhVzUxWlNCcGJpQnVaWGgwSUdWMlpXNTBJSFJ2SUdGMmIybGtJSFJwWTJzZ2NtVmpkWEp6YVc5dUxseHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHbG1JQ2hrYjIxaGFXNHBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ1pHOXRZV2x1TG1WNGFYUW9LVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnYzJWMFZHbHRaVzkxZENobWJIVnphQ3dnTUNrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLR1J2YldGcGJpa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCa2IyMWhhVzR1Wlc1MFpYSW9LVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0I5WEc1Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCMGFISnZkeUJsTzF4dVhHNGdJQ0FnSUNBZ0lDQWdJQ0I5SUdWc2MyVWdlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQzh2SUVsdUlHSnliM2R6WlhKekxDQjFibU5oZFdkb2RDQmxlR05sY0hScGIyNXpJR0Z5WlNCdWIzUWdabUYwWVd3dVhHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0x5OGdVbVV0ZEdoeWIzY2dkR2hsYlNCaGMzbHVZMmh5YjI1dmRYTnNlU0IwYnlCaGRtOXBaQ0J6Ykc5M0xXUnZkMjV6TGx4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhObGRGUnBiV1Z2ZFhRb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCMGFISnZkeUJsTzF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUgwc0lEQXBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQjlYRzVjYmlBZ0lDQWdJQ0FnYVdZZ0tHUnZiV0ZwYmlrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnWkc5dFlXbHVMbVY0YVhRb0tUdGNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lIMWNibHh1SUNBZ0lHNWxlSFJVYVdOcklEMGdablZ1WTNScGIyNGdLSFJoYzJzcElIdGNiaUFnSUNBZ0lDQWdkR0ZwYkNBOUlIUmhhV3d1Ym1WNGRDQTlJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIUmhjMnM2SUhSaGMyc3NYRzRnSUNBZ0lDQWdJQ0FnSUNCa2IyMWhhVzQ2SUdselRtOWtaVXBUSUNZbUlIQnliMk5sYzNNdVpHOXRZV2x1TEZ4dUlDQWdJQ0FnSUNBZ0lDQWdibVY0ZERvZ2JuVnNiRnh1SUNBZ0lDQWdJQ0I5TzF4dVhHNGdJQ0FnSUNBZ0lHbG1JQ2doWm14MWMyaHBibWNwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJR1pzZFhOb2FXNW5JRDBnZEhKMVpUdGNiaUFnSUNBZ0lDQWdJQ0FnSUhKbGNYVmxjM1JVYVdOcktDazdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQjlPMXh1WEc0Z0lDQWdhV1lnS0hSNWNHVnZaaUJ3Y205alpYTnpJRDA5UFNCY0ltOWlhbVZqZEZ3aUlDWW1YRzRnSUNBZ0lDQWdJSEJ5YjJObGMzTXVkRzlUZEhKcGJtY29LU0E5UFQwZ1hDSmJiMkpxWldOMElIQnliMk5sYzNOZFhDSWdKaVlnY0hKdlkyVnpjeTV1WlhoMFZHbGpheWtnZTF4dUlDQWdJQ0FnSUNBdkx5QkZibk4xY21VZ1VTQnBjeUJwYmlCaElISmxZV3dnVG05a1pTQmxiblpwY205dWJXVnVkQ3dnZDJsMGFDQmhJR0J3Y205alpYTnpMbTVsZUhSVWFXTnJZQzVjYmlBZ0lDQWdJQ0FnTHk4Z1ZHOGdjMlZsSUhSb2NtOTFaMmdnWm1GclpTQk9iMlJsSUdWdWRtbHliMjV0Wlc1MGN6cGNiaUFnSUNBZ0lDQWdMeThnS2lCTmIyTm9ZU0IwWlhOMElISjFibTVsY2lBdElHVjRjRzl6WlhNZ1lTQmdjSEp2WTJWemMyQWdaMnh2WW1Gc0lIZHBkR2h2ZFhRZ1lTQmdibVY0ZEZScFkydGdYRzRnSUNBZ0lDQWdJQzh2SUNvZ1FuSnZkM05sY21sbWVTQXRJR1Y0Y0c5elpYTWdZU0JnY0hKdlkyVnpjeTV1WlhoVWFXTnJZQ0JtZFc1amRHbHZiaUIwYUdGMElIVnpaWE5jYmlBZ0lDQWdJQ0FnTHk4Z0lDQmdjMlYwVkdsdFpXOTFkR0F1SUVsdUlIUm9hWE1nWTJGelpTQmdjMlYwU1cxdFpXUnBZWFJsWUNCcGN5QndjbVZtWlhKeVpXUWdZbVZqWVhWelpWeHVJQ0FnSUNBZ0lDQXZMeUFnSUNCcGRDQnBjeUJtWVhOMFpYSXVJRUp5YjNkelpYSnBabmtuY3lCZ2NISnZZMlZ6Y3k1MGIxTjBjbWx1WnlncFlDQjVhV1ZzWkhOY2JpQWdJQ0FnSUNBZ0x5OGdJQ0JjSWx0dlltcGxZM1FnVDJKcVpXTjBYVndpTENCM2FHbHNaU0JwYmlCaElISmxZV3dnVG05a1pTQmxiblpwY205dWJXVnVkRnh1SUNBZ0lDQWdJQ0F2THlBZ0lHQndjbTlqWlhOekxtNWxlSFJVYVdOcktDbGdJSGxwWld4a2N5QmNJbHR2WW1wbFkzUWdjSEp2WTJWemMxMWNJaTVjYmlBZ0lDQWdJQ0FnYVhOT2IyUmxTbE1nUFNCMGNuVmxPMXh1WEc0Z0lDQWdJQ0FnSUhKbGNYVmxjM1JVYVdOcklEMGdablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjSEp2WTJWemN5NXVaWGgwVkdsamF5aG1iSFZ6YUNrN1hHNGdJQ0FnSUNBZ0lIMDdYRzVjYmlBZ0lDQjlJR1ZzYzJVZ2FXWWdLSFI1Y0dWdlppQnpaWFJKYlcxbFpHbGhkR1VnUFQwOUlGd2lablZ1WTNScGIyNWNJaWtnZTF4dUlDQWdJQ0FnSUNBdkx5QkpiaUJKUlRFd0xDQk9iMlJsTG1weklEQXVPU3NzSUc5eUlHaDBkSEJ6T2k4dloybDBhSFZpTG1OdmJTOU9iMkpzWlVwVEwzTmxkRWx0YldWa2FXRjBaVnh1SUNBZ0lDQWdJQ0JwWmlBb2RIbHdaVzltSUhkcGJtUnZkeUFoUFQwZ1hDSjFibVJsWm1sdVpXUmNJaWtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjbVZ4ZFdWemRGUnBZMnNnUFNCelpYUkpiVzFsWkdsaGRHVXVZbWx1WkNoM2FXNWtiM2NzSUdac2RYTm9LVHRjYmlBZ0lDQWdJQ0FnZlNCbGJITmxJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lISmxjWFZsYzNSVWFXTnJJRDBnWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lITmxkRWx0YldWa2FXRjBaU2htYkhWemFDazdYRzRnSUNBZ0lDQWdJQ0FnSUNCOU8xeHVJQ0FnSUNBZ0lDQjlYRzVjYmlBZ0lDQjlJR1ZzYzJVZ2FXWWdLSFI1Y0dWdlppQk5aWE56WVdkbFEyaGhibTVsYkNBaFBUMGdYQ0oxYm1SbFptbHVaV1JjSWlrZ2UxeHVJQ0FnSUNBZ0lDQXZMeUJ0YjJSbGNtNGdZbkp2ZDNObGNuTmNiaUFnSUNBZ0lDQWdMeThnYUhSMGNEb3ZMM2QzZHk1dWIyNWliRzlqYTJsdVp5NXBieTh5TURFeEx6QTJMM2RwYm1SdmQyNWxlSFIwYVdOckxtaDBiV3hjYmlBZ0lDQWdJQ0FnZG1GeUlHTm9ZVzV1Wld3Z1BTQnVaWGNnVFdWemMyRm5aVU5vWVc1dVpXd29LVHRjYmlBZ0lDQWdJQ0FnTHk4Z1FYUWdiR1ZoYzNRZ1UyRm1ZWEpwSUZabGNuTnBiMjRnTmk0d0xqVWdLRGcxTXpZdU16QXVNU2tnYVc1MFpYSnRhWFIwWlc1MGJIa2dZMkZ1Ym05MElHTnlaV0YwWlZ4dUlDQWdJQ0FnSUNBdkx5QjNiM0pyYVc1bklHMWxjM05oWjJVZ2NHOXlkSE1nZEdobElHWnBjbk4wSUhScGJXVWdZU0J3WVdkbElHeHZZV1J6TGx4dUlDQWdJQ0FnSUNCamFHRnVibVZzTG5CdmNuUXhMbTl1YldWemMyRm5aU0E5SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhKbGNYVmxjM1JVYVdOcklEMGdjbVZ4ZFdWemRGQnZjblJVYVdOck8xeHVJQ0FnSUNBZ0lDQWdJQ0FnWTJoaGJtNWxiQzV3YjNKME1TNXZibTFsYzNOaFoyVWdQU0JtYkhWemFEdGNiaUFnSUNBZ0lDQWdJQ0FnSUdac2RYTm9LQ2s3WEc0Z0lDQWdJQ0FnSUgwN1hHNGdJQ0FnSUNBZ0lIWmhjaUJ5WlhGMVpYTjBVRzl5ZEZScFkyc2dQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0F2THlCUGNHVnlZU0J5WlhGMWFYSmxjeUIxY3lCMGJ5QndjbTkyYVdSbElHRWdiV1Z6YzJGblpTQndZWGxzYjJGa0xDQnlaV2RoY21Sc1pYTnpJRzltWEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUIzYUdWMGFHVnlJSGRsSUhWelpTQnBkQzVjYmlBZ0lDQWdJQ0FnSUNBZ0lHTm9ZVzV1Wld3dWNHOXlkREl1Y0c5emRFMWxjM05oWjJVb01DazdYRzRnSUNBZ0lDQWdJSDA3WEc0Z0lDQWdJQ0FnSUhKbGNYVmxjM1JVYVdOcklEMGdablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjMlYwVkdsdFpXOTFkQ2htYkhWemFDd2dNQ2s3WEc0Z0lDQWdJQ0FnSUNBZ0lDQnlaWEYxWlhOMFVHOXlkRlJwWTJzb0tUdGNiaUFnSUNBZ0lDQWdmVHRjYmx4dUlDQWdJSDBnWld4elpTQjdYRzRnSUNBZ0lDQWdJQzh2SUc5c1pDQmljbTkzYzJWeWMxeHVJQ0FnSUNBZ0lDQnlaWEYxWlhOMFZHbGpheUE5SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhObGRGUnBiV1Z2ZFhRb1pteDFjMmdzSURBcE8xeHVJQ0FnSUNBZ0lDQjlPMXh1SUNBZ0lIMWNiaUFnSUNBdkx5QnlkVzV6SUdFZ2RHRnpheUJoWm5SbGNpQmhiR3dnYjNSb1pYSWdkR0Z6YTNNZ2FHRjJaU0JpWldWdUlISjFibHh1SUNBZ0lDOHZJSFJvYVhNZ2FYTWdkWE5sWm5Wc0lHWnZjaUIxYm1oaGJtUnNaV1FnY21WcVpXTjBhVzl1SUhSeVlXTnJhVzVuSUhSb1lYUWdibVZsWkhNZ2RHOGdhR0Z3Y0dWdVhHNGdJQ0FnTHk4Z1lXWjBaWElnWVd4c0lHQjBhR1Z1WUdRZ2RHRnphM01nYUdGMlpTQmlaV1Z1SUhKMWJpNWNiaUFnSUNCdVpYaDBWR2xqYXk1eWRXNUJablJsY2lBOUlHWjFibU4wYVc5dUlDaDBZWE5yS1NCN1hHNGdJQ0FnSUNBZ0lHeGhkR1Z5VVhWbGRXVXVjSFZ6YUNoMFlYTnJLVHRjYmlBZ0lDQWdJQ0FnYVdZZ0tDRm1iSFZ6YUdsdVp5a2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ1pteDFjMmhwYm1jZ1BTQjBjblZsTzF4dUlDQWdJQ0FnSUNBZ0lDQWdjbVZ4ZFdWemRGUnBZMnNvS1R0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUgwN1hHNGdJQ0FnY21WMGRYSnVJRzVsZUhSVWFXTnJPMXh1ZlNrb0tUdGNibHh1THk4Z1FYUjBaVzF3ZENCMGJ5QnRZV3RsSUdkbGJtVnlhV056SUhOaFptVWdhVzRnZEdobElHWmhZMlVnYjJZZ1pHOTNibk4wY21WaGJWeHVMeThnYlc5a2FXWnBZMkYwYVc5dWN5NWNiaTh2SUZSb1pYSmxJR2x6SUc1dklITnBkSFZoZEdsdmJpQjNhR1Z5WlNCMGFHbHpJR2x6SUc1bFkyVnpjMkZ5ZVM1Y2JpOHZJRWxtSUhsdmRTQnVaV1ZrSUdFZ2MyVmpkWEpwZEhrZ1ozVmhjbUZ1ZEdWbExDQjBhR1Z6WlNCd2NtbHRiM0prYVdGc2N5QnVaV1ZrSUhSdklHSmxYRzR2THlCa1pXVndiSGtnWm5KdmVtVnVJR0Z1ZVhkaGVTd2dZVzVrSUdsbUlIbHZkU0JrYjI3aWdKbDBJRzVsWldRZ1lTQnpaV04xY21sMGVTQm5kV0Z5WVc1MFpXVXNYRzR2THlCMGFHbHpJR2x6SUdwMWMzUWdjR3hoYVc0Z2NHRnlZVzV2YVdRdVhHNHZMeUJJYjNkbGRtVnlMQ0IwYUdseklDb3FiV2xuYUhRcUtpQm9ZWFpsSUhSb1pTQnVhV05sSUhOcFpHVXRaV1ptWldOMElHOW1JSEpsWkhWamFXNW5JSFJvWlNCemFYcGxJRzltWEc0dkx5QjBhR1VnYldsdWFXWnBaV1FnWTI5a1pTQmllU0J5WldSMVkybHVaeUI0TG1OaGJHd29LU0IwYnlCdFpYSmxiSGtnZUNncFhHNHZMeUJUWldVZ1RXRnlheUJOYVd4c1pYTGlnSmx6SUdWNGNHeGhibUYwYVc5dUlHOW1JSGRvWVhRZ2RHaHBjeUJrYjJWekxseHVMeThnYUhSMGNEb3ZMM2RwYTJrdVpXTnRZWE5qY21sd2RDNXZjbWN2Wkc5cmRTNXdhSEEvYVdROVkyOXVkbVZ1ZEdsdmJuTTZjMkZtWlY5dFpYUmhYM0J5YjJkeVlXMXRhVzVuWEc1MllYSWdZMkZzYkNBOUlFWjFibU4wYVc5dUxtTmhiR3c3WEc1bWRXNWpkR2x2YmlCMWJtTjFjbko1VkdocGN5aG1LU0I3WEc0Z0lDQWdjbVYwZFhKdUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJR05oYkd3dVlYQndiSGtvWml3Z1lYSm5kVzFsYm5SektUdGNiaUFnSUNCOU8xeHVmVnh1THk4Z1ZHaHBjeUJwY3lCbGNYVnBkbUZzWlc1MExDQmlkWFFnYzJ4dmQyVnlPbHh1THk4Z2RXNWpkWEp5ZVZSb2FYTWdQU0JHZFc1amRHbHZibDlpYVc1a0xtSnBibVFvUm5WdVkzUnBiMjVmWW1sdVpDNWpZV3hzS1R0Y2JpOHZJR2gwZEhBNkx5OXFjM0JsY21ZdVkyOXRMM1Z1WTNWeWNubDBhR2x6WEc1Y2JuWmhjaUJoY25KaGVWOXpiR2xqWlNBOUlIVnVZM1Z5Y25sVWFHbHpLRUZ5Y21GNUxuQnliM1J2ZEhsd1pTNXpiR2xqWlNrN1hHNWNiblpoY2lCaGNuSmhlVjl5WldSMVkyVWdQU0IxYm1OMWNuSjVWR2hwY3loY2JpQWdJQ0JCY25KaGVTNXdjbTkwYjNSNWNHVXVjbVZrZFdObElIeDhJR1oxYm1OMGFXOXVJQ2hqWVd4c1ltRmpheXdnWW1GemFYTXBJSHRjYmlBZ0lDQWdJQ0FnZG1GeUlHbHVaR1Y0SUQwZ01DeGNiaUFnSUNBZ0lDQWdJQ0FnSUd4bGJtZDBhQ0E5SUhSb2FYTXViR1Z1WjNSb08xeHVJQ0FnSUNBZ0lDQXZMeUJqYjI1alpYSnVhVzVuSUhSb1pTQnBibWwwYVdGc0lIWmhiSFZsTENCcFppQnZibVVnYVhNZ2JtOTBJSEJ5YjNacFpHVmtYRzRnSUNBZ0lDQWdJR2xtSUNoaGNtZDFiV1Z1ZEhNdWJHVnVaM1JvSUQwOVBTQXhLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUJ6WldWcklIUnZJSFJvWlNCbWFYSnpkQ0IyWVd4MVpTQnBiaUIwYUdVZ1lYSnlZWGtzSUdGalkyOTFiblJwYm1kY2JpQWdJQ0FnSUNBZ0lDQWdJQzh2SUdadmNpQjBhR1VnY0c5emMybGlhV3hwZEhrZ2RHaGhkQ0JwY3lCcGN5QmhJSE53WVhKelpTQmhjbkpoZVZ4dUlDQWdJQ0FnSUNBZ0lDQWdaRzhnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUdsbUlDaHBibVJsZUNCcGJpQjBhR2x6S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJR0poYzJseklEMGdkR2hwYzF0cGJtUmxlQ3NyWFR0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdZbkpsWVdzN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHbG1JQ2dySzJsdVpHVjRJRDQ5SUd4bGJtZDBhQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjBhSEp2ZHlCdVpYY2dWSGx3WlVWeWNtOXlLQ2s3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNBZ0lDQWdmU0IzYUdsc1pTQW9NU2s3WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ0x5OGdjbVZrZFdObFhHNGdJQ0FnSUNBZ0lHWnZjaUFvT3lCcGJtUmxlQ0E4SUd4bGJtZDBhRHNnYVc1a1pYZ3JLeWtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdMeThnWVdOamIzVnVkQ0JtYjNJZ2RHaGxJSEJ2YzNOcFltbHNhWFI1SUhSb1lYUWdkR2hsSUdGeWNtRjVJR2x6SUhOd1lYSnpaVnh1SUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLR2x1WkdWNElHbHVJSFJvYVhNcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQmlZWE5wY3lBOUlHTmhiR3hpWVdOcktHSmhjMmx6TENCMGFHbHpXMmx1WkdWNFhTd2dhVzVrWlhncE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlCaVlYTnBjenRjYmlBZ0lDQjlYRzRwTzF4dVhHNTJZWElnWVhKeVlYbGZhVzVrWlhoUFppQTlJSFZ1WTNWeWNubFVhR2x6S0Z4dUlDQWdJRUZ5Y21GNUxuQnliM1J2ZEhsd1pTNXBibVJsZUU5bUlIeDhJR1oxYm1OMGFXOXVJQ2gyWVd4MVpTa2dlMXh1SUNBZ0lDQWdJQ0F2THlCdWIzUWdZU0IyWlhKNUlHZHZiMlFnYzJocGJTd2dZblYwSUdkdmIyUWdaVzV2ZFdkb0lHWnZjaUJ2ZFhJZ2IyNWxJSFZ6WlNCdlppQnBkRnh1SUNBZ0lDQWdJQ0JtYjNJZ0tIWmhjaUJwSUQwZ01Ec2dhU0E4SUhSb2FYTXViR1Z1WjNSb095QnBLeXNwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJR2xtSUNoMGFHbHpXMmxkSUQwOVBTQjJZV3gxWlNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lISmxkSFZ5YmlCcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlBdE1UdGNiaUFnSUNCOVhHNHBPMXh1WEc1MllYSWdZWEp5WVhsZmJXRndJRDBnZFc1amRYSnllVlJvYVhNb1hHNGdJQ0FnUVhKeVlYa3VjSEp2ZEc5MGVYQmxMbTFoY0NCOGZDQm1kVzVqZEdsdmJpQW9ZMkZzYkdKaFkyc3NJSFJvYVhOd0tTQjdYRzRnSUNBZ0lDQWdJSFpoY2lCelpXeG1JRDBnZEdocGN6dGNiaUFnSUNBZ0lDQWdkbUZ5SUdOdmJHeGxZM1FnUFNCYlhUdGNiaUFnSUNBZ0lDQWdZWEp5WVhsZmNtVmtkV05sS0hObGJHWXNJR1oxYm1OMGFXOXVJQ2gxYm1SbFptbHVaV1FzSUhaaGJIVmxMQ0JwYm1SbGVDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ1kyOXNiR1ZqZEM1d2RYTm9LR05oYkd4aVlXTnJMbU5oYkd3b2RHaHBjM0FzSUhaaGJIVmxMQ0JwYm1SbGVDd2djMlZzWmlrcE8xeHVJQ0FnSUNBZ0lDQjlMQ0IyYjJsa0lEQXBPMXh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdZMjlzYkdWamREdGNiaUFnSUNCOVhHNHBPMXh1WEc1MllYSWdiMkpxWldOMFgyTnlaV0YwWlNBOUlFOWlhbVZqZEM1amNtVmhkR1VnZkh3Z1puVnVZM1JwYjI0Z0tIQnliM1J2ZEhsd1pTa2dlMXh1SUNBZ0lHWjFibU4wYVc5dUlGUjVjR1VvS1NCN0lIMWNiaUFnSUNCVWVYQmxMbkJ5YjNSdmRIbHdaU0E5SUhCeWIzUnZkSGx3WlR0Y2JpQWdJQ0J5WlhSMWNtNGdibVYzSUZSNWNHVW9LVHRjYm4wN1hHNWNiblpoY2lCdlltcGxZM1JmYUdGelQzZHVVSEp2Y0dWeWRIa2dQU0IxYm1OMWNuSjVWR2hwY3loUFltcGxZM1F1Y0hKdmRHOTBlWEJsTG1oaGMwOTNibEJ5YjNCbGNuUjVLVHRjYmx4dWRtRnlJRzlpYW1WamRGOXJaWGx6SUQwZ1QySnFaV04wTG10bGVYTWdmSHdnWm5WdVkzUnBiMjRnS0c5aWFtVmpkQ2tnZTF4dUlDQWdJSFpoY2lCclpYbHpJRDBnVzEwN1hHNGdJQ0FnWm05eUlDaDJZWElnYTJWNUlHbHVJRzlpYW1WamRDa2dlMXh1SUNBZ0lDQWdJQ0JwWmlBb2IySnFaV04wWDJoaGMwOTNibEJ5YjNCbGNuUjVLRzlpYW1WamRDd2dhMlY1S1NrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnYTJWNWN5NXdkWE5vS0d0bGVTazdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQjlYRzRnSUNBZ2NtVjBkWEp1SUd0bGVYTTdYRzU5TzF4dVhHNTJZWElnYjJKcVpXTjBYM1J2VTNSeWFXNW5JRDBnZFc1amRYSnllVlJvYVhNb1QySnFaV04wTG5CeWIzUnZkSGx3WlM1MGIxTjBjbWx1WnlrN1hHNWNibVoxYm1OMGFXOXVJR2x6VDJKcVpXTjBLSFpoYkhWbEtTQjdYRzRnSUNBZ2NtVjBkWEp1SUhaaGJIVmxJRDA5UFNCUFltcGxZM1FvZG1Gc2RXVXBPMXh1ZlZ4dVhHNHZMeUJuWlc1bGNtRjBiM0lnY21Wc1lYUmxaQ0J6YUdsdGMxeHVYRzR2THlCR1NWaE5SVG9nVW1WdGIzWmxJSFJvYVhNZ1puVnVZM1JwYjI0Z2IyNWpaU0JGVXpZZ1oyVnVaWEpoZEc5eWN5QmhjbVVnYVc0Z1UzQnBaR1Z5VFc5dWEyVjVMbHh1Wm5WdVkzUnBiMjRnYVhOVGRHOXdTWFJsY21GMGFXOXVLR1Y0WTJWd2RHbHZiaWtnZTF4dUlDQWdJSEpsZEhWeWJpQW9YRzRnSUNBZ0lDQWdJRzlpYW1WamRGOTBiMU4wY21sdVp5aGxlR05sY0hScGIyNHBJRDA5UFNCY0lsdHZZbXBsWTNRZ1UzUnZjRWwwWlhKaGRHbHZibDFjSWlCOGZGeHVJQ0FnSUNBZ0lDQmxlR05sY0hScGIyNGdhVzV6ZEdGdVkyVnZaaUJSVW1WMGRYSnVWbUZzZFdWY2JpQWdJQ0FwTzF4dWZWeHVYRzR2THlCR1NWaE5SVG9nVW1WdGIzWmxJSFJvYVhNZ2FHVnNjR1Z5SUdGdVpDQlJMbkpsZEhWeWJpQnZibU5sSUVWVE5pQm5aVzVsY21GMGIzSnpJR0Z5WlNCcGJseHVMeThnVTNCcFpHVnlUVzl1YTJWNUxseHVkbUZ5SUZGU1pYUjFjbTVXWVd4MVpUdGNibWxtSUNoMGVYQmxiMllnVW1WMGRYSnVWbUZzZFdVZ0lUMDlJRndpZFc1a1pXWnBibVZrWENJcElIdGNiaUFnSUNCUlVtVjBkWEp1Vm1Gc2RXVWdQU0JTWlhSMWNtNVdZV3gxWlR0Y2JuMGdaV3h6WlNCN1hHNGdJQ0FnVVZKbGRIVnlibFpoYkhWbElEMGdablZ1WTNScGIyNGdLSFpoYkhWbEtTQjdYRzRnSUNBZ0lDQWdJSFJvYVhNdWRtRnNkV1VnUFNCMllXeDFaVHRjYmlBZ0lDQjlPMXh1ZlZ4dVhHNHZMeUJzYjI1bklITjBZV05ySUhSeVlXTmxjMXh1WEc1MllYSWdVMVJCUTB0ZlNsVk5VRjlUUlZCQlVrRlVUMUlnUFNCY0lrWnliMjBnY0hKbGRtbHZkWE1nWlhabGJuUTZYQ0k3WEc1Y2JtWjFibU4wYVc5dUlHMWhhMlZUZEdGamExUnlZV05sVEc5dVp5aGxjbkp2Y2l3Z2NISnZiV2x6WlNrZ2UxeHVJQ0FnSUM4dklFbG1JSEJ2YzNOcFlteGxMQ0IwY21GdWMyWnZjbTBnZEdobElHVnljbTl5SUhOMFlXTnJJSFJ5WVdObElHSjVJSEpsYlc5MmFXNW5JRTV2WkdVZ1lXNWtJRkZjYmlBZ0lDQXZMeUJqY25WbWRDd2dkR2hsYmlCamIyNWpZWFJsYm1GMGFXNW5JSGRwZEdnZ2RHaGxJSE4wWVdOcklIUnlZV05sSUc5bUlHQndjbTl0YVhObFlDNGdVMlZsSUNNMU55NWNiaUFnSUNCcFppQW9hR0Z6VTNSaFkydHpJQ1ltWEc0Z0lDQWdJQ0FnSUhCeWIyMXBjMlV1YzNSaFkyc2dKaVpjYmlBZ0lDQWdJQ0FnZEhsd1pXOW1JR1Z5Y205eUlEMDlQU0JjSW05aWFtVmpkRndpSUNZbVhHNGdJQ0FnSUNBZ0lHVnljbTl5SUNFOVBTQnVkV3hzSUNZbVhHNGdJQ0FnSUNBZ0lHVnljbTl5TG5OMFlXTnJJQ1ltWEc0Z0lDQWdJQ0FnSUdWeWNtOXlMbk4wWVdOckxtbHVaR1Y0VDJZb1UxUkJRMHRmU2xWTlVGOVRSVkJCVWtGVVQxSXBJRDA5UFNBdE1WeHVJQ0FnSUNrZ2UxeHVJQ0FnSUNBZ0lDQjJZWElnYzNSaFkydHpJRDBnVzEwN1hHNGdJQ0FnSUNBZ0lHWnZjaUFvZG1GeUlIQWdQU0J3Y205dGFYTmxPeUFoSVhBN0lIQWdQU0J3TG5OdmRYSmpaU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdhV1lnS0hBdWMzUmhZMnNwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCemRHRmphM011ZFc1emFHbG1kQ2h3TG5OMFlXTnJLVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIMWNiaUFnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0J6ZEdGamEzTXVkVzV6YUdsbWRDaGxjbkp2Y2k1emRHRmpheWs3WEc1Y2JpQWdJQ0FnSUNBZ2RtRnlJR052Ym1OaGRHVmtVM1JoWTJ0eklEMGdjM1JoWTJ0ekxtcHZhVzRvWENKY1hHNWNJaUFySUZOVVFVTkxYMHBWVFZCZlUwVlFRVkpCVkU5U0lDc2dYQ0pjWEc1Y0lpazdYRzRnSUNBZ0lDQWdJR1Z5Y205eUxuTjBZV05ySUQwZ1ptbHNkR1Z5VTNSaFkydFRkSEpwYm1jb1kyOXVZMkYwWldSVGRHRmphM01wTzF4dUlDQWdJSDFjYm4xY2JseHVablZ1WTNScGIyNGdabWxzZEdWeVUzUmhZMnRUZEhKcGJtY29jM1JoWTJ0VGRISnBibWNwSUh0Y2JpQWdJQ0IyWVhJZ2JHbHVaWE1nUFNCemRHRmphMU4wY21sdVp5NXpjR3hwZENoY0lseGNibHdpS1R0Y2JpQWdJQ0IyWVhJZ1pHVnphWEpsWkV4cGJtVnpJRDBnVzEwN1hHNGdJQ0FnWm05eUlDaDJZWElnYVNBOUlEQTdJR2tnUENCc2FXNWxjeTVzWlc1bmRHZzdJQ3NyYVNrZ2UxeHVJQ0FnSUNBZ0lDQjJZWElnYkdsdVpTQTlJR3hwYm1WelcybGRPMXh1WEc0Z0lDQWdJQ0FnSUdsbUlDZ2hhWE5KYm5SbGNtNWhiRVp5WVcxbEtHeHBibVVwSUNZbUlDRnBjMDV2WkdWR2NtRnRaU2hzYVc1bEtTQW1KaUJzYVc1bEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCa1pYTnBjbVZrVEdsdVpYTXVjSFZ6YUNoc2FXNWxLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJSDFjYmlBZ0lDQnlaWFIxY200Z1pHVnphWEpsWkV4cGJtVnpMbXB2YVc0b1hDSmNYRzVjSWlrN1hHNTlYRzVjYm1aMWJtTjBhVzl1SUdselRtOWtaVVp5WVcxbEtITjBZV05yVEdsdVpTa2dlMXh1SUNBZ0lISmxkSFZ5YmlCemRHRmphMHhwYm1VdWFXNWtaWGhQWmloY0lpaHRiMlIxYkdVdWFuTTZYQ0lwSUNFOVBTQXRNU0I4ZkZ4dUlDQWdJQ0FnSUNBZ0lDQnpkR0ZqYTB4cGJtVXVhVzVrWlhoUFppaGNJaWh1YjJSbExtcHpPbHdpS1NBaFBUMGdMVEU3WEc1OVhHNWNibVoxYm1OMGFXOXVJR2RsZEVacGJHVk9ZVzFsUVc1a1RHbHVaVTUxYldKbGNpaHpkR0ZqYTB4cGJtVXBJSHRjYmlBZ0lDQXZMeUJPWVcxbFpDQm1kVzVqZEdsdmJuTTZJRndpWVhRZ1puVnVZM1JwYjI1T1lXMWxJQ2htYVd4bGJtRnRaVHBzYVc1bFRuVnRZbVZ5T21OdmJIVnRiazUxYldKbGNpbGNJbHh1SUNBZ0lDOHZJRWx1SUVsRk1UQWdablZ1WTNScGIyNGdibUZ0WlNCallXNGdhR0YyWlNCemNHRmpaWE1nS0Z3aVFXNXZibmx0YjNWeklHWjFibU4wYVc5dVhDSXBJRTlmYjF4dUlDQWdJSFpoY2lCaGRIUmxiWEIwTVNBOUlDOWhkQ0F1S3lCY1hDZ29MaXNwT2loY1hHUXJLVG9vUHpwY1hHUXJLVnhjS1NRdkxtVjRaV01vYzNSaFkydE1hVzVsS1R0Y2JpQWdJQ0JwWmlBb1lYUjBaVzF3ZERFcElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlGdGhkSFJsYlhCME1Wc3hYU3dnVG5WdFltVnlLR0YwZEdWdGNIUXhXekpkS1YwN1hHNGdJQ0FnZlZ4dVhHNGdJQ0FnTHk4Z1FXNXZibmx0YjNWeklHWjFibU4wYVc5dWN6b2dYQ0poZENCbWFXeGxibUZ0WlRwc2FXNWxUblZ0WW1WeU9tTnZiSFZ0Yms1MWJXSmxjbHdpWEc0Z0lDQWdkbUZ5SUdGMGRHVnRjSFF5SUQwZ0wyRjBJQ2hiWGlCZEt5azZLRnhjWkNzcE9pZy9PbHhjWkNzcEpDOHVaWGhsWXloemRHRmphMHhwYm1VcE8xeHVJQ0FnSUdsbUlDaGhkSFJsYlhCME1pa2dlMXh1SUNBZ0lDQWdJQ0J5WlhSMWNtNGdXMkYwZEdWdGNIUXlXekZkTENCT2RXMWlaWElvWVhSMFpXMXdkREpiTWwwcFhUdGNiaUFnSUNCOVhHNWNiaUFnSUNBdkx5QkdhWEpsWm05NElITjBlV3hsT2lCY0ltWjFibU4wYVc5dVFHWnBiR1Z1WVcxbE9teHBibVZPZFcxaVpYSWdiM0lnUUdacGJHVnVZVzFsT214cGJtVk9kVzFpWlhKY0lseHVJQ0FnSUhaaGNpQmhkSFJsYlhCME15QTlJQzh1S2tBb0xpc3BPaWhjWEdRcktTUXZMbVY0WldNb2MzUmhZMnRNYVc1bEtUdGNiaUFnSUNCcFppQW9ZWFIwWlcxd2RETXBJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJRnRoZEhSbGJYQjBNMXN4WFN3Z1RuVnRZbVZ5S0dGMGRHVnRjSFF6V3pKZEtWMDdYRzRnSUNBZ2ZWeHVmVnh1WEc1bWRXNWpkR2x2YmlCcGMwbHVkR1Z5Ym1Gc1JuSmhiV1VvYzNSaFkydE1hVzVsS1NCN1hHNGdJQ0FnZG1GeUlHWnBiR1ZPWVcxbFFXNWtUR2x1WlU1MWJXSmxjaUE5SUdkbGRFWnBiR1ZPWVcxbFFXNWtUR2x1WlU1MWJXSmxjaWh6ZEdGamEweHBibVVwTzF4dVhHNGdJQ0FnYVdZZ0tDRm1hV3hsVG1GdFpVRnVaRXhwYm1WT2RXMWlaWElwSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUdaaGJITmxPMXh1SUNBZ0lIMWNibHh1SUNBZ0lIWmhjaUJtYVd4bFRtRnRaU0E5SUdacGJHVk9ZVzFsUVc1a1RHbHVaVTUxYldKbGNsc3dYVHRjYmlBZ0lDQjJZWElnYkdsdVpVNTFiV0psY2lBOUlHWnBiR1ZPWVcxbFFXNWtUR2x1WlU1MWJXSmxjbHN4WFR0Y2JseHVJQ0FnSUhKbGRIVnliaUJtYVd4bFRtRnRaU0E5UFQwZ2NVWnBiR1ZPWVcxbElDWW1YRzRnSUNBZ0lDQWdJR3hwYm1WT2RXMWlaWElnUGowZ2NWTjBZWEowYVc1blRHbHVaU0FtSmx4dUlDQWdJQ0FnSUNCc2FXNWxUblZ0WW1WeUlEdzlJSEZGYm1ScGJtZE1hVzVsTzF4dWZWeHVYRzR2THlCa2FYTmpiM1psY2lCdmQyNGdabWxzWlNCdVlXMWxJR0Z1WkNCc2FXNWxJRzUxYldKbGNpQnlZVzVuWlNCbWIzSWdabWxzZEdWeWFXNW5JSE4wWVdOclhHNHZMeUIwY21GalpYTmNibVoxYm1OMGFXOXVJR05oY0hSMWNtVk1hVzVsS0NrZ2UxeHVJQ0FnSUdsbUlDZ2hhR0Z6VTNSaFkydHpLU0I3WEc0Z0lDQWdJQ0FnSUhKbGRIVnlianRjYmlBZ0lDQjlYRzVjYmlBZ0lDQjBjbmtnZTF4dUlDQWdJQ0FnSUNCMGFISnZkeUJ1WlhjZ1JYSnliM0lvS1R0Y2JpQWdJQ0I5SUdOaGRHTm9JQ2hsS1NCN1hHNGdJQ0FnSUNBZ0lIWmhjaUJzYVc1bGN5QTlJR1V1YzNSaFkyc3VjM0JzYVhRb1hDSmNYRzVjSWlrN1hHNGdJQ0FnSUNBZ0lIWmhjaUJtYVhKemRFeHBibVVnUFNCc2FXNWxjMXN3WFM1cGJtUmxlRTltS0Z3aVFGd2lLU0ErSURBZ1B5QnNhVzVsYzFzeFhTQTZJR3hwYm1Weld6SmRPMXh1SUNBZ0lDQWdJQ0IyWVhJZ1ptbHNaVTVoYldWQmJtUk1hVzVsVG5WdFltVnlJRDBnWjJWMFJtbHNaVTVoYldWQmJtUk1hVzVsVG5WdFltVnlLR1pwY25OMFRHbHVaU2s3WEc0Z0lDQWdJQ0FnSUdsbUlDZ2habWxzWlU1aGJXVkJibVJNYVc1bFRuVnRZbVZ5S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNDdYRzRnSUNBZ0lDQWdJSDFjYmx4dUlDQWdJQ0FnSUNCeFJtbHNaVTVoYldVZ1BTQm1hV3hsVG1GdFpVRnVaRXhwYm1WT2RXMWlaWEpiTUYwN1hHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlCbWFXeGxUbUZ0WlVGdVpFeHBibVZPZFcxaVpYSmJNVjA3WEc0Z0lDQWdmVnh1ZlZ4dVhHNW1kVzVqZEdsdmJpQmtaWEJ5WldOaGRHVW9ZMkZzYkdKaFkyc3NJRzVoYldVc0lHRnNkR1Z5Ym1GMGFYWmxLU0I3WEc0Z0lDQWdjbVYwZFhKdUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnYVdZZ0tIUjVjR1Z2WmlCamIyNXpiMnhsSUNFOVBTQmNJblZ1WkdWbWFXNWxaRndpSUNZbVhHNGdJQ0FnSUNBZ0lDQWdJQ0IwZVhCbGIyWWdZMjl1YzI5c1pTNTNZWEp1SUQwOVBTQmNJbVoxYm1OMGFXOXVYQ0lwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJR052Ym5OdmJHVXVkMkZ5YmlodVlXMWxJQ3NnWENJZ2FYTWdaR1Z3Y21WallYUmxaQ3dnZFhObElGd2lJQ3NnWVd4MFpYSnVZWFJwZG1VZ0sxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lGd2lJR2x1YzNSbFlXUXVYQ0lzSUc1bGR5QkZjbkp2Y2loY0lsd2lLUzV6ZEdGamF5azdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJR05oYkd4aVlXTnJMbUZ3Y0d4NUtHTmhiR3hpWVdOckxDQmhjbWQxYldWdWRITXBPMXh1SUNBZ0lIMDdYRzU5WEc1Y2JpOHZJR1Z1WkNCdlppQnphR2x0YzF4dUx5OGdZbVZuYVc1dWFXNW5JRzltSUhKbFlXd2dkMjl5YTF4dVhHNHZLaXBjYmlBcUlFTnZibk4wY25WamRITWdZU0J3Y205dGFYTmxJR1p2Y2lCaGJpQnBiVzFsWkdsaGRHVWdjbVZtWlhKbGJtTmxMQ0J3WVhOelpYTWdjSEp2YldselpYTWdkR2h5YjNWbmFDd2diM0pjYmlBcUlHTnZaWEpqWlhNZ2NISnZiV2x6WlhNZ1puSnZiU0JrYVdabVpYSmxiblFnYzNsemRHVnRjeTVjYmlBcUlFQndZWEpoYlNCMllXeDFaU0JwYlcxbFpHbGhkR1VnY21WbVpYSmxibU5sSUc5eUlIQnliMjFwYzJWY2JpQXFMMXh1Wm5WdVkzUnBiMjRnVVNoMllXeDFaU2tnZTF4dUlDQWdJQzh2SUVsbUlIUm9aU0J2WW1wbFkzUWdhWE1nWVd4eVpXRmtlU0JoSUZCeWIyMXBjMlVzSUhKbGRIVnliaUJwZENCa2FYSmxZM1JzZVM0Z0lGUm9hWE1nWlc1aFlteGxjMXh1SUNBZ0lDOHZJSFJvWlNCeVpYTnZiSFpsSUdaMWJtTjBhVzl1SUhSdklHSnZkR2dnWW1VZ2RYTmxaQ0IwYnlCamNtVmhkR1ZrSUhKbFptVnlaVzVqWlhNZ1puSnZiU0J2WW1wbFkzUnpMRnh1SUNBZ0lDOHZJR0oxZENCMGJ5QjBiMnhsY21GaWJIa2dZMjlsY21ObElHNXZiaTF3Y205dGFYTmxjeUIwYnlCd2NtOXRhWE5sY3k1Y2JpQWdJQ0JwWmlBb2RtRnNkV1VnYVc1emRHRnVZMlZ2WmlCUWNtOXRhWE5sS1NCN1hHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlCMllXeDFaVHRjYmlBZ0lDQjlYRzVjYmlBZ0lDQXZMeUJoYzNOcGJXbHNZWFJsSUhSb1pXNWhZbXhsYzF4dUlDQWdJR2xtSUNocGMxQnliMjFwYzJWQmJHbHJaU2gyWVd4MVpTa3BJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJR052WlhKalpTaDJZV3gxWlNrN1hHNGdJQ0FnZlNCbGJITmxJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJR1oxYkdacGJHd29kbUZzZFdVcE8xeHVJQ0FnSUgxY2JuMWNibEV1Y21WemIyeDJaU0E5SUZFN1hHNWNiaThxS2x4dUlDb2dVR1Z5Wm05eWJYTWdZU0IwWVhOcklHbHVJR0VnWm5WMGRYSmxJSFIxY200Z2IyWWdkR2hsSUdWMlpXNTBJR3h2YjNBdVhHNGdLaUJBY0dGeVlXMGdlMFoxYm1OMGFXOXVmU0IwWVhOclhHNGdLaTljYmxFdWJtVjRkRlJwWTJzZ1BTQnVaWGgwVkdsamF6dGNibHh1THlvcVhHNGdLaUJEYjI1MGNtOXNjeUIzYUdWMGFHVnlJRzl5SUc1dmRDQnNiMjVuSUhOMFlXTnJJSFJ5WVdObGN5QjNhV3hzSUdKbElHOXVYRzRnS2k5Y2JsRXViRzl1WjFOMFlXTnJVM1Z3Y0c5eWRDQTlJR1poYkhObE8xeHVYRzR2THlCbGJtRmliR1VnYkc5dVp5QnpkR0ZqYTNNZ2FXWWdVVjlFUlVKVlJ5QnBjeUJ6WlhSY2JtbG1JQ2gwZVhCbGIyWWdjSEp2WTJWemN5QTlQVDBnWENKdlltcGxZM1JjSWlBbUppQndjbTlqWlhOeklDWW1JSEJ5YjJObGMzTXVaVzUySUNZbUlIQnliMk5sYzNNdVpXNTJMbEZmUkVWQ1ZVY3BJSHRjYmlBZ0lDQlJMbXh2Ym1kVGRHRmphMU4xY0hCdmNuUWdQU0IwY25WbE8xeHVmVnh1WEc0dktpcGNiaUFxSUVOdmJuTjBjblZqZEhNZ1lTQjdjSEp2YldselpTd2djbVZ6YjJ4MlpTd2djbVZxWldOMGZTQnZZbXBsWTNRdVhHNGdLbHh1SUNvZ1lISmxjMjlzZG1WZ0lHbHpJR0VnWTJGc2JHSmhZMnNnZEc4Z2FXNTJiMnRsSUhkcGRHZ2dZU0J0YjNKbElISmxjMjlzZG1Wa0lIWmhiSFZsSUdadmNpQjBhR1ZjYmlBcUlIQnliMjFwYzJVdUlGUnZJR1oxYkdacGJHd2dkR2hsSUhCeWIyMXBjMlVzSUdsdWRtOXJaU0JnY21WemIyeDJaV0FnZDJsMGFDQmhibmtnZG1Gc2RXVWdkR2hoZENCcGMxeHVJQ29nYm05MElHRWdkR2hsYm1GaWJHVXVJRlJ2SUhKbGFtVmpkQ0IwYUdVZ2NISnZiV2x6WlN3Z2FXNTJiMnRsSUdCeVpYTnZiSFpsWUNCM2FYUm9JR0VnY21WcVpXTjBaV1JjYmlBcUlIUm9aVzVoWW14bExDQnZjaUJwYm5admEyVWdZSEpsYW1WamRHQWdkMmwwYUNCMGFHVWdjbVZoYzI5dUlHUnBjbVZqZEd4NUxpQlVieUJ5WlhOdmJIWmxJSFJvWlZ4dUlDb2djSEp2YldselpTQjBieUJoYm05MGFHVnlJSFJvWlc1aFlteGxMQ0IwYUhWeklIQjFkSFJwYm1jZ2FYUWdhVzRnZEdobElITmhiV1VnYzNSaGRHVXNJR2x1ZG05clpWeHVJQ29nWUhKbGMyOXNkbVZnSUhkcGRHZ2dkR2hoZENCdmRHaGxjaUIwYUdWdVlXSnNaUzVjYmlBcUwxeHVVUzVrWldabGNpQTlJR1JsWm1WeU8xeHVablZ1WTNScGIyNGdaR1ZtWlhJb0tTQjdYRzRnSUNBZ0x5OGdhV1lnWENKdFpYTnpZV2RsYzF3aUlHbHpJR0Z1SUZ3aVFYSnlZWGxjSWl3Z2RHaGhkQ0JwYm1ScFkyRjBaWE1nZEdoaGRDQjBhR1VnY0hKdmJXbHpaU0JvWVhNZ2JtOTBJSGxsZEZ4dUlDQWdJQzh2SUdKbFpXNGdjbVZ6YjJ4MlpXUXVJQ0JKWmlCcGRDQnBjeUJjSW5WdVpHVm1hVzVsWkZ3aUxDQnBkQ0JvWVhNZ1ltVmxiaUJ5WlhOdmJIWmxaQzRnSUVWaFkyaGNiaUFnSUNBdkx5QmxiR1Z0Wlc1MElHOW1JSFJvWlNCdFpYTnpZV2RsY3lCaGNuSmhlU0JwY3lCcGRITmxiR1lnWVc0Z1lYSnlZWGtnYjJZZ1kyOXRjR3hsZEdVZ1lYSm5kVzFsYm5SeklIUnZYRzRnSUNBZ0x5OGdabTl5ZDJGeVpDQjBieUIwYUdVZ2NtVnpiMngyWldRZ2NISnZiV2x6WlM0Z0lGZGxJR052WlhKalpTQjBhR1VnY21WemIyeDFkR2x2YmlCMllXeDFaU0IwYnlCaFhHNGdJQ0FnTHk4Z2NISnZiV2x6WlNCMWMybHVaeUIwYUdVZ1lISmxjMjlzZG1WZ0lHWjFibU4wYVc5dUlHSmxZMkYxYzJVZ2FYUWdhR0Z1Wkd4bGN5QmliM1JvSUdaMWJHeDVYRzRnSUNBZ0x5OGdibTl1TFhSb1pXNWhZbXhsSUhaaGJIVmxjeUJoYm1RZ2IzUm9aWElnZEdobGJtRmliR1Z6SUdkeVlXTmxablZzYkhrdVhHNGdJQ0FnZG1GeUlHMWxjM05oWjJWeklEMGdXMTBzSUhCeWIyZHlaWE56VEdsemRHVnVaWEp6SUQwZ1cxMHNJSEpsYzI5c2RtVmtVSEp2YldselpUdGNibHh1SUNBZ0lIWmhjaUJrWldabGNuSmxaQ0E5SUc5aWFtVmpkRjlqY21WaGRHVW9aR1ZtWlhJdWNISnZkRzkwZVhCbEtUdGNiaUFnSUNCMllYSWdjSEp2YldselpTQTlJRzlpYW1WamRGOWpjbVZoZEdVb1VISnZiV2x6WlM1d2NtOTBiM1I1Y0dVcE8xeHVYRzRnSUNBZ2NISnZiV2x6WlM1d2NtOXRhWE5sUkdsemNHRjBZMmdnUFNCbWRXNWpkR2x2YmlBb2NtVnpiMngyWlN3Z2IzQXNJRzl3WlhKaGJtUnpLU0I3WEc0Z0lDQWdJQ0FnSUhaaGNpQmhjbWR6SUQwZ1lYSnlZWGxmYzJ4cFkyVW9ZWEpuZFcxbGJuUnpLVHRjYmlBZ0lDQWdJQ0FnYVdZZ0tHMWxjM05oWjJWektTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCdFpYTnpZV2RsY3k1d2RYTm9LR0Z5WjNNcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnYVdZZ0tHOXdJRDA5UFNCY0luZG9aVzVjSWlBbUppQnZjR1Z5WVc1a2Mxc3hYU2tnZXlBdkx5QndjbTluY21WemN5QnZjR1Z5WVc1a1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2NISnZaM0psYzNOTWFYTjBaVzVsY25NdWNIVnphQ2h2Y0dWeVlXNWtjMXN4WFNrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUgwZ1pXeHpaU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQlJMbTVsZUhSVWFXTnJLR1oxYm1OMGFXOXVJQ2dwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCeVpYTnZiSFpsWkZCeWIyMXBjMlV1Y0hKdmJXbHpaVVJwYzNCaGRHTm9MbUZ3Y0d4NUtISmxjMjlzZG1Wa1VISnZiV2x6WlN3Z1lYSm5jeWs3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjlLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJSDA3WEc1Y2JpQWdJQ0F2THlCWVdGZ2daR1Z3Y21WallYUmxaRnh1SUNBZ0lIQnliMjFwYzJVdWRtRnNkV1ZQWmlBOUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnYVdZZ0tHMWxjM05oWjJWektTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCeVpYUjFjbTRnY0hKdmJXbHpaVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCMllYSWdibVZoY21WeVZtRnNkV1VnUFNCdVpXRnlaWElvY21WemIyeDJaV1JRY205dGFYTmxLVHRjYmlBZ0lDQWdJQ0FnYVdZZ0tHbHpVSEp2YldselpTaHVaV0Z5WlhKV1lXeDFaU2twSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEpsYzI5c2RtVmtVSEp2YldselpTQTlJRzVsWVhKbGNsWmhiSFZsT3lBdkx5QnphRzl5ZEdWdUlHTm9ZV2x1WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUc1bFlYSmxjbFpoYkhWbE8xeHVJQ0FnSUgwN1hHNWNiaUFnSUNCd2NtOXRhWE5sTG1sdWMzQmxZM1FnUFNCbWRXNWpkR2x2YmlBb0tTQjdYRzRnSUNBZ0lDQWdJR2xtSUNnaGNtVnpiMngyWldSUWNtOXRhWE5sS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNGdleUJ6ZEdGMFpUb2dYQ0p3Wlc1a2FXNW5YQ0lnZlR0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQnlaWFIxY200Z2NtVnpiMngyWldSUWNtOXRhWE5sTG1sdWMzQmxZM1FvS1R0Y2JpQWdJQ0I5TzF4dVhHNGdJQ0FnYVdZZ0tGRXViRzl1WjFOMFlXTnJVM1Z3Y0c5eWRDQW1KaUJvWVhOVGRHRmphM01wSUh0Y2JpQWdJQ0FnSUNBZ2RISjVJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIUm9jbTkzSUc1bGR5QkZjbkp2Y2lncE8xeHVJQ0FnSUNBZ0lDQjlJR05oZEdOb0lDaGxLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUJPVDFSRk9pQmtiMjRuZENCMGNua2dkRzhnZFhObElHQkZjbkp2Y2k1allYQjBkWEpsVTNSaFkydFVjbUZqWldBZ2IzSWdkSEpoYm5ObVpYSWdkR2hsWEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUJoWTJObGMzTnZjaUJoY205MWJtUTdJSFJvWVhRZ1kyRjFjMlZ6SUcxbGJXOXllU0JzWldGcmN5QmhjeUJ3WlhJZ1IwZ3RNVEV4TGlCS2RYTjBYRzRnSUNBZ0lDQWdJQ0FnSUNBdkx5QnlaV2xtZVNCMGFHVWdjM1JoWTJzZ2RISmhZMlVnWVhNZ1lTQnpkSEpwYm1jZ1FWTkJVQzVjYmlBZ0lDQWdJQ0FnSUNBZ0lDOHZYRzRnSUNBZ0lDQWdJQ0FnSUNBdkx5QkJkQ0IwYUdVZ2MyRnRaU0IwYVcxbExDQmpkWFFnYjJabUlIUm9aU0JtYVhKemRDQnNhVzVsT3lCcGRDZHpJR0ZzZDJGNWN5QnFkWE4wWEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUJjSWx0dlltcGxZM1FnVUhKdmJXbHpaVjFjWEc1Y0lpd2dZWE1nY0dWeUlIUm9aU0JnZEc5VGRISnBibWRnTGx4dUlDQWdJQ0FnSUNBZ0lDQWdjSEp2YldselpTNXpkR0ZqYXlBOUlHVXVjM1JoWTJzdWMzVmljM1J5YVc1bktHVXVjM1JoWTJzdWFXNWtaWGhQWmloY0lseGNibHdpS1NBcklERXBPMXh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdmVnh1WEc0Z0lDQWdMeThnVGs5VVJUb2dkMlVnWkc4Z2RHaGxJR05vWldOcmN5Qm1iM0lnWUhKbGMyOXNkbVZrVUhKdmJXbHpaV0FnYVc0Z1pXRmphQ0J0WlhSb2IyUXNJR2x1YzNSbFlXUWdiMlpjYmlBZ0lDQXZMeUJqYjI1emIyeHBaR0YwYVc1bklIUm9aVzBnYVc1MGJ5QmdZbVZqYjIxbFlDd2djMmx1WTJVZ2IzUm9aWEozYVhObElIZGxKMlFnWTNKbFlYUmxJRzVsZDF4dUlDQWdJQzh2SUhCeWIyMXBjMlZ6SUhkcGRHZ2dkR2hsSUd4cGJtVnpJR0JpWldOdmJXVW9kMmhoZEdWMlpYSW9kbUZzZFdVcEtXQXVJRk5sWlNCbExtY3VJRWRJTFRJMU1pNWNibHh1SUNBZ0lHWjFibU4wYVc5dUlHSmxZMjl0WlNodVpYZFFjbTl0YVhObEtTQjdYRzRnSUNBZ0lDQWdJSEpsYzI5c2RtVmtVSEp2YldselpTQTlJRzVsZDFCeWIyMXBjMlU3WEc0Z0lDQWdJQ0FnSUhCeWIyMXBjMlV1YzI5MWNtTmxJRDBnYm1WM1VISnZiV2x6WlR0Y2JseHVJQ0FnSUNBZ0lDQmhjbkpoZVY5eVpXUjFZMlVvYldWemMyRm5aWE1zSUdaMWJtTjBhVzl1SUNoMWJtUmxabWx1WldRc0lHMWxjM05oWjJVcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUZFdWJtVjRkRlJwWTJzb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJRzVsZDFCeWIyMXBjMlV1Y0hKdmJXbHpaVVJwYzNCaGRHTm9MbUZ3Y0d4NUtHNWxkMUJ5YjIxcGMyVXNJRzFsYzNOaFoyVXBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZTazdYRzRnSUNBZ0lDQWdJSDBzSUhadmFXUWdNQ2s3WEc1Y2JpQWdJQ0FnSUNBZ2JXVnpjMkZuWlhNZ1BTQjJiMmxrSURBN1hHNGdJQ0FnSUNBZ0lIQnliMmR5WlhOelRHbHpkR1Z1WlhKeklEMGdkbTlwWkNBd08xeHVJQ0FnSUgxY2JseHVJQ0FnSUdSbFptVnljbVZrTG5CeWIyMXBjMlVnUFNCd2NtOXRhWE5sTzF4dUlDQWdJR1JsWm1WeWNtVmtMbkpsYzI5c2RtVWdQU0JtZFc1amRHbHZiaUFvZG1Gc2RXVXBJSHRjYmlBZ0lDQWdJQ0FnYVdZZ0tISmxjMjlzZG1Wa1VISnZiV2x6WlNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVPMXh1SUNBZ0lDQWdJQ0I5WEc1Y2JpQWdJQ0FnSUNBZ1ltVmpiMjFsS0ZFb2RtRnNkV1VwS1R0Y2JpQWdJQ0I5TzF4dVhHNGdJQ0FnWkdWbVpYSnlaV1F1Wm5Wc1ptbHNiQ0E5SUdaMWJtTjBhVzl1SUNoMllXeDFaU2tnZTF4dUlDQWdJQ0FnSUNCcFppQW9jbVZ6YjJ4MlpXUlFjbTl0YVhObEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCeVpYUjFjbTQ3WEc0Z0lDQWdJQ0FnSUgxY2JseHVJQ0FnSUNBZ0lDQmlaV052YldVb1puVnNabWxzYkNoMllXeDFaU2twTzF4dUlDQWdJSDA3WEc0Z0lDQWdaR1ZtWlhKeVpXUXVjbVZxWldOMElEMGdablZ1WTNScGIyNGdLSEpsWVhOdmJpa2dlMXh1SUNBZ0lDQWdJQ0JwWmlBb2NtVnpiMngyWldSUWNtOXRhWE5sS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNDdYRzRnSUNBZ0lDQWdJSDFjYmx4dUlDQWdJQ0FnSUNCaVpXTnZiV1VvY21WcVpXTjBLSEpsWVhOdmJpa3BPMXh1SUNBZ0lIMDdYRzRnSUNBZ1pHVm1aWEp5WldRdWJtOTBhV1o1SUQwZ1puVnVZM1JwYjI0Z0tIQnliMmR5WlhOektTQjdYRzRnSUNBZ0lDQWdJR2xtSUNoeVpYTnZiSFpsWkZCeWIyMXBjMlVwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJqdGNiaUFnSUNBZ0lDQWdmVnh1WEc0Z0lDQWdJQ0FnSUdGeWNtRjVYM0psWkhWalpTaHdjbTluY21WemMweHBjM1JsYm1WeWN5d2dablZ1WTNScGIyNGdLSFZ1WkdWbWFXNWxaQ3dnY0hKdlozSmxjM05NYVhOMFpXNWxjaWtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdVUzV1WlhoMFZHbGpheWhtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2NISnZaM0psYzNOTWFYTjBaVzVsY2lod2NtOW5jbVZ6Y3lrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5S1R0Y2JpQWdJQ0FnSUNBZ2ZTd2dkbTlwWkNBd0tUdGNiaUFnSUNCOU8xeHVYRzRnSUNBZ2NtVjBkWEp1SUdSbFptVnljbVZrTzF4dWZWeHVYRzR2S2lwY2JpQXFJRU55WldGMFpYTWdZU0JPYjJSbExYTjBlV3hsSUdOaGJHeGlZV05ySUhSb1lYUWdkMmxzYkNCeVpYTnZiSFpsSUc5eUlISmxhbVZqZENCMGFHVWdaR1ZtWlhKeVpXUmNiaUFxSUhCeWIyMXBjMlV1WEc0Z0tpQkFjbVYwZFhKdWN5QmhJRzV2WkdWaVlXTnJYRzRnS2k5Y2JtUmxabVZ5TG5CeWIzUnZkSGx3WlM1dFlXdGxUbTlrWlZKbGMyOXNkbVZ5SUQwZ1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lIWmhjaUJ6Wld4bUlEMGdkR2hwY3p0Y2JpQWdJQ0J5WlhSMWNtNGdablZ1WTNScGIyNGdLR1Z5Y205eUxDQjJZV3gxWlNrZ2UxeHVJQ0FnSUNBZ0lDQnBaaUFvWlhKeWIzSXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lITmxiR1l1Y21WcVpXTjBLR1Z5Y205eUtUdGNiaUFnSUNBZ0lDQWdmU0JsYkhObElHbG1JQ2hoY21kMWJXVnVkSE11YkdWdVozUm9JRDRnTWlrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnYzJWc1ppNXlaWE52YkhabEtHRnljbUY1WDNOc2FXTmxLR0Z5WjNWdFpXNTBjeXdnTVNrcE8xeHVJQ0FnSUNBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnYzJWc1ppNXlaWE52YkhabEtIWmhiSFZsS1R0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUgwN1hHNTlPMXh1WEc0dktpcGNiaUFxSUVCd1lYSmhiU0J5WlhOdmJIWmxjaUI3Um5WdVkzUnBiMjU5SUdFZ1puVnVZM1JwYjI0Z2RHaGhkQ0J5WlhSMWNtNXpJRzV2ZEdocGJtY2dZVzVrSUdGalkyVndkSE5jYmlBcUlIUm9aU0J5WlhOdmJIWmxMQ0J5WldwbFkzUXNJR0Z1WkNCdWIzUnBabmtnWm5WdVkzUnBiMjV6SUdadmNpQmhJR1JsWm1WeWNtVmtMbHh1SUNvZ1FISmxkSFZ5Ym5NZ1lTQndjbTl0YVhObElIUm9ZWFFnYldGNUlHSmxJSEpsYzI5c2RtVmtJSGRwZEdnZ2RHaGxJR2RwZG1WdUlISmxjMjlzZG1VZ1lXNWtJSEpsYW1WamRGeHVJQ29nWm5WdVkzUnBiMjV6TENCdmNpQnlaV3BsWTNSbFpDQmllU0JoSUhSb2NtOTNiaUJsZUdObGNIUnBiMjRnYVc0Z2NtVnpiMngyWlhKY2JpQXFMMXh1VVM1UWNtOXRhWE5sSUQwZ2NISnZiV2x6WlRzZ0x5OGdSVk0yWEc1UkxuQnliMjFwYzJVZ1BTQndjbTl0YVhObE8xeHVablZ1WTNScGIyNGdjSEp2YldselpTaHlaWE52YkhabGNpa2dlMXh1SUNBZ0lHbG1JQ2gwZVhCbGIyWWdjbVZ6YjJ4MlpYSWdJVDA5SUZ3aVpuVnVZM1JwYjI1Y0lpa2dlMXh1SUNBZ0lDQWdJQ0IwYUhKdmR5QnVaWGNnVkhsd1pVVnljbTl5S0Z3aWNtVnpiMngyWlhJZ2JYVnpkQ0JpWlNCaElHWjFibU4wYVc5dUxsd2lLVHRjYmlBZ0lDQjlYRzRnSUNBZ2RtRnlJR1JsWm1WeWNtVmtJRDBnWkdWbVpYSW9LVHRjYmlBZ0lDQjBjbmtnZTF4dUlDQWdJQ0FnSUNCeVpYTnZiSFpsY2loa1pXWmxjbkpsWkM1eVpYTnZiSFpsTENCa1pXWmxjbkpsWkM1eVpXcGxZM1FzSUdSbFptVnljbVZrTG01dmRHbG1lU2s3WEc0Z0lDQWdmU0JqWVhSamFDQW9jbVZoYzI5dUtTQjdYRzRnSUNBZ0lDQWdJR1JsWm1WeWNtVmtMbkpsYW1WamRDaHlaV0Z6YjI0cE8xeHVJQ0FnSUgxY2JpQWdJQ0J5WlhSMWNtNGdaR1ZtWlhKeVpXUXVjSEp2YldselpUdGNibjFjYmx4dWNISnZiV2x6WlM1eVlXTmxJRDBnY21GalpUc2dMeThnUlZNMlhHNXdjbTl0YVhObExtRnNiQ0E5SUdGc2JEc2dMeThnUlZNMlhHNXdjbTl0YVhObExuSmxhbVZqZENBOUlISmxhbVZqZERzZ0x5OGdSVk0yWEc1d2NtOXRhWE5sTG5KbGMyOXNkbVVnUFNCUk95QXZMeUJGVXpaY2JseHVMeThnV0ZoWUlHVjRjR1Z5YVcxbGJuUmhiQzRnSUZSb2FYTWdiV1YwYUc5a0lHbHpJR0VnZDJGNUlIUnZJR1JsYm05MFpTQjBhR0YwSUdFZ2JHOWpZV3dnZG1Gc2RXVWdhWE5jYmk4dklITmxjbWxoYkdsNllXSnNaU0JoYm1RZ2MyaHZkV3hrSUdKbElHbHRiV1ZrYVdGMFpXeDVJR1JwYzNCaGRHTm9aV1FnZEc4Z1lTQnlaVzF2ZEdVZ2RYQnZiaUJ5WlhGMVpYTjBMRnh1THk4Z2FXNXpkR1ZoWkNCdlppQndZWE56YVc1bklHRWdjbVZtWlhKbGJtTmxMbHh1VVM1d1lYTnpRbmxEYjNCNUlEMGdablZ1WTNScGIyNGdLRzlpYW1WamRDa2dlMXh1SUNBZ0lDOHZabkpsWlhwbEtHOWlhbVZqZENrN1hHNGdJQ0FnTHk5d1lYTnpRbmxEYjNCcFpYTXVjMlYwS0c5aWFtVmpkQ3dnZEhKMVpTazdYRzRnSUNBZ2NtVjBkWEp1SUc5aWFtVmpkRHRjYm4wN1hHNWNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbkJoYzNOQ2VVTnZjSGtnUFNCbWRXNWpkR2x2YmlBb0tTQjdYRzRnSUNBZ0x5OW1jbVZsZW1Vb2IySnFaV04wS1R0Y2JpQWdJQ0F2TDNCaGMzTkNlVU52Y0dsbGN5NXpaWFFvYjJKcVpXTjBMQ0IwY25WbEtUdGNiaUFnSUNCeVpYUjFjbTRnZEdocGN6dGNibjA3WEc1Y2JpOHFLbHh1SUNvZ1NXWWdkSGR2SUhCeWIyMXBjMlZ6SUdWMlpXNTBkV0ZzYkhrZ1puVnNabWxzYkNCMGJ5QjBhR1VnYzJGdFpTQjJZV3gxWlN3Z2NISnZiV2x6WlhNZ2RHaGhkQ0IyWVd4MVpTeGNiaUFxSUdKMWRDQnZkR2hsY25kcGMyVWdjbVZxWldOMGN5NWNiaUFxSUVCd1lYSmhiU0I0SUh0QmJua3FmVnh1SUNvZ1FIQmhjbUZ0SUhrZ2UwRnVlU3A5WEc0Z0tpQkFjbVYwZFhKdWN5QjdRVzU1S24wZ1lTQndjbTl0YVhObElHWnZjaUI0SUdGdVpDQjVJR2xtSUhSb1pYa2dZWEpsSUhSb1pTQnpZVzFsTENCaWRYUWdZU0J5WldwbFkzUnBiMjVjYmlBcUlHOTBhR1Z5ZDJselpTNWNiaUFxWEc0Z0tpOWNibEV1YW05cGJpQTlJR1oxYm1OMGFXOXVJQ2g0TENCNUtTQjdYRzRnSUNBZ2NtVjBkWEp1SUZFb2VDa3VhbTlwYmloNUtUdGNibjA3WEc1Y2JsQnliMjFwYzJVdWNISnZkRzkwZVhCbExtcHZhVzRnUFNCbWRXNWpkR2x2YmlBb2RHaGhkQ2tnZTF4dUlDQWdJSEpsZEhWeWJpQlJLRnQwYUdsekxDQjBhR0YwWFNrdWMzQnlaV0ZrS0daMWJtTjBhVzl1SUNoNExDQjVLU0I3WEc0Z0lDQWdJQ0FnSUdsbUlDaDRJRDA5UFNCNUtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNBdkx5QlVUMFJQT2lCY0lqMDlQVndpSUhOb2IzVnNaQ0JpWlNCUFltcGxZM1F1YVhNZ2IzSWdaWEYxYVhaY2JpQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQjRPMXh1SUNBZ0lDQWdJQ0I5SUdWc2MyVWdlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2RHaHliM2NnYm1WM0lFVnljbTl5S0Z3aVEyRnVKM1FnYW05cGJqb2dibTkwSUhSb1pTQnpZVzFsT2lCY0lpQXJJSGdnS3lCY0lpQmNJaUFySUhrcE8xeHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ2ZTazdYRzU5TzF4dVhHNHZLaXBjYmlBcUlGSmxkSFZ5Ym5NZ1lTQndjbTl0YVhObElHWnZjaUIwYUdVZ1ptbHljM1FnYjJZZ1lXNGdZWEp5WVhrZ2IyWWdjSEp2YldselpYTWdkRzhnWW1WamIyMWxJSE5sZEhSc1pXUXVYRzRnS2lCQWNHRnlZVzBnWVc1emQyVnljeUI3UVhKeVlYbGJRVzU1S2wxOUlIQnliMjFwYzJWeklIUnZJSEpoWTJWY2JpQXFJRUJ5WlhSMWNtNXpJSHRCYm5rcWZTQjBhR1VnWm1seWMzUWdjSEp2YldselpTQjBieUJpWlNCelpYUjBiR1ZrWEc0Z0tpOWNibEV1Y21GalpTQTlJSEpoWTJVN1hHNW1kVzVqZEdsdmJpQnlZV05sS0dGdWMzZGxjbEJ6S1NCN1hHNGdJQ0FnY21WMGRYSnVJSEJ5YjIxcGMyVW9ablZ1WTNScGIyNGdLSEpsYzI5c2RtVXNJSEpsYW1WamRDa2dlMXh1SUNBZ0lDQWdJQ0F2THlCVGQybDBZMmdnZEc4Z2RHaHBjeUJ2Ym1ObElIZGxJR05oYmlCaGMzTjFiV1VnWVhRZ2JHVmhjM1FnUlZNMVhHNGdJQ0FnSUNBZ0lDOHZJR0Z1YzNkbGNsQnpMbVp2Y2tWaFkyZ29ablZ1WTNScGIyNGdLR0Z1YzNkbGNsQXBJSHRjYmlBZ0lDQWdJQ0FnTHk4Z0lDQWdJRkVvWVc1emQyVnlVQ2t1ZEdobGJpaHlaWE52YkhabExDQnlaV3BsWTNRcE8xeHVJQ0FnSUNBZ0lDQXZMeUI5S1R0Y2JpQWdJQ0FnSUNBZ0x5OGdWWE5sSUhSb2FYTWdhVzRnZEdobElHMWxZVzUwYVcxbFhHNGdJQ0FnSUNBZ0lHWnZjaUFvZG1GeUlHa2dQU0F3TENCc1pXNGdQU0JoYm5OM1pYSlFjeTVzWlc1bmRHZzdJR2tnUENCc1pXNDdJR2tyS3lrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnVVNoaGJuTjNaWEpRYzF0cFhTa3VkR2hsYmloeVpYTnZiSFpsTENCeVpXcGxZM1FwTzF4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnZlNrN1hHNTlYRzVjYmxCeWIyMXBjMlV1Y0hKdmRHOTBlWEJsTG5KaFkyVWdQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnY21WMGRYSnVJSFJvYVhNdWRHaGxiaWhSTG5KaFkyVXBPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQkRiMjV6ZEhKMVkzUnpJR0VnVUhKdmJXbHpaU0IzYVhSb0lHRWdjSEp2YldselpTQmtaWE5qY21sd2RHOXlJRzlpYW1WamRDQmhibVFnYjNCMGFXOXVZV3dnWm1Gc2JHSmhZMnRjYmlBcUlHWjFibU4wYVc5dUxpQWdWR2hsSUdSbGMyTnlhWEIwYjNJZ1kyOXVkR0ZwYm5NZ2JXVjBhRzlrY3lCc2FXdGxJSGRvWlc0b2NtVnFaV04wWldRcExDQm5aWFFvYm1GdFpTa3NYRzRnS2lCelpYUW9ibUZ0WlN3Z2RtRnNkV1VwTENCd2IzTjBLRzVoYldVc0lHRnlaM01wTENCaGJtUWdaR1ZzWlhSbEtHNWhiV1VwTENCM2FHbGphQ0JoYkd4Y2JpQXFJSEpsZEhWeWJpQmxhWFJvWlhJZ1lTQjJZV3gxWlN3Z1lTQndjbTl0YVhObElHWnZjaUJoSUhaaGJIVmxMQ0J2Y2lCaElISmxhbVZqZEdsdmJpNGdJRlJvWlNCbVlXeHNZbUZqYTF4dUlDb2dZV05qWlhCMGN5QjBhR1VnYjNCbGNtRjBhVzl1SUc1aGJXVXNJR0VnY21WemIyeDJaWElzSUdGdVpDQmhibmtnWm5WeWRHaGxjaUJoY21kMWJXVnVkSE1nZEdoaGRDQjNiM1ZzWkZ4dUlDb2dhR0YyWlNCaVpXVnVJR1p2Y25kaGNtUmxaQ0IwYnlCMGFHVWdZWEJ3Y205d2NtbGhkR1VnYldWMGFHOWtJR0ZpYjNabElHaGhaQ0JoSUcxbGRHaHZaQ0JpWldWdVhHNGdLaUJ3Y205MmFXUmxaQ0IzYVhSb0lIUm9aU0J3Y205d1pYSWdibUZ0WlM0Z0lGUm9aU0JCVUVrZ2JXRnJaWE1nYm04Z1ozVmhjbUZ1ZEdWbGN5QmhZbTkxZENCMGFHVWdibUYwZFhKbFhHNGdLaUJ2WmlCMGFHVWdjbVYwZFhKdVpXUWdiMkpxWldOMExDQmhjR0Z5ZENCbWNtOXRJSFJvWVhRZ2FYUWdhWE1nZFhOaFlteGxJSGRvWlhKbFpYWmxjaUJ3Y205dGFYTmxjeUJoY21WY2JpQXFJR0p2ZFdkb2RDQmhibVFnYzI5c1pDNWNiaUFxTDF4dVVTNXRZV3RsVUhKdmJXbHpaU0E5SUZCeWIyMXBjMlU3WEc1bWRXNWpkR2x2YmlCUWNtOXRhWE5sS0dSbGMyTnlhWEIwYjNJc0lHWmhiR3hpWVdOckxDQnBibk53WldOMEtTQjdYRzRnSUNBZ2FXWWdLR1poYkd4aVlXTnJJRDA5UFNCMmIybGtJREFwSUh0Y2JpQWdJQ0FnSUNBZ1ptRnNiR0poWTJzZ1BTQm1kVzVqZEdsdmJpQW9iM0FwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQnlaV3BsWTNRb2JtVjNJRVZ5Y205eUtGeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lGd2lVSEp2YldselpTQmtiMlZ6SUc1dmRDQnpkWEJ3YjNKMElHOXdaWEpoZEdsdmJqb2dYQ0lnS3lCdmNGeHVJQ0FnSUNBZ0lDQWdJQ0FnS1NrN1hHNGdJQ0FnSUNBZ0lIMDdYRzRnSUNBZ2ZWeHVJQ0FnSUdsbUlDaHBibk53WldOMElEMDlQU0IyYjJsa0lEQXBJSHRjYmlBZ0lDQWdJQ0FnYVc1emNHVmpkQ0E5SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhKbGRIVnliaUI3YzNSaGRHVTZJRndpZFc1cmJtOTNibHdpZlR0Y2JpQWdJQ0FnSUNBZ2ZUdGNiaUFnSUNCOVhHNWNiaUFnSUNCMllYSWdjSEp2YldselpTQTlJRzlpYW1WamRGOWpjbVZoZEdVb1VISnZiV2x6WlM1d2NtOTBiM1I1Y0dVcE8xeHVYRzRnSUNBZ2NISnZiV2x6WlM1d2NtOXRhWE5sUkdsemNHRjBZMmdnUFNCbWRXNWpkR2x2YmlBb2NtVnpiMngyWlN3Z2IzQXNJR0Z5WjNNcElIdGNiaUFnSUNBZ0lDQWdkbUZ5SUhKbGMzVnNkRHRjYmlBZ0lDQWdJQ0FnZEhKNUlIdGNiaUFnSUNBZ0lDQWdJQ0FnSUdsbUlDaGtaWE5qY21sd2RHOXlXMjl3WFNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lISmxjM1ZzZENBOUlHUmxjMk55YVhCMGIzSmJiM0JkTG1Gd2NHeDVLSEJ5YjIxcGMyVXNJR0Z5WjNNcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlNCbGJITmxJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0J5WlhOMWJIUWdQU0JtWVd4c1ltRmpheTVqWVd4c0tIQnliMjFwYzJVc0lHOXdMQ0JoY21kektUdGNiaUFnSUNBZ0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ2ZTQmpZWFJqYUNBb1pYaGpaWEIwYVc5dUtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCeVpYTjFiSFFnUFNCeVpXcGxZM1FvWlhoalpYQjBhVzl1S1R0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQnBaaUFvY21WemIyeDJaU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdjbVZ6YjJ4MlpTaHlaWE4xYkhRcE8xeHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ2ZUdGNibHh1SUNBZ0lIQnliMjFwYzJVdWFXNXpjR1ZqZENBOUlHbHVjM0JsWTNRN1hHNWNiaUFnSUNBdkx5QllXRmdnWkdWd2NtVmpZWFJsWkNCZ2RtRnNkV1ZQWm1BZ1lXNWtJR0JsZUdObGNIUnBiMjVnSUhOMWNIQnZjblJjYmlBZ0lDQnBaaUFvYVc1emNHVmpkQ2tnZTF4dUlDQWdJQ0FnSUNCMllYSWdhVzV6Y0dWamRHVmtJRDBnYVc1emNHVmpkQ2dwTzF4dUlDQWdJQ0FnSUNCcFppQW9hVzV6Y0dWamRHVmtMbk4wWVhSbElEMDlQU0JjSW5KbGFtVmpkR1ZrWENJcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhCeWIyMXBjMlV1WlhoalpYQjBhVzl1SUQwZ2FXNXpjR1ZqZEdWa0xuSmxZWE52Ymp0Y2JpQWdJQ0FnSUNBZ2ZWeHVYRzRnSUNBZ0lDQWdJSEJ5YjIxcGMyVXVkbUZzZFdWUFppQTlJR1oxYm1OMGFXOXVJQ2dwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSFpoY2lCcGJuTndaV04wWldRZ1BTQnBibk53WldOMEtDazdYRzRnSUNBZ0lDQWdJQ0FnSUNCcFppQW9hVzV6Y0dWamRHVmtMbk4wWVhSbElEMDlQU0JjSW5CbGJtUnBibWRjSWlCOGZGeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHbHVjM0JsWTNSbFpDNXpkR0YwWlNBOVBUMGdYQ0p5WldwbFkzUmxaRndpS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUhCeWIyMXBjMlU3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJQ0FnSUNCeVpYUjFjbTRnYVc1emNHVmpkR1ZrTG5aaGJIVmxPMXh1SUNBZ0lDQWdJQ0I5TzF4dUlDQWdJSDFjYmx4dUlDQWdJSEpsZEhWeWJpQndjbTl0YVhObE8xeHVmVnh1WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1MGIxTjBjbWx1WnlBOUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQnlaWFIxY200Z1hDSmJiMkpxWldOMElGQnliMjFwYzJWZFhDSTdYRzU5TzF4dVhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNTBhR1Z1SUQwZ1puVnVZM1JwYjI0Z0tHWjFiR1pwYkd4bFpDd2djbVZxWldOMFpXUXNJSEJ5YjJkeVpYTnpaV1FwSUh0Y2JpQWdJQ0IyWVhJZ2MyVnNaaUE5SUhSb2FYTTdYRzRnSUNBZ2RtRnlJR1JsWm1WeWNtVmtJRDBnWkdWbVpYSW9LVHRjYmlBZ0lDQjJZWElnWkc5dVpTQTlJR1poYkhObE95QWdJQzh2SUdWdWMzVnlaU0IwYUdVZ2RXNTBjblZ6ZEdWa0lIQnliMjFwYzJVZ2JXRnJaWE1nWVhRZ2JXOXpkQ0JoWEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0F2THlCemFXNW5iR1VnWTJGc2JDQjBieUJ2Ym1VZ2IyWWdkR2hsSUdOaGJHeGlZV05yYzF4dVhHNGdJQ0FnWm5WdVkzUnBiMjRnWDJaMWJHWnBiR3hsWkNoMllXeDFaU2tnZTF4dUlDQWdJQ0FnSUNCMGNua2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUhSNWNHVnZaaUJtZFd4bWFXeHNaV1FnUFQwOUlGd2lablZ1WTNScGIyNWNJaUEvSUdaMWJHWnBiR3hsWkNoMllXeDFaU2tnT2lCMllXeDFaVHRjYmlBZ0lDQWdJQ0FnZlNCallYUmphQ0FvWlhoalpYQjBhVzl1S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNGdjbVZxWldOMEtHVjRZMlZ3ZEdsdmJpazdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQjlYRzVjYmlBZ0lDQm1kVzVqZEdsdmJpQmZjbVZxWldOMFpXUW9aWGhqWlhCMGFXOXVLU0I3WEc0Z0lDQWdJQ0FnSUdsbUlDaDBlWEJsYjJZZ2NtVnFaV04wWldRZ1BUMDlJRndpWm5WdVkzUnBiMjVjSWlrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnYldGclpWTjBZV05yVkhKaFkyVk1iMjVuS0dWNFkyVndkR2x2Yml3Z2MyVnNaaWs3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjBjbmtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhKbGRIVnliaUJ5WldwbFkzUmxaQ2hsZUdObGNIUnBiMjRwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdmU0JqWVhSamFDQW9ibVYzUlhoalpYQjBhVzl1S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUhKbGFtVmpkQ2h1WlhkRmVHTmxjSFJwYjI0cE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlCeVpXcGxZM1FvWlhoalpYQjBhVzl1S1R0Y2JpQWdJQ0I5WEc1Y2JpQWdJQ0JtZFc1amRHbHZiaUJmY0hKdlozSmxjM05sWkNoMllXeDFaU2tnZTF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnZEhsd1pXOW1JSEJ5YjJkeVpYTnpaV1FnUFQwOUlGd2lablZ1WTNScGIyNWNJaUEvSUhCeWIyZHlaWE56WldRb2RtRnNkV1VwSURvZ2RtRnNkV1U3WEc0Z0lDQWdmVnh1WEc0Z0lDQWdVUzV1WlhoMFZHbGpheWhtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lITmxiR1l1Y0hKdmJXbHpaVVJwYzNCaGRHTm9LR1oxYm1OMGFXOXVJQ2gyWVd4MVpTa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLR1J2Ym1VcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQnlaWFIxY200N1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUNBZ0lDQmtiMjVsSUQwZ2RISjFaVHRjYmx4dUlDQWdJQ0FnSUNBZ0lDQWdaR1ZtWlhKeVpXUXVjbVZ6YjJ4MlpTaGZablZzWm1sc2JHVmtLSFpoYkhWbEtTazdYRzRnSUNBZ0lDQWdJSDBzSUZ3aWQyaGxibHdpTENCYlpuVnVZM1JwYjI0Z0tHVjRZMlZ3ZEdsdmJpa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLR1J2Ym1VcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQnlaWFIxY200N1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUNBZ0lDQmtiMjVsSUQwZ2RISjFaVHRjYmx4dUlDQWdJQ0FnSUNBZ0lDQWdaR1ZtWlhKeVpXUXVjbVZ6YjJ4MlpTaGZjbVZxWldOMFpXUW9aWGhqWlhCMGFXOXVLU2s3WEc0Z0lDQWdJQ0FnSUgxZEtUdGNiaUFnSUNCOUtUdGNibHh1SUNBZ0lDOHZJRkJ5YjJkeVpYTnpJSEJ5YjNCaFoyRjBiM0lnYm1WbFpDQjBieUJpWlNCaGRIUmhZMmhsWkNCcGJpQjBhR1VnWTNWeWNtVnVkQ0IwYVdOckxseHVJQ0FnSUhObGJHWXVjSEp2YldselpVUnBjM0JoZEdOb0tIWnZhV1FnTUN3Z1hDSjNhR1Z1WENJc0lGdDJiMmxrSURBc0lHWjFibU4wYVc5dUlDaDJZV3gxWlNrZ2UxeHVJQ0FnSUNBZ0lDQjJZWElnYm1WM1ZtRnNkV1U3WEc0Z0lDQWdJQ0FnSUhaaGNpQjBhSEpsZHlBOUlHWmhiSE5sTzF4dUlDQWdJQ0FnSUNCMGNua2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2JtVjNWbUZzZFdVZ1BTQmZjSEp2WjNKbGMzTmxaQ2gyWVd4MVpTazdYRzRnSUNBZ0lDQWdJSDBnWTJGMFkyZ2dLR1VwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJSFJvY21WM0lEMGdkSEoxWlR0Y2JpQWdJQ0FnSUNBZ0lDQWdJR2xtSUNoUkxtOXVaWEp5YjNJcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQlJMbTl1WlhKeWIzSW9aU2s3WEc0Z0lDQWdJQ0FnSUNBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lIUm9jbTkzSUdVN1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUgxY2JseHVJQ0FnSUNBZ0lDQnBaaUFvSVhSb2NtVjNLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQmtaV1psY25KbFpDNXViM1JwWm5rb2JtVjNWbUZzZFdVcE8xeHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ2ZWMHBPMXh1WEc0Z0lDQWdjbVYwZFhKdUlHUmxabVZ5Y21Wa0xuQnliMjFwYzJVN1hHNTlPMXh1WEc1UkxuUmhjQ0E5SUdaMWJtTjBhVzl1SUNod2NtOXRhWE5sTENCallXeHNZbUZqYXlrZ2UxeHVJQ0FnSUhKbGRIVnliaUJSS0hCeWIyMXBjMlVwTG5SaGNDaGpZV3hzWW1GamF5azdYRzU5TzF4dVhHNHZLaXBjYmlBcUlGZHZjbXR6SUdGc2JXOXpkQ0JzYVd0bElGd2labWx1WVd4c2VWd2lMQ0JpZFhRZ2JtOTBJR05oYkd4bFpDQm1iM0lnY21WcVpXTjBhVzl1Y3k1Y2JpQXFJRTl5YVdkcGJtRnNJSEpsYzI5c2RYUnBiMjRnZG1Gc2RXVWdhWE1nY0dGemMyVmtJSFJvY205MVoyZ2dZMkZzYkdKaFkyc2dkVzVoWm1abFkzUmxaQzVjYmlBcUlFTmhiR3hpWVdOcklHMWhlU0J5WlhSMWNtNGdZU0J3Y205dGFYTmxJSFJvWVhRZ2QybHNiQ0JpWlNCaGQyRnBkR1ZrSUdadmNpNWNiaUFxSUVCd1lYSmhiU0I3Um5WdVkzUnBiMjU5SUdOaGJHeGlZV05yWEc0Z0tpQkFjbVYwZFhKdWN5QjdVUzVRY205dGFYTmxmVnh1SUNvZ1FHVjRZVzF3YkdWY2JpQXFJR1J2VTI5dFpYUm9hVzVuS0NsY2JpQXFJQ0FnTG5Sb1pXNG9MaTR1S1Z4dUlDb2dJQ0F1ZEdGd0tHTnZibk52YkdVdWJHOW5LVnh1SUNvZ0lDQXVkR2hsYmlndUxpNHBPMXh1SUNvdlhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNTBZWEFnUFNCbWRXNWpkR2x2YmlBb1kyRnNiR0poWTJzcElIdGNiaUFnSUNCallXeHNZbUZqYXlBOUlGRW9ZMkZzYkdKaFkyc3BPMXh1WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11ZEdobGJpaG1kVzVqZEdsdmJpQW9kbUZzZFdVcElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHTmhiR3hpWVdOckxtWmpZV3hzS0haaGJIVmxLUzUwYUdWdVVtVnpiMngyWlNoMllXeDFaU2s3WEc0Z0lDQWdmU2s3WEc1OU8xeHVYRzR2S2lwY2JpQXFJRkpsWjJsemRHVnljeUJoYmlCdlluTmxjblpsY2lCdmJpQmhJSEJ5YjIxcGMyVXVYRzRnS2x4dUlDb2dSM1ZoY21GdWRHVmxjenBjYmlBcVhHNGdLaUF4TGlCMGFHRjBJR1oxYkdacGJHeGxaQ0JoYm1RZ2NtVnFaV04wWldRZ2QybHNiQ0JpWlNCallXeHNaV1FnYjI1c2VTQnZibU5sTGx4dUlDb2dNaTRnZEdoaGRDQmxhWFJvWlhJZ2RHaGxJR1oxYkdacGJHeGxaQ0JqWVd4c1ltRmpheUJ2Y2lCMGFHVWdjbVZxWldOMFpXUWdZMkZzYkdKaFkyc2dkMmxzYkNCaVpWeHVJQ29nSUNBZ1kyRnNiR1ZrTENCaWRYUWdibTkwSUdKdmRHZ3VYRzRnS2lBekxpQjBhR0YwSUdaMWJHWnBiR3hsWkNCaGJtUWdjbVZxWldOMFpXUWdkMmxzYkNCdWIzUWdZbVVnWTJGc2JHVmtJR2x1SUhSb2FYTWdkSFZ5Ymk1Y2JpQXFYRzRnS2lCQWNHRnlZVzBnZG1Gc2RXVWdJQ0FnSUNCd2NtOXRhWE5sSUc5eUlHbHRiV1ZrYVdGMFpTQnlaV1psY21WdVkyVWdkRzhnYjJKelpYSjJaVnh1SUNvZ1FIQmhjbUZ0SUdaMWJHWnBiR3hsWkNBZ1puVnVZM1JwYjI0Z2RHOGdZbVVnWTJGc2JHVmtJSGRwZEdnZ2RHaGxJR1oxYkdacGJHeGxaQ0IyWVd4MVpWeHVJQ29nUUhCaGNtRnRJSEpsYW1WamRHVmtJQ0FnWm5WdVkzUnBiMjRnZEc4Z1ltVWdZMkZzYkdWa0lIZHBkR2dnZEdobElISmxhbVZqZEdsdmJpQmxlR05sY0hScGIyNWNiaUFxSUVCd1lYSmhiU0J3Y205bmNtVnpjMlZrSUdaMWJtTjBhVzl1SUhSdklHSmxJR05oYkd4bFpDQnZiaUJoYm5rZ2NISnZaM0psYzNNZ2JtOTBhV1pwWTJGMGFXOXVjMXh1SUNvZ1FISmxkSFZ5YmlCd2NtOXRhWE5sSUdadmNpQjBhR1VnY21WMGRYSnVJSFpoYkhWbElHWnliMjBnZEdobElHbHVkbTlyWldRZ1kyRnNiR0poWTJ0Y2JpQXFMMXh1VVM1M2FHVnVJRDBnZDJobGJqdGNibVoxYm1OMGFXOXVJSGRvWlc0b2RtRnNkV1VzSUdaMWJHWnBiR3hsWkN3Z2NtVnFaV04wWldRc0lIQnliMmR5WlhOelpXUXBJSHRjYmlBZ0lDQnlaWFIxY200Z1VTaDJZV3gxWlNrdWRHaGxiaWhtZFd4bWFXeHNaV1FzSUhKbGFtVmpkR1ZrTENCd2NtOW5jbVZ6YzJWa0tUdGNibjFjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdWRHaGxibEpsYzI5c2RtVWdQU0JtZFc1amRHbHZiaUFvZG1Gc2RXVXBJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTUwYUdWdUtHWjFibU4wYVc5dUlDZ3BJSHNnY21WMGRYSnVJSFpoYkhWbE95QjlLVHRjYm4wN1hHNWNibEV1ZEdobGJsSmxjMjlzZG1VZ1BTQm1kVzVqZEdsdmJpQW9jSEp2YldselpTd2dkbUZzZFdVcElIdGNiaUFnSUNCeVpYUjFjbTRnVVNod2NtOXRhWE5sS1M1MGFHVnVVbVZ6YjJ4MlpTaDJZV3gxWlNrN1hHNTlPMXh1WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1MGFHVnVVbVZxWldOMElEMGdablZ1WTNScGIyNGdLSEpsWVhOdmJpa2dlMXh1SUNBZ0lISmxkSFZ5YmlCMGFHbHpMblJvWlc0b1puVnVZM1JwYjI0Z0tDa2dleUIwYUhKdmR5QnlaV0Z6YjI0N0lIMHBPMXh1ZlR0Y2JseHVVUzUwYUdWdVVtVnFaV04wSUQwZ1puVnVZM1JwYjI0Z0tIQnliMjFwYzJVc0lISmxZWE52YmlrZ2UxeHVJQ0FnSUhKbGRIVnliaUJSS0hCeWIyMXBjMlVwTG5Sb1pXNVNaV3BsWTNRb2NtVmhjMjl1S1R0Y2JuMDdYRzVjYmk4cUtseHVJQ29nU1dZZ1lXNGdiMkpxWldOMElHbHpJRzV2ZENCaElIQnliMjFwYzJVc0lHbDBJR2x6SUdGeklGd2libVZoY2x3aUlHRnpJSEJ2YzNOcFlteGxMbHh1SUNvZ1NXWWdZU0J3Y205dGFYTmxJR2x6SUhKbGFtVmpkR1ZrTENCcGRDQnBjeUJoY3lCY0ltNWxZWEpjSWlCaGN5QndiM056YVdKc1pTQjBiMjh1WEc0Z0tpQkpaaUJwZE9LQW1YTWdZU0JtZFd4bWFXeHNaV1FnY0hKdmJXbHpaU3dnZEdobElHWjFiR1pwYkd4dFpXNTBJSFpoYkhWbElHbHpJRzVsWVhKbGNpNWNiaUFxSUVsbUlHbDA0b0NaY3lCaElHUmxabVZ5Y21Wa0lIQnliMjFwYzJVZ1lXNWtJSFJvWlNCa1pXWmxjbkpsWkNCb1lYTWdZbVZsYmlCeVpYTnZiSFpsWkN3Z2RHaGxYRzRnS2lCeVpYTnZiSFYwYVc5dUlHbHpJRndpYm1WaGNtVnlYQ0l1WEc0Z0tpQkFjR0Z5WVcwZ2IySnFaV04wWEc0Z0tpQkFjbVYwZFhKdWN5QnRiM04wSUhKbGMyOXNkbVZrSUNodVpXRnlaWE4wS1NCbWIzSnRJRzltSUhSb1pTQnZZbXBsWTNSY2JpQXFMMXh1WEc0dkx5QllXRmdnYzJodmRXeGtJSGRsSUhKbExXUnZJSFJvYVhNL1hHNVJMbTVsWVhKbGNpQTlJRzVsWVhKbGNqdGNibVoxYm1OMGFXOXVJRzVsWVhKbGNpaDJZV3gxWlNrZ2UxeHVJQ0FnSUdsbUlDaHBjMUJ5YjIxcGMyVW9kbUZzZFdVcEtTQjdYRzRnSUNBZ0lDQWdJSFpoY2lCcGJuTndaV04wWldRZ1BTQjJZV3gxWlM1cGJuTndaV04wS0NrN1hHNGdJQ0FnSUNBZ0lHbG1JQ2hwYm5Od1pXTjBaV1F1YzNSaGRHVWdQVDA5SUZ3aVpuVnNabWxzYkdWa1hDSXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lISmxkSFZ5YmlCcGJuTndaV04wWldRdWRtRnNkV1U3WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0I5WEc0Z0lDQWdjbVYwZFhKdUlIWmhiSFZsTzF4dWZWeHVYRzR2S2lwY2JpQXFJRUJ5WlhSMWNtNXpJSGRvWlhSb1pYSWdkR2hsSUdkcGRtVnVJRzlpYW1WamRDQnBjeUJoSUhCeWIyMXBjMlV1WEc0Z0tpQlBkR2hsY25kcGMyVWdhWFFnYVhNZ1lTQm1kV3htYVd4c1pXUWdkbUZzZFdVdVhHNGdLaTljYmxFdWFYTlFjbTl0YVhObElEMGdhWE5RY205dGFYTmxPMXh1Wm5WdVkzUnBiMjRnYVhOUWNtOXRhWE5sS0c5aWFtVmpkQ2tnZTF4dUlDQWdJSEpsZEhWeWJpQnZZbXBsWTNRZ2FXNXpkR0Z1WTJWdlppQlFjbTl0YVhObE8xeHVmVnh1WEc1UkxtbHpVSEp2YldselpVRnNhV3RsSUQwZ2FYTlFjbTl0YVhObFFXeHBhMlU3WEc1bWRXNWpkR2x2YmlCcGMxQnliMjFwYzJWQmJHbHJaU2h2WW1wbFkzUXBJSHRjYmlBZ0lDQnlaWFIxY200Z2FYTlBZbXBsWTNRb2IySnFaV04wS1NBbUppQjBlWEJsYjJZZ2IySnFaV04wTG5Sb1pXNGdQVDA5SUZ3aVpuVnVZM1JwYjI1Y0lqdGNibjFjYmx4dUx5b3FYRzRnS2lCQWNtVjBkWEp1Y3lCM2FHVjBhR1Z5SUhSb1pTQm5hWFpsYmlCdlltcGxZM1FnYVhNZ1lTQndaVzVrYVc1bklIQnliMjFwYzJVc0lHMWxZVzVwYm1jZ2JtOTBYRzRnS2lCbWRXeG1hV3hzWldRZ2IzSWdjbVZxWldOMFpXUXVYRzRnS2k5Y2JsRXVhWE5RWlc1a2FXNW5JRDBnYVhOUVpXNWthVzVuTzF4dVpuVnVZM1JwYjI0Z2FYTlFaVzVrYVc1bktHOWlhbVZqZENrZ2UxeHVJQ0FnSUhKbGRIVnliaUJwYzFCeWIyMXBjMlVvYjJKcVpXTjBLU0FtSmlCdlltcGxZM1F1YVc1emNHVmpkQ2dwTG5OMFlYUmxJRDA5UFNCY0luQmxibVJwYm1kY0lqdGNibjFjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdWFYTlFaVzVrYVc1bklEMGdablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJSEpsZEhWeWJpQjBhR2x6TG1sdWMzQmxZM1FvS1M1emRHRjBaU0E5UFQwZ1hDSndaVzVrYVc1blhDSTdYRzU5TzF4dVhHNHZLaXBjYmlBcUlFQnlaWFIxY201eklIZG9aWFJvWlhJZ2RHaGxJR2RwZG1WdUlHOWlhbVZqZENCcGN5QmhJSFpoYkhWbElHOXlJR1oxYkdacGJHeGxaRnh1SUNvZ2NISnZiV2x6WlM1Y2JpQXFMMXh1VVM1cGMwWjFiR1pwYkd4bFpDQTlJR2x6Um5Wc1ptbHNiR1ZrTzF4dVpuVnVZM1JwYjI0Z2FYTkdkV3htYVd4c1pXUW9iMkpxWldOMEtTQjdYRzRnSUNBZ2NtVjBkWEp1SUNGcGMxQnliMjFwYzJVb2IySnFaV04wS1NCOGZDQnZZbXBsWTNRdWFXNXpjR1ZqZENncExuTjBZWFJsSUQwOVBTQmNJbVoxYkdacGJHeGxaRndpTzF4dWZWeHVYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaUzVwYzBaMWJHWnBiR3hsWkNBOUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTVwYm5Od1pXTjBLQ2t1YzNSaGRHVWdQVDA5SUZ3aVpuVnNabWxzYkdWa1hDSTdYRzU5TzF4dVhHNHZLaXBjYmlBcUlFQnlaWFIxY201eklIZG9aWFJvWlhJZ2RHaGxJR2RwZG1WdUlHOWlhbVZqZENCcGN5QmhJSEpsYW1WamRHVmtJSEJ5YjIxcGMyVXVYRzRnS2k5Y2JsRXVhWE5TWldwbFkzUmxaQ0E5SUdselVtVnFaV04wWldRN1hHNW1kVzVqZEdsdmJpQnBjMUpsYW1WamRHVmtLRzlpYW1WamRDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCcGMxQnliMjFwYzJVb2IySnFaV04wS1NBbUppQnZZbXBsWTNRdWFXNXpjR1ZqZENncExuTjBZWFJsSUQwOVBTQmNJbkpsYW1WamRHVmtYQ0k3WEc1OVhHNWNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbWx6VW1WcVpXTjBaV1FnUFNCbWRXNWpkR2x2YmlBb0tTQjdYRzRnSUNBZ2NtVjBkWEp1SUhSb2FYTXVhVzV6Y0dWamRDZ3BMbk4wWVhSbElEMDlQU0JjSW5KbGFtVmpkR1ZrWENJN1hHNTlPMXh1WEc0dkx5OHZJRUpGUjBsT0lGVk9TRUZPUkV4RlJDQlNSVXBGUTFSSlQwNGdWRkpCUTB0SlRrZGNibHh1THk4Z1ZHaHBjeUJ3Y205dGFYTmxJR3hwWW5KaGNua2dZMjl1YzNWdFpYTWdaWGhqWlhCMGFXOXVjeUIwYUhKdmQyNGdhVzRnYUdGdVpHeGxjbk1nYzI4Z2RHaGxlU0JqWVc0Z1ltVmNiaTh2SUdoaGJtUnNaV1FnWW5rZ1lTQnpkV0p6WlhGMVpXNTBJSEJ5YjIxcGMyVXVJQ0JVYUdVZ1pYaGpaWEIwYVc5dWN5Qm5aWFFnWVdSa1pXUWdkRzhnZEdocGN5QmhjbkpoZVNCM2FHVnVYRzR2THlCMGFHVjVJR0Z5WlNCamNtVmhkR1ZrTENCaGJtUWdjbVZ0YjNabFpDQjNhR1Z1SUhSb1pYa2dZWEpsSUdoaGJtUnNaV1F1SUNCT2IzUmxJSFJvWVhRZ2FXNGdSVk0ySUc5eVhHNHZMeUJ6YUdsdGJXVmtJR1Z1ZG1seWIyNXRaVzUwY3l3Z2RHaHBjeUIzYjNWc1pDQnVZWFIxY21Gc2JIa2dZbVVnWVNCZ1UyVjBZQzVjYm5aaGNpQjFibWhoYm1Sc1pXUlNaV0Z6YjI1eklEMGdXMTA3WEc1MllYSWdkVzVvWVc1a2JHVmtVbVZxWldOMGFXOXVjeUE5SUZ0ZE8xeHVkbUZ5SUhKbGNHOXlkR1ZrVlc1b1lXNWtiR1ZrVW1WcVpXTjBhVzl1Y3lBOUlGdGRPMXh1ZG1GeUlIUnlZV05yVlc1b1lXNWtiR1ZrVW1WcVpXTjBhVzl1Y3lBOUlIUnlkV1U3WEc1Y2JtWjFibU4wYVc5dUlISmxjMlYwVlc1b1lXNWtiR1ZrVW1WcVpXTjBhVzl1Y3lncElIdGNiaUFnSUNCMWJtaGhibVJzWldSU1pXRnpiMjV6TG14bGJtZDBhQ0E5SURBN1hHNGdJQ0FnZFc1b1lXNWtiR1ZrVW1WcVpXTjBhVzl1Y3k1c1pXNW5kR2dnUFNBd08xeHVYRzRnSUNBZ2FXWWdLQ0YwY21GamExVnVhR0Z1Wkd4bFpGSmxhbVZqZEdsdmJuTXBJSHRjYmlBZ0lDQWdJQ0FnZEhKaFkydFZibWhoYm1Sc1pXUlNaV3BsWTNScGIyNXpJRDBnZEhKMVpUdGNiaUFnSUNCOVhHNTlYRzVjYm1aMWJtTjBhVzl1SUhSeVlXTnJVbVZxWldOMGFXOXVLSEJ5YjIxcGMyVXNJSEpsWVhOdmJpa2dlMXh1SUNBZ0lHbG1JQ2doZEhKaFkydFZibWhoYm1Sc1pXUlNaV3BsWTNScGIyNXpLU0I3WEc0Z0lDQWdJQ0FnSUhKbGRIVnlianRjYmlBZ0lDQjlYRzRnSUNBZ2FXWWdLSFI1Y0dWdlppQndjbTlqWlhOeklEMDlQU0JjSW05aWFtVmpkRndpSUNZbUlIUjVjR1Z2WmlCd2NtOWpaWE56TG1WdGFYUWdQVDA5SUZ3aVpuVnVZM1JwYjI1Y0lpa2dlMXh1SUNBZ0lDQWdJQ0JSTG01bGVIUlVhV05yTG5KMWJrRm1kR1Z5S0daMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUdsbUlDaGhjbkpoZVY5cGJtUmxlRTltS0hWdWFHRnVaR3hsWkZKbGFtVmpkR2x2Ym5Nc0lIQnliMjFwYzJVcElDRTlQU0F0TVNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lIQnliMk5sYzNNdVpXMXBkQ2hjSW5WdWFHRnVaR3hsWkZKbGFtVmpkR2x2Ymx3aUxDQnlaV0Z6YjI0c0lIQnliMjFwYzJVcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lISmxjRzl5ZEdWa1ZXNW9ZVzVrYkdWa1VtVnFaV04wYVc5dWN5NXdkWE5vS0hCeWIyMXBjMlVwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0I5S1R0Y2JpQWdJQ0I5WEc1Y2JpQWdJQ0IxYm1oaGJtUnNaV1JTWldwbFkzUnBiMjV6TG5CMWMyZ29jSEp2YldselpTazdYRzRnSUNBZ2FXWWdLSEpsWVhOdmJpQW1KaUIwZVhCbGIyWWdjbVZoYzI5dUxuTjBZV05ySUNFOVBTQmNJblZ1WkdWbWFXNWxaRndpS1NCN1hHNGdJQ0FnSUNBZ0lIVnVhR0Z1Wkd4bFpGSmxZWE52Ym5NdWNIVnphQ2h5WldGemIyNHVjM1JoWTJzcE8xeHVJQ0FnSUgwZ1pXeHpaU0I3WEc0Z0lDQWdJQ0FnSUhWdWFHRnVaR3hsWkZKbFlYTnZibk11Y0hWemFDaGNJaWh1YnlCemRHRmpheWtnWENJZ0t5QnlaV0Z6YjI0cE8xeHVJQ0FnSUgxY2JuMWNibHh1Wm5WdVkzUnBiMjRnZFc1MGNtRmphMUpsYW1WamRHbHZiaWh3Y205dGFYTmxLU0I3WEc0Z0lDQWdhV1lnS0NGMGNtRmphMVZ1YUdGdVpHeGxaRkpsYW1WamRHbHZibk1wSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1TzF4dUlDQWdJSDFjYmx4dUlDQWdJSFpoY2lCaGRDQTlJR0Z5Y21GNVgybHVaR1Y0VDJZb2RXNW9ZVzVrYkdWa1VtVnFaV04wYVc5dWN5d2djSEp2YldselpTazdYRzRnSUNBZ2FXWWdLR0YwSUNFOVBTQXRNU2tnZTF4dUlDQWdJQ0FnSUNCcFppQW9kSGx3Wlc5bUlIQnliMk5sYzNNZ1BUMDlJRndpYjJKcVpXTjBYQ0lnSmlZZ2RIbHdaVzltSUhCeWIyTmxjM011WlcxcGRDQTlQVDBnWENKbWRXNWpkR2x2Ymx3aUtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCUkxtNWxlSFJVYVdOckxuSjFia0ZtZEdWeUtHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0IyWVhJZ1lYUlNaWEJ2Y25RZ1BTQmhjbkpoZVY5cGJtUmxlRTltS0hKbGNHOXlkR1ZrVlc1b1lXNWtiR1ZrVW1WcVpXTjBhVzl1Y3l3Z2NISnZiV2x6WlNrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLR0YwVW1Wd2IzSjBJQ0U5UFNBdE1Ta2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCd2NtOWpaWE56TG1WdGFYUW9YQ0p5WldwbFkzUnBiMjVJWVc1a2JHVmtYQ0lzSUhWdWFHRnVaR3hsWkZKbFlYTnZibk5iWVhSZExDQndjbTl0YVhObEtUdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnY21Wd2IzSjBaV1JWYm1oaGJtUnNaV1JTWldwbFkzUnBiMjV6TG5Od2JHbGpaU2hoZEZKbGNHOXlkQ3dnTVNrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQWdJQ0FnZlNrN1hHNGdJQ0FnSUNBZ0lIMWNiaUFnSUNBZ0lDQWdkVzVvWVc1a2JHVmtVbVZxWldOMGFXOXVjeTV6Y0d4cFkyVW9ZWFFzSURFcE8xeHVJQ0FnSUNBZ0lDQjFibWhoYm1Sc1pXUlNaV0Z6YjI1ekxuTndiR2xqWlNoaGRDd2dNU2s3WEc0Z0lDQWdmVnh1ZlZ4dVhHNVJMbkpsYzJWMFZXNW9ZVzVrYkdWa1VtVnFaV04wYVc5dWN5QTlJSEpsYzJWMFZXNW9ZVzVrYkdWa1VtVnFaV04wYVc5dWN6dGNibHh1VVM1blpYUlZibWhoYm1Sc1pXUlNaV0Z6YjI1eklEMGdablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJQzh2SUUxaGEyVWdZU0JqYjNCNUlITnZJSFJvWVhRZ1kyOXVjM1Z0WlhKeklHTmhiaWQwSUdsdWRHVnlabVZ5WlNCM2FYUm9JRzkxY2lCcGJuUmxjbTVoYkNCemRHRjBaUzVjYmlBZ0lDQnlaWFIxY200Z2RXNW9ZVzVrYkdWa1VtVmhjMjl1Y3k1emJHbGpaU2dwTzF4dWZUdGNibHh1VVM1emRHOXdWVzVvWVc1a2JHVmtVbVZxWldOMGFXOXVWSEpoWTJ0cGJtY2dQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnY21WelpYUlZibWhoYm1Sc1pXUlNaV3BsWTNScGIyNXpLQ2s3WEc0Z0lDQWdkSEpoWTJ0VmJtaGhibVJzWldSU1pXcGxZM1JwYjI1eklEMGdabUZzYzJVN1hHNTlPMXh1WEc1eVpYTmxkRlZ1YUdGdVpHeGxaRkpsYW1WamRHbHZibk1vS1R0Y2JseHVMeTh2THlCRlRrUWdWVTVJUVU1RVRFVkVJRkpGU2tWRFZFbFBUaUJVVWtGRFMwbE9SMXh1WEc0dktpcGNiaUFxSUVOdmJuTjBjblZqZEhNZ1lTQnlaV3BsWTNSbFpDQndjbTl0YVhObExseHVJQ29nUUhCaGNtRnRJSEpsWVhOdmJpQjJZV3gxWlNCa1pYTmpjbWxpYVc1bklIUm9aU0JtWVdsc2RYSmxYRzRnS2k5Y2JsRXVjbVZxWldOMElEMGdjbVZxWldOME8xeHVablZ1WTNScGIyNGdjbVZxWldOMEtISmxZWE52YmlrZ2UxeHVJQ0FnSUhaaGNpQnlaV3BsWTNScGIyNGdQU0JRY205dGFYTmxLSHRjYmlBZ0lDQWdJQ0FnWENKM2FHVnVYQ0k2SUdaMWJtTjBhVzl1SUNoeVpXcGxZM1JsWkNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnTHk4Z2JtOTBaU0IwYUdGMElIUm9aU0JsY25KdmNpQm9ZWE1nWW1WbGJpQm9ZVzVrYkdWa1hHNGdJQ0FnSUNBZ0lDQWdJQ0JwWmlBb2NtVnFaV04wWldRcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjFiblJ5WVdOclVtVnFaV04wYVc5dUtIUm9hWE1wTzF4dUlDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUhKbGFtVmpkR1ZrSUQ4Z2NtVnFaV04wWldRb2NtVmhjMjl1S1NBNklIUm9hWE03WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0I5TENCbWRXNWpkR2x2YmlCbVlXeHNZbUZqYXlncElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlIUm9hWE03WEc0Z0lDQWdmU3dnWm5WdVkzUnBiMjRnYVc1emNHVmpkQ2dwSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUhzZ2MzUmhkR1U2SUZ3aWNtVnFaV04wWldSY0lpd2djbVZoYzI5dU9pQnlaV0Z6YjI0Z2ZUdGNiaUFnSUNCOUtUdGNibHh1SUNBZ0lDOHZJRTV2ZEdVZ2RHaGhkQ0IwYUdVZ2NtVmhjMjl1SUdoaGN5QnViM1FnWW1WbGJpQm9ZVzVrYkdWa0xseHVJQ0FnSUhSeVlXTnJVbVZxWldOMGFXOXVLSEpsYW1WamRHbHZiaXdnY21WaGMyOXVLVHRjYmx4dUlDQWdJSEpsZEhWeWJpQnlaV3BsWTNScGIyNDdYRzU5WEc1Y2JpOHFLbHh1SUNvZ1EyOXVjM1J5ZFdOMGN5QmhJR1oxYkdacGJHeGxaQ0J3Y205dGFYTmxJR1p2Y2lCaGJpQnBiVzFsWkdsaGRHVWdjbVZtWlhKbGJtTmxMbHh1SUNvZ1FIQmhjbUZ0SUhaaGJIVmxJR2x0YldWa2FXRjBaU0J5WldabGNtVnVZMlZjYmlBcUwxeHVVUzVtZFd4bWFXeHNJRDBnWm5Wc1ptbHNiRHRjYm1aMWJtTjBhVzl1SUdaMWJHWnBiR3dvZG1Gc2RXVXBJSHRjYmlBZ0lDQnlaWFIxY200Z1VISnZiV2x6WlNoN1hHNGdJQ0FnSUNBZ0lGd2lkMmhsYmx3aU9pQm1kVzVqZEdsdmJpQW9LU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQnlaWFIxY200Z2RtRnNkV1U3WEc0Z0lDQWdJQ0FnSUgwc1hHNGdJQ0FnSUNBZ0lGd2laMlYwWENJNklHWjFibU4wYVc5dUlDaHVZVzFsS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNGdkbUZzZFdWYmJtRnRaVjA3WEc0Z0lDQWdJQ0FnSUgwc1hHNGdJQ0FnSUNBZ0lGd2ljMlYwWENJNklHWjFibU4wYVc5dUlDaHVZVzFsTENCeWFITXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIWmhiSFZsVzI1aGJXVmRJRDBnY21oek8xeHVJQ0FnSUNBZ0lDQjlMRnh1SUNBZ0lDQWdJQ0JjSW1SbGJHVjBaVndpT2lCbWRXNWpkR2x2YmlBb2JtRnRaU2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdaR1ZzWlhSbElIWmhiSFZsVzI1aGJXVmRPMXh1SUNBZ0lDQWdJQ0I5TEZ4dUlDQWdJQ0FnSUNCY0luQnZjM1JjSWpvZ1puVnVZM1JwYjI0Z0tHNWhiV1VzSUdGeVozTXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDOHZJRTFoY21zZ1RXbHNiR1Z5SUhCeWIzQnZjMlZ6SUhSb1lYUWdjRzl6ZENCM2FYUm9JRzV2SUc1aGJXVWdjMmh2ZFd4a0lHRndjR3g1SUdGY2JpQWdJQ0FnSUNBZ0lDQWdJQzh2SUhCeWIyMXBjMlZrSUdaMWJtTjBhVzl1TGx4dUlDQWdJQ0FnSUNBZ0lDQWdhV1lnS0c1aGJXVWdQVDA5SUc1MWJHd2dmSHdnYm1GdFpTQTlQVDBnZG05cFpDQXdLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSFpoYkhWbExtRndjR3g1S0hadmFXUWdNQ3dnWVhKbmN5azdYRzRnSUNBZ0lDQWdJQ0FnSUNCOUlHVnNjMlVnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhKbGRIVnliaUIyWVd4MVpWdHVZVzFsWFM1aGNIQnNlU2gyWVd4MVpTd2dZWEpuY3lrN1hHNGdJQ0FnSUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUgwc1hHNGdJQ0FnSUNBZ0lGd2lZWEJ3YkhsY0lqb2dablZ1WTNScGIyNGdLSFJvYVhOd0xDQmhjbWR6S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNGdkbUZzZFdVdVlYQndiSGtvZEdocGMzQXNJR0Z5WjNNcE8xeHVJQ0FnSUNBZ0lDQjlMRnh1SUNBZ0lDQWdJQ0JjSW10bGVYTmNJam9nWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJRzlpYW1WamRGOXJaWGx6S0haaGJIVmxLVHRjYmlBZ0lDQWdJQ0FnZlZ4dUlDQWdJSDBzSUhadmFXUWdNQ3dnWm5WdVkzUnBiMjRnYVc1emNHVmpkQ2dwSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUhzZ2MzUmhkR1U2SUZ3aVpuVnNabWxzYkdWa1hDSXNJSFpoYkhWbE9pQjJZV3gxWlNCOU8xeHVJQ0FnSUgwcE8xeHVmVnh1WEc0dktpcGNiaUFxSUVOdmJuWmxjblJ6SUhSb1pXNWhZbXhsY3lCMGJ5QlJJSEJ5YjIxcGMyVnpMbHh1SUNvZ1FIQmhjbUZ0SUhCeWIyMXBjMlVnZEdobGJtRmliR1VnY0hKdmJXbHpaVnh1SUNvZ1FISmxkSFZ5Ym5NZ1lTQlJJSEJ5YjIxcGMyVmNiaUFxTDF4dVpuVnVZM1JwYjI0Z1kyOWxjbU5sS0hCeWIyMXBjMlVwSUh0Y2JpQWdJQ0IyWVhJZ1pHVm1aWEp5WldRZ1BTQmtaV1psY2lncE8xeHVJQ0FnSUZFdWJtVjRkRlJwWTJzb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0IwY25rZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnY0hKdmJXbHpaUzUwYUdWdUtHUmxabVZ5Y21Wa0xuSmxjMjlzZG1Vc0lHUmxabVZ5Y21Wa0xuSmxhbVZqZEN3Z1pHVm1aWEp5WldRdWJtOTBhV1o1S1R0Y2JpQWdJQ0FnSUNBZ2ZTQmpZWFJqYUNBb1pYaGpaWEIwYVc5dUtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCa1pXWmxjbkpsWkM1eVpXcGxZM1FvWlhoalpYQjBhVzl1S1R0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUgwcE8xeHVJQ0FnSUhKbGRIVnliaUJrWldabGNuSmxaQzV3Y205dGFYTmxPMXh1ZlZ4dVhHNHZLaXBjYmlBcUlFRnVibTkwWVhSbGN5QmhiaUJ2WW1wbFkzUWdjM1ZqYUNCMGFHRjBJR2wwSUhkcGJHd2dibVYyWlhJZ1ltVmNiaUFxSUhSeVlXNXpabVZ5Y21Wa0lHRjNZWGtnWm5KdmJTQjBhR2x6SUhCeWIyTmxjM01nYjNabGNpQmhibmtnY0hKdmJXbHpaVnh1SUNvZ1kyOXRiWFZ1YVdOaGRHbHZiaUJqYUdGdWJtVnNMbHh1SUNvZ1FIQmhjbUZ0SUc5aWFtVmpkRnh1SUNvZ1FISmxkSFZ5Ym5NZ2NISnZiV2x6WlNCaElIZHlZWEJ3YVc1bklHOW1JSFJvWVhRZ2IySnFaV04wSUhSb1lYUmNiaUFxSUdGa1pHbDBhVzl1WVd4c2VTQnlaWE53YjI1a2N5QjBieUIwYUdVZ1hDSnBjMFJsWmx3aUlHMWxjM05oWjJWY2JpQXFJSGRwZEdodmRYUWdZU0J5WldwbFkzUnBiMjR1WEc0Z0tpOWNibEV1YldGemRHVnlJRDBnYldGemRHVnlPMXh1Wm5WdVkzUnBiMjRnYldGemRHVnlLRzlpYW1WamRDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCUWNtOXRhWE5sS0h0Y2JpQWdJQ0FnSUNBZ1hDSnBjMFJsWmx3aU9pQm1kVzVqZEdsdmJpQW9LU0I3ZlZ4dUlDQWdJSDBzSUdaMWJtTjBhVzl1SUdaaGJHeGlZV05yS0c5d0xDQmhjbWR6S1NCN1hHNGdJQ0FnSUNBZ0lISmxkSFZ5YmlCa2FYTndZWFJqYUNodlltcGxZM1FzSUc5d0xDQmhjbWR6S1R0Y2JpQWdJQ0I5TENCbWRXNWpkR2x2YmlBb0tTQjdYRzRnSUNBZ0lDQWdJSEpsZEhWeWJpQlJLRzlpYW1WamRDa3VhVzV6Y0dWamRDZ3BPMXh1SUNBZ0lIMHBPMXh1ZlZ4dVhHNHZLaXBjYmlBcUlGTndjbVZoWkhNZ2RHaGxJSFpoYkhWbGN5QnZaaUJoSUhCeWIyMXBjMlZrSUdGeWNtRjVJRzltSUdGeVozVnRaVzUwY3lCcGJuUnZJSFJvWlZ4dUlDb2dablZzWm1sc2JHMWxiblFnWTJGc2JHSmhZMnN1WEc0Z0tpQkFjR0Z5WVcwZ1puVnNabWxzYkdWa0lHTmhiR3hpWVdOcklIUm9ZWFFnY21WalpXbDJaWE1nZG1GeWFXRmthV01nWVhKbmRXMWxiblJ6SUdaeWIyMGdkR2hsWEc0Z0tpQndjbTl0YVhObFpDQmhjbkpoZVZ4dUlDb2dRSEJoY21GdElISmxhbVZqZEdWa0lHTmhiR3hpWVdOcklIUm9ZWFFnY21WalpXbDJaWE1nZEdobElHVjRZMlZ3ZEdsdmJpQnBaaUIwYUdVZ2NISnZiV2x6WlZ4dUlDb2dhWE1nY21WcVpXTjBaV1F1WEc0Z0tpQkFjbVYwZFhKdWN5QmhJSEJ5YjIxcGMyVWdabTl5SUhSb1pTQnlaWFIxY200Z2RtRnNkV1VnYjNJZ2RHaHliM2R1SUdWNFkyVndkR2x2YmlCdlpseHVJQ29nWldsMGFHVnlJR05oYkd4aVlXTnJMbHh1SUNvdlhHNVJMbk53Y21WaFpDQTlJSE53Y21WaFpEdGNibVoxYm1OMGFXOXVJSE53Y21WaFpDaDJZV3gxWlN3Z1puVnNabWxzYkdWa0xDQnlaV3BsWTNSbFpDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCUktIWmhiSFZsS1M1emNISmxZV1FvWm5Wc1ptbHNiR1ZrTENCeVpXcGxZM1JsWkNrN1hHNTlYRzVjYmxCeWIyMXBjMlV1Y0hKdmRHOTBlWEJsTG5Od2NtVmhaQ0E5SUdaMWJtTjBhVzl1SUNobWRXeG1hV3hzWldRc0lISmxhbVZqZEdWa0tTQjdYRzRnSUNBZ2NtVjBkWEp1SUhSb2FYTXVZV3hzS0NrdWRHaGxiaWhtZFc1amRHbHZiaUFvWVhKeVlYa3BJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJR1oxYkdacGJHeGxaQzVoY0hCc2VTaDJiMmxrSURBc0lHRnljbUY1S1R0Y2JpQWdJQ0I5TENCeVpXcGxZM1JsWkNrN1hHNTlPMXh1WEc0dktpcGNiaUFxSUZSb1pTQmhjM2x1WXlCbWRXNWpkR2x2YmlCcGN5QmhJR1JsWTI5eVlYUnZjaUJtYjNJZ1oyVnVaWEpoZEc5eUlHWjFibU4wYVc5dWN5d2dkSFZ5Ym1sdVoxeHVJQ29nZEdobGJTQnBiblJ2SUdGemVXNWphSEp2Ym05MWN5Qm5aVzVsY21GMGIzSnpMaUFnUVd4MGFHOTFaMmdnWjJWdVpYSmhkRzl5Y3lCaGNtVWdiMjVzZVNCd1lYSjBYRzRnS2lCdlppQjBhR1VnYm1WM1pYTjBJRVZEVFVGVFkzSnBjSFFnTmlCa2NtRm1kSE1zSUhSb2FYTWdZMjlrWlNCa2IyVnpJRzV2ZENCallYVnpaU0J6ZVc1MFlYaGNiaUFxSUdWeWNtOXljeUJwYmlCdmJHUmxjaUJsYm1kcGJtVnpMaUFnVkdocGN5QmpiMlJsSUhOb2IzVnNaQ0JqYjI1MGFXNTFaU0IwYnlCM2IzSnJJR0Z1WkNCM2FXeHNYRzRnS2lCcGJpQm1ZV04wSUdsdGNISnZkbVVnYjNabGNpQjBhVzFsSUdGeklIUm9aU0JzWVc1bmRXRm5aU0JwYlhCeWIzWmxjeTVjYmlBcVhHNGdLaUJGVXpZZ1oyVnVaWEpoZEc5eWN5QmhjbVVnWTNWeWNtVnVkR3g1SUhCaGNuUWdiMllnVmpnZ2RtVnljMmx2YmlBekxqRTVJSGRwZEdnZ2RHaGxYRzRnS2lBdExXaGhjbTF2Ym5rdFoyVnVaWEpoZEc5eWN5QnlkVzUwYVcxbElHWnNZV2NnWlc1aFlteGxaQzRnSUZOd2FXUmxjazF2Ym10bGVTQm9ZWE1nYUdGa0lIUm9aVzFjYmlBcUlHWnZjaUJzYjI1blpYSXNJR0oxZENCMWJtUmxjaUJoYmlCdmJHUmxjaUJRZVhSb2IyNHRhVzV6Y0dseVpXUWdabTl5YlM0Z0lGUm9hWE1nWm5WdVkzUnBiMjVjYmlBcUlIZHZjbXR6SUc5dUlHSnZkR2dnYTJsdVpITWdiMllnWjJWdVpYSmhkRzl5Y3k1Y2JpQXFYRzRnS2lCRVpXTnZjbUYwWlhNZ1lTQm5aVzVsY21GMGIzSWdablZ1WTNScGIyNGdjM1ZqYUNCMGFHRjBPbHh1SUNvZ0lDMGdhWFFnYldGNUlIbHBaV3hrSUhCeWIyMXBjMlZ6WEc0Z0tpQWdMU0JsZUdWamRYUnBiMjRnZDJsc2JDQmpiMjUwYVc1MVpTQjNhR1Z1SUhSb1lYUWdjSEp2YldselpTQnBjeUJtZFd4bWFXeHNaV1JjYmlBcUlDQXRJSFJvWlNCMllXeDFaU0J2WmlCMGFHVWdlV2xsYkdRZ1pYaHdjbVZ6YzJsdmJpQjNhV3hzSUdKbElIUm9aU0JtZFd4bWFXeHNaV1FnZG1Gc2RXVmNiaUFxSUNBdElHbDBJSEpsZEhWeWJuTWdZU0J3Y205dGFYTmxJR1p2Y2lCMGFHVWdjbVYwZFhKdUlIWmhiSFZsSUNoM2FHVnVJSFJvWlNCblpXNWxjbUYwYjNKY2JpQXFJQ0FnSUhOMGIzQnpJR2wwWlhKaGRHbHVaeWxjYmlBcUlDQXRJSFJvWlNCa1pXTnZjbUYwWldRZ1puVnVZM1JwYjI0Z2NtVjBkWEp1Y3lCaElIQnliMjFwYzJVZ1ptOXlJSFJvWlNCeVpYUjFjbTRnZG1Gc2RXVmNiaUFxSUNBZ0lHOW1JSFJvWlNCblpXNWxjbUYwYjNJZ2IzSWdkR2hsSUdacGNuTjBJSEpsYW1WamRHVmtJSEJ5YjIxcGMyVWdZVzF2Ym1jZ2RHaHZjMlZjYmlBcUlDQWdJSGxwWld4a1pXUXVYRzRnS2lBZ0xTQnBaaUJoYmlCbGNuSnZjaUJwY3lCMGFISnZkMjRnYVc0Z2RHaGxJR2RsYm1WeVlYUnZjaXdnYVhRZ2NISnZjR0ZuWVhSbGN5QjBhSEp2ZFdkb1hHNGdLaUFnSUNCbGRtVnllU0JtYjJ4c2IzZHBibWNnZVdsbGJHUWdkVzUwYVd3Z2FYUWdhWE1nWTJGMVoyaDBMQ0J2Y2lCMWJuUnBiQ0JwZENCbGMyTmhjR1Z6WEc0Z0tpQWdJQ0IwYUdVZ1oyVnVaWEpoZEc5eUlHWjFibU4wYVc5dUlHRnNkRzluWlhSb1pYSXNJR0Z1WkNCcGN5QjBjbUZ1YzJ4aGRHVmtJR2x1ZEc4Z1lWeHVJQ29nSUNBZ2NtVnFaV04wYVc5dUlHWnZjaUIwYUdVZ2NISnZiV2x6WlNCeVpYUjFjbTVsWkNCaWVTQjBhR1VnWkdWamIzSmhkR1ZrSUdkbGJtVnlZWFJ2Y2k1Y2JpQXFMMXh1VVM1aGMzbHVZeUE5SUdGemVXNWpPMXh1Wm5WdVkzUnBiMjRnWVhONWJtTW9iV0ZyWlVkbGJtVnlZWFJ2Y2lrZ2UxeHVJQ0FnSUhKbGRIVnliaUJtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lDOHZJSGRvWlc0Z2RtVnlZaUJwY3lCY0luTmxibVJjSWl3Z1lYSm5JR2x6SUdFZ2RtRnNkV1ZjYmlBZ0lDQWdJQ0FnTHk4Z2QyaGxiaUIyWlhKaUlHbHpJRndpZEdoeWIzZGNJaXdnWVhKbklHbHpJR0Z1SUdWNFkyVndkR2x2Ymx4dUlDQWdJQ0FnSUNCbWRXNWpkR2x2YmlCamIyNTBhVzUxWlhJb2RtVnlZaXdnWVhKbktTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCMllYSWdjbVZ6ZFd4ME8xeHVYRzRnSUNBZ0lDQWdJQ0FnSUNBdkx5QlZiblJwYkNCV09DQXpMakU1SUM4Z1EyaHliMjFwZFcwZ01qa2dhWE1nY21Wc1pXRnpaV1FzSUZOd2FXUmxjazF2Ym10bGVTQnBjeUIwYUdVZ2IyNXNlVnh1SUNBZ0lDQWdJQ0FnSUNBZ0x5OGdaVzVuYVc1bElIUm9ZWFFnYUdGeklHRWdaR1Z3Ykc5NVpXUWdZbUZ6WlNCdlppQmljbTkzYzJWeWN5QjBhR0YwSUhOMWNIQnZjblFnWjJWdVpYSmhkRzl5Y3k1Y2JpQWdJQ0FnSUNBZ0lDQWdJQzh2SUVodmQyVjJaWElzSUZOTkozTWdaMlZ1WlhKaGRHOXljeUIxYzJVZ2RHaGxJRkI1ZEdodmJpMXBibk53YVhKbFpDQnpaVzFoYm5ScFkzTWdiMlpjYmlBZ0lDQWdJQ0FnSUNBZ0lDOHZJRzkxZEdSaGRHVmtJRVZUTmlCa2NtRm1kSE11SUNCWFpTQjNiM1ZzWkNCc2FXdGxJSFJ2SUhOMWNIQnZjblFnUlZNMkxDQmlkWFFnZDJVblpDQmhiSE52WEc0Z0lDQWdJQ0FnSUNBZ0lDQXZMeUJzYVd0bElIUnZJRzFoYTJVZ2FYUWdjRzl6YzJsaWJHVWdkRzhnZFhObElHZGxibVZ5WVhSdmNuTWdhVzRnWkdWd2JHOTVaV1FnWW5KdmQzTmxjbk1zSUhOdlhHNGdJQ0FnSUNBZ0lDQWdJQ0F2THlCM1pTQmhiSE52SUhOMWNIQnZjblFnVUhsMGFHOXVMWE4wZVd4bElHZGxibVZ5WVhSdmNuTXVJQ0JCZENCemIyMWxJSEJ2YVc1MElIZGxJR05oYmlCeVpXMXZkbVZjYmlBZ0lDQWdJQ0FnSUNBZ0lDOHZJSFJvYVhNZ1lteHZZMnN1WEc1Y2JpQWdJQ0FnSUNBZ0lDQWdJR2xtSUNoMGVYQmxiMllnVTNSdmNFbDBaWEpoZEdsdmJpQTlQVDBnWENKMWJtUmxabWx1WldSY0lpa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQzh2SUVWVE5pQkhaVzVsY21GMGIzSnpYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdkSEo1SUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdjbVZ6ZFd4MElEMGdaMlZ1WlhKaGRHOXlXM1psY21KZEtHRnlaeWs3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnZlNCallYUmphQ0FvWlhoalpYQjBhVzl1S1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQnlaV3BsWTNRb1pYaGpaWEIwYVc5dUtUdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdhV1lnS0hKbGMzVnNkQzVrYjI1bEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUhKbGRIVnliaUJSS0hKbGMzVnNkQzUyWVd4MVpTazdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdmU0JsYkhObElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSGRvWlc0b2NtVnpkV3gwTG5aaGJIVmxMQ0JqWVd4c1ltRmpheXdnWlhKeVltRmpheWs3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNBZ0lDQWdmU0JsYkhObElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQXZMeUJUY0dsa1pYSk5iMjVyWlhrZ1IyVnVaWEpoZEc5eWMxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDOHZJRVpKV0UxRk9pQlNaVzF2ZG1VZ2RHaHBjeUJqWVhObElIZG9aVzRnVTAwZ1pHOWxjeUJGVXpZZ1oyVnVaWEpoZEc5eWN5NWNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjBjbmtnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQnlaWE4xYkhRZ1BTQm5aVzVsY21GMGIzSmJkbVZ5WWwwb1lYSm5LVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0I5SUdOaGRHTm9JQ2hsZUdObGNIUnBiMjRwSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdhV1lnS0dselUzUnZjRWwwWlhKaGRHbHZiaWhsZUdObGNIUnBiMjRwS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCeVpYUjFjbTRnVVNobGVHTmxjSFJwYjI0dWRtRnNkV1VwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUhKbGFtVmpkQ2hsZUdObGNIUnBiMjRwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJSEpsZEhWeWJpQjNhR1Z1S0hKbGMzVnNkQ3dnWTJGc2JHSmhZMnNzSUdWeWNtSmhZMnNwTzF4dUlDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0I5WEc0Z0lDQWdJQ0FnSUhaaGNpQm5aVzVsY21GMGIzSWdQU0J0WVd0bFIyVnVaWEpoZEc5eUxtRndjR3g1S0hSb2FYTXNJR0Z5WjNWdFpXNTBjeWs3WEc0Z0lDQWdJQ0FnSUhaaGNpQmpZV3hzWW1GamF5QTlJR052Ym5ScGJuVmxjaTVpYVc1a0tHTnZiblJwYm5WbGNpd2dYQ0p1WlhoMFhDSXBPMXh1SUNBZ0lDQWdJQ0IyWVhJZ1pYSnlZbUZqYXlBOUlHTnZiblJwYm5WbGNpNWlhVzVrS0dOdmJuUnBiblZsY2l3Z1hDSjBhSEp2ZDF3aUtUdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHTmhiR3hpWVdOcktDazdYRzRnSUNBZ2ZUdGNibjFjYmx4dUx5b3FYRzRnS2lCVWFHVWdjM0JoZDI0Z1puVnVZM1JwYjI0Z2FYTWdZU0J6YldGc2JDQjNjbUZ3Y0dWeUlHRnliM1Z1WkNCaGMzbHVZeUIwYUdGMElHbHRiV1ZrYVdGMFpXeDVYRzRnS2lCallXeHNjeUIwYUdVZ1oyVnVaWEpoZEc5eUlHRnVaQ0JoYkhOdklHVnVaSE1nZEdobElIQnliMjFwYzJVZ1kyaGhhVzRzSUhOdklIUm9ZWFFnWVc1NVhHNGdLaUIxYm1oaGJtUnNaV1FnWlhKeWIzSnpJR0Z5WlNCMGFISnZkMjRnYVc1emRHVmhaQ0J2WmlCbWIzSjNZWEprWldRZ2RHOGdkR2hsSUdWeWNtOXlYRzRnS2lCb1lXNWtiR1Z5TGlCVWFHbHpJR2x6SUhWelpXWjFiQ0JpWldOaGRYTmxJR2wwSjNNZ1pYaDBjbVZ0Wld4NUlHTnZiVzF2YmlCMGJ5QnlkVzVjYmlBcUlHZGxibVZ5WVhSdmNuTWdZWFFnZEdobElIUnZjQzFzWlhabGJDQjBieUIzYjNKcklIZHBkR2dnYkdsaWNtRnlhV1Z6TGx4dUlDb3ZYRzVSTG5Od1lYZHVJRDBnYzNCaGQyNDdYRzVtZFc1amRHbHZiaUJ6Y0dGM2JpaHRZV3RsUjJWdVpYSmhkRzl5S1NCN1hHNGdJQ0FnVVM1a2IyNWxLRkV1WVhONWJtTW9iV0ZyWlVkbGJtVnlZWFJ2Y2lrb0tTazdYRzU5WEc1Y2JpOHZJRVpKV0UxRk9pQlNaVzF2ZG1VZ2RHaHBjeUJwYm5SbGNtWmhZMlVnYjI1alpTQkZVellnWjJWdVpYSmhkRzl5Y3lCaGNtVWdhVzRnVTNCcFpHVnlUVzl1YTJWNUxseHVMeW9xWEc0Z0tpQlVhSEp2ZDNNZ1lTQlNaWFIxY201V1lXeDFaU0JsZUdObGNIUnBiMjRnZEc4Z2MzUnZjQ0JoYmlCaGMzbHVZMmh5YjI1dmRYTWdaMlZ1WlhKaGRHOXlMbHh1SUNwY2JpQXFJRlJvYVhNZ2FXNTBaWEptWVdObElHbHpJR0VnYzNSdmNDMW5ZWEFnYldWaGMzVnlaU0IwYnlCemRYQndiM0owSUdkbGJtVnlZWFJ2Y2lCeVpYUjFjbTVjYmlBcUlIWmhiSFZsY3lCcGJpQnZiR1JsY2lCR2FYSmxabTk0TDFOd2FXUmxjazF2Ym10bGVTNGdJRWx1SUdKeWIzZHpaWEp6SUhSb1lYUWdjM1Z3Y0c5eWRDQkZVelpjYmlBcUlHZGxibVZ5WVhSdmNuTWdiR2xyWlNCRGFISnZiV2wxYlNBeU9Td2dhblZ6ZENCMWMyVWdYQ0p5WlhSMWNtNWNJaUJwYmlCNWIzVnlJR2RsYm1WeVlYUnZjbHh1SUNvZ1puVnVZM1JwYjI1ekxseHVJQ3BjYmlBcUlFQndZWEpoYlNCMllXeDFaU0IwYUdVZ2NtVjBkWEp1SUhaaGJIVmxJR1p2Y2lCMGFHVWdjM1Z5Y205MWJtUnBibWNnWjJWdVpYSmhkRzl5WEc0Z0tpQkFkR2h5YjNkeklGSmxkSFZ5YmxaaGJIVmxJR1Y0WTJWd2RHbHZiaUIzYVhSb0lIUm9aU0IyWVd4MVpTNWNiaUFxSUVCbGVHRnRjR3hsWEc0Z0tpQXZMeUJGVXpZZ2MzUjViR1ZjYmlBcUlGRXVZWE41Ym1Nb1puVnVZM1JwYjI0cUlDZ3BJSHRjYmlBcUlDQWdJQ0FnZG1GeUlHWnZieUE5SUhscFpXeGtJR2RsZEVadmIxQnliMjFwYzJVb0tUdGNiaUFxSUNBZ0lDQWdkbUZ5SUdKaGNpQTlJSGxwWld4a0lHZGxkRUpoY2xCeWIyMXBjMlVvS1R0Y2JpQXFJQ0FnSUNBZ2NtVjBkWEp1SUdadmJ5QXJJR0poY2p0Y2JpQXFJSDBwWEc0Z0tpQXZMeUJQYkdSbGNpQlRjR2xrWlhKTmIyNXJaWGtnYzNSNWJHVmNiaUFxSUZFdVlYTjVibU1vWm5WdVkzUnBiMjRnS0NrZ2UxeHVJQ29nSUNBZ0lDQjJZWElnWm05dklEMGdlV2xsYkdRZ1oyVjBSbTl2VUhKdmJXbHpaU2dwTzF4dUlDb2dJQ0FnSUNCMllYSWdZbUZ5SUQwZ2VXbGxiR1FnWjJWMFFtRnlVSEp2YldselpTZ3BPMXh1SUNvZ0lDQWdJQ0JSTG5KbGRIVnliaWhtYjI4Z0t5QmlZWElwTzF4dUlDb2dmU2xjYmlBcUwxeHVVVnRjSW5KbGRIVnlibHdpWFNBOUlGOXlaWFIxY200N1hHNW1kVzVqZEdsdmJpQmZjbVYwZFhKdUtIWmhiSFZsS1NCN1hHNGdJQ0FnZEdoeWIzY2dibVYzSUZGU1pYUjFjbTVXWVd4MVpTaDJZV3gxWlNrN1hHNTlYRzVjYmk4cUtseHVJQ29nVkdobElIQnliMjFwYzJWa0lHWjFibU4wYVc5dUlHUmxZMjl5WVhSdmNpQmxibk4xY21WeklIUm9ZWFFnWVc1NUlIQnliMjFwYzJVZ1lYSm5kVzFsYm5SelhHNGdLaUJoY21VZ2MyVjBkR3hsWkNCaGJtUWdjR0Z6YzJWa0lHRnpJSFpoYkhWbGN5QW9ZSFJvYVhOZ0lHbHpJR0ZzYzI4Z2MyVjBkR3hsWkNCaGJtUWdjR0Z6YzJWa1hHNGdLaUJoY3lCaElIWmhiSFZsS1M0Z0lFbDBJSGRwYkd3Z1lXeHpieUJsYm5OMWNtVWdkR2hoZENCMGFHVWdjbVZ6ZFd4MElHOW1JR0VnWm5WdVkzUnBiMjRnYVhOY2JpQXFJR0ZzZDJGNWN5QmhJSEJ5YjIxcGMyVXVYRzRnS2x4dUlDb2dRR1Y0WVcxd2JHVmNiaUFxSUhaaGNpQmhaR1FnUFNCUkxuQnliMjFwYzJWa0tHWjFibU4wYVc5dUlDaGhMQ0JpS1NCN1hHNGdLaUFnSUNBZ2NtVjBkWEp1SUdFZ0t5QmlPMXh1SUNvZ2ZTazdYRzRnS2lCaFpHUW9VU2hoS1N3Z1VTaENLU2s3WEc0Z0tseHVJQ29nUUhCaGNtRnRJSHRtZFc1amRHbHZibjBnWTJGc2JHSmhZMnNnVkdobElHWjFibU4wYVc5dUlIUnZJR1JsWTI5eVlYUmxYRzRnS2lCQWNtVjBkWEp1Y3lCN1puVnVZM1JwYjI1OUlHRWdablZ1WTNScGIyNGdkR2hoZENCb1lYTWdZbVZsYmlCa1pXTnZjbUYwWldRdVhHNGdLaTljYmxFdWNISnZiV2x6WldRZ1BTQndjbTl0YVhObFpEdGNibVoxYm1OMGFXOXVJSEJ5YjIxcGMyVmtLR05oYkd4aVlXTnJLU0I3WEc0Z0lDQWdjbVYwZFhKdUlHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJSE53Y21WaFpDaGJkR2hwY3l3Z1lXeHNLR0Z5WjNWdFpXNTBjeWxkTENCbWRXNWpkR2x2YmlBb2MyVnNaaXdnWVhKbmN5a2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUdOaGJHeGlZV05yTG1Gd2NHeDVLSE5sYkdZc0lHRnlaM01wTzF4dUlDQWdJQ0FnSUNCOUtUdGNiaUFnSUNCOU8xeHVmVnh1WEc0dktpcGNiaUFxSUhObGJtUnpJR0VnYldWemMyRm5aU0IwYnlCaElIWmhiSFZsSUdsdUlHRWdablYwZFhKbElIUjFjbTVjYmlBcUlFQndZWEpoYlNCdlltcGxZM1FxSUhSb1pTQnlaV05wY0dsbGJuUmNiaUFxSUVCd1lYSmhiU0J2Y0NCMGFHVWdibUZ0WlNCdlppQjBhR1VnYldWemMyRm5aU0J2Y0dWeVlYUnBiMjRzSUdVdVp5NHNJRndpZDJobGJsd2lMRnh1SUNvZ1FIQmhjbUZ0SUdGeVozTWdablZ5ZEdobGNpQmhjbWQxYldWdWRITWdkRzhnWW1VZ1ptOXlkMkZ5WkdWa0lIUnZJSFJvWlNCdmNHVnlZWFJwYjI1Y2JpQXFJRUJ5WlhSMWNtNXpJSEpsYzNWc2RDQjdVSEp2YldselpYMGdZU0J3Y205dGFYTmxJR1p2Y2lCMGFHVWdjbVZ6ZFd4MElHOW1JSFJvWlNCdmNHVnlZWFJwYjI1Y2JpQXFMMXh1VVM1a2FYTndZWFJqYUNBOUlHUnBjM0JoZEdOb08xeHVablZ1WTNScGIyNGdaR2x6Y0dGMFkyZ29iMkpxWldOMExDQnZjQ3dnWVhKbmN5a2dlMXh1SUNBZ0lISmxkSFZ5YmlCUktHOWlhbVZqZENrdVpHbHpjR0YwWTJnb2IzQXNJR0Z5WjNNcE8xeHVmVnh1WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1a2FYTndZWFJqYUNBOUlHWjFibU4wYVc5dUlDaHZjQ3dnWVhKbmN5a2dlMXh1SUNBZ0lIWmhjaUJ6Wld4bUlEMGdkR2hwY3p0Y2JpQWdJQ0IyWVhJZ1pHVm1aWEp5WldRZ1BTQmtaV1psY2lncE8xeHVJQ0FnSUZFdWJtVjRkRlJwWTJzb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0J6Wld4bUxuQnliMjFwYzJWRWFYTndZWFJqYUNoa1pXWmxjbkpsWkM1eVpYTnZiSFpsTENCdmNDd2dZWEpuY3lrN1hHNGdJQ0FnZlNrN1hHNGdJQ0FnY21WMGRYSnVJR1JsWm1WeWNtVmtMbkJ5YjIxcGMyVTdYRzU5TzF4dVhHNHZLaXBjYmlBcUlFZGxkSE1nZEdobElIWmhiSFZsSUc5bUlHRWdjSEp2Y0dWeWRIa2dhVzRnWVNCbWRYUjFjbVVnZEhWeWJpNWNiaUFxSUVCd1lYSmhiU0J2WW1wbFkzUWdJQ0FnY0hKdmJXbHpaU0J2Y2lCcGJXMWxaR2xoZEdVZ2NtVm1aWEpsYm1ObElHWnZjaUIwWVhKblpYUWdiMkpxWldOMFhHNGdLaUJBY0dGeVlXMGdibUZ0WlNBZ0lDQWdJRzVoYldVZ2IyWWdjSEp2Y0dWeWRIa2dkRzhnWjJWMFhHNGdLaUJBY21WMGRYSnVJSEJ5YjIxcGMyVWdabTl5SUhSb1pTQndjbTl3WlhKMGVTQjJZV3gxWlZ4dUlDb3ZYRzVSTG1kbGRDQTlJR1oxYm1OMGFXOXVJQ2h2WW1wbFkzUXNJR3RsZVNrZ2UxeHVJQ0FnSUhKbGRIVnliaUJSS0c5aWFtVmpkQ2t1WkdsemNHRjBZMmdvWENKblpYUmNJaXdnVzJ0bGVWMHBPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXVaMlYwSUQwZ1puVnVZM1JwYjI0Z0tHdGxlU2tnZTF4dUlDQWdJSEpsZEhWeWJpQjBhR2x6TG1ScGMzQmhkR05vS0Z3aVoyVjBYQ0lzSUZ0clpYbGRLVHRjYm4wN1hHNWNiaThxS2x4dUlDb2dVMlYwY3lCMGFHVWdkbUZzZFdVZ2IyWWdZU0J3Y205d1pYSjBlU0JwYmlCaElHWjFkSFZ5WlNCMGRYSnVMbHh1SUNvZ1FIQmhjbUZ0SUc5aWFtVmpkQ0FnSUNCd2NtOXRhWE5sSUc5eUlHbHRiV1ZrYVdGMFpTQnlaV1psY21WdVkyVWdabTl5SUc5aWFtVmpkQ0J2WW1wbFkzUmNiaUFxSUVCd1lYSmhiU0J1WVcxbElDQWdJQ0FnYm1GdFpTQnZaaUJ3Y205d1pYSjBlU0IwYnlCelpYUmNiaUFxSUVCd1lYSmhiU0IyWVd4MVpTQWdJQ0FnYm1WM0lIWmhiSFZsSUc5bUlIQnliM0JsY25SNVhHNGdLaUJBY21WMGRYSnVJSEJ5YjIxcGMyVWdabTl5SUhSb1pTQnlaWFIxY200Z2RtRnNkV1ZjYmlBcUwxeHVVUzV6WlhRZ1BTQm1kVzVqZEdsdmJpQW9iMkpxWldOMExDQnJaWGtzSUhaaGJIVmxLU0I3WEc0Z0lDQWdjbVYwZFhKdUlGRW9iMkpxWldOMEtTNWthWE53WVhSamFDaGNJbk5sZEZ3aUxDQmJhMlY1TENCMllXeDFaVjBwTzF4dWZUdGNibHh1VUhKdmJXbHpaUzV3Y205MGIzUjVjR1V1YzJWMElEMGdablZ1WTNScGIyNGdLR3RsZVN3Z2RtRnNkV1VwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdkR2hwY3k1a2FYTndZWFJqYUNoY0luTmxkRndpTENCYmEyVjVMQ0IyWVd4MVpWMHBPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQkVaV3hsZEdWeklHRWdjSEp2Y0dWeWRIa2dhVzRnWVNCbWRYUjFjbVVnZEhWeWJpNWNiaUFxSUVCd1lYSmhiU0J2WW1wbFkzUWdJQ0FnY0hKdmJXbHpaU0J2Y2lCcGJXMWxaR2xoZEdVZ2NtVm1aWEpsYm1ObElHWnZjaUIwWVhKblpYUWdiMkpxWldOMFhHNGdLaUJBY0dGeVlXMGdibUZ0WlNBZ0lDQWdJRzVoYldVZ2IyWWdjSEp2Y0dWeWRIa2dkRzhnWkdWc1pYUmxYRzRnS2lCQWNtVjBkWEp1SUhCeWIyMXBjMlVnWm05eUlIUm9aU0J5WlhSMWNtNGdkbUZzZFdWY2JpQXFMMXh1VVM1a1pXd2dQU0F2THlCWVdGZ2diR1ZuWVdONVhHNVJXMXdpWkdWc1pYUmxYQ0pkSUQwZ1puVnVZM1JwYjI0Z0tHOWlhbVZqZEN3Z2EyVjVLU0I3WEc0Z0lDQWdjbVYwZFhKdUlGRW9iMkpxWldOMEtTNWthWE53WVhSamFDaGNJbVJsYkdWMFpWd2lMQ0JiYTJWNVhTazdYRzU5TzF4dVhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNWtaV3dnUFNBdkx5QllXRmdnYkdWbllXTjVYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaVnRjSW1SbGJHVjBaVndpWFNBOUlHWjFibU4wYVc5dUlDaHJaWGtwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdkR2hwY3k1a2FYTndZWFJqYUNoY0ltUmxiR1YwWlZ3aUxDQmJhMlY1WFNrN1hHNTlPMXh1WEc0dktpcGNiaUFxSUVsdWRtOXJaWE1nWVNCdFpYUm9iMlFnYVc0Z1lTQm1kWFIxY21VZ2RIVnliaTVjYmlBcUlFQndZWEpoYlNCdlltcGxZM1FnSUNBZ2NISnZiV2x6WlNCdmNpQnBiVzFsWkdsaGRHVWdjbVZtWlhKbGJtTmxJR1p2Y2lCMFlYSm5aWFFnYjJKcVpXTjBYRzRnS2lCQWNHRnlZVzBnYm1GdFpTQWdJQ0FnSUc1aGJXVWdiMllnYldWMGFHOWtJSFJ2SUdsdWRtOXJaVnh1SUNvZ1FIQmhjbUZ0SUhaaGJIVmxJQ0FnSUNCaElIWmhiSFZsSUhSdklIQnZjM1FzSUhSNWNHbGpZV3hzZVNCaGJpQmhjbkpoZVNCdlpseHVJQ29nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JwYm5adlkyRjBhVzl1SUdGeVozVnRaVzUwY3lCbWIzSWdjSEp2YldselpYTWdkR2hoZEZ4dUlDb2dJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQmhjbVVnZFd4MGFXMWhkR1ZzZVNCaVlXTnJaV1FnZDJsMGFDQmdjbVZ6YjJ4MlpXQWdkbUZzZFdWekxGeHVJQ29nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JoY3lCdmNIQnZjMlZrSUhSdklIUm9iM05sSUdKaFkydGxaQ0IzYVhSb0lGVlNUSE5jYmlBcUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2QyaGxjbVZwYmlCMGFHVWdjRzl6ZEdWa0lIWmhiSFZsSUdOaGJpQmlaU0JoYm5sY2JpQXFJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdTbE5QVGlCelpYSnBZV3hwZW1GaWJHVWdiMkpxWldOMExseHVJQ29nUUhKbGRIVnliaUJ3Y205dGFYTmxJR1p2Y2lCMGFHVWdjbVYwZFhKdUlIWmhiSFZsWEc0Z0tpOWNiaTh2SUdKdmRXNWtJR3h2WTJGc2JIa2dZbVZqWVhWelpTQnBkQ0JwY3lCMWMyVmtJR0o1SUc5MGFHVnlJRzFsZEdodlpITmNibEV1YldGd2NHeDVJRDBnTHk4Z1dGaFlJRUZ6SUhCeWIzQnZjMlZrSUdKNUlGd2lVbVZrYzJGdVpISnZYQ0pjYmxFdWNHOXpkQ0E5SUdaMWJtTjBhVzl1SUNodlltcGxZM1FzSUc1aGJXVXNJR0Z5WjNNcElIdGNiaUFnSUNCeVpYUjFjbTRnVVNodlltcGxZM1FwTG1ScGMzQmhkR05vS0Z3aWNHOXpkRndpTENCYmJtRnRaU3dnWVhKbmMxMHBPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXViV0Z3Y0d4NUlEMGdMeThnV0ZoWUlFRnpJSEJ5YjNCdmMyVmtJR0o1SUZ3aVVtVmtjMkZ1WkhKdlhDSmNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbkJ2YzNRZ1BTQm1kVzVqZEdsdmJpQW9ibUZ0WlN3Z1lYSm5jeWtnZTF4dUlDQWdJSEpsZEhWeWJpQjBhR2x6TG1ScGMzQmhkR05vS0Z3aWNHOXpkRndpTENCYmJtRnRaU3dnWVhKbmMxMHBPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQkpiblp2YTJWeklHRWdiV1YwYUc5a0lHbHVJR0VnWm5WMGRYSmxJSFIxY200dVhHNGdLaUJBY0dGeVlXMGdiMkpxWldOMElDQWdJSEJ5YjIxcGMyVWdiM0lnYVcxdFpXUnBZWFJsSUhKbFptVnlaVzVqWlNCbWIzSWdkR0Z5WjJWMElHOWlhbVZqZEZ4dUlDb2dRSEJoY21GdElHNWhiV1VnSUNBZ0lDQnVZVzFsSUc5bUlHMWxkR2h2WkNCMGJ5QnBiblp2YTJWY2JpQXFJRUJ3WVhKaGJTQXVMaTVoY21keklDQWdZWEp5WVhrZ2IyWWdhVzUyYjJOaGRHbHZiaUJoY21kMWJXVnVkSE5jYmlBcUlFQnlaWFIxY200Z2NISnZiV2x6WlNCbWIzSWdkR2hsSUhKbGRIVnliaUIyWVd4MVpWeHVJQ292WEc1UkxuTmxibVFnUFNBdkx5QllXRmdnVFdGeWF5Qk5hV3hzWlhJbmN5QndjbTl3YjNObFpDQndZWEpzWVc1alpWeHVVUzV0WTJGc2JDQTlJQzh2SUZoWVdDQkJjeUJ3Y205d2IzTmxaQ0JpZVNCY0lsSmxaSE5oYm1SeWIxd2lYRzVSTG1sdWRtOXJaU0E5SUdaMWJtTjBhVzl1SUNodlltcGxZM1FzSUc1aGJXVWdMeW91TGk1aGNtZHpLaThwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdVU2h2WW1wbFkzUXBMbVJwYzNCaGRHTm9LRndpY0c5emRGd2lMQ0JiYm1GdFpTd2dZWEp5WVhsZmMyeHBZMlVvWVhKbmRXMWxiblJ6TENBeUtWMHBPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXVjMlZ1WkNBOUlDOHZJRmhZV0NCTllYSnJJRTFwYkd4bGNpZHpJSEJ5YjNCdmMyVmtJSEJoY214aGJtTmxYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaUzV0WTJGc2JDQTlJQzh2SUZoWVdDQkJjeUJ3Y205d2IzTmxaQ0JpZVNCY0lsSmxaSE5oYm1SeWIxd2lYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaUzVwYm5admEyVWdQU0JtZFc1amRHbHZiaUFvYm1GdFpTQXZLaTR1TG1GeVozTXFMeWtnZTF4dUlDQWdJSEpsZEhWeWJpQjBhR2x6TG1ScGMzQmhkR05vS0Z3aWNHOXpkRndpTENCYmJtRnRaU3dnWVhKeVlYbGZjMnhwWTJVb1lYSm5kVzFsYm5SekxDQXhLVjBwTzF4dWZUdGNibHh1THlvcVhHNGdLaUJCY0hCc2FXVnpJSFJvWlNCd2NtOXRhWE5sWkNCbWRXNWpkR2x2YmlCcGJpQmhJR1oxZEhWeVpTQjBkWEp1TGx4dUlDb2dRSEJoY21GdElHOWlhbVZqZENBZ0lDQndjbTl0YVhObElHOXlJR2x0YldWa2FXRjBaU0J5WldabGNtVnVZMlVnWm05eUlIUmhjbWRsZENCbWRXNWpkR2x2Ymx4dUlDb2dRSEJoY21GdElHRnlaM01nSUNBZ0lDQmhjbkpoZVNCdlppQmhjSEJzYVdOaGRHbHZiaUJoY21kMWJXVnVkSE5jYmlBcUwxeHVVUzVtWVhCd2JIa2dQU0JtZFc1amRHbHZiaUFvYjJKcVpXTjBMQ0JoY21kektTQjdYRzRnSUNBZ2NtVjBkWEp1SUZFb2IySnFaV04wS1M1a2FYTndZWFJqYUNoY0ltRndjR3g1WENJc0lGdDJiMmxrSURBc0lHRnlaM05kS1R0Y2JuMDdYRzVjYmxCeWIyMXBjMlV1Y0hKdmRHOTBlWEJsTG1aaGNIQnNlU0E5SUdaMWJtTjBhVzl1SUNoaGNtZHpLU0I3WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11WkdsemNHRjBZMmdvWENKaGNIQnNlVndpTENCYmRtOXBaQ0F3TENCaGNtZHpYU2s3WEc1OU8xeHVYRzR2S2lwY2JpQXFJRU5oYkd4eklIUm9aU0J3Y205dGFYTmxaQ0JtZFc1amRHbHZiaUJwYmlCaElHWjFkSFZ5WlNCMGRYSnVMbHh1SUNvZ1FIQmhjbUZ0SUc5aWFtVmpkQ0FnSUNCd2NtOXRhWE5sSUc5eUlHbHRiV1ZrYVdGMFpTQnlaV1psY21WdVkyVWdabTl5SUhSaGNtZGxkQ0JtZFc1amRHbHZibHh1SUNvZ1FIQmhjbUZ0SUM0dUxtRnlaM01nSUNCaGNuSmhlU0J2WmlCaGNIQnNhV05oZEdsdmJpQmhjbWQxYldWdWRITmNiaUFxTDF4dVVWdGNJblJ5ZVZ3aVhTQTlYRzVSTG1aallXeHNJRDBnWm5WdVkzUnBiMjRnS0c5aWFtVmpkQ0F2S2lBdUxpNWhjbWR6S2k4cElIdGNiaUFnSUNCeVpYUjFjbTRnVVNodlltcGxZM1FwTG1ScGMzQmhkR05vS0Z3aVlYQndiSGxjSWl3Z1czWnZhV1FnTUN3Z1lYSnlZWGxmYzJ4cFkyVW9ZWEpuZFcxbGJuUnpMQ0F4S1YwcE8xeHVmVHRjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdVptTmhiR3dnUFNCbWRXNWpkR2x2YmlBb0x5b3VMaTVoY21kektpOHBJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTVrYVhOd1lYUmphQ2hjSW1Gd2NHeDVYQ0lzSUZ0MmIybGtJREFzSUdGeWNtRjVYM05zYVdObEtHRnlaM1Z0Wlc1MGN5bGRLVHRjYm4wN1hHNWNiaThxS2x4dUlDb2dRbWx1WkhNZ2RHaGxJSEJ5YjIxcGMyVmtJR1oxYm1OMGFXOXVMQ0IwY21GdWMyWnZjbTFwYm1jZ2NtVjBkWEp1SUhaaGJIVmxjeUJwYm5SdklHRWdablZzWm1sc2JHVmtYRzRnS2lCd2NtOXRhWE5sSUdGdVpDQjBhSEp2ZDI0Z1pYSnliM0p6SUdsdWRHOGdZU0J5WldwbFkzUmxaQ0J2Ym1VdVhHNGdLaUJBY0dGeVlXMGdiMkpxWldOMElDQWdJSEJ5YjIxcGMyVWdiM0lnYVcxdFpXUnBZWFJsSUhKbFptVnlaVzVqWlNCbWIzSWdkR0Z5WjJWMElHWjFibU4wYVc5dVhHNGdLaUJBY0dGeVlXMGdMaTR1WVhKbmN5QWdJR0Z5Y21GNUlHOW1JR0Z3Y0d4cFkyRjBhVzl1SUdGeVozVnRaVzUwYzF4dUlDb3ZYRzVSTG1aaWFXNWtJRDBnWm5WdVkzUnBiMjRnS0c5aWFtVmpkQ0F2S2k0dUxtRnlaM01xTHlrZ2UxeHVJQ0FnSUhaaGNpQndjbTl0YVhObElEMGdVU2h2WW1wbFkzUXBPMXh1SUNBZ0lIWmhjaUJoY21keklEMGdZWEp5WVhsZmMyeHBZMlVvWVhKbmRXMWxiblJ6TENBeEtUdGNiaUFnSUNCeVpYUjFjbTRnWm5WdVkzUnBiMjRnWm1KdmRXNWtLQ2tnZTF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnY0hKdmJXbHpaUzVrYVhOd1lYUmphQ2hjSW1Gd2NHeDVYQ0lzSUZ0Y2JpQWdJQ0FnSUNBZ0lDQWdJSFJvYVhNc1hHNGdJQ0FnSUNBZ0lDQWdJQ0JoY21kekxtTnZibU5oZENoaGNuSmhlVjl6YkdsalpTaGhjbWQxYldWdWRITXBLVnh1SUNBZ0lDQWdJQ0JkS1R0Y2JpQWdJQ0I5TzF4dWZUdGNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbVppYVc1a0lEMGdablZ1WTNScGIyNGdLQzhxTGk0dVlYSm5jeW92S1NCN1hHNGdJQ0FnZG1GeUlIQnliMjFwYzJVZ1BTQjBhR2x6TzF4dUlDQWdJSFpoY2lCaGNtZHpJRDBnWVhKeVlYbGZjMnhwWTJVb1lYSm5kVzFsYm5SektUdGNiaUFnSUNCeVpYUjFjbTRnWm5WdVkzUnBiMjRnWm1KdmRXNWtLQ2tnZTF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnY0hKdmJXbHpaUzVrYVhOd1lYUmphQ2hjSW1Gd2NHeDVYQ0lzSUZ0Y2JpQWdJQ0FnSUNBZ0lDQWdJSFJvYVhNc1hHNGdJQ0FnSUNBZ0lDQWdJQ0JoY21kekxtTnZibU5oZENoaGNuSmhlVjl6YkdsalpTaGhjbWQxYldWdWRITXBLVnh1SUNBZ0lDQWdJQ0JkS1R0Y2JpQWdJQ0I5TzF4dWZUdGNibHh1THlvcVhHNGdLaUJTWlhGMVpYTjBjeUIwYUdVZ2JtRnRaWE1nYjJZZ2RHaGxJRzkzYm1Wa0lIQnliM0JsY25ScFpYTWdiMllnWVNCd2NtOXRhWE5sWkZ4dUlDb2diMkpxWldOMElHbHVJR0VnWm5WMGRYSmxJSFIxY200dVhHNGdLaUJBY0dGeVlXMGdiMkpxWldOMElDQWdJSEJ5YjIxcGMyVWdiM0lnYVcxdFpXUnBZWFJsSUhKbFptVnlaVzVqWlNCbWIzSWdkR0Z5WjJWMElHOWlhbVZqZEZ4dUlDb2dRSEpsZEhWeWJpQndjbTl0YVhObElHWnZjaUIwYUdVZ2EyVjVjeUJ2WmlCMGFHVWdaWFpsYm5SMVlXeHNlU0J6WlhSMGJHVmtJRzlpYW1WamRGeHVJQ292WEc1UkxtdGxlWE1nUFNCbWRXNWpkR2x2YmlBb2IySnFaV04wS1NCN1hHNGdJQ0FnY21WMGRYSnVJRkVvYjJKcVpXTjBLUzVrYVhOd1lYUmphQ2hjSW10bGVYTmNJaXdnVzEwcE8xeHVmVHRjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdWEyVjVjeUE5SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNCeVpYUjFjbTRnZEdocGN5NWthWE53WVhSamFDaGNJbXRsZVhOY0lpd2dXMTBwTzF4dWZUdGNibHh1THlvcVhHNGdLaUJVZFhKdWN5QmhiaUJoY25KaGVTQnZaaUJ3Y205dGFYTmxjeUJwYm5SdklHRWdjSEp2YldselpTQm1iM0lnWVc0Z1lYSnlZWGt1SUNCSlppQmhibmtnYjJaY2JpQXFJSFJvWlNCd2NtOXRhWE5sY3lCblpYUnpJSEpsYW1WamRHVmtMQ0IwYUdVZ2QyaHZiR1VnWVhKeVlYa2dhWE1nY21WcVpXTjBaV1FnYVcxdFpXUnBZWFJsYkhrdVhHNGdLaUJBY0dGeVlXMGdlMEZ5Y21GNUtuMGdZVzRnWVhKeVlYa2dLRzl5SUhCeWIyMXBjMlVnWm05eUlHRnVJR0Z5Y21GNUtTQnZaaUIyWVd4MVpYTWdLRzl5WEc0Z0tpQndjbTl0YVhObGN5Qm1iM0lnZG1Gc2RXVnpLVnh1SUNvZ1FISmxkSFZ5Ym5NZ1lTQndjbTl0YVhObElHWnZjaUJoYmlCaGNuSmhlU0J2WmlCMGFHVWdZMjl5Y21WemNHOXVaR2x1WnlCMllXeDFaWE5jYmlBcUwxeHVMeThnUW5rZ1RXRnlheUJOYVd4c1pYSmNiaTh2SUdoMGRIQTZMeTkzYVd0cExtVmpiV0Z6WTNKcGNIUXViM0puTDJSdmEzVXVjR2h3UDJsa1BYTjBjbUYzYldGdU9tTnZibU4xY25KbGJtTjVKbkpsZGoweE16QTROemMyTlRJeEkyRnNiR1oxYkdacGJHeGxaRnh1VVM1aGJHd2dQU0JoYkd3N1hHNW1kVzVqZEdsdmJpQmhiR3dvY0hKdmJXbHpaWE1wSUh0Y2JpQWdJQ0J5WlhSMWNtNGdkMmhsYmlod2NtOXRhWE5sY3l3Z1puVnVZM1JwYjI0Z0tIQnliMjFwYzJWektTQjdYRzRnSUNBZ0lDQWdJSFpoY2lCd1pXNWthVzVuUTI5MWJuUWdQU0F3TzF4dUlDQWdJQ0FnSUNCMllYSWdaR1ZtWlhKeVpXUWdQU0JrWldabGNpZ3BPMXh1SUNBZ0lDQWdJQ0JoY25KaGVWOXlaV1IxWTJVb2NISnZiV2x6WlhNc0lHWjFibU4wYVc5dUlDaDFibVJsWm1sdVpXUXNJSEJ5YjIxcGMyVXNJR2x1WkdWNEtTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCMllYSWdjMjVoY0hOb2IzUTdYRzRnSUNBZ0lDQWdJQ0FnSUNCcFppQW9YRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdhWE5RY205dGFYTmxLSEJ5YjIxcGMyVXBJQ1ltWEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnS0hOdVlYQnphRzkwSUQwZ2NISnZiV2x6WlM1cGJuTndaV04wS0NrcExuTjBZWFJsSUQwOVBTQmNJbVoxYkdacGJHeGxaRndpWEc0Z0lDQWdJQ0FnSUNBZ0lDQXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0J3Y205dGFYTmxjMXRwYm1SbGVGMGdQU0J6Ym1Gd2MyaHZkQzUyWVd4MVpUdGNiaUFnSUNBZ0lDQWdJQ0FnSUgwZ1pXeHpaU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnS3l0d1pXNWthVzVuUTI5MWJuUTdYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdkMmhsYmloY2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdjSEp2YldselpTeGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnWm5WdVkzUnBiMjRnS0haaGJIVmxLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0J3Y205dGFYTmxjMXRwYm1SbGVGMGdQU0IyWVd4MVpUdGNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lHbG1JQ2d0TFhCbGJtUnBibWREYjNWdWRDQTlQVDBnTUNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJR1JsWm1WeWNtVmtMbkpsYzI5c2RtVW9jSEp2YldselpYTXBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdmVnh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCOUxGeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JrWldabGNuSmxaQzV5WldwbFkzUXNYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUdaMWJtTjBhVzl1SUNod2NtOW5jbVZ6Y3lrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ1pHVm1aWEp5WldRdWJtOTBhV1o1S0hzZ2FXNWtaWGc2SUdsdVpHVjRMQ0IyWVd4MVpUb2djSEp2WjNKbGMzTWdmU2s3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lIMWNiaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQXBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQjlMQ0IyYjJsa0lEQXBPMXh1SUNBZ0lDQWdJQ0JwWmlBb2NHVnVaR2x1WjBOdmRXNTBJRDA5UFNBd0tTQjdYRzRnSUNBZ0lDQWdJQ0FnSUNCa1pXWmxjbkpsWkM1eVpYTnZiSFpsS0hCeWIyMXBjMlZ6S1R0Y2JpQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQnlaWFIxY200Z1pHVm1aWEp5WldRdWNISnZiV2x6WlR0Y2JpQWdJQ0I5S1R0Y2JuMWNibHh1VUhKdmJXbHpaUzV3Y205MGIzUjVjR1V1WVd4c0lEMGdablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJSEpsZEhWeWJpQmhiR3dvZEdocGN5azdYRzU5TzF4dVhHNHZLaXBjYmlBcUlGSmxkSFZ5Ym5NZ2RHaGxJR1pwY25OMElISmxjMjlzZG1Wa0lIQnliMjFwYzJVZ2IyWWdZVzRnWVhKeVlYa3VJRkJ5YVc5eUlISmxhbVZqZEdWa0lIQnliMjFwYzJWeklHRnlaVnh1SUNvZ2FXZHViM0psWkM0Z0lGSmxhbVZqZEhNZ2IyNXNlU0JwWmlCaGJHd2djSEp2YldselpYTWdZWEpsSUhKbGFtVmpkR1ZrTGx4dUlDb2dRSEJoY21GdElIdEJjbkpoZVNwOUlHRnVJR0Z5Y21GNUlHTnZiblJoYVc1cGJtY2dkbUZzZFdWeklHOXlJSEJ5YjIxcGMyVnpJR1p2Y2lCMllXeDFaWE5jYmlBcUlFQnlaWFIxY201eklHRWdjSEp2YldselpTQm1kV3htYVd4c1pXUWdkMmwwYUNCMGFHVWdkbUZzZFdVZ2IyWWdkR2hsSUdacGNuTjBJSEpsYzI5c2RtVmtJSEJ5YjIxcGMyVXNYRzRnS2lCdmNpQmhJSEpsYW1WamRHVmtJSEJ5YjIxcGMyVWdhV1lnWVd4c0lIQnliMjFwYzJWeklHRnlaU0J5WldwbFkzUmxaQzVjYmlBcUwxeHVVUzVoYm5rZ1BTQmhibms3WEc1Y2JtWjFibU4wYVc5dUlHRnVlU2h3Y205dGFYTmxjeWtnZTF4dUlDQWdJR2xtSUNod2NtOXRhWE5sY3k1c1pXNW5kR2dnUFQwOUlEQXBJSHRjYmlBZ0lDQWdJQ0FnY21WMGRYSnVJRkV1Y21WemIyeDJaU2dwTzF4dUlDQWdJSDFjYmx4dUlDQWdJSFpoY2lCa1pXWmxjbkpsWkNBOUlGRXVaR1ZtWlhJb0tUdGNiaUFnSUNCMllYSWdjR1Z1WkdsdVowTnZkVzUwSUQwZ01EdGNiaUFnSUNCaGNuSmhlVjl5WldSMVkyVW9jSEp2YldselpYTXNJR1oxYm1OMGFXOXVJQ2h3Y21WMkxDQmpkWEp5Wlc1MExDQnBibVJsZUNrZ2UxeHVJQ0FnSUNBZ0lDQjJZWElnY0hKdmJXbHpaU0E5SUhCeWIyMXBjMlZ6VzJsdVpHVjRYVHRjYmx4dUlDQWdJQ0FnSUNCd1pXNWthVzVuUTI5MWJuUXJLenRjYmx4dUlDQWdJQ0FnSUNCM2FHVnVLSEJ5YjIxcGMyVXNJRzl1Um5Wc1ptbHNiR1ZrTENCdmJsSmxhbVZqZEdWa0xDQnZibEJ5YjJkeVpYTnpLVHRjYmlBZ0lDQWdJQ0FnWm5WdVkzUnBiMjRnYjI1R2RXeG1hV3hzWldRb2NtVnpkV3gwS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0JrWldabGNuSmxaQzV5WlhOdmJIWmxLSEpsYzNWc2RDazdYRzRnSUNBZ0lDQWdJSDFjYmlBZ0lDQWdJQ0FnWm5WdVkzUnBiMjRnYjI1U1pXcGxZM1JsWkNncElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUhCbGJtUnBibWREYjNWdWRDMHRPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2FXWWdLSEJsYm1ScGJtZERiM1Z1ZENBOVBUMGdNQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUdSbFptVnljbVZrTG5KbGFtVmpkQ2h1WlhjZ1JYSnliM0lvWEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lGd2lRMkZ1SjNRZ1oyVjBJR1oxYkdacGJHeHRaVzUwSUhaaGJIVmxJR1p5YjIwZ1lXNTVJSEJ5YjIxcGMyVXNJR0ZzYkNCY0lpQXJYRzRnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUZ3aWNISnZiV2x6WlhNZ2QyVnlaU0J5WldwbFkzUmxaQzVjSWx4dUlDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNrcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnZlZ4dUlDQWdJQ0FnSUNCOVhHNGdJQ0FnSUNBZ0lHWjFibU4wYVc5dUlHOXVVSEp2WjNKbGMzTW9jSEp2WjNKbGMzTXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lHUmxabVZ5Y21Wa0xtNXZkR2xtZVNoN1hHNGdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ2FXNWtaWGc2SUdsdVpHVjRMRnh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJSFpoYkhWbE9pQndjbTluY21WemMxeHVJQ0FnSUNBZ0lDQWdJQ0FnZlNrN1hHNGdJQ0FnSUNBZ0lIMWNiaUFnSUNCOUxDQjFibVJsWm1sdVpXUXBPMXh1WEc0Z0lDQWdjbVYwZFhKdUlHUmxabVZ5Y21Wa0xuQnliMjFwYzJVN1hHNTlYRzVjYmxCeWIyMXBjMlV1Y0hKdmRHOTBlWEJsTG1GdWVTQTlJR1oxYm1OMGFXOXVJQ2dwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdZVzU1S0hSb2FYTXBPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQlhZV2wwY3lCbWIzSWdZV3hzSUhCeWIyMXBjMlZ6SUhSdklHSmxJSE5sZEhSc1pXUXNJR1ZwZEdobGNpQm1kV3htYVd4c1pXUWdiM0pjYmlBcUlISmxhbVZqZEdWa0xpQWdWR2hwY3lCcGN5QmthWE4wYVc1amRDQm1jbTl0SUdCaGJHeGdJSE5wYm1ObElIUm9ZWFFnZDI5MWJHUWdjM1J2Y0Z4dUlDb2dkMkZwZEdsdVp5QmhkQ0IwYUdVZ1ptbHljM1FnY21WcVpXTjBhVzl1TGlBZ1ZHaGxJSEJ5YjIxcGMyVWdjbVYwZFhKdVpXUWdZbmxjYmlBcUlHQmhiR3hTWlhOdmJIWmxaR0FnZDJsc2JDQnVaWFpsY2lCaVpTQnlaV3BsWTNSbFpDNWNiaUFxSUVCd1lYSmhiU0J3Y205dGFYTmxjeUJoSUhCeWIyMXBjMlVnWm05eUlHRnVJR0Z5Y21GNUlDaHZjaUJoYmlCaGNuSmhlU2tnYjJZZ2NISnZiV2x6WlhOY2JpQXFJQ2h2Y2lCMllXeDFaWE1wWEc0Z0tpQkFjbVYwZFhKdUlHRWdjSEp2YldselpTQm1iM0lnWVc0Z1lYSnlZWGtnYjJZZ2NISnZiV2x6WlhOY2JpQXFMMXh1VVM1aGJHeFNaWE52YkhabFpDQTlJR1JsY0hKbFkyRjBaU2hoYkd4U1pYTnZiSFpsWkN3Z1hDSmhiR3hTWlhOdmJIWmxaRndpTENCY0ltRnNiRk5sZEhSc1pXUmNJaWs3WEc1bWRXNWpkR2x2YmlCaGJHeFNaWE52YkhabFpDaHdjbTl0YVhObGN5a2dlMXh1SUNBZ0lISmxkSFZ5YmlCM2FHVnVLSEJ5YjIxcGMyVnpMQ0JtZFc1amRHbHZiaUFvY0hKdmJXbHpaWE1wSUh0Y2JpQWdJQ0FnSUNBZ2NISnZiV2x6WlhNZ1BTQmhjbkpoZVY5dFlYQW9jSEp2YldselpYTXNJRkVwTzF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnZDJobGJpaGhiR3dvWVhKeVlYbGZiV0Z3S0hCeWIyMXBjMlZ6TENCbWRXNWpkR2x2YmlBb2NISnZiV2x6WlNrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSGRvWlc0b2NISnZiV2x6WlN3Z2JtOXZjQ3dnYm05dmNDazdYRzRnSUNBZ0lDQWdJSDBwS1N3Z1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ2NtVjBkWEp1SUhCeWIyMXBjMlZ6TzF4dUlDQWdJQ0FnSUNCOUtUdGNiaUFnSUNCOUtUdGNibjFjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdVlXeHNVbVZ6YjJ4MlpXUWdQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnY21WMGRYSnVJR0ZzYkZKbGMyOXNkbVZrS0hSb2FYTXBPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQkFjMlZsSUZCeWIyMXBjMlVqWVd4c1UyVjBkR3hsWkZ4dUlDb3ZYRzVSTG1Gc2JGTmxkSFJzWldRZ1BTQmhiR3hUWlhSMGJHVmtPMXh1Wm5WdVkzUnBiMjRnWVd4c1UyVjBkR3hsWkNod2NtOXRhWE5sY3lrZ2UxeHVJQ0FnSUhKbGRIVnliaUJSS0hCeWIyMXBjMlZ6S1M1aGJHeFRaWFIwYkdWa0tDazdYRzU5WEc1Y2JpOHFLbHh1SUNvZ1ZIVnlibk1nWVc0Z1lYSnlZWGtnYjJZZ2NISnZiV2x6WlhNZ2FXNTBieUJoSUhCeWIyMXBjMlVnWm05eUlHRnVJR0Z5Y21GNUlHOW1JSFJvWldseUlITjBZWFJsY3lBb1lYTmNiaUFxSUhKbGRIVnlibVZrSUdKNUlHQnBibk53WldOMFlDa2dkMmhsYmlCMGFHVjVJR2hoZG1VZ1lXeHNJSE5sZEhSc1pXUXVYRzRnS2lCQWNHRnlZVzBnZTBGeWNtRjVXMEZ1ZVNwZGZTQjJZV3gxWlhNZ1lXNGdZWEp5WVhrZ0tHOXlJSEJ5YjIxcGMyVWdabTl5SUdGdUlHRnljbUY1S1NCdlppQjJZV3gxWlhNZ0tHOXlYRzRnS2lCd2NtOXRhWE5sY3lCbWIzSWdkbUZzZFdWektWeHVJQ29nUUhKbGRIVnlibk1nZTBGeWNtRjVXMU4wWVhSbFhYMGdZVzRnWVhKeVlYa2diMllnYzNSaGRHVnpJR1p2Y2lCMGFHVWdjbVZ6Y0dWamRHbDJaU0IyWVd4MVpYTXVYRzRnS2k5Y2JsQnliMjFwYzJVdWNISnZkRzkwZVhCbExtRnNiRk5sZEhSc1pXUWdQU0JtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnY21WMGRYSnVJSFJvYVhNdWRHaGxiaWhtZFc1amRHbHZiaUFvY0hKdmJXbHpaWE1wSUh0Y2JpQWdJQ0FnSUNBZ2NtVjBkWEp1SUdGc2JDaGhjbkpoZVY5dFlYQW9jSEp2YldselpYTXNJR1oxYm1OMGFXOXVJQ2h3Y205dGFYTmxLU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQndjbTl0YVhObElEMGdVU2h3Y205dGFYTmxLVHRjYmlBZ0lDQWdJQ0FnSUNBZ0lHWjFibU4wYVc5dUlISmxaMkZ5Wkd4bGMzTW9LU0I3WEc0Z0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSEJ5YjIxcGMyVXVhVzV6Y0dWamRDZ3BPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZWeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJSEJ5YjIxcGMyVXVkR2hsYmloeVpXZGhjbVJzWlhOekxDQnlaV2RoY21Sc1pYTnpLVHRjYmlBZ0lDQWdJQ0FnZlNrcE8xeHVJQ0FnSUgwcE8xeHVmVHRjYmx4dUx5b3FYRzRnS2lCRFlYQjBkWEpsY3lCMGFHVWdabUZwYkhWeVpTQnZaaUJoSUhCeWIyMXBjMlVzSUdkcGRtbHVaeUJoYmlCdmNHOXlkSFZ1YVhSNUlIUnZJSEpsWTI5MlpYSmNiaUFxSUhkcGRHZ2dZU0JqWVd4c1ltRmpheTRnSUVsbUlIUm9aU0JuYVhabGJpQndjbTl0YVhObElHbHpJR1oxYkdacGJHeGxaQ3dnZEdobElISmxkSFZ5Ym1Wa1hHNGdLaUJ3Y205dGFYTmxJR2x6SUdaMWJHWnBiR3hsWkM1Y2JpQXFJRUJ3WVhKaGJTQjdRVzU1S24wZ2NISnZiV2x6WlNCbWIzSWdjMjl0WlhSb2FXNW5YRzRnS2lCQWNHRnlZVzBnZTBaMWJtTjBhVzl1ZlNCallXeHNZbUZqYXlCMGJ5Qm1kV3htYVd4c0lIUm9aU0J5WlhSMWNtNWxaQ0J3Y205dGFYTmxJR2xtSUhSb1pWeHVJQ29nWjJsMlpXNGdjSEp2YldselpTQnBjeUJ5WldwbFkzUmxaRnh1SUNvZ1FISmxkSFZ5Ym5NZ1lTQndjbTl0YVhObElHWnZjaUIwYUdVZ2NtVjBkWEp1SUhaaGJIVmxJRzltSUhSb1pTQmpZV3hzWW1GamExeHVJQ292WEc1UkxtWmhhV3dnUFNBdkx5QllXRmdnYkdWbllXTjVYRzVSVzF3aVkyRjBZMmhjSWwwZ1BTQm1kVzVqZEdsdmJpQW9iMkpxWldOMExDQnlaV3BsWTNSbFpDa2dlMXh1SUNBZ0lISmxkSFZ5YmlCUktHOWlhbVZqZENrdWRHaGxiaWgyYjJsa0lEQXNJSEpsYW1WamRHVmtLVHRjYm4wN1hHNWNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbVpoYVd3Z1BTQXZMeUJZV0ZnZ2JHVm5ZV041WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlZ0Y0ltTmhkR05vWENKZElEMGdablZ1WTNScGIyNGdLSEpsYW1WamRHVmtLU0I3WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11ZEdobGJpaDJiMmxrSURBc0lISmxhbVZqZEdWa0tUdGNibjA3WEc1Y2JpOHFLbHh1SUNvZ1FYUjBZV05vWlhNZ1lTQnNhWE4wWlc1bGNpQjBhR0YwSUdOaGJpQnlaWE53YjI1a0lIUnZJSEJ5YjJkeVpYTnpJRzV2ZEdsbWFXTmhkR2x2Ym5NZ1puSnZiU0JoWEc0Z0tpQndjbTl0YVhObEozTWdiM0pwWjJsdVlYUnBibWNnWkdWbVpYSnlaV1F1SUZSb2FYTWdiR2x6ZEdWdVpYSWdjbVZqWldsMlpYTWdkR2hsSUdWNFlXTjBJR0Z5WjNWdFpXNTBjMXh1SUNvZ2NHRnpjMlZrSUhSdklHQmdaR1ZtWlhKeVpXUXVibTkwYVdaNVlHQXVYRzRnS2lCQWNHRnlZVzBnZTBGdWVTcDlJSEJ5YjIxcGMyVWdabTl5SUhOdmJXVjBhR2x1WjF4dUlDb2dRSEJoY21GdElIdEdkVzVqZEdsdmJuMGdZMkZzYkdKaFkyc2dkRzhnY21WalpXbDJaU0JoYm5rZ2NISnZaM0psYzNNZ2JtOTBhV1pwWTJGMGFXOXVjMXh1SUNvZ1FISmxkSFZ5Ym5NZ2RHaGxJR2RwZG1WdUlIQnliMjFwYzJVc0lIVnVZMmhoYm1kbFpGeHVJQ292WEc1UkxuQnliMmR5WlhOeklEMGdjSEp2WjNKbGMzTTdYRzVtZFc1amRHbHZiaUJ3Y205bmNtVnpjeWh2WW1wbFkzUXNJSEJ5YjJkeVpYTnpaV1FwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdVU2h2WW1wbFkzUXBMblJvWlc0b2RtOXBaQ0F3TENCMmIybGtJREFzSUhCeWIyZHlaWE56WldRcE8xeHVmVnh1WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1d2NtOW5jbVZ6Y3lBOUlHWjFibU4wYVc5dUlDaHdjbTluY21WemMyVmtLU0I3WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11ZEdobGJpaDJiMmxrSURBc0lIWnZhV1FnTUN3Z2NISnZaM0psYzNObFpDazdYRzU5TzF4dVhHNHZLaXBjYmlBcUlGQnliM1pwWkdWeklHRnVJRzl3Y0c5eWRIVnVhWFI1SUhSdklHOWljMlZ5ZG1VZ2RHaGxJSE5sZEhSc2FXNW5JRzltSUdFZ2NISnZiV2x6WlN4Y2JpQXFJSEpsWjJGeVpHeGxjM01nYjJZZ2QyaGxkR2hsY2lCMGFHVWdjSEp2YldselpTQnBjeUJtZFd4bWFXeHNaV1FnYjNJZ2NtVnFaV04wWldRdUlDQkdiM0ozWVhKa2MxeHVJQ29nZEdobElISmxjMjlzZFhScGIyNGdkRzhnZEdobElISmxkSFZ5Ym1Wa0lIQnliMjFwYzJVZ2QyaGxiaUIwYUdVZ1kyRnNiR0poWTJzZ2FYTWdaRzl1WlM1Y2JpQXFJRlJvWlNCallXeHNZbUZqYXlCallXNGdjbVYwZFhKdUlHRWdjSEp2YldselpTQjBieUJrWldabGNpQmpiMjF3YkdWMGFXOXVMbHh1SUNvZ1FIQmhjbUZ0SUh0QmJua3FmU0J3Y205dGFYTmxYRzRnS2lCQWNHRnlZVzBnZTBaMWJtTjBhVzl1ZlNCallXeHNZbUZqYXlCMGJ5QnZZbk5sY25abElIUm9aU0J5WlhOdmJIVjBhVzl1SUc5bUlIUm9aU0JuYVhabGJseHVJQ29nY0hKdmJXbHpaU3dnZEdGclpYTWdibThnWVhKbmRXMWxiblJ6TGx4dUlDb2dRSEpsZEhWeWJuTWdZU0J3Y205dGFYTmxJR1p2Y2lCMGFHVWdjbVZ6YjJ4MWRHbHZiaUJ2WmlCMGFHVWdaMmwyWlc0Z2NISnZiV2x6WlNCM2FHVnVYRzRnS2lCZ1lHWnBibUJnSUdseklHUnZibVV1WEc0Z0tpOWNibEV1Wm1sdUlEMGdMeThnV0ZoWUlHeGxaMkZqZVZ4dVVWdGNJbVpwYm1Gc2JIbGNJbDBnUFNCbWRXNWpkR2x2YmlBb2IySnFaV04wTENCallXeHNZbUZqYXlrZ2UxeHVJQ0FnSUhKbGRIVnliaUJSS0c5aWFtVmpkQ2xiWENKbWFXNWhiR3g1WENKZEtHTmhiR3hpWVdOcktUdGNibjA3WEc1Y2JsQnliMjFwYzJVdWNISnZkRzkwZVhCbExtWnBiaUE5SUM4dklGaFlXQ0JzWldkaFkzbGNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxXMXdpWm1sdVlXeHNlVndpWFNBOUlHWjFibU4wYVc5dUlDaGpZV3hzWW1GamF5a2dlMXh1SUNBZ0lHTmhiR3hpWVdOcklEMGdVU2hqWVd4c1ltRmpheWs3WEc0Z0lDQWdjbVYwZFhKdUlIUm9hWE11ZEdobGJpaG1kVzVqZEdsdmJpQW9kbUZzZFdVcElIdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHTmhiR3hpWVdOckxtWmpZV3hzS0NrdWRHaGxiaWhtZFc1amRHbHZiaUFvS1NCN1hHNGdJQ0FnSUNBZ0lDQWdJQ0J5WlhSMWNtNGdkbUZzZFdVN1hHNGdJQ0FnSUNBZ0lIMHBPMXh1SUNBZ0lIMHNJR1oxYm1OMGFXOXVJQ2h5WldGemIyNHBJSHRjYmlBZ0lDQWdJQ0FnTHk4Z1ZFOUVUeUJoZEhSbGJYQjBJSFJ2SUhKbFkzbGpiR1VnZEdobElISmxhbVZqZEdsdmJpQjNhWFJvSUZ3aWRHaHBjMXdpTGx4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnWTJGc2JHSmhZMnN1Wm1OaGJHd29LUzUwYUdWdUtHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lIUm9jbTkzSUhKbFlYTnZianRjYmlBZ0lDQWdJQ0FnZlNrN1hHNGdJQ0FnZlNrN1hHNTlPMXh1WEc0dktpcGNiaUFxSUZSbGNtMXBibUYwWlhNZ1lTQmphR0ZwYmlCdlppQndjbTl0YVhObGN5d2dabTl5WTJsdVp5QnlaV3BsWTNScGIyNXpJSFJ2SUdKbFhHNGdLaUIwYUhKdmQyNGdZWE1nWlhoalpYQjBhVzl1Y3k1Y2JpQXFJRUJ3WVhKaGJTQjdRVzU1S24wZ2NISnZiV2x6WlNCaGRDQjBhR1VnWlc1a0lHOW1JR0VnWTJoaGFXNGdiMllnY0hKdmJXbHpaWE5jYmlBcUlFQnlaWFIxY201eklHNXZkR2hwYm1kY2JpQXFMMXh1VVM1a2IyNWxJRDBnWm5WdVkzUnBiMjRnS0c5aWFtVmpkQ3dnWm5Wc1ptbHNiR1ZrTENCeVpXcGxZM1JsWkN3Z2NISnZaM0psYzNNcElIdGNiaUFnSUNCeVpYUjFjbTRnVVNodlltcGxZM1FwTG1SdmJtVW9ablZzWm1sc2JHVmtMQ0J5WldwbFkzUmxaQ3dnY0hKdlozSmxjM01wTzF4dWZUdGNibHh1VUhKdmJXbHpaUzV3Y205MGIzUjVjR1V1Wkc5dVpTQTlJR1oxYm1OMGFXOXVJQ2htZFd4bWFXeHNaV1FzSUhKbGFtVmpkR1ZrTENCd2NtOW5jbVZ6Y3lrZ2UxeHVJQ0FnSUhaaGNpQnZibFZ1YUdGdVpHeGxaRVZ5Y205eUlEMGdablZ1WTNScGIyNGdLR1Z5Y205eUtTQjdYRzRnSUNBZ0lDQWdJQzh2SUdadmNuZGhjbVFnZEc4Z1lTQm1kWFIxY21VZ2RIVnliaUJ6YnlCMGFHRjBJR0JnZDJobGJtQmdYRzRnSUNBZ0lDQWdJQzh2SUdSdlpYTWdibTkwSUdOaGRHTm9JR2wwSUdGdVpDQjBkWEp1SUdsMElHbHVkRzhnWVNCeVpXcGxZM1JwYjI0dVhHNGdJQ0FnSUNBZ0lGRXVibVY0ZEZScFkyc29ablZ1WTNScGIyNGdLQ2tnZTF4dUlDQWdJQ0FnSUNBZ0lDQWdiV0ZyWlZOMFlXTnJWSEpoWTJWTWIyNW5LR1Z5Y205eUxDQndjbTl0YVhObEtUdGNiaUFnSUNBZ0lDQWdJQ0FnSUdsbUlDaFJMbTl1WlhKeWIzSXBJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0JSTG05dVpYSnliM0lvWlhKeWIzSXBPMXh1SUNBZ0lDQWdJQ0FnSUNBZ2ZTQmxiSE5sSUh0Y2JpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNCMGFISnZkeUJsY25KdmNqdGNiaUFnSUNBZ0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ2ZTazdYRzRnSUNBZ2ZUdGNibHh1SUNBZ0lDOHZJRUYyYjJsa0lIVnVibVZqWlhOellYSjVJR0J1WlhoMFZHbGphMkJwYm1jZ2RtbGhJR0Z1SUhWdWJtVmpaWE56WVhKNUlHQjNhR1Z1WUM1Y2JpQWdJQ0IyWVhJZ2NISnZiV2x6WlNBOUlHWjFiR1pwYkd4bFpDQjhmQ0J5WldwbFkzUmxaQ0I4ZkNCd2NtOW5jbVZ6Y3lBL1hHNGdJQ0FnSUNBZ0lIUm9hWE11ZEdobGJpaG1kV3htYVd4c1pXUXNJSEpsYW1WamRHVmtMQ0J3Y205bmNtVnpjeWtnT2x4dUlDQWdJQ0FnSUNCMGFHbHpPMXh1WEc0Z0lDQWdhV1lnS0hSNWNHVnZaaUJ3Y205alpYTnpJRDA5UFNCY0ltOWlhbVZqZEZ3aUlDWW1JSEJ5YjJObGMzTWdKaVlnY0hKdlkyVnpjeTVrYjIxaGFXNHBJSHRjYmlBZ0lDQWdJQ0FnYjI1VmJtaGhibVJzWldSRmNuSnZjaUE5SUhCeWIyTmxjM011Wkc5dFlXbHVMbUpwYm1Rb2IyNVZibWhoYm1Sc1pXUkZjbkp2Y2lrN1hHNGdJQ0FnZlZ4dVhHNGdJQ0FnY0hKdmJXbHpaUzUwYUdWdUtIWnZhV1FnTUN3Z2IyNVZibWhoYm1Sc1pXUkZjbkp2Y2lrN1hHNTlPMXh1WEc0dktpcGNiaUFxSUVOaGRYTmxjeUJoSUhCeWIyMXBjMlVnZEc4Z1ltVWdjbVZxWldOMFpXUWdhV1lnYVhRZ1pHOWxjeUJ1YjNRZ1oyVjBJR1oxYkdacGJHeGxaQ0JpWldadmNtVmNiaUFxSUhOdmJXVWdiV2xzYkdselpXTnZibVJ6SUhScGJXVWdiM1YwTGx4dUlDb2dRSEJoY21GdElIdEJibmtxZlNCd2NtOXRhWE5sWEc0Z0tpQkFjR0Z5WVcwZ2UwNTFiV0psY24wZ2JXbHNiR2x6WldOdmJtUnpJSFJwYldWdmRYUmNiaUFxSUVCd1lYSmhiU0I3UVc1NUtuMGdZM1Z6ZEc5dElHVnljbTl5SUcxbGMzTmhaMlVnYjNJZ1JYSnliM0lnYjJKcVpXTjBJQ2h2Y0hScGIyNWhiQ2xjYmlBcUlFQnlaWFIxY201eklHRWdjSEp2YldselpTQm1iM0lnZEdobElISmxjMjlzZFhScGIyNGdiMllnZEdobElHZHBkbVZ1SUhCeWIyMXBjMlVnYVdZZ2FYUWdhWE5jYmlBcUlHWjFiR1pwYkd4bFpDQmlaV1p2Y21VZ2RHaGxJSFJwYldWdmRYUXNJRzkwYUdWeWQybHpaU0J5WldwbFkzUmxaQzVjYmlBcUwxeHVVUzUwYVcxbGIzVjBJRDBnWm5WdVkzUnBiMjRnS0c5aWFtVmpkQ3dnYlhNc0lHVnljbTl5S1NCN1hHNGdJQ0FnY21WMGRYSnVJRkVvYjJKcVpXTjBLUzUwYVcxbGIzVjBLRzF6TENCbGNuSnZjaWs3WEc1OU8xeHVYRzVRY205dGFYTmxMbkJ5YjNSdmRIbHdaUzUwYVcxbGIzVjBJRDBnWm5WdVkzUnBiMjRnS0cxekxDQmxjbkp2Y2lrZ2UxeHVJQ0FnSUhaaGNpQmtaV1psY25KbFpDQTlJR1JsWm1WeUtDazdYRzRnSUNBZ2RtRnlJSFJwYldWdmRYUkpaQ0E5SUhObGRGUnBiV1Z2ZFhRb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0JwWmlBb0lXVnljbTl5SUh4OElGd2ljM1J5YVc1blhDSWdQVDA5SUhSNWNHVnZaaUJsY25KdmNpa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ1pYSnliM0lnUFNCdVpYY2dSWEp5YjNJb1pYSnliM0lnZkh3Z1hDSlVhVzFsWkNCdmRYUWdZV1owWlhJZ1hDSWdLeUJ0Y3lBcklGd2lJRzF6WENJcE8xeHVJQ0FnSUNBZ0lDQWdJQ0FnWlhKeWIzSXVZMjlrWlNBOUlGd2lSVlJKVFVWRVQxVlVYQ0k3WEc0Z0lDQWdJQ0FnSUgxY2JpQWdJQ0FnSUNBZ1pHVm1aWEp5WldRdWNtVnFaV04wS0dWeWNtOXlLVHRjYmlBZ0lDQjlMQ0J0Y3lrN1hHNWNiaUFnSUNCMGFHbHpMblJvWlc0b1puVnVZM1JwYjI0Z0tIWmhiSFZsS1NCN1hHNGdJQ0FnSUNBZ0lHTnNaV0Z5VkdsdFpXOTFkQ2gwYVcxbGIzVjBTV1FwTzF4dUlDQWdJQ0FnSUNCa1pXWmxjbkpsWkM1eVpYTnZiSFpsS0haaGJIVmxLVHRjYmlBZ0lDQjlMQ0JtZFc1amRHbHZiaUFvWlhoalpYQjBhVzl1S1NCN1hHNGdJQ0FnSUNBZ0lHTnNaV0Z5VkdsdFpXOTFkQ2gwYVcxbGIzVjBTV1FwTzF4dUlDQWdJQ0FnSUNCa1pXWmxjbkpsWkM1eVpXcGxZM1FvWlhoalpYQjBhVzl1S1R0Y2JpQWdJQ0I5TENCa1pXWmxjbkpsWkM1dWIzUnBabmtwTzF4dVhHNGdJQ0FnY21WMGRYSnVJR1JsWm1WeWNtVmtMbkJ5YjIxcGMyVTdYRzU5TzF4dVhHNHZLaXBjYmlBcUlGSmxkSFZ5Ym5NZ1lTQndjbTl0YVhObElHWnZjaUIwYUdVZ1oybDJaVzRnZG1Gc2RXVWdLRzl5SUhCeWIyMXBjMlZrSUhaaGJIVmxLU3dnYzI5dFpWeHVJQ29nYldsc2JHbHpaV052Ym1SeklHRm1kR1Z5SUdsMElISmxjMjlzZG1Wa0xpQlFZWE56WlhNZ2NtVnFaV04wYVc5dWN5QnBiVzFsWkdsaGRHVnNlUzVjYmlBcUlFQndZWEpoYlNCN1FXNTVLbjBnY0hKdmJXbHpaVnh1SUNvZ1FIQmhjbUZ0SUh0T2RXMWlaWEo5SUcxcGJHeHBjMlZqYjI1a2MxeHVJQ29nUUhKbGRIVnlibk1nWVNCd2NtOXRhWE5sSUdadmNpQjBhR1VnY21WemIyeDFkR2x2YmlCdlppQjBhR1VnWjJsMlpXNGdjSEp2YldselpTQmhablJsY2lCdGFXeHNhWE5sWTI5dVpITmNiaUFxSUhScGJXVWdhR0Z6SUdWc1lYQnpaV1FnYzJsdVkyVWdkR2hsSUhKbGMyOXNkWFJwYjI0Z2IyWWdkR2hsSUdkcGRtVnVJSEJ5YjIxcGMyVXVYRzRnS2lCSlppQjBhR1VnWjJsMlpXNGdjSEp2YldselpTQnlaV3BsWTNSekxDQjBhR0YwSUdseklIQmhjM05sWkNCcGJXMWxaR2xoZEdWc2VTNWNiaUFxTDF4dVVTNWtaV3hoZVNBOUlHWjFibU4wYVc5dUlDaHZZbXBsWTNRc0lIUnBiV1Z2ZFhRcElIdGNiaUFnSUNCcFppQW9kR2x0Wlc5MWRDQTlQVDBnZG05cFpDQXdLU0I3WEc0Z0lDQWdJQ0FnSUhScGJXVnZkWFFnUFNCdlltcGxZM1E3WEc0Z0lDQWdJQ0FnSUc5aWFtVmpkQ0E5SUhadmFXUWdNRHRjYmlBZ0lDQjlYRzRnSUNBZ2NtVjBkWEp1SUZFb2IySnFaV04wS1M1a1pXeGhlU2gwYVcxbGIzVjBLVHRjYm4wN1hHNWNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbVJsYkdGNUlEMGdablZ1WTNScGIyNGdLSFJwYldWdmRYUXBJSHRjYmlBZ0lDQnlaWFIxY200Z2RHaHBjeTUwYUdWdUtHWjFibU4wYVc5dUlDaDJZV3gxWlNrZ2UxeHVJQ0FnSUNBZ0lDQjJZWElnWkdWbVpYSnlaV1FnUFNCa1pXWmxjaWdwTzF4dUlDQWdJQ0FnSUNCelpYUlVhVzFsYjNWMEtHWjFibU4wYVc5dUlDZ3BJSHRjYmlBZ0lDQWdJQ0FnSUNBZ0lHUmxabVZ5Y21Wa0xuSmxjMjlzZG1Vb2RtRnNkV1VwTzF4dUlDQWdJQ0FnSUNCOUxDQjBhVzFsYjNWMEtUdGNiaUFnSUNBZ0lDQWdjbVYwZFhKdUlHUmxabVZ5Y21Wa0xuQnliMjFwYzJVN1hHNGdJQ0FnZlNrN1hHNTlPMXh1WEc0dktpcGNiaUFxSUZCaGMzTmxjeUJoSUdOdmJuUnBiblZoZEdsdmJpQjBieUJoSUU1dlpHVWdablZ1WTNScGIyNHNJSGRvYVdOb0lHbHpJR05oYkd4bFpDQjNhWFJvSUhSb1pTQm5hWFpsYmx4dUlDb2dZWEpuZFcxbGJuUnpJSEJ5YjNacFpHVmtJR0Z6SUdGdUlHRnljbUY1TENCaGJtUWdjbVYwZFhKdWN5QmhJSEJ5YjIxcGMyVXVYRzRnS2x4dUlDb2dJQ0FnSUNCUkxtNW1ZWEJ3Ykhrb1JsTXVjbVZoWkVacGJHVXNJRnRmWDJacGJHVnVZVzFsWFNsY2JpQXFJQ0FnSUNBZ0xuUm9aVzRvWm5WdVkzUnBiMjRnS0dOdmJuUmxiblFwSUh0Y2JpQXFJQ0FnSUNBZ2ZTbGNiaUFxWEc0Z0tpOWNibEV1Ym1aaGNIQnNlU0E5SUdaMWJtTjBhVzl1SUNoallXeHNZbUZqYXl3Z1lYSm5jeWtnZTF4dUlDQWdJSEpsZEhWeWJpQlJLR05oYkd4aVlXTnJLUzV1Wm1Gd2NHeDVLR0Z5WjNNcE8xeHVmVHRjYmx4dVVISnZiV2x6WlM1d2NtOTBiM1I1Y0dVdWJtWmhjSEJzZVNBOUlHWjFibU4wYVc5dUlDaGhjbWR6S1NCN1hHNGdJQ0FnZG1GeUlHUmxabVZ5Y21Wa0lEMGdaR1ZtWlhJb0tUdGNiaUFnSUNCMllYSWdibTlrWlVGeVozTWdQU0JoY25KaGVWOXpiR2xqWlNoaGNtZHpLVHRjYmlBZ0lDQnViMlJsUVhKbmN5NXdkWE5vS0dSbFptVnljbVZrTG0xaGEyVk9iMlJsVW1WemIyeDJaWElvS1NrN1hHNGdJQ0FnZEdocGN5NW1ZWEJ3Ykhrb2JtOWtaVUZ5WjNNcExtWmhhV3dvWkdWbVpYSnlaV1F1Y21WcVpXTjBLVHRjYmlBZ0lDQnlaWFIxY200Z1pHVm1aWEp5WldRdWNISnZiV2x6WlR0Y2JuMDdYRzVjYmk4cUtseHVJQ29nVUdGemMyVnpJR0VnWTI5dWRHbHVkV0YwYVc5dUlIUnZJR0VnVG05a1pTQm1kVzVqZEdsdmJpd2dkMmhwWTJnZ2FYTWdZMkZzYkdWa0lIZHBkR2dnZEdobElHZHBkbVZ1WEc0Z0tpQmhjbWQxYldWdWRITWdjSEp2ZG1sa1pXUWdhVzVrYVhacFpIVmhiR3g1TENCaGJtUWdjbVYwZFhKdWN5QmhJSEJ5YjIxcGMyVXVYRzRnS2lCQVpYaGhiWEJzWlZ4dUlDb2dVUzV1Wm1OaGJHd29SbE11Y21WaFpFWnBiR1VzSUY5ZlptbHNaVzVoYldVcFhHNGdLaUF1ZEdobGJpaG1kVzVqZEdsdmJpQW9ZMjl1ZEdWdWRDa2dlMXh1SUNvZ2ZTbGNiaUFxWEc0Z0tpOWNibEV1Ym1aallXeHNJRDBnWm5WdVkzUnBiMjRnS0dOaGJHeGlZV05ySUM4cUxpNHVZWEpuY3lvdktTQjdYRzRnSUNBZ2RtRnlJR0Z5WjNNZ1BTQmhjbkpoZVY5emJHbGpaU2hoY21kMWJXVnVkSE1zSURFcE8xeHVJQ0FnSUhKbGRIVnliaUJSS0dOaGJHeGlZV05yS1M1dVptRndjR3g1S0dGeVozTXBPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXVibVpqWVd4c0lEMGdablZ1WTNScGIyNGdLQzhxTGk0dVlYSm5jeW92S1NCN1hHNGdJQ0FnZG1GeUlHNXZaR1ZCY21keklEMGdZWEp5WVhsZmMyeHBZMlVvWVhKbmRXMWxiblJ6S1R0Y2JpQWdJQ0IyWVhJZ1pHVm1aWEp5WldRZ1BTQmtaV1psY2lncE8xeHVJQ0FnSUc1dlpHVkJjbWR6TG5CMWMyZ29aR1ZtWlhKeVpXUXViV0ZyWlU1dlpHVlNaWE52YkhabGNpZ3BLVHRjYmlBZ0lDQjBhR2x6TG1aaGNIQnNlU2h1YjJSbFFYSm5jeWt1Wm1GcGJDaGtaV1psY25KbFpDNXlaV3BsWTNRcE8xeHVJQ0FnSUhKbGRIVnliaUJrWldabGNuSmxaQzV3Y205dGFYTmxPMXh1ZlR0Y2JseHVMeW9xWEc0Z0tpQlhjbUZ3Y3lCaElFNXZaR1ZLVXlCamIyNTBhVzUxWVhScGIyNGdjR0Z6YzJsdVp5Qm1kVzVqZEdsdmJpQmhibVFnY21WMGRYSnVjeUJoYmlCbGNYVnBkbUZzWlc1MFhHNGdLaUIyWlhKemFXOXVJSFJvWVhRZ2NtVjBkWEp1Y3lCaElIQnliMjFwYzJVdVhHNGdLaUJBWlhoaGJYQnNaVnh1SUNvZ1VTNXVabUpwYm1Rb1JsTXVjbVZoWkVacGJHVXNJRjlmWm1sc1pXNWhiV1VwS0Z3aWRYUm1MVGhjSWlsY2JpQXFJQzUwYUdWdUtHTnZibk52YkdVdWJHOW5LVnh1SUNvZ0xtUnZibVVvS1Z4dUlDb3ZYRzVSTG01bVltbHVaQ0E5WEc1UkxtUmxibTlrWldsbWVTQTlJR1oxYm1OMGFXOXVJQ2hqWVd4c1ltRmpheUF2S2k0dUxtRnlaM01xTHlrZ2UxeHVJQ0FnSUhaaGNpQmlZWE5sUVhKbmN5QTlJR0Z5Y21GNVgzTnNhV05sS0dGeVozVnRaVzUwY3l3Z01TazdYRzRnSUNBZ2NtVjBkWEp1SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdkbUZ5SUc1dlpHVkJjbWR6SUQwZ1ltRnpaVUZ5WjNNdVkyOXVZMkYwS0dGeWNtRjVYM05zYVdObEtHRnlaM1Z0Wlc1MGN5a3BPMXh1SUNBZ0lDQWdJQ0IyWVhJZ1pHVm1aWEp5WldRZ1BTQmtaV1psY2lncE8xeHVJQ0FnSUNBZ0lDQnViMlJsUVhKbmN5NXdkWE5vS0dSbFptVnljbVZrTG0xaGEyVk9iMlJsVW1WemIyeDJaWElvS1NrN1hHNGdJQ0FnSUNBZ0lGRW9ZMkZzYkdKaFkyc3BMbVpoY0hCc2VTaHViMlJsUVhKbmN5a3VabUZwYkNoa1pXWmxjbkpsWkM1eVpXcGxZM1FwTzF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnWkdWbVpYSnlaV1F1Y0hKdmJXbHpaVHRjYmlBZ0lDQjlPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXVibVppYVc1a0lEMWNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbVJsYm05a1pXbG1lU0E5SUdaMWJtTjBhVzl1SUNndktpNHVMbUZ5WjNNcUx5a2dlMXh1SUNBZ0lIWmhjaUJoY21keklEMGdZWEp5WVhsZmMyeHBZMlVvWVhKbmRXMWxiblJ6S1R0Y2JpQWdJQ0JoY21kekxuVnVjMmhwWm5Rb2RHaHBjeWs3WEc0Z0lDQWdjbVYwZFhKdUlGRXVaR1Z1YjJSbGFXWjVMbUZ3Y0d4NUtIWnZhV1FnTUN3Z1lYSm5jeWs3WEc1OU8xeHVYRzVSTG01aWFXNWtJRDBnWm5WdVkzUnBiMjRnS0dOaGJHeGlZV05yTENCMGFHbHpjQ0F2S2k0dUxtRnlaM01xTHlrZ2UxeHVJQ0FnSUhaaGNpQmlZWE5sUVhKbmN5QTlJR0Z5Y21GNVgzTnNhV05sS0dGeVozVnRaVzUwY3l3Z01pazdYRzRnSUNBZ2NtVjBkWEp1SUdaMWJtTjBhVzl1SUNncElIdGNiaUFnSUNBZ0lDQWdkbUZ5SUc1dlpHVkJjbWR6SUQwZ1ltRnpaVUZ5WjNNdVkyOXVZMkYwS0dGeWNtRjVYM05zYVdObEtHRnlaM1Z0Wlc1MGN5a3BPMXh1SUNBZ0lDQWdJQ0IyWVhJZ1pHVm1aWEp5WldRZ1BTQmtaV1psY2lncE8xeHVJQ0FnSUNBZ0lDQnViMlJsUVhKbmN5NXdkWE5vS0dSbFptVnljbVZrTG0xaGEyVk9iMlJsVW1WemIyeDJaWElvS1NrN1hHNGdJQ0FnSUNBZ0lHWjFibU4wYVc5dUlHSnZkVzVrS0NrZ2UxeHVJQ0FnSUNBZ0lDQWdJQ0FnY21WMGRYSnVJR05oYkd4aVlXTnJMbUZ3Y0d4NUtIUm9hWE53TENCaGNtZDFiV1Z1ZEhNcE8xeHVJQ0FnSUNBZ0lDQjlYRzRnSUNBZ0lDQWdJRkVvWW05MWJtUXBMbVpoY0hCc2VTaHViMlJsUVhKbmN5a3VabUZwYkNoa1pXWmxjbkpsWkM1eVpXcGxZM1FwTzF4dUlDQWdJQ0FnSUNCeVpYUjFjbTRnWkdWbVpYSnlaV1F1Y0hKdmJXbHpaVHRjYmlBZ0lDQjlPMXh1ZlR0Y2JseHVVSEp2YldselpTNXdjbTkwYjNSNWNHVXVibUpwYm1RZ1BTQm1kVzVqZEdsdmJpQW9MeXAwYUdsemNDd2dMaTR1WVhKbmN5b3ZLU0I3WEc0Z0lDQWdkbUZ5SUdGeVozTWdQU0JoY25KaGVWOXpiR2xqWlNoaGNtZDFiV1Z1ZEhNc0lEQXBPMXh1SUNBZ0lHRnlaM011ZFc1emFHbG1kQ2gwYUdsektUdGNiaUFnSUNCeVpYUjFjbTRnVVM1dVltbHVaQzVoY0hCc2VTaDJiMmxrSURBc0lHRnlaM01wTzF4dWZUdGNibHh1THlvcVhHNGdLaUJEWVd4c2N5QmhJRzFsZEdodlpDQnZaaUJoSUU1dlpHVXRjM1I1YkdVZ2IySnFaV04wSUhSb1lYUWdZV05qWlhCMGN5QmhJRTV2WkdVdGMzUjViR1ZjYmlBcUlHTmhiR3hpWVdOcklIZHBkR2dnWVNCbmFYWmxiaUJoY25KaGVTQnZaaUJoY21kMWJXVnVkSE1zSUhCc2RYTWdZU0J3Y205MmFXUmxaQ0JqWVd4c1ltRmpheTVjYmlBcUlFQndZWEpoYlNCdlltcGxZM1FnWVc0Z2IySnFaV04wSUhSb1lYUWdhR0Z6SUhSb1pTQnVZVzFsWkNCdFpYUm9iMlJjYmlBcUlFQndZWEpoYlNCN1UzUnlhVzVuZlNCdVlXMWxJRzVoYldVZ2IyWWdkR2hsSUcxbGRHaHZaQ0J2WmlCdlltcGxZM1JjYmlBcUlFQndZWEpoYlNCN1FYSnlZWGw5SUdGeVozTWdZWEpuZFcxbGJuUnpJSFJ2SUhCaGMzTWdkRzhnZEdobElHMWxkR2h2WkRzZ2RHaGxJR05oYkd4aVlXTnJYRzRnS2lCM2FXeHNJR0psSUhCeWIzWnBaR1ZrSUdKNUlGRWdZVzVrSUdGd2NHVnVaR1ZrSUhSdklIUm9aWE5sSUdGeVozVnRaVzUwY3k1Y2JpQXFJRUJ5WlhSMWNtNXpJR0VnY0hKdmJXbHpaU0JtYjNJZ2RHaGxJSFpoYkhWbElHOXlJR1Z5Y205eVhHNGdLaTljYmxFdWJtMWhjSEJzZVNBOUlDOHZJRmhZV0NCQmN5QndjbTl3YjNObFpDQmllU0JjSWxKbFpITmhibVJ5YjF3aVhHNVJMbTV3YjNOMElEMGdablZ1WTNScGIyNGdLRzlpYW1WamRDd2dibUZ0WlN3Z1lYSm5jeWtnZTF4dUlDQWdJSEpsZEhWeWJpQlJLRzlpYW1WamRDa3VibkJ2YzNRb2JtRnRaU3dnWVhKbmN5azdYRzU5TzF4dVhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNXViV0Z3Y0d4NUlEMGdMeThnV0ZoWUlFRnpJSEJ5YjNCdmMyVmtJR0o1SUZ3aVVtVmtjMkZ1WkhKdlhDSmNibEJ5YjIxcGMyVXVjSEp2ZEc5MGVYQmxMbTV3YjNOMElEMGdablZ1WTNScGIyNGdLRzVoYldVc0lHRnlaM01wSUh0Y2JpQWdJQ0IyWVhJZ2JtOWtaVUZ5WjNNZ1BTQmhjbkpoZVY5emJHbGpaU2hoY21keklIeDhJRnRkS1R0Y2JpQWdJQ0IyWVhJZ1pHVm1aWEp5WldRZ1BTQmtaV1psY2lncE8xeHVJQ0FnSUc1dlpHVkJjbWR6TG5CMWMyZ29aR1ZtWlhKeVpXUXViV0ZyWlU1dlpHVlNaWE52YkhabGNpZ3BLVHRjYmlBZ0lDQjBhR2x6TG1ScGMzQmhkR05vS0Z3aWNHOXpkRndpTENCYmJtRnRaU3dnYm05a1pVRnlaM05kS1M1bVlXbHNLR1JsWm1WeWNtVmtMbkpsYW1WamRDazdYRzRnSUNBZ2NtVjBkWEp1SUdSbFptVnljbVZrTG5CeWIyMXBjMlU3WEc1OU8xeHVYRzR2S2lwY2JpQXFJRU5oYkd4eklHRWdiV1YwYUc5a0lHOW1JR0VnVG05a1pTMXpkSGxzWlNCdlltcGxZM1FnZEdoaGRDQmhZMk5sY0hSeklHRWdUbTlrWlMxemRIbHNaVnh1SUNvZ1kyRnNiR0poWTJzc0lHWnZjbmRoY21ScGJtY2dkR2hsSUdkcGRtVnVJSFpoY21saFpHbGpJR0Z5WjNWdFpXNTBjeXdnY0d4MWN5QmhJSEJ5YjNacFpHVmtYRzRnS2lCallXeHNZbUZqYXlCaGNtZDFiV1Z1ZEM1Y2JpQXFJRUJ3WVhKaGJTQnZZbXBsWTNRZ1lXNGdiMkpxWldOMElIUm9ZWFFnYUdGeklIUm9aU0J1WVcxbFpDQnRaWFJvYjJSY2JpQXFJRUJ3WVhKaGJTQjdVM1J5YVc1bmZTQnVZVzFsSUc1aGJXVWdiMllnZEdobElHMWxkR2h2WkNCdlppQnZZbXBsWTNSY2JpQXFJRUJ3WVhKaGJTQXVMaTVoY21keklHRnlaM1Z0Wlc1MGN5QjBieUJ3WVhOeklIUnZJSFJvWlNCdFpYUm9iMlE3SUhSb1pTQmpZV3hzWW1GamF5QjNhV3hzWEc0Z0tpQmlaU0J3Y205MmFXUmxaQ0JpZVNCUklHRnVaQ0JoY0hCbGJtUmxaQ0IwYnlCMGFHVnpaU0JoY21kMWJXVnVkSE11WEc0Z0tpQkFjbVYwZFhKdWN5QmhJSEJ5YjIxcGMyVWdabTl5SUhSb1pTQjJZV3gxWlNCdmNpQmxjbkp2Y2x4dUlDb3ZYRzVSTG01elpXNWtJRDBnTHk4Z1dGaFlJRUpoYzJWa0lHOXVJRTFoY21zZ1RXbHNiR1Z5SjNNZ2NISnZjRzl6WldRZ1hDSnpaVzVrWENKY2JsRXVibTFqWVd4c0lEMGdMeThnV0ZoWUlFSmhjMlZrSUc5dUlGd2lVbVZrYzJGdVpISnZKM05jSWlCd2NtOXdiM05oYkZ4dVVTNXVhVzUyYjJ0bElEMGdablZ1WTNScGIyNGdLRzlpYW1WamRDd2dibUZ0WlNBdktpNHVMbUZ5WjNNcUx5a2dlMXh1SUNBZ0lIWmhjaUJ1YjJSbFFYSm5jeUE5SUdGeWNtRjVYM05zYVdObEtHRnlaM1Z0Wlc1MGN5d2dNaWs3WEc0Z0lDQWdkbUZ5SUdSbFptVnljbVZrSUQwZ1pHVm1aWElvS1R0Y2JpQWdJQ0J1YjJSbFFYSm5jeTV3ZFhOb0tHUmxabVZ5Y21Wa0xtMWhhMlZPYjJSbFVtVnpiMngyWlhJb0tTazdYRzRnSUNBZ1VTaHZZbXBsWTNRcExtUnBjM0JoZEdOb0tGd2ljRzl6ZEZ3aUxDQmJibUZ0WlN3Z2JtOWtaVUZ5WjNOZEtTNW1ZV2xzS0dSbFptVnljbVZrTG5KbGFtVmpkQ2s3WEc0Z0lDQWdjbVYwZFhKdUlHUmxabVZ5Y21Wa0xuQnliMjFwYzJVN1hHNTlPMXh1WEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1dWMyVnVaQ0E5SUM4dklGaFlXQ0JDWVhObFpDQnZiaUJOWVhKcklFMXBiR3hsY2lkeklIQnliM0J2YzJWa0lGd2ljMlZ1WkZ3aVhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNXViV05oYkd3Z1BTQXZMeUJZV0ZnZ1FtRnpaV1FnYjI0Z1hDSlNaV1J6WVc1a2NtOG5jMXdpSUhCeWIzQnZjMkZzWEc1UWNtOXRhWE5sTG5CeWIzUnZkSGx3WlM1dWFXNTJiMnRsSUQwZ1puVnVZM1JwYjI0Z0tHNWhiV1VnTHlvdUxpNWhjbWR6S2k4cElIdGNiaUFnSUNCMllYSWdibTlrWlVGeVozTWdQU0JoY25KaGVWOXpiR2xqWlNoaGNtZDFiV1Z1ZEhNc0lERXBPMXh1SUNBZ0lIWmhjaUJrWldabGNuSmxaQ0E5SUdSbFptVnlLQ2s3WEc0Z0lDQWdibTlrWlVGeVozTXVjSFZ6YUNoa1pXWmxjbkpsWkM1dFlXdGxUbTlrWlZKbGMyOXNkbVZ5S0NrcE8xeHVJQ0FnSUhSb2FYTXVaR2x6Y0dGMFkyZ29YQ0p3YjNOMFhDSXNJRnR1WVcxbExDQnViMlJsUVhKbmMxMHBMbVpoYVd3b1pHVm1aWEp5WldRdWNtVnFaV04wS1R0Y2JpQWdJQ0J5WlhSMWNtNGdaR1ZtWlhKeVpXUXVjSEp2YldselpUdGNibjA3WEc1Y2JpOHFLbHh1SUNvZ1NXWWdZU0JtZFc1amRHbHZiaUIzYjNWc1pDQnNhV3RsSUhSdklITjFjSEJ2Y25RZ1ltOTBhQ0JPYjJSbElHTnZiblJwYm5WaGRHbHZiaTF3WVhOemFXNW5MWE4wZVd4bElHRnVaRnh1SUNvZ2NISnZiV2x6WlMxeVpYUjFjbTVwYm1jdGMzUjViR1VzSUdsMElHTmhiaUJsYm1RZ2FYUnpJR2x1ZEdWeWJtRnNJSEJ5YjIxcGMyVWdZMmhoYVc0Z2QybDBhRnh1SUNvZ1lHNXZaR1ZwWm5rb2JtOWtaV0poWTJzcFlDd2dabTl5ZDJGeVpHbHVaeUIwYUdVZ2IzQjBhVzl1WVd3Z2JtOWtaV0poWTJzZ1lYSm5kVzFsYm5RdUlDQkpaaUIwYUdVZ2RYTmxjbHh1SUNvZ1pXeGxZM1J6SUhSdklIVnpaU0JoSUc1dlpHVmlZV05yTENCMGFHVWdjbVZ6ZFd4MElIZHBiR3dnWW1VZ2MyVnVkQ0IwYUdWeVpTNGdJRWxtSUhSb1pYa2daRzhnYm05MFhHNGdLaUJ3WVhOeklHRWdibTlrWldKaFkyc3NJSFJvWlhrZ2QybHNiQ0J5WldObGFYWmxJSFJvWlNCeVpYTjFiSFFnY0hKdmJXbHpaUzVjYmlBcUlFQndZWEpoYlNCdlltcGxZM1FnWVNCeVpYTjFiSFFnS0c5eUlHRWdjSEp2YldselpTQm1iM0lnWVNCeVpYTjFiSFFwWEc0Z0tpQkFjR0Z5WVcwZ2UwWjFibU4wYVc5dWZTQnViMlJsWW1GamF5QmhJRTV2WkdVdWFuTXRjM1I1YkdVZ1kyRnNiR0poWTJ0Y2JpQXFJRUJ5WlhSMWNtNXpJR1ZwZEdobGNpQjBhR1VnY0hKdmJXbHpaU0J2Y2lCdWIzUm9hVzVuWEc0Z0tpOWNibEV1Ym05a1pXbG1lU0E5SUc1dlpHVnBabms3WEc1bWRXNWpkR2x2YmlCdWIyUmxhV1o1S0c5aWFtVmpkQ3dnYm05a1pXSmhZMnNwSUh0Y2JpQWdJQ0J5WlhSMWNtNGdVU2h2WW1wbFkzUXBMbTV2WkdWcFpua29ibTlrWldKaFkyc3BPMXh1ZlZ4dVhHNVFjbTl0YVhObExuQnliM1J2ZEhsd1pTNXViMlJsYVdaNUlEMGdablZ1WTNScGIyNGdLRzV2WkdWaVlXTnJLU0I3WEc0Z0lDQWdhV1lnS0c1dlpHVmlZV05yS1NCN1hHNGdJQ0FnSUNBZ0lIUm9hWE11ZEdobGJpaG1kVzVqZEdsdmJpQW9kbUZzZFdVcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUZFdWJtVjRkRlJwWTJzb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJRzV2WkdWaVlXTnJLRzUxYkd3c0lIWmhiSFZsS1R0Y2JpQWdJQ0FnSUNBZ0lDQWdJSDBwTzF4dUlDQWdJQ0FnSUNCOUxDQm1kVzVqZEdsdmJpQW9aWEp5YjNJcElIdGNiaUFnSUNBZ0lDQWdJQ0FnSUZFdWJtVjRkRlJwWTJzb1puVnVZM1JwYjI0Z0tDa2dlMXh1SUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJRzV2WkdWaVlXTnJLR1Z5Y205eUtUdGNiaUFnSUNBZ0lDQWdJQ0FnSUgwcE8xeHVJQ0FnSUNBZ0lDQjlLVHRjYmlBZ0lDQjlJR1ZzYzJVZ2UxeHVJQ0FnSUNBZ0lDQnlaWFIxY200Z2RHaHBjenRjYmlBZ0lDQjlYRzU5TzF4dVhHNVJMbTV2UTI5dVpteHBZM1FnUFNCbWRXNWpkR2x2YmlncElIdGNiaUFnSUNCMGFISnZkeUJ1WlhjZ1JYSnliM0lvWENKUkxtNXZRMjl1Wm14cFkzUWdiMjVzZVNCM2IzSnJjeUIzYUdWdUlGRWdhWE1nZFhObFpDQmhjeUJoSUdkc2IySmhiRndpS1R0Y2JuMDdYRzVjYmk4dklFRnNiQ0JqYjJSbElHSmxabTl5WlNCMGFHbHpJSEJ2YVc1MElIZHBiR3dnWW1VZ1ptbHNkR1Z5WldRZ1puSnZiU0J6ZEdGamF5QjBjbUZqWlhNdVhHNTJZWElnY1VWdVpHbHVaMHhwYm1VZ1BTQmpZWEIwZFhKbFRHbHVaU2dwTzF4dVhHNXlaWFIxY200Z1VUdGNibHh1ZlNrN1hHNGlYWDA9IiwiLyoqXG4gKiBSb290IHJlZmVyZW5jZSBmb3IgaWZyYW1lcy5cbiAqL1xuXG52YXIgcm9vdDtcbmlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykgeyAvLyBCcm93c2VyIHdpbmRvd1xuICByb290ID0gd2luZG93O1xufSBlbHNlIGlmICh0eXBlb2Ygc2VsZiAhPT0gJ3VuZGVmaW5lZCcpIHsgLy8gV2ViIFdvcmtlclxuICByb290ID0gc2VsZjtcbn0gZWxzZSB7IC8vIE90aGVyIGVudmlyb25tZW50c1xuICBjb25zb2xlLndhcm4oXCJVc2luZyBicm93c2VyLW9ubHkgdmVyc2lvbiBvZiBzdXBlcmFnZW50IGluIG5vbi1icm93c2VyIGVudmlyb25tZW50XCIpO1xuICByb290ID0gdGhpcztcbn1cblxudmFyIEVtaXR0ZXIgPSByZXF1aXJlKCdlbWl0dGVyJyk7XG52YXIgcmVxdWVzdEJhc2UgPSByZXF1aXJlKCcuL3JlcXVlc3QtYmFzZScpO1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9pcy1vYmplY3QnKTtcblxuLyoqXG4gKiBOb29wLlxuICovXG5cbmZ1bmN0aW9uIG5vb3AoKXt9O1xuXG4vKipcbiAqIEV4cG9zZSBgcmVxdWVzdGAuXG4gKi9cblxudmFyIHJlcXVlc3QgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vcmVxdWVzdCcpLmJpbmQobnVsbCwgUmVxdWVzdCk7XG5cbi8qKlxuICogRGV0ZXJtaW5lIFhIUi5cbiAqL1xuXG5yZXF1ZXN0LmdldFhIUiA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHJvb3QuWE1MSHR0cFJlcXVlc3RcbiAgICAgICYmICghcm9vdC5sb2NhdGlvbiB8fCAnZmlsZTonICE9IHJvb3QubG9jYXRpb24ucHJvdG9jb2xcbiAgICAgICAgICB8fCAhcm9vdC5BY3RpdmVYT2JqZWN0KSkge1xuICAgIHJldHVybiBuZXcgWE1MSHR0cFJlcXVlc3Q7XG4gIH0gZWxzZSB7XG4gICAgdHJ5IHsgcmV0dXJuIG5ldyBBY3RpdmVYT2JqZWN0KCdNaWNyb3NvZnQuWE1MSFRUUCcpOyB9IGNhdGNoKGUpIHt9XG4gICAgdHJ5IHsgcmV0dXJuIG5ldyBBY3RpdmVYT2JqZWN0KCdNc3htbDIuWE1MSFRUUC42LjAnKTsgfSBjYXRjaChlKSB7fVxuICAgIHRyeSB7IHJldHVybiBuZXcgQWN0aXZlWE9iamVjdCgnTXN4bWwyLlhNTEhUVFAuMy4wJyk7IH0gY2F0Y2goZSkge31cbiAgICB0cnkgeyByZXR1cm4gbmV3IEFjdGl2ZVhPYmplY3QoJ01zeG1sMi5YTUxIVFRQJyk7IH0gY2F0Y2goZSkge31cbiAgfVxuICB0aHJvdyBFcnJvcihcIkJyb3dzZXItb25seSB2ZXJpc29uIG9mIHN1cGVyYWdlbnQgY291bGQgbm90IGZpbmQgWEhSXCIpO1xufTtcblxuLyoqXG4gKiBSZW1vdmVzIGxlYWRpbmcgYW5kIHRyYWlsaW5nIHdoaXRlc3BhY2UsIGFkZGVkIHRvIHN1cHBvcnQgSUUuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHNcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbnZhciB0cmltID0gJycudHJpbVxuICA/IGZ1bmN0aW9uKHMpIHsgcmV0dXJuIHMudHJpbSgpOyB9XG4gIDogZnVuY3Rpb24ocykgeyByZXR1cm4gcy5yZXBsYWNlKC8oXlxccyp8XFxzKiQpL2csICcnKTsgfTtcblxuLyoqXG4gKiBTZXJpYWxpemUgdGhlIGdpdmVuIGBvYmpgLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHNlcmlhbGl6ZShvYmopIHtcbiAgaWYgKCFpc09iamVjdChvYmopKSByZXR1cm4gb2JqO1xuICB2YXIgcGFpcnMgPSBbXTtcbiAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgIHB1c2hFbmNvZGVkS2V5VmFsdWVQYWlyKHBhaXJzLCBrZXksIG9ialtrZXldKTtcbiAgfVxuICByZXR1cm4gcGFpcnMuam9pbignJicpO1xufVxuXG4vKipcbiAqIEhlbHBzICdzZXJpYWxpemUnIHdpdGggc2VyaWFsaXppbmcgYXJyYXlzLlxuICogTXV0YXRlcyB0aGUgcGFpcnMgYXJyYXkuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gcGFpcnNcbiAqIEBwYXJhbSB7U3RyaW5nfSBrZXlcbiAqIEBwYXJhbSB7TWl4ZWR9IHZhbFxuICovXG5cbmZ1bmN0aW9uIHB1c2hFbmNvZGVkS2V5VmFsdWVQYWlyKHBhaXJzLCBrZXksIHZhbCkge1xuICBpZiAodmFsICE9IG51bGwpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWwpKSB7XG4gICAgICB2YWwuZm9yRWFjaChmdW5jdGlvbih2KSB7XG4gICAgICAgIHB1c2hFbmNvZGVkS2V5VmFsdWVQYWlyKHBhaXJzLCBrZXksIHYpO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmIChpc09iamVjdCh2YWwpKSB7XG4gICAgICBmb3IodmFyIHN1YmtleSBpbiB2YWwpIHtcbiAgICAgICAgcHVzaEVuY29kZWRLZXlWYWx1ZVBhaXIocGFpcnMsIGtleSArICdbJyArIHN1YmtleSArICddJywgdmFsW3N1YmtleV0pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBwYWlycy5wdXNoKGVuY29kZVVSSUNvbXBvbmVudChrZXkpXG4gICAgICAgICsgJz0nICsgZW5jb2RlVVJJQ29tcG9uZW50KHZhbCkpO1xuICAgIH1cbiAgfSBlbHNlIGlmICh2YWwgPT09IG51bGwpIHtcbiAgICBwYWlycy5wdXNoKGVuY29kZVVSSUNvbXBvbmVudChrZXkpKTtcbiAgfVxufVxuXG4vKipcbiAqIEV4cG9zZSBzZXJpYWxpemF0aW9uIG1ldGhvZC5cbiAqL1xuXG4gcmVxdWVzdC5zZXJpYWxpemVPYmplY3QgPSBzZXJpYWxpemU7XG5cbiAvKipcbiAgKiBQYXJzZSB0aGUgZ2l2ZW4geC13d3ctZm9ybS11cmxlbmNvZGVkIGBzdHJgLlxuICAqXG4gICogQHBhcmFtIHtTdHJpbmd9IHN0clxuICAqIEByZXR1cm4ge09iamVjdH1cbiAgKiBAYXBpIHByaXZhdGVcbiAgKi9cblxuZnVuY3Rpb24gcGFyc2VTdHJpbmcoc3RyKSB7XG4gIHZhciBvYmogPSB7fTtcbiAgdmFyIHBhaXJzID0gc3RyLnNwbGl0KCcmJyk7XG4gIHZhciBwYWlyO1xuICB2YXIgcG9zO1xuXG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBwYWlycy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgIHBhaXIgPSBwYWlyc1tpXTtcbiAgICBwb3MgPSBwYWlyLmluZGV4T2YoJz0nKTtcbiAgICBpZiAocG9zID09IC0xKSB7XG4gICAgICBvYmpbZGVjb2RlVVJJQ29tcG9uZW50KHBhaXIpXSA9ICcnO1xuICAgIH0gZWxzZSB7XG4gICAgICBvYmpbZGVjb2RlVVJJQ29tcG9uZW50KHBhaXIuc2xpY2UoMCwgcG9zKSldID1cbiAgICAgICAgZGVjb2RlVVJJQ29tcG9uZW50KHBhaXIuc2xpY2UocG9zICsgMSkpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvYmo7XG59XG5cbi8qKlxuICogRXhwb3NlIHBhcnNlci5cbiAqL1xuXG5yZXF1ZXN0LnBhcnNlU3RyaW5nID0gcGFyc2VTdHJpbmc7XG5cbi8qKlxuICogRGVmYXVsdCBNSU1FIHR5cGUgbWFwLlxuICpcbiAqICAgICBzdXBlcmFnZW50LnR5cGVzLnhtbCA9ICdhcHBsaWNhdGlvbi94bWwnO1xuICpcbiAqL1xuXG5yZXF1ZXN0LnR5cGVzID0ge1xuICBodG1sOiAndGV4dC9odG1sJyxcbiAganNvbjogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICB4bWw6ICdhcHBsaWNhdGlvbi94bWwnLFxuICB1cmxlbmNvZGVkOiAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJyxcbiAgJ2Zvcm0nOiAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJyxcbiAgJ2Zvcm0tZGF0YSc6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnXG59O1xuXG4vKipcbiAqIERlZmF1bHQgc2VyaWFsaXphdGlvbiBtYXAuXG4gKlxuICogICAgIHN1cGVyYWdlbnQuc2VyaWFsaXplWydhcHBsaWNhdGlvbi94bWwnXSA9IGZ1bmN0aW9uKG9iail7XG4gKiAgICAgICByZXR1cm4gJ2dlbmVyYXRlZCB4bWwgaGVyZSc7XG4gKiAgICAgfTtcbiAqXG4gKi9cblxuIHJlcXVlc3Quc2VyaWFsaXplID0ge1xuICAgJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCc6IHNlcmlhbGl6ZSxcbiAgICdhcHBsaWNhdGlvbi9qc29uJzogSlNPTi5zdHJpbmdpZnlcbiB9O1xuXG4gLyoqXG4gICogRGVmYXVsdCBwYXJzZXJzLlxuICAqXG4gICogICAgIHN1cGVyYWdlbnQucGFyc2VbJ2FwcGxpY2F0aW9uL3htbCddID0gZnVuY3Rpb24oc3RyKXtcbiAgKiAgICAgICByZXR1cm4geyBvYmplY3QgcGFyc2VkIGZyb20gc3RyIH07XG4gICogICAgIH07XG4gICpcbiAgKi9cblxucmVxdWVzdC5wYXJzZSA9IHtcbiAgJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCc6IHBhcnNlU3RyaW5nLFxuICAnYXBwbGljYXRpb24vanNvbic6IEpTT04ucGFyc2Vcbn07XG5cbi8qKlxuICogUGFyc2UgdGhlIGdpdmVuIGhlYWRlciBgc3RyYCBpbnRvXG4gKiBhbiBvYmplY3QgY29udGFpbmluZyB0aGUgbWFwcGVkIGZpZWxkcy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBwYXJzZUhlYWRlcihzdHIpIHtcbiAgdmFyIGxpbmVzID0gc3RyLnNwbGl0KC9cXHI/XFxuLyk7XG4gIHZhciBmaWVsZHMgPSB7fTtcbiAgdmFyIGluZGV4O1xuICB2YXIgbGluZTtcbiAgdmFyIGZpZWxkO1xuICB2YXIgdmFsO1xuXG4gIGxpbmVzLnBvcCgpOyAvLyB0cmFpbGluZyBDUkxGXG5cbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGxpbmVzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgbGluZSA9IGxpbmVzW2ldO1xuICAgIGluZGV4ID0gbGluZS5pbmRleE9mKCc6Jyk7XG4gICAgZmllbGQgPSBsaW5lLnNsaWNlKDAsIGluZGV4KS50b0xvd2VyQ2FzZSgpO1xuICAgIHZhbCA9IHRyaW0obGluZS5zbGljZShpbmRleCArIDEpKTtcbiAgICBmaWVsZHNbZmllbGRdID0gdmFsO1xuICB9XG5cbiAgcmV0dXJuIGZpZWxkcztcbn1cblxuLyoqXG4gKiBDaGVjayBpZiBgbWltZWAgaXMganNvbiBvciBoYXMgK2pzb24gc3RydWN0dXJlZCBzeW50YXggc3VmZml4LlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtaW1lXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gaXNKU09OKG1pbWUpIHtcbiAgcmV0dXJuIC9bXFwvK11qc29uXFxiLy50ZXN0KG1pbWUpO1xufVxuXG4vKipcbiAqIFJldHVybiB0aGUgbWltZSB0eXBlIGZvciB0aGUgZ2l2ZW4gYHN0cmAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHN0clxuICogQHJldHVybiB7U3RyaW5nfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gdHlwZShzdHIpe1xuICByZXR1cm4gc3RyLnNwbGl0KC8gKjsgKi8pLnNoaWZ0KCk7XG59O1xuXG4vKipcbiAqIFJldHVybiBoZWFkZXIgZmllbGQgcGFyYW1ldGVycy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBwYXJhbXMoc3RyKXtcbiAgcmV0dXJuIHN0ci5zcGxpdCgvICo7ICovKS5yZWR1Y2UoZnVuY3Rpb24ob2JqLCBzdHIpe1xuICAgIHZhciBwYXJ0cyA9IHN0ci5zcGxpdCgvICo9ICovKSxcbiAgICAgICAga2V5ID0gcGFydHMuc2hpZnQoKSxcbiAgICAgICAgdmFsID0gcGFydHMuc2hpZnQoKTtcblxuICAgIGlmIChrZXkgJiYgdmFsKSBvYmpba2V5XSA9IHZhbDtcbiAgICByZXR1cm4gb2JqO1xuICB9LCB7fSk7XG59O1xuXG4vKipcbiAqIEluaXRpYWxpemUgYSBuZXcgYFJlc3BvbnNlYCB3aXRoIHRoZSBnaXZlbiBgeGhyYC5cbiAqXG4gKiAgLSBzZXQgZmxhZ3MgKC5vaywgLmVycm9yLCBldGMpXG4gKiAgLSBwYXJzZSBoZWFkZXJcbiAqXG4gKiBFeGFtcGxlczpcbiAqXG4gKiAgQWxpYXNpbmcgYHN1cGVyYWdlbnRgIGFzIGByZXF1ZXN0YCBpcyBuaWNlOlxuICpcbiAqICAgICAgcmVxdWVzdCA9IHN1cGVyYWdlbnQ7XG4gKlxuICogIFdlIGNhbiB1c2UgdGhlIHByb21pc2UtbGlrZSBBUEksIG9yIHBhc3MgY2FsbGJhY2tzOlxuICpcbiAqICAgICAgcmVxdWVzdC5nZXQoJy8nKS5lbmQoZnVuY3Rpb24ocmVzKXt9KTtcbiAqICAgICAgcmVxdWVzdC5nZXQoJy8nLCBmdW5jdGlvbihyZXMpe30pO1xuICpcbiAqICBTZW5kaW5nIGRhdGEgY2FuIGJlIGNoYWluZWQ6XG4gKlxuICogICAgICByZXF1ZXN0XG4gKiAgICAgICAgLnBvc3QoJy91c2VyJylcbiAqICAgICAgICAuc2VuZCh7IG5hbWU6ICd0aicgfSlcbiAqICAgICAgICAuZW5kKGZ1bmN0aW9uKHJlcyl7fSk7XG4gKlxuICogIE9yIHBhc3NlZCB0byBgLnNlbmQoKWA6XG4gKlxuICogICAgICByZXF1ZXN0XG4gKiAgICAgICAgLnBvc3QoJy91c2VyJylcbiAqICAgICAgICAuc2VuZCh7IG5hbWU6ICd0aicgfSwgZnVuY3Rpb24ocmVzKXt9KTtcbiAqXG4gKiAgT3IgcGFzc2VkIHRvIGAucG9zdCgpYDpcbiAqXG4gKiAgICAgIHJlcXVlc3RcbiAqICAgICAgICAucG9zdCgnL3VzZXInLCB7IG5hbWU6ICd0aicgfSlcbiAqICAgICAgICAuZW5kKGZ1bmN0aW9uKHJlcyl7fSk7XG4gKlxuICogT3IgZnVydGhlciByZWR1Y2VkIHRvIGEgc2luZ2xlIGNhbGwgZm9yIHNpbXBsZSBjYXNlczpcbiAqXG4gKiAgICAgIHJlcXVlc3RcbiAqICAgICAgICAucG9zdCgnL3VzZXInLCB7IG5hbWU6ICd0aicgfSwgZnVuY3Rpb24ocmVzKXt9KTtcbiAqXG4gKiBAcGFyYW0ge1hNTEhUVFBSZXF1ZXN0fSB4aHJcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBSZXNwb25zZShyZXEsIG9wdGlvbnMpIHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIHRoaXMucmVxID0gcmVxO1xuICB0aGlzLnhociA9IHRoaXMucmVxLnhocjtcbiAgLy8gcmVzcG9uc2VUZXh0IGlzIGFjY2Vzc2libGUgb25seSBpZiByZXNwb25zZVR5cGUgaXMgJycgb3IgJ3RleHQnIGFuZCBvbiBvbGRlciBicm93c2Vyc1xuICB0aGlzLnRleHQgPSAoKHRoaXMucmVxLm1ldGhvZCAhPSdIRUFEJyAmJiAodGhpcy54aHIucmVzcG9uc2VUeXBlID09PSAnJyB8fCB0aGlzLnhoci5yZXNwb25zZVR5cGUgPT09ICd0ZXh0JykpIHx8IHR5cGVvZiB0aGlzLnhoci5yZXNwb25zZVR5cGUgPT09ICd1bmRlZmluZWQnKVxuICAgICA/IHRoaXMueGhyLnJlc3BvbnNlVGV4dFxuICAgICA6IG51bGw7XG4gIHRoaXMuc3RhdHVzVGV4dCA9IHRoaXMucmVxLnhoci5zdGF0dXNUZXh0O1xuICB0aGlzLl9zZXRTdGF0dXNQcm9wZXJ0aWVzKHRoaXMueGhyLnN0YXR1cyk7XG4gIHRoaXMuaGVhZGVyID0gdGhpcy5oZWFkZXJzID0gcGFyc2VIZWFkZXIodGhpcy54aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKCkpO1xuICAvLyBnZXRBbGxSZXNwb25zZUhlYWRlcnMgc29tZXRpbWVzIGZhbHNlbHkgcmV0dXJucyBcIlwiIGZvciBDT1JTIHJlcXVlc3RzLCBidXRcbiAgLy8gZ2V0UmVzcG9uc2VIZWFkZXIgc3RpbGwgd29ya3MuIHNvIHdlIGdldCBjb250ZW50LXR5cGUgZXZlbiBpZiBnZXR0aW5nXG4gIC8vIG90aGVyIGhlYWRlcnMgZmFpbHMuXG4gIHRoaXMuaGVhZGVyWydjb250ZW50LXR5cGUnXSA9IHRoaXMueGhyLmdldFJlc3BvbnNlSGVhZGVyKCdjb250ZW50LXR5cGUnKTtcbiAgdGhpcy5fc2V0SGVhZGVyUHJvcGVydGllcyh0aGlzLmhlYWRlcik7XG4gIHRoaXMuYm9keSA9IHRoaXMucmVxLm1ldGhvZCAhPSAnSEVBRCdcbiAgICA/IHRoaXMuX3BhcnNlQm9keSh0aGlzLnRleHQgPyB0aGlzLnRleHQgOiB0aGlzLnhoci5yZXNwb25zZSlcbiAgICA6IG51bGw7XG59XG5cbi8qKlxuICogR2V0IGNhc2UtaW5zZW5zaXRpdmUgYGZpZWxkYCB2YWx1ZS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZmllbGRcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVzcG9uc2UucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKGZpZWxkKXtcbiAgcmV0dXJuIHRoaXMuaGVhZGVyW2ZpZWxkLnRvTG93ZXJDYXNlKCldO1xufTtcblxuLyoqXG4gKiBTZXQgaGVhZGVyIHJlbGF0ZWQgcHJvcGVydGllczpcbiAqXG4gKiAgIC0gYC50eXBlYCB0aGUgY29udGVudCB0eXBlIHdpdGhvdXQgcGFyYW1zXG4gKlxuICogQSByZXNwb25zZSBvZiBcIkNvbnRlbnQtVHlwZTogdGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOFwiXG4gKiB3aWxsIHByb3ZpZGUgeW91IHdpdGggYSBgLnR5cGVgIG9mIFwidGV4dC9wbGFpblwiLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBoZWFkZXJcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblJlc3BvbnNlLnByb3RvdHlwZS5fc2V0SGVhZGVyUHJvcGVydGllcyA9IGZ1bmN0aW9uKGhlYWRlcil7XG4gIC8vIGNvbnRlbnQtdHlwZVxuICB2YXIgY3QgPSB0aGlzLmhlYWRlclsnY29udGVudC10eXBlJ10gfHwgJyc7XG4gIHRoaXMudHlwZSA9IHR5cGUoY3QpO1xuXG4gIC8vIHBhcmFtc1xuICB2YXIgb2JqID0gcGFyYW1zKGN0KTtcbiAgZm9yICh2YXIga2V5IGluIG9iaikgdGhpc1trZXldID0gb2JqW2tleV07XG59O1xuXG4vKipcbiAqIFBhcnNlIHRoZSBnaXZlbiBib2R5IGBzdHJgLlxuICpcbiAqIFVzZWQgZm9yIGF1dG8tcGFyc2luZyBvZiBib2RpZXMuIFBhcnNlcnNcbiAqIGFyZSBkZWZpbmVkIG9uIHRoZSBgc3VwZXJhZ2VudC5wYXJzZWAgb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge01peGVkfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVzcG9uc2UucHJvdG90eXBlLl9wYXJzZUJvZHkgPSBmdW5jdGlvbihzdHIpe1xuICB2YXIgcGFyc2UgPSByZXF1ZXN0LnBhcnNlW3RoaXMudHlwZV07XG4gIGlmICghcGFyc2UgJiYgaXNKU09OKHRoaXMudHlwZSkpIHtcbiAgICBwYXJzZSA9IHJlcXVlc3QucGFyc2VbJ2FwcGxpY2F0aW9uL2pzb24nXTtcbiAgfVxuICByZXR1cm4gcGFyc2UgJiYgc3RyICYmIChzdHIubGVuZ3RoIHx8IHN0ciBpbnN0YW5jZW9mIE9iamVjdClcbiAgICA/IHBhcnNlKHN0cilcbiAgICA6IG51bGw7XG59O1xuXG4vKipcbiAqIFNldCBmbGFncyBzdWNoIGFzIGAub2tgIGJhc2VkIG9uIGBzdGF0dXNgLlxuICpcbiAqIEZvciBleGFtcGxlIGEgMnh4IHJlc3BvbnNlIHdpbGwgZ2l2ZSB5b3UgYSBgLm9rYCBvZiBfX3RydWVfX1xuICogd2hlcmVhcyA1eHggd2lsbCBiZSBfX2ZhbHNlX18gYW5kIGAuZXJyb3JgIHdpbGwgYmUgX190cnVlX18uIFRoZVxuICogYC5jbGllbnRFcnJvcmAgYW5kIGAuc2VydmVyRXJyb3JgIGFyZSBhbHNvIGF2YWlsYWJsZSB0byBiZSBtb3JlXG4gKiBzcGVjaWZpYywgYW5kIGAuc3RhdHVzVHlwZWAgaXMgdGhlIGNsYXNzIG9mIGVycm9yIHJhbmdpbmcgZnJvbSAxLi41XG4gKiBzb21ldGltZXMgdXNlZnVsIGZvciBtYXBwaW5nIHJlc3BvbmQgY29sb3JzIGV0Yy5cbiAqXG4gKiBcInN1Z2FyXCIgcHJvcGVydGllcyBhcmUgYWxzbyBkZWZpbmVkIGZvciBjb21tb24gY2FzZXMuIEN1cnJlbnRseSBwcm92aWRpbmc6XG4gKlxuICogICAtIC5ub0NvbnRlbnRcbiAqICAgLSAuYmFkUmVxdWVzdFxuICogICAtIC51bmF1dGhvcml6ZWRcbiAqICAgLSAubm90QWNjZXB0YWJsZVxuICogICAtIC5ub3RGb3VuZFxuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSBzdGF0dXNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblJlc3BvbnNlLnByb3RvdHlwZS5fc2V0U3RhdHVzUHJvcGVydGllcyA9IGZ1bmN0aW9uKHN0YXR1cyl7XG4gIC8vIGhhbmRsZSBJRTkgYnVnOiBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzEwMDQ2OTcyL21zaWUtcmV0dXJucy1zdGF0dXMtY29kZS1vZi0xMjIzLWZvci1hamF4LXJlcXVlc3RcbiAgaWYgKHN0YXR1cyA9PT0gMTIyMykge1xuICAgIHN0YXR1cyA9IDIwNDtcbiAgfVxuXG4gIHZhciB0eXBlID0gc3RhdHVzIC8gMTAwIHwgMDtcblxuICAvLyBzdGF0dXMgLyBjbGFzc1xuICB0aGlzLnN0YXR1cyA9IHRoaXMuc3RhdHVzQ29kZSA9IHN0YXR1cztcbiAgdGhpcy5zdGF0dXNUeXBlID0gdHlwZTtcblxuICAvLyBiYXNpY3NcbiAgdGhpcy5pbmZvID0gMSA9PSB0eXBlO1xuICB0aGlzLm9rID0gMiA9PSB0eXBlO1xuICB0aGlzLmNsaWVudEVycm9yID0gNCA9PSB0eXBlO1xuICB0aGlzLnNlcnZlckVycm9yID0gNSA9PSB0eXBlO1xuICB0aGlzLmVycm9yID0gKDQgPT0gdHlwZSB8fCA1ID09IHR5cGUpXG4gICAgPyB0aGlzLnRvRXJyb3IoKVxuICAgIDogZmFsc2U7XG5cbiAgLy8gc3VnYXJcbiAgdGhpcy5hY2NlcHRlZCA9IDIwMiA9PSBzdGF0dXM7XG4gIHRoaXMubm9Db250ZW50ID0gMjA0ID09IHN0YXR1cztcbiAgdGhpcy5iYWRSZXF1ZXN0ID0gNDAwID09IHN0YXR1cztcbiAgdGhpcy51bmF1dGhvcml6ZWQgPSA0MDEgPT0gc3RhdHVzO1xuICB0aGlzLm5vdEFjY2VwdGFibGUgPSA0MDYgPT0gc3RhdHVzO1xuICB0aGlzLm5vdEZvdW5kID0gNDA0ID09IHN0YXR1cztcbiAgdGhpcy5mb3JiaWRkZW4gPSA0MDMgPT0gc3RhdHVzO1xufTtcblxuLyoqXG4gKiBSZXR1cm4gYW4gYEVycm9yYCByZXByZXNlbnRhdGl2ZSBvZiB0aGlzIHJlc3BvbnNlLlxuICpcbiAqIEByZXR1cm4ge0Vycm9yfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXNwb25zZS5wcm90b3R5cGUudG9FcnJvciA9IGZ1bmN0aW9uKCl7XG4gIHZhciByZXEgPSB0aGlzLnJlcTtcbiAgdmFyIG1ldGhvZCA9IHJlcS5tZXRob2Q7XG4gIHZhciB1cmwgPSByZXEudXJsO1xuXG4gIHZhciBtc2cgPSAnY2Fubm90ICcgKyBtZXRob2QgKyAnICcgKyB1cmwgKyAnICgnICsgdGhpcy5zdGF0dXMgKyAnKSc7XG4gIHZhciBlcnIgPSBuZXcgRXJyb3IobXNnKTtcbiAgZXJyLnN0YXR1cyA9IHRoaXMuc3RhdHVzO1xuICBlcnIubWV0aG9kID0gbWV0aG9kO1xuICBlcnIudXJsID0gdXJsO1xuXG4gIHJldHVybiBlcnI7XG59O1xuXG4vKipcbiAqIEV4cG9zZSBgUmVzcG9uc2VgLlxuICovXG5cbnJlcXVlc3QuUmVzcG9uc2UgPSBSZXNwb25zZTtcblxuLyoqXG4gKiBJbml0aWFsaXplIGEgbmV3IGBSZXF1ZXN0YCB3aXRoIHRoZSBnaXZlbiBgbWV0aG9kYCBhbmQgYHVybGAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZFxuICogQHBhcmFtIHtTdHJpbmd9IHVybFxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBSZXF1ZXN0KG1ldGhvZCwgdXJsKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdGhpcy5fcXVlcnkgPSB0aGlzLl9xdWVyeSB8fCBbXTtcbiAgdGhpcy5tZXRob2QgPSBtZXRob2Q7XG4gIHRoaXMudXJsID0gdXJsO1xuICB0aGlzLmhlYWRlciA9IHt9OyAvLyBwcmVzZXJ2ZXMgaGVhZGVyIG5hbWUgY2FzZVxuICB0aGlzLl9oZWFkZXIgPSB7fTsgLy8gY29lcmNlcyBoZWFkZXIgbmFtZXMgdG8gbG93ZXJjYXNlXG4gIHRoaXMub24oJ2VuZCcsIGZ1bmN0aW9uKCl7XG4gICAgdmFyIGVyciA9IG51bGw7XG4gICAgdmFyIHJlcyA9IG51bGw7XG5cbiAgICB0cnkge1xuICAgICAgcmVzID0gbmV3IFJlc3BvbnNlKHNlbGYpO1xuICAgIH0gY2F0Y2goZSkge1xuICAgICAgZXJyID0gbmV3IEVycm9yKCdQYXJzZXIgaXMgdW5hYmxlIHRvIHBhcnNlIHRoZSByZXNwb25zZScpO1xuICAgICAgZXJyLnBhcnNlID0gdHJ1ZTtcbiAgICAgIGVyci5vcmlnaW5hbCA9IGU7XG4gICAgICAvLyBpc3N1ZSAjNjc1OiByZXR1cm4gdGhlIHJhdyByZXNwb25zZSBpZiB0aGUgcmVzcG9uc2UgcGFyc2luZyBmYWlsc1xuICAgICAgZXJyLnJhd1Jlc3BvbnNlID0gc2VsZi54aHIgJiYgc2VsZi54aHIucmVzcG9uc2VUZXh0ID8gc2VsZi54aHIucmVzcG9uc2VUZXh0IDogbnVsbDtcbiAgICAgIC8vIGlzc3VlICM4NzY6IHJldHVybiB0aGUgaHR0cCBzdGF0dXMgY29kZSBpZiB0aGUgcmVzcG9uc2UgcGFyc2luZyBmYWlsc1xuICAgICAgZXJyLnN0YXR1c0NvZGUgPSBzZWxmLnhociAmJiBzZWxmLnhoci5zdGF0dXMgPyBzZWxmLnhoci5zdGF0dXMgOiBudWxsO1xuICAgICAgcmV0dXJuIHNlbGYuY2FsbGJhY2soZXJyKTtcbiAgICB9XG5cbiAgICBzZWxmLmVtaXQoJ3Jlc3BvbnNlJywgcmVzKTtcblxuICAgIHZhciBuZXdfZXJyO1xuICAgIHRyeSB7XG4gICAgICBpZiAocmVzLnN0YXR1cyA8IDIwMCB8fCByZXMuc3RhdHVzID49IDMwMCkge1xuICAgICAgICBuZXdfZXJyID0gbmV3IEVycm9yKHJlcy5zdGF0dXNUZXh0IHx8ICdVbnN1Y2Nlc3NmdWwgSFRUUCByZXNwb25zZScpO1xuICAgICAgICBuZXdfZXJyLm9yaWdpbmFsID0gZXJyO1xuICAgICAgICBuZXdfZXJyLnJlc3BvbnNlID0gcmVzO1xuICAgICAgICBuZXdfZXJyLnN0YXR1cyA9IHJlcy5zdGF0dXM7XG4gICAgICB9XG4gICAgfSBjYXRjaChlKSB7XG4gICAgICBuZXdfZXJyID0gZTsgLy8gIzk4NSB0b3VjaGluZyByZXMgbWF5IGNhdXNlIElOVkFMSURfU1RBVEVfRVJSIG9uIG9sZCBBbmRyb2lkXG4gICAgfVxuXG4gICAgLy8gIzEwMDAgZG9uJ3QgY2F0Y2ggZXJyb3JzIGZyb20gdGhlIGNhbGxiYWNrIHRvIGF2b2lkIGRvdWJsZSBjYWxsaW5nIGl0XG4gICAgaWYgKG5ld19lcnIpIHtcbiAgICAgIHNlbGYuY2FsbGJhY2sobmV3X2VyciwgcmVzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc2VsZi5jYWxsYmFjayhudWxsLCByZXMpO1xuICAgIH1cbiAgfSk7XG59XG5cbi8qKlxuICogTWl4aW4gYEVtaXR0ZXJgIGFuZCBgcmVxdWVzdEJhc2VgLlxuICovXG5cbkVtaXR0ZXIoUmVxdWVzdC5wcm90b3R5cGUpO1xuZm9yICh2YXIga2V5IGluIHJlcXVlc3RCYXNlKSB7XG4gIFJlcXVlc3QucHJvdG90eXBlW2tleV0gPSByZXF1ZXN0QmFzZVtrZXldO1xufVxuXG4vKipcbiAqIFNldCBDb250ZW50LVR5cGUgdG8gYHR5cGVgLCBtYXBwaW5nIHZhbHVlcyBmcm9tIGByZXF1ZXN0LnR5cGVzYC5cbiAqXG4gKiBFeGFtcGxlczpcbiAqXG4gKiAgICAgIHN1cGVyYWdlbnQudHlwZXMueG1sID0gJ2FwcGxpY2F0aW9uL3htbCc7XG4gKlxuICogICAgICByZXF1ZXN0LnBvc3QoJy8nKVxuICogICAgICAgIC50eXBlKCd4bWwnKVxuICogICAgICAgIC5zZW5kKHhtbHN0cmluZylcbiAqICAgICAgICAuZW5kKGNhbGxiYWNrKTtcbiAqXG4gKiAgICAgIHJlcXVlc3QucG9zdCgnLycpXG4gKiAgICAgICAgLnR5cGUoJ2FwcGxpY2F0aW9uL3htbCcpXG4gKiAgICAgICAgLnNlbmQoeG1sc3RyaW5nKVxuICogICAgICAgIC5lbmQoY2FsbGJhY2spO1xuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUudHlwZSA9IGZ1bmN0aW9uKHR5cGUpe1xuICB0aGlzLnNldCgnQ29udGVudC1UeXBlJywgcmVxdWVzdC50eXBlc1t0eXBlXSB8fCB0eXBlKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNldCByZXNwb25zZVR5cGUgdG8gYHZhbGAuIFByZXNlbnRseSB2YWxpZCByZXNwb25zZVR5cGVzIGFyZSAnYmxvYicgYW5kXG4gKiAnYXJyYXlidWZmZXInLlxuICpcbiAqIEV4YW1wbGVzOlxuICpcbiAqICAgICAgcmVxLmdldCgnLycpXG4gKiAgICAgICAgLnJlc3BvbnNlVHlwZSgnYmxvYicpXG4gKiAgICAgICAgLmVuZChjYWxsYmFjayk7XG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHZhbFxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLnJlc3BvbnNlVHlwZSA9IGZ1bmN0aW9uKHZhbCl7XG4gIHRoaXMuX3Jlc3BvbnNlVHlwZSA9IHZhbDtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNldCBBY2NlcHQgdG8gYHR5cGVgLCBtYXBwaW5nIHZhbHVlcyBmcm9tIGByZXF1ZXN0LnR5cGVzYC5cbiAqXG4gKiBFeGFtcGxlczpcbiAqXG4gKiAgICAgIHN1cGVyYWdlbnQudHlwZXMuanNvbiA9ICdhcHBsaWNhdGlvbi9qc29uJztcbiAqXG4gKiAgICAgIHJlcXVlc3QuZ2V0KCcvYWdlbnQnKVxuICogICAgICAgIC5hY2NlcHQoJ2pzb24nKVxuICogICAgICAgIC5lbmQoY2FsbGJhY2spO1xuICpcbiAqICAgICAgcmVxdWVzdC5nZXQoJy9hZ2VudCcpXG4gKiAgICAgICAgLmFjY2VwdCgnYXBwbGljYXRpb24vanNvbicpXG4gKiAgICAgICAgLmVuZChjYWxsYmFjayk7XG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGFjY2VwdFxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmFjY2VwdCA9IGZ1bmN0aW9uKHR5cGUpe1xuICB0aGlzLnNldCgnQWNjZXB0JywgcmVxdWVzdC50eXBlc1t0eXBlXSB8fCB0eXBlKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNldCBBdXRob3JpemF0aW9uIGZpZWxkIHZhbHVlIHdpdGggYHVzZXJgIGFuZCBgcGFzc2AuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHVzZXJcbiAqIEBwYXJhbSB7U3RyaW5nfSBwYXNzXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyB3aXRoICd0eXBlJyBwcm9wZXJ0eSAnYXV0bycgb3IgJ2Jhc2ljJyAoZGVmYXVsdCAnYmFzaWMnKVxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmF1dGggPSBmdW5jdGlvbih1c2VyLCBwYXNzLCBvcHRpb25zKXtcbiAgaWYgKCFvcHRpb25zKSB7XG4gICAgb3B0aW9ucyA9IHtcbiAgICAgIHR5cGU6ICdiYXNpYydcbiAgICB9XG4gIH1cblxuICBzd2l0Y2ggKG9wdGlvbnMudHlwZSkge1xuICAgIGNhc2UgJ2Jhc2ljJzpcbiAgICAgIHZhciBzdHIgPSBidG9hKHVzZXIgKyAnOicgKyBwYXNzKTtcbiAgICAgIHRoaXMuc2V0KCdBdXRob3JpemF0aW9uJywgJ0Jhc2ljICcgKyBzdHIpO1xuICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnYXV0byc6XG4gICAgICB0aGlzLnVzZXJuYW1lID0gdXNlcjtcbiAgICAgIHRoaXMucGFzc3dvcmQgPSBwYXNzO1xuICAgIGJyZWFrO1xuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4qIEFkZCBxdWVyeS1zdHJpbmcgYHZhbGAuXG4qXG4qIEV4YW1wbGVzOlxuKlxuKiAgIHJlcXVlc3QuZ2V0KCcvc2hvZXMnKVxuKiAgICAgLnF1ZXJ5KCdzaXplPTEwJylcbiogICAgIC5xdWVyeSh7IGNvbG9yOiAnYmx1ZScgfSlcbipcbiogQHBhcmFtIHtPYmplY3R8U3RyaW5nfSB2YWxcbiogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4qIEBhcGkgcHVibGljXG4qL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5xdWVyeSA9IGZ1bmN0aW9uKHZhbCl7XG4gIGlmICgnc3RyaW5nJyAhPSB0eXBlb2YgdmFsKSB2YWwgPSBzZXJpYWxpemUodmFsKTtcbiAgaWYgKHZhbCkgdGhpcy5fcXVlcnkucHVzaCh2YWwpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogUXVldWUgdGhlIGdpdmVuIGBmaWxlYCBhcyBhbiBhdHRhY2htZW50IHRvIHRoZSBzcGVjaWZpZWQgYGZpZWxkYCxcbiAqIHdpdGggb3B0aW9uYWwgYGZpbGVuYW1lYC5cbiAqXG4gKiBgYGAganNcbiAqIHJlcXVlc3QucG9zdCgnL3VwbG9hZCcpXG4gKiAgIC5hdHRhY2goJ2NvbnRlbnQnLCBuZXcgQmxvYihbJzxhIGlkPVwiYVwiPjxiIGlkPVwiYlwiPmhleSE8L2I+PC9hPiddLCB7IHR5cGU6IFwidGV4dC9odG1sXCJ9KSlcbiAqICAgLmVuZChjYWxsYmFjayk7XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZmllbGRcbiAqIEBwYXJhbSB7QmxvYnxGaWxlfSBmaWxlXG4gKiBAcGFyYW0ge1N0cmluZ30gZmlsZW5hbWVcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5hdHRhY2ggPSBmdW5jdGlvbihmaWVsZCwgZmlsZSwgZmlsZW5hbWUpe1xuICB0aGlzLl9nZXRGb3JtRGF0YSgpLmFwcGVuZChmaWVsZCwgZmlsZSwgZmlsZW5hbWUgfHwgZmlsZS5uYW1lKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5fZ2V0Rm9ybURhdGEgPSBmdW5jdGlvbigpe1xuICBpZiAoIXRoaXMuX2Zvcm1EYXRhKSB7XG4gICAgdGhpcy5fZm9ybURhdGEgPSBuZXcgcm9vdC5Gb3JtRGF0YSgpO1xuICB9XG4gIHJldHVybiB0aGlzLl9mb3JtRGF0YTtcbn07XG5cbi8qKlxuICogSW52b2tlIHRoZSBjYWxsYmFjayB3aXRoIGBlcnJgIGFuZCBgcmVzYFxuICogYW5kIGhhbmRsZSBhcml0eSBjaGVjay5cbiAqXG4gKiBAcGFyYW0ge0Vycm9yfSBlcnJcbiAqIEBwYXJhbSB7UmVzcG9uc2V9IHJlc1xuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuY2FsbGJhY2sgPSBmdW5jdGlvbihlcnIsIHJlcyl7XG4gIHZhciBmbiA9IHRoaXMuX2NhbGxiYWNrO1xuICB0aGlzLmNsZWFyVGltZW91dCgpO1xuICBmbihlcnIsIHJlcyk7XG59O1xuXG4vKipcbiAqIEludm9rZSBjYWxsYmFjayB3aXRoIHgtZG9tYWluIGVycm9yLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmNyb3NzRG9tYWluRXJyb3IgPSBmdW5jdGlvbigpe1xuICB2YXIgZXJyID0gbmV3IEVycm9yKCdSZXF1ZXN0IGhhcyBiZWVuIHRlcm1pbmF0ZWRcXG5Qb3NzaWJsZSBjYXVzZXM6IHRoZSBuZXR3b3JrIGlzIG9mZmxpbmUsIE9yaWdpbiBpcyBub3QgYWxsb3dlZCBieSBBY2Nlc3MtQ29udHJvbC1BbGxvdy1PcmlnaW4sIHRoZSBwYWdlIGlzIGJlaW5nIHVubG9hZGVkLCBldGMuJyk7XG4gIGVyci5jcm9zc0RvbWFpbiA9IHRydWU7XG5cbiAgZXJyLnN0YXR1cyA9IHRoaXMuc3RhdHVzO1xuICBlcnIubWV0aG9kID0gdGhpcy5tZXRob2Q7XG4gIGVyci51cmwgPSB0aGlzLnVybDtcblxuICB0aGlzLmNhbGxiYWNrKGVycik7XG59O1xuXG4vKipcbiAqIEludm9rZSBjYWxsYmFjayB3aXRoIHRpbWVvdXQgZXJyb3IuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuX3RpbWVvdXRFcnJvciA9IGZ1bmN0aW9uKCl7XG4gIHZhciB0aW1lb3V0ID0gdGhpcy5fdGltZW91dDtcbiAgdmFyIGVyciA9IG5ldyBFcnJvcigndGltZW91dCBvZiAnICsgdGltZW91dCArICdtcyBleGNlZWRlZCcpO1xuICBlcnIudGltZW91dCA9IHRpbWVvdXQ7XG4gIHRoaXMuY2FsbGJhY2soZXJyKTtcbn07XG5cbi8qKlxuICogQ29tcG9zZSBxdWVyeXN0cmluZyB0byBhcHBlbmQgdG8gcmVxLnVybFxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblJlcXVlc3QucHJvdG90eXBlLl9hcHBlbmRRdWVyeVN0cmluZyA9IGZ1bmN0aW9uKCl7XG4gIHZhciBxdWVyeSA9IHRoaXMuX3F1ZXJ5LmpvaW4oJyYnKTtcbiAgaWYgKHF1ZXJ5KSB7XG4gICAgdGhpcy51cmwgKz0gfnRoaXMudXJsLmluZGV4T2YoJz8nKVxuICAgICAgPyAnJicgKyBxdWVyeVxuICAgICAgOiAnPycgKyBxdWVyeTtcbiAgfVxufTtcblxuLyoqXG4gKiBJbml0aWF0ZSByZXF1ZXN0LCBpbnZva2luZyBjYWxsYmFjayBgZm4ocmVzKWBcbiAqIHdpdGggYW4gaW5zdGFuY2VvZiBgUmVzcG9uc2VgLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuZW5kID0gZnVuY3Rpb24oZm4pe1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHZhciB4aHIgPSB0aGlzLnhociA9IHJlcXVlc3QuZ2V0WEhSKCk7XG4gIHZhciB0aW1lb3V0ID0gdGhpcy5fdGltZW91dDtcbiAgdmFyIGRhdGEgPSB0aGlzLl9mb3JtRGF0YSB8fCB0aGlzLl9kYXRhO1xuXG4gIC8vIHN0b3JlIGNhbGxiYWNrXG4gIHRoaXMuX2NhbGxiYWNrID0gZm4gfHwgbm9vcDtcblxuICAvLyBzdGF0ZSBjaGFuZ2VcbiAgeGhyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uKCl7XG4gICAgaWYgKDQgIT0geGhyLnJlYWR5U3RhdGUpIHJldHVybjtcblxuICAgIC8vIEluIElFOSwgcmVhZHMgdG8gYW55IHByb3BlcnR5IChlLmcuIHN0YXR1cykgb2ZmIG9mIGFuIGFib3J0ZWQgWEhSIHdpbGxcbiAgICAvLyByZXN1bHQgaW4gdGhlIGVycm9yIFwiQ291bGQgbm90IGNvbXBsZXRlIHRoZSBvcGVyYXRpb24gZHVlIHRvIGVycm9yIGMwMGMwMjNmXCJcbiAgICB2YXIgc3RhdHVzO1xuICAgIHRyeSB7IHN0YXR1cyA9IHhoci5zdGF0dXMgfSBjYXRjaChlKSB7IHN0YXR1cyA9IDA7IH1cblxuICAgIGlmICgwID09IHN0YXR1cykge1xuICAgICAgaWYgKHNlbGYudGltZWRvdXQpIHJldHVybiBzZWxmLl90aW1lb3V0RXJyb3IoKTtcbiAgICAgIGlmIChzZWxmLl9hYm9ydGVkKSByZXR1cm47XG4gICAgICByZXR1cm4gc2VsZi5jcm9zc0RvbWFpbkVycm9yKCk7XG4gICAgfVxuICAgIHNlbGYuZW1pdCgnZW5kJyk7XG4gIH07XG5cbiAgLy8gcHJvZ3Jlc3NcbiAgdmFyIGhhbmRsZVByb2dyZXNzID0gZnVuY3Rpb24oZSl7XG4gICAgaWYgKGUudG90YWwgPiAwKSB7XG4gICAgICBlLnBlcmNlbnQgPSBlLmxvYWRlZCAvIGUudG90YWwgKiAxMDA7XG4gICAgfVxuICAgIGUuZGlyZWN0aW9uID0gJ2Rvd25sb2FkJztcbiAgICBzZWxmLmVtaXQoJ3Byb2dyZXNzJywgZSk7XG4gIH07XG4gIGlmICh0aGlzLmhhc0xpc3RlbmVycygncHJvZ3Jlc3MnKSkge1xuICAgIHhoci5vbnByb2dyZXNzID0gaGFuZGxlUHJvZ3Jlc3M7XG4gIH1cbiAgdHJ5IHtcbiAgICBpZiAoeGhyLnVwbG9hZCAmJiB0aGlzLmhhc0xpc3RlbmVycygncHJvZ3Jlc3MnKSkge1xuICAgICAgeGhyLnVwbG9hZC5vbnByb2dyZXNzID0gaGFuZGxlUHJvZ3Jlc3M7XG4gICAgfVxuICB9IGNhdGNoKGUpIHtcbiAgICAvLyBBY2Nlc3NpbmcgeGhyLnVwbG9hZCBmYWlscyBpbiBJRSBmcm9tIGEgd2ViIHdvcmtlciwgc28ganVzdCBwcmV0ZW5kIGl0IGRvZXNuJ3QgZXhpc3QuXG4gICAgLy8gUmVwb3J0ZWQgaGVyZTpcbiAgICAvLyBodHRwczovL2Nvbm5lY3QubWljcm9zb2Z0LmNvbS9JRS9mZWVkYmFjay9kZXRhaWxzLzgzNzI0NS94bWxodHRwcmVxdWVzdC11cGxvYWQtdGhyb3dzLWludmFsaWQtYXJndW1lbnQtd2hlbi11c2VkLWZyb20td2ViLXdvcmtlci1jb250ZXh0XG4gIH1cblxuICAvLyB0aW1lb3V0XG4gIGlmICh0aW1lb3V0ICYmICF0aGlzLl90aW1lcikge1xuICAgIHRoaXMuX3RpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbigpe1xuICAgICAgc2VsZi50aW1lZG91dCA9IHRydWU7XG4gICAgICBzZWxmLmFib3J0KCk7XG4gICAgfSwgdGltZW91dCk7XG4gIH1cblxuICAvLyBxdWVyeXN0cmluZ1xuICB0aGlzLl9hcHBlbmRRdWVyeVN0cmluZygpO1xuXG4gIC8vIGluaXRpYXRlIHJlcXVlc3RcbiAgaWYgKHRoaXMudXNlcm5hbWUgJiYgdGhpcy5wYXNzd29yZCkge1xuICAgIHhoci5vcGVuKHRoaXMubWV0aG9kLCB0aGlzLnVybCwgdHJ1ZSwgdGhpcy51c2VybmFtZSwgdGhpcy5wYXNzd29yZCk7XG4gIH0gZWxzZSB7XG4gICAgeGhyLm9wZW4odGhpcy5tZXRob2QsIHRoaXMudXJsLCB0cnVlKTtcbiAgfVxuXG4gIC8vIENPUlNcbiAgaWYgKHRoaXMuX3dpdGhDcmVkZW50aWFscykgeGhyLndpdGhDcmVkZW50aWFscyA9IHRydWU7XG5cbiAgLy8gYm9keVxuICBpZiAoJ0dFVCcgIT0gdGhpcy5tZXRob2QgJiYgJ0hFQUQnICE9IHRoaXMubWV0aG9kICYmICdzdHJpbmcnICE9IHR5cGVvZiBkYXRhICYmICF0aGlzLl9pc0hvc3QoZGF0YSkpIHtcbiAgICAvLyBzZXJpYWxpemUgc3R1ZmZcbiAgICB2YXIgY29udGVudFR5cGUgPSB0aGlzLl9oZWFkZXJbJ2NvbnRlbnQtdHlwZSddO1xuICAgIHZhciBzZXJpYWxpemUgPSB0aGlzLl9zZXJpYWxpemVyIHx8IHJlcXVlc3Quc2VyaWFsaXplW2NvbnRlbnRUeXBlID8gY29udGVudFR5cGUuc3BsaXQoJzsnKVswXSA6ICcnXTtcbiAgICBpZiAoIXNlcmlhbGl6ZSAmJiBpc0pTT04oY29udGVudFR5cGUpKSBzZXJpYWxpemUgPSByZXF1ZXN0LnNlcmlhbGl6ZVsnYXBwbGljYXRpb24vanNvbiddO1xuICAgIGlmIChzZXJpYWxpemUpIGRhdGEgPSBzZXJpYWxpemUoZGF0YSk7XG4gIH1cblxuICAvLyBzZXQgaGVhZGVyIGZpZWxkc1xuICBmb3IgKHZhciBmaWVsZCBpbiB0aGlzLmhlYWRlcikge1xuICAgIGlmIChudWxsID09IHRoaXMuaGVhZGVyW2ZpZWxkXSkgY29udGludWU7XG4gICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoZmllbGQsIHRoaXMuaGVhZGVyW2ZpZWxkXSk7XG4gIH1cblxuICBpZiAodGhpcy5fcmVzcG9uc2VUeXBlKSB7XG4gICAgeGhyLnJlc3BvbnNlVHlwZSA9IHRoaXMuX3Jlc3BvbnNlVHlwZTtcbiAgfVxuXG4gIC8vIHNlbmQgc3R1ZmZcbiAgdGhpcy5lbWl0KCdyZXF1ZXN0JywgdGhpcyk7XG5cbiAgLy8gSUUxMSB4aHIuc2VuZCh1bmRlZmluZWQpIHNlbmRzICd1bmRlZmluZWQnIHN0cmluZyBhcyBQT1NUIHBheWxvYWQgKGluc3RlYWQgb2Ygbm90aGluZylcbiAgLy8gV2UgbmVlZCBudWxsIGhlcmUgaWYgZGF0YSBpcyB1bmRlZmluZWRcbiAgeGhyLnNlbmQodHlwZW9mIGRhdGEgIT09ICd1bmRlZmluZWQnID8gZGF0YSA6IG51bGwpO1xuICByZXR1cm4gdGhpcztcbn07XG5cblxuLyoqXG4gKiBFeHBvc2UgYFJlcXVlc3RgLlxuICovXG5cbnJlcXVlc3QuUmVxdWVzdCA9IFJlcXVlc3Q7XG5cbi8qKlxuICogR0VUIGB1cmxgIHdpdGggb3B0aW9uYWwgY2FsbGJhY2sgYGZuKHJlcylgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1cmxcbiAqIEBwYXJhbSB7TWl4ZWR8RnVuY3Rpb259IFtkYXRhXSBvciBmblxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2ZuXVxuICogQHJldHVybiB7UmVxdWVzdH1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxucmVxdWVzdC5nZXQgPSBmdW5jdGlvbih1cmwsIGRhdGEsIGZuKXtcbiAgdmFyIHJlcSA9IHJlcXVlc3QoJ0dFVCcsIHVybCk7XG4gIGlmICgnZnVuY3Rpb24nID09IHR5cGVvZiBkYXRhKSBmbiA9IGRhdGEsIGRhdGEgPSBudWxsO1xuICBpZiAoZGF0YSkgcmVxLnF1ZXJ5KGRhdGEpO1xuICBpZiAoZm4pIHJlcS5lbmQoZm4pO1xuICByZXR1cm4gcmVxO1xufTtcblxuLyoqXG4gKiBIRUFEIGB1cmxgIHdpdGggb3B0aW9uYWwgY2FsbGJhY2sgYGZuKHJlcylgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1cmxcbiAqIEBwYXJhbSB7TWl4ZWR8RnVuY3Rpb259IFtkYXRhXSBvciBmblxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2ZuXVxuICogQHJldHVybiB7UmVxdWVzdH1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxucmVxdWVzdC5oZWFkID0gZnVuY3Rpb24odXJsLCBkYXRhLCBmbil7XG4gIHZhciByZXEgPSByZXF1ZXN0KCdIRUFEJywgdXJsKTtcbiAgaWYgKCdmdW5jdGlvbicgPT0gdHlwZW9mIGRhdGEpIGZuID0gZGF0YSwgZGF0YSA9IG51bGw7XG4gIGlmIChkYXRhKSByZXEuc2VuZChkYXRhKTtcbiAgaWYgKGZuKSByZXEuZW5kKGZuKTtcbiAgcmV0dXJuIHJlcTtcbn07XG5cbi8qKlxuICogT1BUSU9OUyBxdWVyeSB0byBgdXJsYCB3aXRoIG9wdGlvbmFsIGNhbGxiYWNrIGBmbihyZXMpYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdXJsXG4gKiBAcGFyYW0ge01peGVkfEZ1bmN0aW9ufSBbZGF0YV0gb3IgZm5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtmbl1cbiAqIEByZXR1cm4ge1JlcXVlc3R9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbnJlcXVlc3Qub3B0aW9ucyA9IGZ1bmN0aW9uKHVybCwgZGF0YSwgZm4pe1xuICB2YXIgcmVxID0gcmVxdWVzdCgnT1BUSU9OUycsIHVybCk7XG4gIGlmICgnZnVuY3Rpb24nID09IHR5cGVvZiBkYXRhKSBmbiA9IGRhdGEsIGRhdGEgPSBudWxsO1xuICBpZiAoZGF0YSkgcmVxLnNlbmQoZGF0YSk7XG4gIGlmIChmbikgcmVxLmVuZChmbik7XG4gIHJldHVybiByZXE7XG59O1xuXG4vKipcbiAqIERFTEVURSBgdXJsYCB3aXRoIG9wdGlvbmFsIGNhbGxiYWNrIGBmbihyZXMpYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdXJsXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbZm5dXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBkZWwodXJsLCBmbil7XG4gIHZhciByZXEgPSByZXF1ZXN0KCdERUxFVEUnLCB1cmwpO1xuICBpZiAoZm4pIHJlcS5lbmQoZm4pO1xuICByZXR1cm4gcmVxO1xufTtcblxucmVxdWVzdFsnZGVsJ10gPSBkZWw7XG5yZXF1ZXN0WydkZWxldGUnXSA9IGRlbDtcblxuLyoqXG4gKiBQQVRDSCBgdXJsYCB3aXRoIG9wdGlvbmFsIGBkYXRhYCBhbmQgY2FsbGJhY2sgYGZuKHJlcylgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1cmxcbiAqIEBwYXJhbSB7TWl4ZWR9IFtkYXRhXVxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2ZuXVxuICogQHJldHVybiB7UmVxdWVzdH1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxucmVxdWVzdC5wYXRjaCA9IGZ1bmN0aW9uKHVybCwgZGF0YSwgZm4pe1xuICB2YXIgcmVxID0gcmVxdWVzdCgnUEFUQ0gnLCB1cmwpO1xuICBpZiAoJ2Z1bmN0aW9uJyA9PSB0eXBlb2YgZGF0YSkgZm4gPSBkYXRhLCBkYXRhID0gbnVsbDtcbiAgaWYgKGRhdGEpIHJlcS5zZW5kKGRhdGEpO1xuICBpZiAoZm4pIHJlcS5lbmQoZm4pO1xuICByZXR1cm4gcmVxO1xufTtcblxuLyoqXG4gKiBQT1NUIGB1cmxgIHdpdGggb3B0aW9uYWwgYGRhdGFgIGFuZCBjYWxsYmFjayBgZm4ocmVzKWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHVybFxuICogQHBhcmFtIHtNaXhlZH0gW2RhdGFdXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbZm5dXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5yZXF1ZXN0LnBvc3QgPSBmdW5jdGlvbih1cmwsIGRhdGEsIGZuKXtcbiAgdmFyIHJlcSA9IHJlcXVlc3QoJ1BPU1QnLCB1cmwpO1xuICBpZiAoJ2Z1bmN0aW9uJyA9PSB0eXBlb2YgZGF0YSkgZm4gPSBkYXRhLCBkYXRhID0gbnVsbDtcbiAgaWYgKGRhdGEpIHJlcS5zZW5kKGRhdGEpO1xuICBpZiAoZm4pIHJlcS5lbmQoZm4pO1xuICByZXR1cm4gcmVxO1xufTtcblxuLyoqXG4gKiBQVVQgYHVybGAgd2l0aCBvcHRpb25hbCBgZGF0YWAgYW5kIGNhbGxiYWNrIGBmbihyZXMpYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdXJsXG4gKiBAcGFyYW0ge01peGVkfEZ1bmN0aW9ufSBbZGF0YV0gb3IgZm5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtmbl1cbiAqIEByZXR1cm4ge1JlcXVlc3R9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbnJlcXVlc3QucHV0ID0gZnVuY3Rpb24odXJsLCBkYXRhLCBmbil7XG4gIHZhciByZXEgPSByZXF1ZXN0KCdQVVQnLCB1cmwpO1xuICBpZiAoJ2Z1bmN0aW9uJyA9PSB0eXBlb2YgZGF0YSkgZm4gPSBkYXRhLCBkYXRhID0gbnVsbDtcbiAgaWYgKGRhdGEpIHJlcS5zZW5kKGRhdGEpO1xuICBpZiAoZm4pIHJlcS5lbmQoZm4pO1xuICByZXR1cm4gcmVxO1xufTtcbiIsIi8qKlxuICogQ2hlY2sgaWYgYG9iamAgaXMgYW4gb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBpc09iamVjdChvYmopIHtcbiAgcmV0dXJuIG51bGwgIT09IG9iaiAmJiAnb2JqZWN0JyA9PT0gdHlwZW9mIG9iajtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc09iamVjdDtcbiIsIi8qKlxuICogTW9kdWxlIG9mIG1peGVkLWluIGZ1bmN0aW9ucyBzaGFyZWQgYmV0d2VlbiBub2RlIGFuZCBjbGllbnQgY29kZVxuICovXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL2lzLW9iamVjdCcpO1xuXG4vKipcbiAqIENsZWFyIHByZXZpb3VzIHRpbWVvdXQuXG4gKlxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuY2xlYXJUaW1lb3V0ID0gZnVuY3Rpb24gX2NsZWFyVGltZW91dCgpe1xuICB0aGlzLl90aW1lb3V0ID0gMDtcbiAgY2xlYXJUaW1lb3V0KHRoaXMuX3RpbWVyKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIE92ZXJyaWRlIGRlZmF1bHQgcmVzcG9uc2UgYm9keSBwYXJzZXJcbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIHdpbGwgYmUgY2FsbGVkIHRvIGNvbnZlcnQgaW5jb21pbmcgZGF0YSBpbnRvIHJlcXVlc3QuYm9keVxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMucGFyc2UgPSBmdW5jdGlvbiBwYXJzZShmbil7XG4gIHRoaXMuX3BhcnNlciA9IGZuO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogT3ZlcnJpZGUgZGVmYXVsdCByZXF1ZXN0IGJvZHkgc2VyaWFsaXplclxuICpcbiAqIFRoaXMgZnVuY3Rpb24gd2lsbCBiZSBjYWxsZWQgdG8gY29udmVydCBkYXRhIHNldCB2aWEgLnNlbmQgb3IgLmF0dGFjaCBpbnRvIHBheWxvYWQgdG8gc2VuZFxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuc2VyaWFsaXplID0gZnVuY3Rpb24gc2VyaWFsaXplKGZuKXtcbiAgdGhpcy5fc2VyaWFsaXplciA9IGZuO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0IHRpbWVvdXQgdG8gYG1zYC5cbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gbXNcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLnRpbWVvdXQgPSBmdW5jdGlvbiB0aW1lb3V0KG1zKXtcbiAgdGhpcy5fdGltZW91dCA9IG1zO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogUHJvbWlzZSBzdXBwb3J0XG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gcmVzb2x2ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gcmVqZWN0XG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICovXG5cbmV4cG9ydHMudGhlbiA9IGZ1bmN0aW9uIHRoZW4ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gIGlmICghdGhpcy5fZnVsbGZpbGxlZFByb21pc2UpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdGhpcy5fZnVsbGZpbGxlZFByb21pc2UgPSBuZXcgUHJvbWlzZShmdW5jdGlvbihpbm5lclJlc29sdmUsIGlubmVyUmVqZWN0KXtcbiAgICAgIHNlbGYuZW5kKGZ1bmN0aW9uKGVyciwgcmVzKXtcbiAgICAgICAgaWYgKGVycikgaW5uZXJSZWplY3QoZXJyKTsgZWxzZSBpbm5lclJlc29sdmUocmVzKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG4gIHJldHVybiB0aGlzLl9mdWxsZmlsbGVkUHJvbWlzZS50aGVuKHJlc29sdmUsIHJlamVjdCk7XG59XG5cbi8qKlxuICogQWxsb3cgZm9yIGV4dGVuc2lvblxuICovXG5cbmV4cG9ydHMudXNlID0gZnVuY3Rpb24gdXNlKGZuKSB7XG4gIGZuKHRoaXMpO1xuICByZXR1cm4gdGhpcztcbn1cblxuXG4vKipcbiAqIEdldCByZXF1ZXN0IGhlYWRlciBgZmllbGRgLlxuICogQ2FzZS1pbnNlbnNpdGl2ZS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZmllbGRcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5nZXQgPSBmdW5jdGlvbihmaWVsZCl7XG4gIHJldHVybiB0aGlzLl9oZWFkZXJbZmllbGQudG9Mb3dlckNhc2UoKV07XG59O1xuXG4vKipcbiAqIEdldCBjYXNlLWluc2Vuc2l0aXZlIGhlYWRlciBgZmllbGRgIHZhbHVlLlxuICogVGhpcyBpcyBhIGRlcHJlY2F0ZWQgaW50ZXJuYWwgQVBJLiBVc2UgYC5nZXQoZmllbGQpYCBpbnN0ZWFkLlxuICpcbiAqIChnZXRIZWFkZXIgaXMgbm8gbG9uZ2VyIHVzZWQgaW50ZXJuYWxseSBieSB0aGUgc3VwZXJhZ2VudCBjb2RlIGJhc2UpXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGZpZWxkXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqIEBkZXByZWNhdGVkXG4gKi9cblxuZXhwb3J0cy5nZXRIZWFkZXIgPSBleHBvcnRzLmdldDtcblxuLyoqXG4gKiBTZXQgaGVhZGVyIGBmaWVsZGAgdG8gYHZhbGAsIG9yIG11bHRpcGxlIGZpZWxkcyB3aXRoIG9uZSBvYmplY3QuXG4gKiBDYXNlLWluc2Vuc2l0aXZlLlxuICpcbiAqIEV4YW1wbGVzOlxuICpcbiAqICAgICAgcmVxLmdldCgnLycpXG4gKiAgICAgICAgLnNldCgnQWNjZXB0JywgJ2FwcGxpY2F0aW9uL2pzb24nKVxuICogICAgICAgIC5zZXQoJ1gtQVBJLUtleScsICdmb29iYXInKVxuICogICAgICAgIC5lbmQoY2FsbGJhY2spO1xuICpcbiAqICAgICAgcmVxLmdldCgnLycpXG4gKiAgICAgICAgLnNldCh7IEFjY2VwdDogJ2FwcGxpY2F0aW9uL2pzb24nLCAnWC1BUEktS2V5JzogJ2Zvb2JhcicgfSlcbiAqICAgICAgICAuZW5kKGNhbGxiYWNrKTtcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ3xPYmplY3R9IGZpZWxkXG4gKiBAcGFyYW0ge1N0cmluZ30gdmFsXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5zZXQgPSBmdW5jdGlvbihmaWVsZCwgdmFsKXtcbiAgaWYgKGlzT2JqZWN0KGZpZWxkKSkge1xuICAgIGZvciAodmFyIGtleSBpbiBmaWVsZCkge1xuICAgICAgdGhpcy5zZXQoa2V5LCBmaWVsZFtrZXldKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgdGhpcy5faGVhZGVyW2ZpZWxkLnRvTG93ZXJDYXNlKCldID0gdmFsO1xuICB0aGlzLmhlYWRlcltmaWVsZF0gPSB2YWw7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBSZW1vdmUgaGVhZGVyIGBmaWVsZGAuXG4gKiBDYXNlLWluc2Vuc2l0aXZlLlxuICpcbiAqIEV4YW1wbGU6XG4gKlxuICogICAgICByZXEuZ2V0KCcvJylcbiAqICAgICAgICAudW5zZXQoJ1VzZXItQWdlbnQnKVxuICogICAgICAgIC5lbmQoY2FsbGJhY2spO1xuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBmaWVsZFxuICovXG5leHBvcnRzLnVuc2V0ID0gZnVuY3Rpb24oZmllbGQpe1xuICBkZWxldGUgdGhpcy5faGVhZGVyW2ZpZWxkLnRvTG93ZXJDYXNlKCldO1xuICBkZWxldGUgdGhpcy5oZWFkZXJbZmllbGRdO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogV3JpdGUgdGhlIGZpZWxkIGBuYW1lYCBhbmQgYHZhbGAgZm9yIFwibXVsdGlwYXJ0L2Zvcm0tZGF0YVwiXG4gKiByZXF1ZXN0IGJvZGllcy5cbiAqXG4gKiBgYGAganNcbiAqIHJlcXVlc3QucG9zdCgnL3VwbG9hZCcpXG4gKiAgIC5maWVsZCgnZm9vJywgJ2JhcicpXG4gKiAgIC5lbmQoY2FsbGJhY2spO1xuICogYGBgXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcbiAqIEBwYXJhbSB7U3RyaW5nfEJsb2J8RmlsZXxCdWZmZXJ8ZnMuUmVhZFN0cmVhbX0gdmFsXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fSBmb3IgY2hhaW5pbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cbmV4cG9ydHMuZmllbGQgPSBmdW5jdGlvbihuYW1lLCB2YWwpIHtcbiAgdGhpcy5fZ2V0Rm9ybURhdGEoKS5hcHBlbmQobmFtZSwgdmFsKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEFib3J0IHRoZSByZXF1ZXN0LCBhbmQgY2xlYXIgcG90ZW50aWFsIHRpbWVvdXQuXG4gKlxuICogQHJldHVybiB7UmVxdWVzdH1cbiAqIEBhcGkgcHVibGljXG4gKi9cbmV4cG9ydHMuYWJvcnQgPSBmdW5jdGlvbigpe1xuICBpZiAodGhpcy5fYWJvcnRlZCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9XG4gIHRoaXMuX2Fib3J0ZWQgPSB0cnVlO1xuICB0aGlzLnhociAmJiB0aGlzLnhoci5hYm9ydCgpOyAvLyBicm93c2VyXG4gIHRoaXMucmVxICYmIHRoaXMucmVxLmFib3J0KCk7IC8vIG5vZGVcbiAgdGhpcy5jbGVhclRpbWVvdXQoKTtcbiAgdGhpcy5lbWl0KCdhYm9ydCcpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogRW5hYmxlIHRyYW5zbWlzc2lvbiBvZiBjb29raWVzIHdpdGggeC1kb21haW4gcmVxdWVzdHMuXG4gKlxuICogTm90ZSB0aGF0IGZvciB0aGlzIHRvIHdvcmsgdGhlIG9yaWdpbiBtdXN0IG5vdCBiZVxuICogdXNpbmcgXCJBY2Nlc3MtQ29udHJvbC1BbGxvdy1PcmlnaW5cIiB3aXRoIGEgd2lsZGNhcmQsXG4gKiBhbmQgYWxzbyBtdXN0IHNldCBcIkFjY2Vzcy1Db250cm9sLUFsbG93LUNyZWRlbnRpYWxzXCJcbiAqIHRvIFwidHJ1ZVwiLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy53aXRoQ3JlZGVudGlhbHMgPSBmdW5jdGlvbigpe1xuICAvLyBUaGlzIGlzIGJyb3dzZXItb25seSBmdW5jdGlvbmFsaXR5LiBOb2RlIHNpZGUgaXMgbm8tb3AuXG4gIHRoaXMuX3dpdGhDcmVkZW50aWFscyA9IHRydWU7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZXQgdGhlIG1heCByZWRpcmVjdHMgdG8gYG5gLiBEb2VzIG5vdGluZyBpbiBicm93c2VyIFhIUiBpbXBsZW1lbnRhdGlvbi5cbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gblxuICogQHJldHVybiB7UmVxdWVzdH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMucmVkaXJlY3RzID0gZnVuY3Rpb24obil7XG4gIHRoaXMuX21heFJlZGlyZWN0cyA9IG47XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBDb252ZXJ0IHRvIGEgcGxhaW4gamF2YXNjcmlwdCBvYmplY3QgKG5vdCBKU09OIHN0cmluZykgb2Ygc2NhbGFyIHByb3BlcnRpZXMuXG4gKiBOb3RlIGFzIHRoaXMgbWV0aG9kIGlzIGRlc2lnbmVkIHRvIHJldHVybiBhIHVzZWZ1bCBub24tdGhpcyB2YWx1ZSxcbiAqIGl0IGNhbm5vdCBiZSBjaGFpbmVkLlxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gZGVzY3JpYmluZyBtZXRob2QsIHVybCwgYW5kIGRhdGEgb2YgdGhpcyByZXF1ZXN0XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMudG9KU09OID0gZnVuY3Rpb24oKXtcbiAgcmV0dXJuIHtcbiAgICBtZXRob2Q6IHRoaXMubWV0aG9kLFxuICAgIHVybDogdGhpcy51cmwsXG4gICAgZGF0YTogdGhpcy5fZGF0YSxcbiAgICBoZWFkZXJzOiB0aGlzLl9oZWFkZXJcbiAgfTtcbn07XG5cbi8qKlxuICogQ2hlY2sgaWYgYG9iamAgaXMgYSBob3N0IG9iamVjdCxcbiAqIHdlIGRvbid0IHdhbnQgdG8gc2VyaWFsaXplIHRoZXNlIDopXG4gKlxuICogVE9ETzogZnV0dXJlIHByb29mLCBtb3ZlIHRvIGNvbXBvZW50IGxhbmRcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZXhwb3J0cy5faXNIb3N0ID0gZnVuY3Rpb24gX2lzSG9zdChvYmopIHtcbiAgdmFyIHN0ciA9IHt9LnRvU3RyaW5nLmNhbGwob2JqKTtcblxuICBzd2l0Y2ggKHN0cikge1xuICAgIGNhc2UgJ1tvYmplY3QgRmlsZV0nOlxuICAgIGNhc2UgJ1tvYmplY3QgQmxvYl0nOlxuICAgIGNhc2UgJ1tvYmplY3QgRm9ybURhdGFdJzpcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuLyoqXG4gKiBTZW5kIGBkYXRhYCBhcyB0aGUgcmVxdWVzdCBib2R5LCBkZWZhdWx0aW5nIHRoZSBgLnR5cGUoKWAgdG8gXCJqc29uXCIgd2hlblxuICogYW4gb2JqZWN0IGlzIGdpdmVuLlxuICpcbiAqIEV4YW1wbGVzOlxuICpcbiAqICAgICAgIC8vIG1hbnVhbCBqc29uXG4gKiAgICAgICByZXF1ZXN0LnBvc3QoJy91c2VyJylcbiAqICAgICAgICAgLnR5cGUoJ2pzb24nKVxuICogICAgICAgICAuc2VuZCgne1wibmFtZVwiOlwidGpcIn0nKVxuICogICAgICAgICAuZW5kKGNhbGxiYWNrKVxuICpcbiAqICAgICAgIC8vIGF1dG8ganNvblxuICogICAgICAgcmVxdWVzdC5wb3N0KCcvdXNlcicpXG4gKiAgICAgICAgIC5zZW5kKHsgbmFtZTogJ3RqJyB9KVxuICogICAgICAgICAuZW5kKGNhbGxiYWNrKVxuICpcbiAqICAgICAgIC8vIG1hbnVhbCB4LXd3dy1mb3JtLXVybGVuY29kZWRcbiAqICAgICAgIHJlcXVlc3QucG9zdCgnL3VzZXInKVxuICogICAgICAgICAudHlwZSgnZm9ybScpXG4gKiAgICAgICAgIC5zZW5kKCduYW1lPXRqJylcbiAqICAgICAgICAgLmVuZChjYWxsYmFjaylcbiAqXG4gKiAgICAgICAvLyBhdXRvIHgtd3d3LWZvcm0tdXJsZW5jb2RlZFxuICogICAgICAgcmVxdWVzdC5wb3N0KCcvdXNlcicpXG4gKiAgICAgICAgIC50eXBlKCdmb3JtJylcbiAqICAgICAgICAgLnNlbmQoeyBuYW1lOiAndGonIH0pXG4gKiAgICAgICAgIC5lbmQoY2FsbGJhY2spXG4gKlxuICogICAgICAgLy8gZGVmYXVsdHMgdG8geC13d3ctZm9ybS11cmxlbmNvZGVkXG4gKiAgICAgIHJlcXVlc3QucG9zdCgnL3VzZXInKVxuICogICAgICAgIC5zZW5kKCduYW1lPXRvYmknKVxuICogICAgICAgIC5zZW5kKCdzcGVjaWVzPWZlcnJldCcpXG4gKiAgICAgICAgLmVuZChjYWxsYmFjaylcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ3xPYmplY3R9IGRhdGFcbiAqIEByZXR1cm4ge1JlcXVlc3R9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLnNlbmQgPSBmdW5jdGlvbihkYXRhKXtcbiAgdmFyIG9iaiA9IGlzT2JqZWN0KGRhdGEpO1xuICB2YXIgdHlwZSA9IHRoaXMuX2hlYWRlclsnY29udGVudC10eXBlJ107XG5cbiAgLy8gbWVyZ2VcbiAgaWYgKG9iaiAmJiBpc09iamVjdCh0aGlzLl9kYXRhKSkge1xuICAgIGZvciAodmFyIGtleSBpbiBkYXRhKSB7XG4gICAgICB0aGlzLl9kYXRhW2tleV0gPSBkYXRhW2tleV07XG4gICAgfVxuICB9IGVsc2UgaWYgKCdzdHJpbmcnID09IHR5cGVvZiBkYXRhKSB7XG4gICAgLy8gZGVmYXVsdCB0byB4LXd3dy1mb3JtLXVybGVuY29kZWRcbiAgICBpZiAoIXR5cGUpIHRoaXMudHlwZSgnZm9ybScpO1xuICAgIHR5cGUgPSB0aGlzLl9oZWFkZXJbJ2NvbnRlbnQtdHlwZSddO1xuICAgIGlmICgnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJyA9PSB0eXBlKSB7XG4gICAgICB0aGlzLl9kYXRhID0gdGhpcy5fZGF0YVxuICAgICAgICA/IHRoaXMuX2RhdGEgKyAnJicgKyBkYXRhXG4gICAgICAgIDogZGF0YTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fZGF0YSA9ICh0aGlzLl9kYXRhIHx8ICcnKSArIGRhdGE7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRoaXMuX2RhdGEgPSBkYXRhO1xuICB9XG5cbiAgaWYgKCFvYmogfHwgdGhpcy5faXNIb3N0KGRhdGEpKSByZXR1cm4gdGhpcztcblxuICAvLyBkZWZhdWx0IHRvIGpzb25cbiAgaWYgKCF0eXBlKSB0aGlzLnR5cGUoJ2pzb24nKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuIiwiLy8gVGhlIG5vZGUgYW5kIGJyb3dzZXIgbW9kdWxlcyBleHBvc2UgdmVyc2lvbnMgb2YgdGhpcyB3aXRoIHRoZVxuLy8gYXBwcm9wcmlhdGUgY29uc3RydWN0b3IgZnVuY3Rpb24gYm91bmQgYXMgZmlyc3QgYXJndW1lbnRcbi8qKlxuICogSXNzdWUgYSByZXF1ZXN0OlxuICpcbiAqIEV4YW1wbGVzOlxuICpcbiAqICAgIHJlcXVlc3QoJ0dFVCcsICcvdXNlcnMnKS5lbmQoY2FsbGJhY2spXG4gKiAgICByZXF1ZXN0KCcvdXNlcnMnKS5lbmQoY2FsbGJhY2spXG4gKiAgICByZXF1ZXN0KCcvdXNlcnMnLCBjYWxsYmFjaylcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbWV0aG9kXG4gKiBAcGFyYW0ge1N0cmluZ3xGdW5jdGlvbn0gdXJsIG9yIGNhbGxiYWNrXG4gKiBAcmV0dXJuIHtSZXF1ZXN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiByZXF1ZXN0KFJlcXVlc3RDb25zdHJ1Y3RvciwgbWV0aG9kLCB1cmwpIHtcbiAgLy8gY2FsbGJhY2tcbiAgaWYgKCdmdW5jdGlvbicgPT0gdHlwZW9mIHVybCkge1xuICAgIHJldHVybiBuZXcgUmVxdWVzdENvbnN0cnVjdG9yKCdHRVQnLCBtZXRob2QpLmVuZCh1cmwpO1xuICB9XG5cbiAgLy8gdXJsIGZpcnN0XG4gIGlmICgyID09IGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICByZXR1cm4gbmV3IFJlcXVlc3RDb25zdHJ1Y3RvcignR0VUJywgbWV0aG9kKTtcbiAgfVxuXG4gIHJldHVybiBuZXcgUmVxdWVzdENvbnN0cnVjdG9yKG1ldGhvZCwgdXJsKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSByZXF1ZXN0O1xuIiwiXHJcbi8qKlxyXG4gKiBFeHBvc2UgYEVtaXR0ZXJgLlxyXG4gKi9cclxuXHJcbmlmICh0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJykge1xyXG4gIG1vZHVsZS5leHBvcnRzID0gRW1pdHRlcjtcclxufVxyXG5cclxuLyoqXHJcbiAqIEluaXRpYWxpemUgYSBuZXcgYEVtaXR0ZXJgLlxyXG4gKlxyXG4gKiBAYXBpIHB1YmxpY1xyXG4gKi9cclxuXHJcbmZ1bmN0aW9uIEVtaXR0ZXIob2JqKSB7XHJcbiAgaWYgKG9iaikgcmV0dXJuIG1peGluKG9iaik7XHJcbn07XHJcblxyXG4vKipcclxuICogTWl4aW4gdGhlIGVtaXR0ZXIgcHJvcGVydGllcy5cclxuICpcclxuICogQHBhcmFtIHtPYmplY3R9IG9ialxyXG4gKiBAcmV0dXJuIHtPYmplY3R9XHJcbiAqIEBhcGkgcHJpdmF0ZVxyXG4gKi9cclxuXHJcbmZ1bmN0aW9uIG1peGluKG9iaikge1xyXG4gIGZvciAodmFyIGtleSBpbiBFbWl0dGVyLnByb3RvdHlwZSkge1xyXG4gICAgb2JqW2tleV0gPSBFbWl0dGVyLnByb3RvdHlwZVtrZXldO1xyXG4gIH1cclxuICByZXR1cm4gb2JqO1xyXG59XHJcblxyXG4vKipcclxuICogTGlzdGVuIG9uIHRoZSBnaXZlbiBgZXZlbnRgIHdpdGggYGZuYC5cclxuICpcclxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XHJcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXHJcbiAqIEByZXR1cm4ge0VtaXR0ZXJ9XHJcbiAqIEBhcGkgcHVibGljXHJcbiAqL1xyXG5cclxuRW1pdHRlci5wcm90b3R5cGUub24gPVxyXG5FbWl0dGVyLnByb3RvdHlwZS5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24oZXZlbnQsIGZuKXtcclxuICB0aGlzLl9jYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3MgfHwge307XHJcbiAgKHRoaXMuX2NhbGxiYWNrc1snJCcgKyBldmVudF0gPSB0aGlzLl9jYWxsYmFja3NbJyQnICsgZXZlbnRdIHx8IFtdKVxyXG4gICAgLnB1c2goZm4pO1xyXG4gIHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIEFkZHMgYW4gYGV2ZW50YCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBhIHNpbmdsZVxyXG4gKiB0aW1lIHRoZW4gYXV0b21hdGljYWxseSByZW1vdmVkLlxyXG4gKlxyXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcclxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cclxuICogQHJldHVybiB7RW1pdHRlcn1cclxuICogQGFwaSBwdWJsaWNcclxuICovXHJcblxyXG5FbWl0dGVyLnByb3RvdHlwZS5vbmNlID0gZnVuY3Rpb24oZXZlbnQsIGZuKXtcclxuICBmdW5jdGlvbiBvbigpIHtcclxuICAgIHRoaXMub2ZmKGV2ZW50LCBvbik7XHJcbiAgICBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xyXG4gIH1cclxuXHJcbiAgb24uZm4gPSBmbjtcclxuICB0aGlzLm9uKGV2ZW50LCBvbik7XHJcbiAgcmV0dXJuIHRoaXM7XHJcbn07XHJcblxyXG4vKipcclxuICogUmVtb3ZlIHRoZSBnaXZlbiBjYWxsYmFjayBmb3IgYGV2ZW50YCBvciBhbGxcclxuICogcmVnaXN0ZXJlZCBjYWxsYmFja3MuXHJcbiAqXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxyXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxyXG4gKiBAcmV0dXJuIHtFbWl0dGVyfVxyXG4gKiBAYXBpIHB1YmxpY1xyXG4gKi9cclxuXHJcbkVtaXR0ZXIucHJvdG90eXBlLm9mZiA9XHJcbkVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID1cclxuRW1pdHRlci5wcm90b3R5cGUucmVtb3ZlQWxsTGlzdGVuZXJzID1cclxuRW1pdHRlci5wcm90b3R5cGUucmVtb3ZlRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50LCBmbil7XHJcbiAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xyXG5cclxuICAvLyBhbGxcclxuICBpZiAoMCA9PSBhcmd1bWVudHMubGVuZ3RoKSB7XHJcbiAgICB0aGlzLl9jYWxsYmFja3MgPSB7fTtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLy8gc3BlY2lmaWMgZXZlbnRcclxuICB2YXIgY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzWyckJyArIGV2ZW50XTtcclxuICBpZiAoIWNhbGxiYWNrcykgcmV0dXJuIHRoaXM7XHJcblxyXG4gIC8vIHJlbW92ZSBhbGwgaGFuZGxlcnNcclxuICBpZiAoMSA9PSBhcmd1bWVudHMubGVuZ3RoKSB7XHJcbiAgICBkZWxldGUgdGhpcy5fY2FsbGJhY2tzWyckJyArIGV2ZW50XTtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLy8gcmVtb3ZlIHNwZWNpZmljIGhhbmRsZXJcclxuICB2YXIgY2I7XHJcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBjYWxsYmFja3MubGVuZ3RoOyBpKyspIHtcclxuICAgIGNiID0gY2FsbGJhY2tzW2ldO1xyXG4gICAgaWYgKGNiID09PSBmbiB8fCBjYi5mbiA9PT0gZm4pIHtcclxuICAgICAgY2FsbGJhY2tzLnNwbGljZShpLCAxKTtcclxuICAgICAgYnJlYWs7XHJcbiAgICB9XHJcbiAgfVxyXG4gIHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIEVtaXQgYGV2ZW50YCB3aXRoIHRoZSBnaXZlbiBhcmdzLlxyXG4gKlxyXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcclxuICogQHBhcmFtIHtNaXhlZH0gLi4uXHJcbiAqIEByZXR1cm4ge0VtaXR0ZXJ9XHJcbiAqL1xyXG5cclxuRW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uKGV2ZW50KXtcclxuICB0aGlzLl9jYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3MgfHwge307XHJcbiAgdmFyIGFyZ3MgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSlcclxuICAgICwgY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzWyckJyArIGV2ZW50XTtcclxuXHJcbiAgaWYgKGNhbGxiYWNrcykge1xyXG4gICAgY2FsbGJhY2tzID0gY2FsbGJhY2tzLnNsaWNlKDApO1xyXG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGNhbGxiYWNrcy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xyXG4gICAgICBjYWxsYmFja3NbaV0uYXBwbHkodGhpcywgYXJncyk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZXR1cm4gdGhpcztcclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm4gYXJyYXkgb2YgY2FsbGJhY2tzIGZvciBgZXZlbnRgLlxyXG4gKlxyXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcclxuICogQHJldHVybiB7QXJyYXl9XHJcbiAqIEBhcGkgcHVibGljXHJcbiAqL1xyXG5cclxuRW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJzID0gZnVuY3Rpb24oZXZlbnQpe1xyXG4gIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcclxuICByZXR1cm4gdGhpcy5fY2FsbGJhY2tzWyckJyArIGV2ZW50XSB8fCBbXTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBDaGVjayBpZiB0aGlzIGVtaXR0ZXIgaGFzIGBldmVudGAgaGFuZGxlcnMuXHJcbiAqXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxyXG4gKiBAcmV0dXJuIHtCb29sZWFufVxyXG4gKiBAYXBpIHB1YmxpY1xyXG4gKi9cclxuXHJcbkVtaXR0ZXIucHJvdG90eXBlLmhhc0xpc3RlbmVycyA9IGZ1bmN0aW9uKGV2ZW50KXtcclxuICByZXR1cm4gISEgdGhpcy5saXN0ZW5lcnMoZXZlbnQpLmxlbmd0aDtcclxufTtcclxuIiwiIC8qZ2xvYmFsIEpTT05FZGl0b3IqL1xuJ3VzZSBzdHJpY3QnO1xuXG53aW5kb3cuU3dhZ2dlclVpID0gQmFja2JvbmUuUm91dGVyLmV4dGVuZCh7XG5cbiAgZG9tX2lkOiAnc3dhZ2dlcl91aScsXG5cbiAgLy8gQXR0cmlidXRlc1xuICBvcHRpb25zOiBudWxsLFxuICBhcGk6IG51bGwsXG4gIGhlYWRlclZpZXc6IG51bGwsXG4gIG1haW5WaWV3OiBudWxsLFxuXG4gIC8vIFN3YWdnZXJVaSBhY2NlcHRzIGFsbCB0aGUgc2FtZSBvcHRpb25zIGFzIFN3YWdnZXJBcGlcbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24ob3B0aW9ucykge1xuICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gICAgaWYgKG9wdGlvbnMuZGVmYXVsdE1vZGVsUmVuZGVyaW5nICE9PSAnbW9kZWwnKSB7XG4gICAgICBvcHRpb25zLmRlZmF1bHRNb2RlbFJlbmRlcmluZyA9ICdzY2hlbWEnO1xuICAgIH1cblxuICAgIGlmICghb3B0aW9ucy5oaWdobGlnaHRTaXplVGhyZXNob2xkKSB7XG4gICAgICBvcHRpb25zLmhpZ2hsaWdodFNpemVUaHJlc2hvbGQgPSAxMDAwMDA7XG4gICAgfVxuXG4gICAgLy8gQWxsb3cgZG9tX2lkIHRvIGJlIG92ZXJyaWRkZW5cbiAgICBpZiAob3B0aW9ucy5kb21faWQpIHtcbiAgICAgIHRoaXMuZG9tX2lkID0gb3B0aW9ucy5kb21faWQ7XG4gICAgICBkZWxldGUgb3B0aW9ucy5kb21faWQ7XG4gICAgfVxuXG4gICAgaWYgKCFvcHRpb25zLnN1cHBvcnRlZFN1Ym1pdE1ldGhvZHMpe1xuICAgICAgb3B0aW9ucy5zdXBwb3J0ZWRTdWJtaXRNZXRob2RzID0gW1xuICAgICAgICAnZ2V0JyxcbiAgICAgICAgJ3B1dCcsXG4gICAgICAgICdwb3N0JyxcbiAgICAgICAgJ2RlbGV0ZScsXG4gICAgICAgICdoZWFkJyxcbiAgICAgICAgJ29wdGlvbnMnLFxuICAgICAgICAncGF0Y2gnXG4gICAgICBdO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5vYXV0aDJSZWRpcmVjdFVybCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHdpbmRvdy5vQXV0aFJlZGlyZWN0VXJsID0gb3B0aW9ucy5vYXV0aDJSZWRpcmVjdFVybDtcbiAgICB9XG5cbiAgICAvLyBDcmVhdGUgYW4gZW1wdHkgZGl2IHdoaWNoIGNvbnRhaW5zIHRoZSBkb21faWRcbiAgICBpZiAoISAkKCcjJyArIHRoaXMuZG9tX2lkKS5sZW5ndGgpe1xuICAgICAgJCgnYm9keScpLmFwcGVuZCgnPGRpdiBpZD1cIicgKyB0aGlzLmRvbV9pZCArICdcIj48L2Rpdj4nKSA7XG4gICAgfVxuXG4gICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcblxuICAgIC8vIHNldCBtYXJrZWQgb3B0aW9uc1xuICAgIG1hcmtlZC5zZXRPcHRpb25zKHtnZm06IHRydWV9KTtcblxuICAgIC8vIFNldCB0aGUgY2FsbGJhY2tzXG4gICAgdmFyIHRoYXQgPSB0aGlzO1xuICAgIHRoaXMub3B0aW9ucy5zdWNjZXNzID0gZnVuY3Rpb24oKSB7IHJldHVybiB0aGF0LnJlbmRlcigpOyB9O1xuICAgIHRoaXMub3B0aW9ucy5wcm9ncmVzcyA9IGZ1bmN0aW9uKGQpIHsgcmV0dXJuIHRoYXQuc2hvd01lc3NhZ2UoZCk7IH07XG4gICAgdGhpcy5vcHRpb25zLmZhaWx1cmUgPSBmdW5jdGlvbihkKSB7IHJldHVybiB0aGF0Lm9uTG9hZEZhaWx1cmUoZCk7IH07XG5cbiAgICAvLyBDcmVhdGUgdmlldyB0byBoYW5kbGUgdGhlIGhlYWRlciBpbnB1dHNcbiAgICB0aGlzLmhlYWRlclZpZXcgPSBuZXcgU3dhZ2dlclVpLlZpZXdzLkhlYWRlclZpZXcoe2VsOiAkKCcjaGVhZGVyJyl9KTtcblxuICAgIC8vIEV2ZW50IGhhbmRsZXIgZm9yIHdoZW4gdGhlIGJhc2VVcmwvYXBpS2V5IGlzIGVudGVyZWQgYnkgdXNlclxuICAgIHRoaXMuaGVhZGVyVmlldy5vbigndXBkYXRlLXN3YWdnZXItdWknLCBmdW5jdGlvbihkYXRhKSB7XG4gICAgICByZXR1cm4gdGhhdC51cGRhdGVTd2FnZ2VyVWkoZGF0YSk7XG4gICAgfSk7XG5cbiAgICAvLyBKU29uIEVkaXRvciBjdXN0b20gdGhlbWluZ1xuICAgICBKU09ORWRpdG9yLmRlZmF1bHRzLmljb25saWJzLnN3YWdnZXIgPSBKU09ORWRpdG9yLkFic3RyYWN0SWNvbkxpYi5leHRlbmQoe1xuICAgICAgbWFwcGluZzoge1xuICAgICAgICBjb2xsYXBzZTogJ2NvbGxhcHNlJyxcbiAgICAgICAgZXhwYW5kOiAnZXhwYW5kJ1xuICAgICAgICB9LFxuICAgICAgaWNvbl9wcmVmaXg6ICdzd2FnZ2VyLSdcbiAgICAgIH0pO1xuXG4gIH0sXG5cbiAgLy8gU2V0IGFuIG9wdGlvbiBhZnRlciBpbml0aWFsaXppbmdcbiAgc2V0T3B0aW9uOiBmdW5jdGlvbihvcHRpb24sIHZhbHVlKSB7XG4gICAgdGhpcy5vcHRpb25zW29wdGlvbl0gPSB2YWx1ZTtcbiAgfSxcblxuICAvLyBHZXQgdGhlIHZhbHVlIG9mIGEgcHJldmlvdXNseSBzZXQgb3B0aW9uXG4gIGdldE9wdGlvbjogZnVuY3Rpb24ob3B0aW9uKSB7XG4gICAgcmV0dXJuIHRoaXMub3B0aW9uc1tvcHRpb25dO1xuICB9LFxuXG4gIC8vIEV2ZW50IGhhbmRsZXIgZm9yIHdoZW4gdXJsL2tleSBpcyByZWNlaXZlZCBmcm9tIHVzZXJcbiAgdXBkYXRlU3dhZ2dlclVpOiBmdW5jdGlvbihkYXRhKXtcbiAgICB0aGlzLm9wdGlvbnMudXJsID0gZGF0YS51cmw7XG4gICAgdGhpcy5sb2FkKCk7XG4gIH0sXG5cbiAgLy8gQ3JlYXRlIGFuIGFwaSBhbmQgcmVuZGVyXG4gIGxvYWQ6IGZ1bmN0aW9uKCl7XG4gICAgLy8gSW5pdGlhbGl6ZSB0aGUgQVBJIG9iamVjdFxuICAgIGlmICh0aGlzLm1haW5WaWV3KSB7XG4gICAgICB0aGlzLm1haW5WaWV3LmNsZWFyKCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuYXV0aFZpZXcpIHtcbiAgICAgIHRoaXMuYXV0aFZpZXcucmVtb3ZlKCk7XG4gICAgfVxuICAgIHZhciB1cmwgPSB0aGlzLm9wdGlvbnMudXJsO1xuICAgIGlmICh1cmwgJiYgdXJsLmluZGV4T2YoJ2h0dHAnKSAhPT0gMCkge1xuICAgICAgdXJsID0gdGhpcy5idWlsZFVybCh3aW5kb3cubG9jYXRpb24uaHJlZi50b1N0cmluZygpLCB1cmwpO1xuICAgIH1cbiAgICBpZih0aGlzLmFwaSkge1xuICAgICAgdGhpcy5vcHRpb25zLmF1dGhvcml6YXRpb25zID0gdGhpcy5hcGkuY2xpZW50QXV0aG9yaXphdGlvbnMuYXV0aHo7XG4gICAgfVxuICAgIHRoaXMub3B0aW9ucy51cmwgPSB1cmw7XG4gICAgdGhpcy5oZWFkZXJWaWV3LnVwZGF0ZSh1cmwpO1xuXG4gICAgdGhpcy5hcGkgPSBuZXcgU3dhZ2dlckNsaWVudCh0aGlzLm9wdGlvbnMpO1xuICB9LFxuXG4gIC8vIGNvbGxhcHNlIGFsbCBzZWN0aW9uc1xuICBjb2xsYXBzZUFsbDogZnVuY3Rpb24oKXtcbiAgICBEb2NzLmNvbGxhcHNlRW5kcG9pbnRMaXN0Rm9yUmVzb3VyY2UoJycpO1xuICB9LFxuXG4gIC8vIGxpc3Qgb3BlcmF0aW9ucyBmb3IgYWxsIHNlY3Rpb25zXG4gIGxpc3RBbGw6IGZ1bmN0aW9uKCl7XG4gICAgRG9jcy5jb2xsYXBzZU9wZXJhdGlvbnNGb3JSZXNvdXJjZSgnJyk7XG4gIH0sXG5cbiAgLy8gZXhwYW5kIG9wZXJhdGlvbnMgZm9yIGFsbCBzZWN0aW9uc1xuICBleHBhbmRBbGw6IGZ1bmN0aW9uKCl7XG4gICAgRG9jcy5leHBhbmRPcGVyYXRpb25zRm9yUmVzb3VyY2UoJycpO1xuICB9LFxuXG4gIC8vIFRoaXMgaXMgYm91bmQgdG8gc3VjY2VzcyBoYW5kbGVyIGZvciBTd2FnZ2VyQXBpXG4gIC8vICBzbyBpdCBnZXRzIGNhbGxlZCB3aGVuIFN3YWdnZXJBcGkgY29tcGxldGVzIGxvYWRpbmdcbiAgcmVuZGVyOiBmdW5jdGlvbigpe1xuICAgIHZhciBhdXRoc01vZGVsO1xuICAgIHRoaXMuc2hvd01lc3NhZ2UoJ0ZpbmlzaGVkIExvYWRpbmcgUmVzb3VyY2UgSW5mb3JtYXRpb24uIFJlbmRlcmluZyBTd2FnZ2VyIFVJLi4uJyk7XG4gICAgdGhpcy5tYWluVmlldyA9IG5ldyBTd2FnZ2VyVWkuVmlld3MuTWFpblZpZXcoe1xuICAgICAgbW9kZWw6IHRoaXMuYXBpLFxuICAgICAgZWw6ICQoJyMnICsgdGhpcy5kb21faWQpLFxuICAgICAgc3dhZ2dlck9wdGlvbnM6IHRoaXMub3B0aW9ucyxcbiAgICAgIHJvdXRlcjogdGhpc1xuICAgIH0pLnJlbmRlcigpO1xuICAgIGlmICghXy5pc0VtcHR5KHRoaXMuYXBpLnNlY3VyaXR5RGVmaW5pdGlvbnMpKXtcbiAgICAgIGF1dGhzTW9kZWwgPSBfLm1hcCh0aGlzLmFwaS5zZWN1cml0eURlZmluaXRpb25zLCBmdW5jdGlvbiAoYXV0aCwgbmFtZSkge1xuICAgICAgICB2YXIgcmVzdWx0ID0ge307XG4gICAgICAgIHJlc3VsdFtuYW1lXSA9IGF1dGg7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9KTtcbiAgICAgIHRoaXMuYXV0aFZpZXcgPSBuZXcgU3dhZ2dlclVpLlZpZXdzLkF1dGhCdXR0b25WaWV3KHtcbiAgICAgICAgZGF0YTogU3dhZ2dlclVpLnV0aWxzLnBhcnNlU2VjdXJpdHlEZWZpbml0aW9ucyhhdXRoc01vZGVsKSxcbiAgICAgICAgcm91dGVyOiB0aGlzXG4gICAgICB9KTtcbiAgICAgICQoJyNhdXRoX2NvbnRhaW5lcicpLmFwcGVuZCh0aGlzLmF1dGhWaWV3LnJlbmRlcigpLmVsKTtcbiAgICB9XG4gICAgdGhpcy5zaG93TWVzc2FnZSgpO1xuICAgIHN3aXRjaCAodGhpcy5vcHRpb25zLmRvY0V4cGFuc2lvbikge1xuICAgICAgY2FzZSAnZnVsbCc6XG4gICAgICAgIHRoaXMuZXhwYW5kQWxsKCk7IGJyZWFrO1xuICAgICAgY2FzZSAnbGlzdCc6XG4gICAgICAgIHRoaXMubGlzdEFsbCgpOyBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICB0aGlzLnJlbmRlckdGTSgpO1xuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5vbkNvbXBsZXRlKXtcbiAgICAgIHRoaXMub3B0aW9ucy5vbkNvbXBsZXRlKHRoaXMuYXBpLCB0aGlzKTtcbiAgICB9XG5cbiAgICBzZXRUaW1lb3V0KERvY3Muc2hlYmFuZy5iaW5kKHRoaXMpLCAxMDApO1xuICB9LFxuXG4gIGJ1aWxkVXJsOiBmdW5jdGlvbihiYXNlLCB1cmwpe1xuICAgIGlmICh1cmwuaW5kZXhPZignLycpID09PSAwKSB7XG4gICAgICB2YXIgcGFydHMgPSBiYXNlLnNwbGl0KCcvJyk7XG4gICAgICBiYXNlID0gcGFydHNbMF0gKyAnLy8nICsgcGFydHNbMl07XG4gICAgICByZXR1cm4gYmFzZSArIHVybDtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGVuZE9mUGF0aCA9IGJhc2UubGVuZ3RoO1xuXG4gICAgICBpZiAoYmFzZS5pbmRleE9mKCc/JykgPiAtMSl7XG4gICAgICAgIGVuZE9mUGF0aCA9IE1hdGgubWluKGVuZE9mUGF0aCwgYmFzZS5pbmRleE9mKCc/JykpO1xuICAgICAgfVxuXG4gICAgICBpZiAoYmFzZS5pbmRleE9mKCcjJykgPiAtMSl7XG4gICAgICAgIGVuZE9mUGF0aCA9IE1hdGgubWluKGVuZE9mUGF0aCwgYmFzZS5pbmRleE9mKCcjJykpO1xuICAgICAgfVxuXG4gICAgICBiYXNlID0gYmFzZS5zdWJzdHJpbmcoMCwgZW5kT2ZQYXRoKTtcblxuICAgICAgaWYgKGJhc2UuaW5kZXhPZignLycsIGJhc2UubGVuZ3RoIC0gMSApICE9PSAtMSl7XG4gICAgICAgIHJldHVybiBiYXNlICsgdXJsO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gYmFzZSArICcvJyArIHVybDtcbiAgICB9XG4gIH0sXG5cbiAgLy8gU2hvd3MgbWVzc2FnZSBvbiB0b3BiYXIgb2YgdGhlIHVpXG4gIHNob3dNZXNzYWdlOiBmdW5jdGlvbihkYXRhKXtcbiAgICBpZiAoZGF0YSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBkYXRhID0gJyc7XG4gICAgfVxuICAgIHZhciAkbXNnYmFyID0gJCgnI21lc3NhZ2UtYmFyJyk7XG4gICAgJG1zZ2Jhci5yZW1vdmVDbGFzcygnbWVzc2FnZS1mYWlsJyk7XG4gICAgJG1zZ2Jhci5hZGRDbGFzcygnbWVzc2FnZS1zdWNjZXNzJyk7XG4gICAgJG1zZ2Jhci50ZXh0KGRhdGEpO1xuICAgIGlmKHdpbmRvdy5Td2FnZ2VyVHJhbnNsYXRvcikge1xuICAgICAgd2luZG93LlN3YWdnZXJUcmFuc2xhdG9yLnRyYW5zbGF0ZSgkbXNnYmFyKTtcbiAgICB9XG4gIH0sXG5cbiAgLy8gc2hvd3MgbWVzc2FnZSBpbiByZWRcbiAgb25Mb2FkRmFpbHVyZTogZnVuY3Rpb24oZGF0YSl7XG4gICAgaWYgKGRhdGEgPT09IHVuZGVmaW5lZCkge1xuICAgICAgZGF0YSA9ICcnO1xuICAgIH1cbiAgICAkKCcjbWVzc2FnZS1iYXInKS5yZW1vdmVDbGFzcygnbWVzc2FnZS1zdWNjZXNzJyk7XG4gICAgJCgnI21lc3NhZ2UtYmFyJykuYWRkQ2xhc3MoJ21lc3NhZ2UtZmFpbCcpO1xuXG4gICAgdmFyIHZhbCA9ICQoJyNtZXNzYWdlLWJhcicpLnRleHQoZGF0YSk7XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLm9uRmFpbHVyZSkge1xuICAgICAgdGhpcy5vcHRpb25zLm9uRmFpbHVyZShkYXRhKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsO1xuICB9LFxuXG4gIC8vIFJlbmRlcnMgR0ZNIGZvciBlbGVtZW50cyB3aXRoICdtYXJrZG93bicgY2xhc3NcbiAgcmVuZGVyR0ZNOiBmdW5jdGlvbigpe1xuICAgICQoJy5tYXJrZG93bicpLmVhY2goZnVuY3Rpb24oKXtcbiAgICAgICQodGhpcykuaHRtbChtYXJrZWQoJCh0aGlzKS5odG1sKCkpKTtcbiAgICB9KTtcblxuICAgICQoJy5wcm9wRGVzYycsICcubW9kZWwtc2lnbmF0dXJlIC5kZXNjcmlwdGlvbicpLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgJCh0aGlzKS5odG1sKG1hcmtlZCgkKHRoaXMpLmh0bWwoKSkpLmFkZENsYXNzKCdtYXJrZG93bicpO1xuICAgIH0pO1xuICB9XG5cbn0pO1xuXG53aW5kb3cuU3dhZ2dlclVpLlZpZXdzID0ge307XG53aW5kb3cuU3dhZ2dlclVpLk1vZGVscyA9IHt9O1xud2luZG93LlN3YWdnZXJVaS5Db2xsZWN0aW9ucyA9IHt9O1xud2luZG93LlN3YWdnZXJVaS5wYXJ0aWFscyA9IHt9O1xud2luZG93LlN3YWdnZXJVaS51dGlscyA9IHt9O1xuXG4vLyBkb24ndCBicmVhayBiYWNrd2FyZCBjb21wYXRpYmlsaXR5IHdpdGggcHJldmlvdXMgdmVyc2lvbnMgYW5kIHdhcm4gdXNlcnMgdG8gdXBncmFkZSB0aGVpciBjb2RlXG4oZnVuY3Rpb24oKXtcbiAgd2luZG93LmF1dGhvcml6YXRpb25zID0ge1xuICAgIGFkZDogZnVuY3Rpb24oKSB7XG4gICAgICB3YXJuKCdVc2luZyB3aW5kb3cuYXV0aG9yaXphdGlvbnMgaXMgZGVwcmVjYXRlZC4gUGxlYXNlIHVzZSBTd2FnZ2VyVWkuYXBpLmNsaWVudEF1dGhvcml6YXRpb25zLmFkZCgpLicpO1xuXG4gICAgICBpZiAodHlwZW9mIHdpbmRvdy5zd2FnZ2VyVWkgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3dpbmRvdy5zd2FnZ2VyVWkgaXMgbm90IGRlZmluZWQnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHdpbmRvdy5zd2FnZ2VyVWkgaW5zdGFuY2VvZiBTd2FnZ2VyVWkpIHtcbiAgICAgICAgd2luZG93LnN3YWdnZXJVaS5hcGkuY2xpZW50QXV0aG9yaXphdGlvbnMuYWRkLmFwcGx5KHdpbmRvdy5zd2FnZ2VyVWkuYXBpLmNsaWVudEF1dGhvcml6YXRpb25zLCBhcmd1bWVudHMpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICB3aW5kb3cuQXBpS2V5QXV0aG9yaXphdGlvbiA9IGZ1bmN0aW9uKCkge1xuICAgIHdhcm4oJ3dpbmRvdy5BcGlLZXlBdXRob3JpemF0aW9uIGlzIGRlcHJlY2F0ZWQuIFBsZWFzZSB1c2UgU3dhZ2dlckNsaWVudC5BcGlLZXlBdXRob3JpemF0aW9uLicpO1xuICAgIFN3YWdnZXJDbGllbnQuQXBpS2V5QXV0aG9yaXphdGlvbi5hcHBseSh3aW5kb3csIGFyZ3VtZW50cyk7XG4gIH07XG5cbiAgd2luZG93LlBhc3N3b3JkQXV0aG9yaXphdGlvbiA9IGZ1bmN0aW9uKCkge1xuICAgIHdhcm4oJ3dpbmRvdy5QYXNzd29yZEF1dGhvcml6YXRpb24gaXMgZGVwcmVjYXRlZC4gUGxlYXNlIHVzZSBTd2FnZ2VyQ2xpZW50LlBhc3N3b3JkQXV0aG9yaXphdGlvbi4nKTtcbiAgICBTd2FnZ2VyQ2xpZW50LlBhc3N3b3JkQXV0aG9yaXphdGlvbi5hcHBseSh3aW5kb3csIGFyZ3VtZW50cyk7XG4gIH07XG5cbiAgZnVuY3Rpb24gd2FybihtZXNzYWdlKSB7XG4gICAgaWYgKCdjb25zb2xlJyBpbiB3aW5kb3cgJiYgdHlwZW9mIHdpbmRvdy5jb25zb2xlLndhcm4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGNvbnNvbGUud2FybihtZXNzYWdlKTtcbiAgICB9XG4gIH1cbn0pKCk7XG5cblxuLy8gVU1EXG4oZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnkpIHtcbiAgICBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7XG4gICAgICAgIC8vIEFNRC4gUmVnaXN0ZXIgYXMgYW4gYW5vbnltb3VzIG1vZHVsZS5cbiAgICAgICAgZGVmaW5lKFsnYiddLCBmdW5jdGlvbiAoYikge1xuICAgICAgICAgICAgcmV0dXJuIChyb290LlN3YWdnZXJVaSA9IGZhY3RvcnkoYikpO1xuICAgICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0Jykge1xuICAgICAgICAvLyBOb2RlLiBEb2VzIG5vdCB3b3JrIHdpdGggc3RyaWN0IENvbW1vbkpTLCBidXRcbiAgICAgICAgLy8gb25seSBDb21tb25KUy1saWtlIGVudmlyb25tZW50cyB0aGF0IHN1cHBvcnQgbW9kdWxlLmV4cG9ydHMsXG4gICAgICAgIC8vIGxpa2UgTm9kZS5cbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmUoJ2InKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQnJvd3NlciBnbG9iYWxzXG4gICAgICAgIHJvb3QuU3dhZ2dlclVpID0gZmFjdG9yeShyb290LmIpO1xuICAgIH1cbn0odGhpcywgZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBTd2FnZ2VyVWk7XG59KSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbndpbmRvdy5Td2FnZ2VyVWkudXRpbHMgPSB7XG4gICAgcGFyc2VTZWN1cml0eURlZmluaXRpb25zOiBmdW5jdGlvbiAoc2VjdXJpdHksIHNlY3VyaXR5RGVmaW5pdGlvbnMpIHtcbiAgICAgICAgdmFyIGF1dGhzID0gT2JqZWN0LmFzc2lnbih7fSwgc2VjdXJpdHlEZWZpbml0aW9ucyk7XG4gICAgICAgIHZhciBvYXV0aDJBcnIgPSBbXTtcbiAgICAgICAgdmFyIGF1dGhzQXJyID0gW107XG4gICAgICAgIHZhciBzY29wZXMgPSBbXTtcbiAgICAgICAgdmFyIHV0aWxzID0gd2luZG93LlN3YWdnZXJVaS51dGlscztcblxuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkoc2VjdXJpdHkpKSB7IHJldHVybiBudWxsOyB9XG5cbiAgICAgICAgc2VjdXJpdHkuZm9yRWFjaChmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgICAgdmFyIHNpbmdsZVNlY3VyaXR5ID0ge307XG4gICAgICAgICAgICB2YXIgc2luZ2xlT2F1dGgyU2VjdXJpdHkgPSB7fTtcblxuICAgICAgICAgICAgZm9yICh2YXIga2V5IGluIGl0ZW0pIHtcbiAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShpdGVtW2tleV0pKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghYXV0aHNba2V5XSkgeyBjb250aW51ZTsgfVxuICAgICAgICAgICAgICAgICAgICBhdXRoc1trZXldID0gYXV0aHNba2V5XSB8fCB7fTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGF1dGhzW2tleV0udHlwZSA9PT0gJ29hdXRoMicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpbmdsZU9hdXRoMlNlY3VyaXR5W2tleV0gPSBPYmplY3QuYXNzaWduKHt9LCBhdXRoc1trZXldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpbmdsZU9hdXRoMlNlY3VyaXR5W2tleV0uc2NvcGVzID0gT2JqZWN0LmFzc2lnbih7fSwgYXV0aHNba2V5XS5zY29wZXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBzaW5nbGVPYXV0aDJTZWN1cml0eVtrZXldLnNjb3Blcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpdGVtW2tleV0uaW5kZXhPZihpKSA8IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHNpbmdsZU9hdXRoMlNlY3VyaXR5W2tleV0uc2NvcGVzW2ldO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHNpbmdsZU9hdXRoMlNlY3VyaXR5W2tleV0uc2NvcGVzID0gdXRpbHMucGFyc2VPYXV0aDJTY29wZXMoc2luZ2xlT2F1dGgyU2VjdXJpdHlba2V5XS5zY29wZXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2NvcGVzID0gXy5tZXJnZShzY29wZXMsIHNpbmdsZU9hdXRoMlNlY3VyaXR5W2tleV0uc2NvcGVzKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpbmdsZVNlY3VyaXR5W2tleV0gPSBPYmplY3QuYXNzaWduKHt9LCBhdXRoc1trZXldKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpdGVtW2tleV0udHlwZSA9PT0gJ29hdXRoMicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpbmdsZU9hdXRoMlNlY3VyaXR5W2tleV0gPSBPYmplY3QuYXNzaWduKHt9LCBpdGVtW2tleV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2luZ2xlT2F1dGgyU2VjdXJpdHlba2V5XS5zY29wZXMgPSB1dGlscy5wYXJzZU9hdXRoMlNjb3BlcyhzaW5nbGVPYXV0aDJTZWN1cml0eVtrZXldLnNjb3Blcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBzY29wZXMgPSBfLm1lcmdlKHNjb3Blcywgc2luZ2xlT2F1dGgyU2VjdXJpdHlba2V5XS5zY29wZXMpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2luZ2xlU2VjdXJpdHlba2V5XSA9IGl0ZW1ba2V5XTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCFfLmlzRW1wdHkoc2luZ2xlU2VjdXJpdHkpKSB7XG4gICAgICAgICAgICAgICAgYXV0aHNBcnIucHVzaChzaW5nbGVTZWN1cml0eSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghXy5pc0VtcHR5KHNpbmdsZU9hdXRoMlNlY3VyaXR5KSl7XG4gICAgICAgICAgICAgICAgb2F1dGgyQXJyLnB1c2goc2luZ2xlT2F1dGgyU2VjdXJpdHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgYXV0aHMgOiBhdXRoc0FycixcbiAgICAgICAgICAgIG9hdXRoMjogb2F1dGgyQXJyLFxuICAgICAgICAgICAgc2NvcGVzOiBzY29wZXNcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgcGFyc2VPYXV0aDJTY29wZXM6IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgIHZhciBzY29wZXMgPSBPYmplY3QuYXNzaWduKHt9LCBkYXRhKTtcbiAgICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgICAgICB2YXIga2V5O1xuXG4gICAgICAgIGZvciAoa2V5IGluIHNjb3Blcykge1xuICAgICAgICAgICAgcmVzdWx0LnB1c2goe3Njb3BlOiBrZXksIGRlc2NyaXB0aW9uOiBzY29wZXNba2V5XX0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9LFxuXG4gICAgc2FuaXRpemU6IGZ1bmN0aW9uKGh0bWwpIHtcbiAgICAgICAgLy8gU3RyaXAgdGhlIHNjcmlwdCB0YWdzIGZyb20gdGhlIGh0bWwgYW5kIGlubGluZSBldmVuaGFuZGxlcnNcbiAgICAgICAgaHRtbCA9IGh0bWwucmVwbGFjZSgvPHNjcmlwdFxcYltePF0qKD86KD8hPFxcL3NjcmlwdD4pPFtePF0qKSo8XFwvc2NyaXB0Pi9naSwgJycpO1xuICAgICAgICBodG1sID0gaHRtbC5yZXBsYWNlKC8ob25cXHcrPVwiW15cIl0qXCIpKihvblxcdys9J1teJ10qJykqKG9uXFx3Kz1cXHcqXFwoXFx3KlxcKSkqL2dpLCAnJyk7XG5cbiAgICAgICAgcmV0dXJuIGh0bWw7XG4gICAgfVxufTsiLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5Nb2RlbHMuQXBpS2V5QXV0aE1vZGVsID0gQmFja2JvbmUuTW9kZWwuZXh0ZW5kKHtcbiAgICBkZWZhdWx0czoge1xuICAgICAgICAnaW4nOiAnJyxcbiAgICAgICAgbmFtZTogJycsXG4gICAgICAgIHRpdGxlOiAnJyxcbiAgICAgICAgdmFsdWU6ICcnXG4gICAgfSxcblxuICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5vbignY2hhbmdlJywgdGhpcy52YWxpZGF0ZSk7XG4gICAgfSxcblxuICAgIHZhbGlkYXRlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB2YWxpZCA9ICEhdGhpcy5nZXQoJ3ZhbHVlJyk7XG5cbiAgICAgICAgdGhpcy5zZXQoJ3ZhbGlkJywgdmFsaWQpO1xuXG4gICAgICAgIHJldHVybiB2YWxpZDtcbiAgICB9XG59KTsiLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5WaWV3cy5BcGlLZXlBdXRoVmlldyA9IEJhY2tib25lLlZpZXcuZXh0ZW5kKHsgLy8gVE9ETzogYXBwZW5kIHRoaXMgdG8gZ2xvYmFsIFN3YWdnZXJVaVxuXG4gICAgZXZlbnRzOiB7XG4gICAgICAgICdjaGFuZ2UgLmlucHV0X2FwaUtleV9lbnRyeSc6ICdhcGlLZXlDaGFuZ2UnXG4gICAgfSxcblxuICAgIHNlbGVjdG9yczoge1xuICAgICAgICBhcGlrZXlJbnB1dDogJy5pbnB1dF9hcGlLZXlfZW50cnknXG4gICAgfSxcblxuICAgIHRlbXBsYXRlOiBIYW5kbGViYXJzLnRlbXBsYXRlcy5hcGlrZXlfYXV0aCxcblxuICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uKG9wdHMpIHtcbiAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0cyB8fCB7fTtcbiAgICAgICAgdGhpcy5yb3V0ZXIgPSB0aGlzLm9wdGlvbnMucm91dGVyO1xuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uICgpe1xuICAgICAgICB0aGlzLiRlbC5odG1sKHRoaXMudGVtcGxhdGUodGhpcy5tb2RlbC50b0pTT04oKSkpO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICBhcGlLZXlDaGFuZ2U6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIHZhciB2YWwgPSAkKGUudGFyZ2V0KS52YWwoKTtcbiAgICAgICAgaWYgKHZhbCkge1xuICAgICAgICAgICAgdGhpcy4kKHRoaXMuc2VsZWN0b3JzLmFwaWtleUlucHV0KS5yZW1vdmVDbGFzcygnZXJyb3InKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMubW9kZWwuc2V0KCd2YWx1ZScsIHZhbCk7XG4gICAgfSxcblxuICAgIGlzVmFsaWQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubW9kZWwudmFsaWRhdGUoKTtcbiAgICB9LFxuXG4gICAgaGlnaGxpZ2h0SW52YWxpZDogZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoIXRoaXMuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICB0aGlzLiQodGhpcy5zZWxlY3RvcnMuYXBpa2V5SW5wdXQpLmFkZENsYXNzKCdlcnJvcicpO1xuICAgICAgICB9XG4gICAgfVxuXG59KTsiLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5WaWV3cy5BdXRoQnV0dG9uVmlldyA9IEJhY2tib25lLlZpZXcuZXh0ZW5kKHtcbiAgICBldmVudHM6IHtcbiAgICAgICAgJ2NsaWNrIC5hdXRob3JpemVfX2J0bic6ICdhdXRob3JpemVCdG5DbGljaydcbiAgICB9LFxuXG4gICAgdHBsczoge1xuICAgICAgICBwb3B1cDogSGFuZGxlYmFycy50ZW1wbGF0ZXMucG9wdXAsXG4gICAgICAgIGF1dGhCdG46IEhhbmRsZWJhcnMudGVtcGxhdGVzLmF1dGhfYnV0dG9uLFxuICAgICAgICBhdXRoQnRuT3BlcmF0aW9uOiBIYW5kbGViYXJzLnRlbXBsYXRlcy5hdXRoX2J1dHRvbl9vcGVyYXRpb25cbiAgICB9LFxuXG4gICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24ob3B0cykge1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSBvcHRzIHx8IHt9O1xuICAgICAgICB0aGlzLm9wdGlvbnMuZGF0YSA9IHRoaXMub3B0aW9ucy5kYXRhIHx8IHt9O1xuICAgICAgICB0aGlzLmlzT3BlcmF0aW9uID0gdGhpcy5vcHRpb25zLmlzT3BlcmF0aW9uO1xuICAgICAgICB0aGlzLm1vZGVsID0gdGhpcy5tb2RlbCB8fCB7fTtcbiAgICAgICAgdGhpcy5yb3V0ZXIgPSB0aGlzLm9wdGlvbnMucm91dGVyO1xuICAgICAgICB0aGlzLmF1dGhzID0gdGhpcy5vcHRpb25zLmRhdGEub2F1dGgyLmNvbmNhdCh0aGlzLm9wdGlvbnMuZGF0YS5hdXRocyk7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdHBsTmFtZSA9IHRoaXMuaXNPcGVyYXRpb24gPyAnYXV0aEJ0bk9wZXJhdGlvbicgOiAnYXV0aEJ0bic7XG5cbiAgICAgICAgdGhpcy4kYXV0aEVsID0gdGhpcy5yZW5kZXJBdXRocyh0aGlzLmF1dGhzKTtcbiAgICAgICAgdGhpcy4kZWwuaHRtbCh0aGlzLnRwbHNbdHBsTmFtZV0odGhpcy5tb2RlbCkpO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICBhdXRob3JpemVCdG5DbGljazogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgdmFyIGF1dGhzTW9kZWw7XG5cbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgIGF1dGhzTW9kZWwgPSB7XG4gICAgICAgICAgICB0aXRsZTogJ0F2YWlsYWJsZSBhdXRob3JpemF0aW9ucycsXG4gICAgICAgICAgICBjb250ZW50OiB0aGlzLiRhdXRoRWxcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBUaGUgY29udGVudCBvZiB0aGUgcG9wdXAgaXMgcmVtb3ZlZCBhbmQgYWxsIGV2ZW50cyB1bmJvdW5kIGFmdGVyIGNsaWNraW5nIHRoZSAnQ2FuY2VsJyBidXR0b24gb2YgdGhlIHBvcHVwLlxuICAgICAgICAvLyBXZSdsbCBoYXZlIHRvIHJlLXJlbmRlciB0aGUgY29udGVudHMgYmVmb3JlIGNyZWF0aW5nIGEgbmV3IHBvcHVwIHZpZXcuXG4gICAgICAgIHRoaXMucmVuZGVyKCk7XG5cbiAgICAgICAgdGhpcy5wb3B1cCA9IG5ldyBTd2FnZ2VyVWkuVmlld3MuUG9wdXBWaWV3KHttb2RlbDogYXV0aHNNb2RlbH0pO1xuICAgICAgICB0aGlzLnBvcHVwLnJlbmRlcigpO1xuICAgIH0sXG5cbiAgICByZW5kZXJBdXRoczogZnVuY3Rpb24gKGF1dGhzKSB7XG4gICAgICAgIHZhciAkZWwgPSAkKCc8ZGl2PicpO1xuICAgICAgICB2YXIgaXNMb2dvdXQgPSBmYWxzZTtcblxuICAgICAgICBhdXRocy5mb3JFYWNoKGZ1bmN0aW9uIChhdXRoKSB7XG4gICAgICAgICAgICB2YXIgYXV0aFZpZXcgPSBuZXcgU3dhZ2dlclVpLlZpZXdzLkF1dGhWaWV3KHtkYXRhOiBhdXRoLCByb3V0ZXI6IHRoaXMucm91dGVyfSk7XG4gICAgICAgICAgICB2YXIgYXV0aEVsID0gYXV0aFZpZXcucmVuZGVyKCkuZWw7XG4gICAgICAgICAgICAkZWwuYXBwZW5kKGF1dGhFbCk7XG4gICAgICAgICAgICBpZiAoYXV0aFZpZXcuaXNMb2dvdXQpIHtcbiAgICAgICAgICAgICAgICBpc0xvZ291dCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sIHRoaXMpO1xuXG4gICAgICAgIHRoaXMubW9kZWwuaXNMb2dvdXQgPSBpc0xvZ291dDtcblxuICAgICAgICByZXR1cm4gJGVsO1xuICAgIH1cblxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5Db2xsZWN0aW9ucy5BdXRoc0NvbGxlY3Rpb24gPSBCYWNrYm9uZS5Db2xsZWN0aW9uLmV4dGVuZCh7XG4gICAgY29uc3RydWN0b3I6IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG5cbiAgICAgICAgYXJnc1swXSA9IHRoaXMucGFyc2UoYXJnc1swXSk7XG5cbiAgICAgICAgQmFja2JvbmUuQ29sbGVjdGlvbi5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9LFxuXG4gICAgYWRkOiBmdW5jdGlvbiAobW9kZWwpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KG1vZGVsKSkge1xuICAgICAgICAgICAgYXJnc1swXSA9IF8ubWFwKG1vZGVsLCBmdW5jdGlvbih2YWwpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5oYW5kbGVPbmUodmFsKTtcbiAgICAgICAgICAgIH0sIHRoaXMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYXJnc1swXSA9IHRoaXMuaGFuZGxlT25lKG1vZGVsKTtcbiAgICAgICAgfVxuXG4gICAgICAgIEJhY2tib25lLkNvbGxlY3Rpb24ucHJvdG90eXBlLmFkZC5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9LFxuXG4gICAgaGFuZGxlT25lOiBmdW5jdGlvbiAobW9kZWwpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IG1vZGVsO1xuXG4gICAgICAgIGlmICghIChtb2RlbCBpbnN0YW5jZW9mIEJhY2tib25lLk1vZGVsKSApIHtcbiAgICAgICAgICAgIHN3aXRjaCAobW9kZWwudHlwZSkge1xuICAgICAgICAgICAgICAgIGNhc2UgJ29hdXRoMic6XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBTd2FnZ2VyVWkuTW9kZWxzLk9hdXRoMk1vZGVsKG1vZGVsKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnYmFzaWMnOlxuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBuZXcgU3dhZ2dlclVpLk1vZGVscy5CYXNpY0F1dGhNb2RlbChtb2RlbCk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ2FwaUtleSc6XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBTd2FnZ2VyVWkuTW9kZWxzLkFwaUtleUF1dGhNb2RlbChtb2RlbCk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBCYWNrYm9uZS5Nb2RlbChtb2RlbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0sXG5cbiAgICBpc1ZhbGlkOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB2YWxpZCA9IHRydWU7XG5cbiAgICAgICAgdGhpcy5tb2RlbHMuZm9yRWFjaChmdW5jdGlvbihtb2RlbCkge1xuICAgICAgICAgICAgaWYgKCFtb2RlbC52YWxpZGF0ZSgpKSB7XG4gICAgICAgICAgICAgICAgdmFsaWQgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHZhbGlkO1xuICAgIH0sXG5cbiAgICBpc0F1dGhvcml6ZWQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubGVuZ3RoID09PSB0aGlzLndoZXJlKHsgaXNMb2dvdXQ6IHRydWUgfSkubGVuZ3RoO1xuICAgIH0sXG5cbiAgICBpc1BhcnRpYWxseUF1dGhvcml6ZWQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2hlcmUoeyBpc0xvZ291dDogdHJ1ZSB9KS5sZW5ndGggPiAwO1xuICAgIH0sXG5cbiAgICBwYXJzZTogZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgdmFyIGF1dGh6ID0ge307XG5cbiAgICAgICAgaWYodHlwZW9mIHdpbmRvdy5zd2FnZ2VyVWkgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBhdXRoeiA9IE9iamVjdC5hc3NpZ24oe30sIHdpbmRvdy5zd2FnZ2VyVWkuYXBpLmNsaWVudEF1dGhvcml6YXRpb25zLmF1dGh6KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBfLm1hcChkYXRhLCBmdW5jdGlvbiAoYXV0aCwgbmFtZSkge1xuICAgICAgICAgICAgdmFyIGlzQmFzaWMgPSBhdXRoeltuYW1lXSAmJiBhdXRoLnR5cGUgPT09ICdiYXNpYycgJiYgYXV0aHpbbmFtZV0udXNlcm5hbWUgJiYgYXV0aHpbbmFtZV0ucGFzc3dvcmQ7XG5cbiAgICAgICAgICAgIF8uZXh0ZW5kKGF1dGgsIHtcbiAgICAgICAgICAgICAgICB0aXRsZTogbmFtZVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGlmIChhdXRoeltuYW1lXSB8fCBpc0Jhc2ljKSB7XG4gICAgICAgICAgICAgICAgXy5leHRlbmQoYXV0aCwge1xuICAgICAgICAgICAgICAgICAgICBpc0xvZ291dDogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGlzQmFzaWMgPyB1bmRlZmluZWQgOiBhdXRoeltuYW1lXS52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgdXNlcm5hbWU6IGlzQmFzaWMgPyBhdXRoeltuYW1lXS51c2VybmFtZSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgcGFzc3dvcmQ6IGlzQmFzaWMgPyBhdXRoeltuYW1lXS5wYXNzd29yZCA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgdmFsaWQ6IHRydWVcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGF1dGg7XG4gICAgICAgIH0pO1xuICAgIH1cbn0pOyIsIid1c2Ugc3RyaWN0JztcblxuU3dhZ2dlclVpLlZpZXdzLkF1dGhzQ29sbGVjdGlvblZpZXcgPSBCYWNrYm9uZS5WaWV3LmV4dGVuZCh7XG5cbiAgICBpbml0aWFsaXplOiBmdW5jdGlvbihvcHRzKSB7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdHMgfHwge307XG4gICAgICAgIHRoaXMub3B0aW9ucy5kYXRhID0gdGhpcy5vcHRpb25zLmRhdGEgfHwge307XG4gICAgICAgIHRoaXMucm91dGVyID0gdGhpcy5vcHRpb25zLnJvdXRlcjtcblxuICAgICAgICB0aGlzLmNvbGxlY3Rpb24gPSBuZXcgU3dhZ2dlclVpLkNvbGxlY3Rpb25zLkF1dGhzQ29sbGVjdGlvbihvcHRzLmRhdGEpO1xuXG4gICAgICAgIHRoaXMuJGlubmVyRWwgPSAkKCc8ZGl2PicpO1xuICAgICAgICB0aGlzLmF1dGhWaWV3cyA9IFtdO1xuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5jb2xsZWN0aW9uLmVhY2goZnVuY3Rpb24gKGF1dGgpIHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyT25lQXV0aChhdXRoKTtcbiAgICAgICAgfSwgdGhpcyk7XG5cbiAgICAgICAgdGhpcy4kZWwuaHRtbCh0aGlzLiRpbm5lckVsLmh0bWwoKSA/IHRoaXMuJGlubmVyRWwgOiAnJyk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIHJlbmRlck9uZUF1dGg6IGZ1bmN0aW9uIChhdXRoTW9kZWwpIHtcbiAgICAgICAgdmFyIGF1dGhWaWV3RWwsIGF1dGhWaWV3LCBhdXRoVmlld05hbWU7XG4gICAgICAgIHZhciB0eXBlID0gYXV0aE1vZGVsLmdldCgndHlwZScpO1xuXG4gICAgICAgIGlmICh0eXBlID09PSAnYXBpS2V5Jykge1xuICAgICAgICAgICAgYXV0aFZpZXdOYW1lID0gJ0FwaUtleUF1dGhWaWV3JztcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnYmFzaWMnICYmIHRoaXMuJGlubmVyRWwuZmluZCgnLmJhc2ljX2F1dGhfY29udGFpbmVyJykubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICBhdXRoVmlld05hbWUgPSAnQmFzaWNBdXRoVmlldyc7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ29hdXRoMicpIHtcbiAgICAgICAgICAgIGF1dGhWaWV3TmFtZSA9ICdPYXV0aDJWaWV3JztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChhdXRoVmlld05hbWUpIHtcbiAgICAgICAgICAgIGF1dGhWaWV3ID0gbmV3IFN3YWdnZXJVaS5WaWV3c1thdXRoVmlld05hbWVdKHttb2RlbDogYXV0aE1vZGVsLCByb3V0ZXI6IHRoaXMucm91dGVyfSk7XG4gICAgICAgICAgICBhdXRoVmlld0VsID0gYXV0aFZpZXcucmVuZGVyKCkuZWw7XG4gICAgICAgICAgICB0aGlzLmF1dGhWaWV3cy5wdXNoKGF1dGhWaWV3KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuJGlubmVyRWwuYXBwZW5kKGF1dGhWaWV3RWwpO1xuICAgIH0sXG5cbiAgICBoaWdobGlnaHRJbnZhbGlkOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuYXV0aFZpZXdzLmZvckVhY2goZnVuY3Rpb24gKHZpZXcpIHtcbiAgICAgICAgICAgIHZpZXcuaGlnaGxpZ2h0SW52YWxpZCgpO1xuICAgICAgICB9LCB0aGlzKTtcbiAgICB9XG5cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKiBnbG9iYWwgcmVkaXJlY3RfdXJpOnRydWUgKi9cbi8qIGdsb2JhbCBjbGllbnRJZCAqL1xuLyogZ2xvYmFsIHNjb3BlU2VwYXJhdG9yICovXG4vKiBnbG9iYWwgYWRkaXRpb25hbFF1ZXJ5U3RyaW5nUGFyYW1zICovXG4vKiBnbG9iYWwgY2xpZW50U2VjcmV0ICovXG4vKiBnbG9iYWwgb25PQXV0aENvbXBsZXRlICovXG4vKiBnbG9iYWwgcmVhbG0gKi9cbi8qanNoaW50IHVudXNlZDpmYWxzZSovXG5cblN3YWdnZXJVaS5WaWV3cy5BdXRoVmlldyA9IEJhY2tib25lLlZpZXcuZXh0ZW5kKHtcbiAgICBldmVudHM6IHtcbiAgICAgICAgJ2NsaWNrIC5hdXRoX3N1Ym1pdF9fYnV0dG9uJzogJ2F1dGhvcml6ZUNsaWNrJyxcbiAgICAgICAgJ2NsaWNrIC5hdXRoX2xvZ291dF9fYnV0dG9uJzogJ2xvZ291dENsaWNrJ1xuICAgIH0sXG5cbiAgICB0cGxzOiB7XG4gICAgICAgIG1haW46IEhhbmRsZWJhcnMudGVtcGxhdGVzLmF1dGhfdmlld1xuICAgIH0sXG5cbiAgICBzZWxlY3RvcnM6IHtcbiAgICAgICAgaW5uZXJFbDogJy5hdXRoX2lubmVyJyxcbiAgICAgICAgYXV0aEJ0bjogJy5hdXRoX3N1Ym1pdF9fYnV0dG9uJ1xuICAgIH0sXG5cbiAgICBpbml0aWFsaXplOiBmdW5jdGlvbihvcHRzKSB7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdHMgfHwge307XG4gICAgICAgIG9wdHMuZGF0YSA9IG9wdHMuZGF0YSB8fCB7fTtcbiAgICAgICAgdGhpcy5yb3V0ZXIgPSB0aGlzLm9wdGlvbnMucm91dGVyO1xuXG4gICAgICAgIHRoaXMuYXV0aHNDb2xsZWN0aW9uVmlldyA9IG5ldyBTd2FnZ2VyVWkuVmlld3MuQXV0aHNDb2xsZWN0aW9uVmlldyh7ZGF0YTogb3B0cy5kYXRhfSk7XG5cbiAgICAgICAgdGhpcy4kZWwuaHRtbCh0aGlzLnRwbHMubWFpbih7XG4gICAgICAgICAgICBpc0xvZ291dDogdGhpcy5hdXRoc0NvbGxlY3Rpb25WaWV3LmNvbGxlY3Rpb24uaXNBdXRob3JpemVkKCksXG4gICAgICAgICAgICBpc0F1dGhvcml6ZWQ6IHRoaXMuYXV0aHNDb2xsZWN0aW9uVmlldy5jb2xsZWN0aW9uLmlzUGFydGlhbGx5QXV0aG9yaXplZCgpXG4gICAgICAgIH0pKTtcbiAgICAgICAgdGhpcy4kaW5uZXJFbCA9IHRoaXMuJCh0aGlzLnNlbGVjdG9ycy5pbm5lckVsKTtcbiAgICAgICAgdGhpcy5pc0xvZ291dCA9IHRoaXMuYXV0aHNDb2xsZWN0aW9uVmlldy5jb2xsZWN0aW9uLmlzUGFydGlhbGx5QXV0aG9yaXplZCgpO1xuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy4kaW5uZXJFbC5odG1sKHRoaXMuYXV0aHNDb2xsZWN0aW9uVmlldy5yZW5kZXIoKS5lbCk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIGF1dGhvcml6ZUNsaWNrOiBmdW5jdGlvbiAoZSkge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICAgICAgaWYgKHRoaXMuYXV0aHNDb2xsZWN0aW9uVmlldy5jb2xsZWN0aW9uLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgdGhpcy5hdXRob3JpemUoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuYXV0aHNDb2xsZWN0aW9uVmlldy5oaWdobGlnaHRJbnZhbGlkKCk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgYXV0aG9yaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuYXV0aHNDb2xsZWN0aW9uVmlldy5jb2xsZWN0aW9uLmZvckVhY2goZnVuY3Rpb24gKGF1dGgpIHtcbiAgICAgICAgICAgIHZhciBrZXlBdXRoLCBiYXNpY0F1dGg7XG4gICAgICAgICAgICB2YXIgdHlwZSA9IGF1dGguZ2V0KCd0eXBlJyk7XG5cbiAgICAgICAgICAgIGlmICh0eXBlID09PSAnYXBpS2V5Jykge1xuICAgICAgICAgICAgICAgIGtleUF1dGggPSBuZXcgU3dhZ2dlckNsaWVudC5BcGlLZXlBdXRob3JpemF0aW9uKFxuICAgICAgICAgICAgICAgICAgICBhdXRoLmdldCgnbmFtZScpLFxuICAgICAgICAgICAgICAgICAgICBhdXRoLmdldCgndmFsdWUnKSxcbiAgICAgICAgICAgICAgICAgICAgYXV0aC5nZXQoJ2luJylcbiAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5yb3V0ZXIuYXBpLmNsaWVudEF1dGhvcml6YXRpb25zLmFkZChhdXRoLmdldCgndGl0bGUnKSwga2V5QXV0aCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdiYXNpYycpIHtcbiAgICAgICAgICAgICAgICBiYXNpY0F1dGggPSBuZXcgU3dhZ2dlckNsaWVudC5QYXNzd29yZEF1dGhvcml6YXRpb24oYXV0aC5nZXQoJ3VzZXJuYW1lJyksIGF1dGguZ2V0KCdwYXNzd29yZCcpKTtcbiAgICAgICAgICAgICAgICB0aGlzLnJvdXRlci5hcGkuY2xpZW50QXV0aG9yaXphdGlvbnMuYWRkKGF1dGguZ2V0KCd0aXRsZScpLCBiYXNpY0F1dGgpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnb2F1dGgyJykge1xuICAgICAgICAgICAgICAgIHRoaXMuaGFuZGxlT2F1dGgyTG9naW4oYXV0aCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sIHRoaXMpO1xuXG4gICAgICAgIHRoaXMucm91dGVyLmxvYWQoKTtcbiAgICB9LFxuXG4gICAgbG9nb3V0Q2xpY2s6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICB0aGlzLmF1dGhzQ29sbGVjdGlvblZpZXcuY29sbGVjdGlvbi5mb3JFYWNoKGZ1bmN0aW9uIChhdXRoKSB7XG4gICAgICAgICAgICB3aW5kb3cuc3dhZ2dlclVpLmFwaS5jbGllbnRBdXRob3JpemF0aW9ucy5yZW1vdmUoYXV0aC5nZXQoJ3RpdGxlJykpO1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLnJvdXRlci5sb2FkKCk7XG4gICAgfSxcblxuICAgIC8vIHRha2VuIGZyb20gbGliL3N3YWdnZXItb2F1dGguanNcbiAgICBoYW5kbGVPYXV0aDJMb2dpbjogZnVuY3Rpb24gKGF1dGgpIHtcbiAgICAgICAgdmFyIGhvc3QgPSB3aW5kb3cubG9jYXRpb247XG4gICAgICAgIHZhciBwYXRobmFtZSA9IGxvY2F0aW9uLnBhdGhuYW1lLnN1YnN0cmluZygwLCBsb2NhdGlvbi5wYXRobmFtZS5sYXN0SW5kZXhPZignLycpKTtcbiAgICAgICAgdmFyIGRlZmF1bHRSZWRpcmVjdFVybCA9IGhvc3QucHJvdG9jb2wgKyAnLy8nICsgaG9zdC5ob3N0ICsgcGF0aG5hbWUgKyAnL28yYy5odG1sJztcbiAgICAgICAgdmFyIHJlZGlyZWN0VXJsID0gd2luZG93Lm9BdXRoUmVkaXJlY3RVcmwgfHwgZGVmYXVsdFJlZGlyZWN0VXJsO1xuICAgICAgICB2YXIgdXJsID0gbnVsbDtcbiAgICAgICAgdmFyIHNjb3BlcyA9IF8ubWFwKGF1dGguZ2V0KCdzY29wZXMnKSwgZnVuY3Rpb24gKHNjb3BlKSB7XG4gICAgICAgICAgICBpZihzY29wZS5jaGVja2VkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNjb3BlLnNjb3BlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgdmFyIGNvbnRhaW5lciA9IHdpbmRvdy5zd2FnZ2VyVWlBdXRoIHx8ICh3aW5kb3cuc3dhZ2dlclVpQXV0aCA9IHt9KTtcbiAgICAgICAgdmFyIHN0YXRlLCBkZXRzLCBlcDtcbiAgICAgICAgY29udGFpbmVyLk9BdXRoU2NoZW1lS2V5ID0gYXV0aC5nZXQoJ3RpdGxlJyk7XG5cbiAgICAgICAgd2luZG93LmVuYWJsZWRTY29wZXMgPSBzY29wZXM7XG4gICAgICAgIHZhciBmbG93ID0gYXV0aC5nZXQoJ2Zsb3cnKTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgYWNjZXNzIHRva2VuIHBhcmFtZXRlciByZXR1cm5lZCBieSB0aGUgc2VydmVyLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0gZGV0c1xuICAgICAgICAgKiAgICAgVGhlIGF1dGhvcmlzYXRpb24gc2NoZW1lIGNvbmZpZ3VyYXRpb24uXG4gICAgICAgICAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhlIGFjY2VzcyB0b2tlbiBwYXJhbWV0ZXJcbiAgICAgICAgICovXG4gICAgICAgIGZ1bmN0aW9uIGdldFRva2VuTmFtZShkZXRzKSB7XG4gICAgICAgICAgICByZXR1cm4gZGV0cy52ZW5kb3JFeHRlbnNpb25zWyd4LXRva2VuTmFtZSddIHx8IGRldHMudG9rZW5OYW1lO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYoYXV0aC5nZXQoJ3R5cGUnKSA9PT0gJ29hdXRoMicgJiYgZmxvdyAmJiAoZmxvdyA9PT0gJ2ltcGxpY2l0JyB8fCBmbG93ID09PSAnYWNjZXNzQ29kZScpKSB7XG4gICAgICAgICAgICBkZXRzID0gYXV0aC5hdHRyaWJ1dGVzO1xuICAgICAgICAgICAgdXJsID0gZGV0cy5hdXRob3JpemF0aW9uVXJsICsgJz9yZXNwb25zZV90eXBlPScgKyAoZmxvdyA9PT0gJ2ltcGxpY2l0JyA/ICd0b2tlbicgOiAnY29kZScpO1xuICAgICAgICAgICAgY29udGFpbmVyLnRva2VuTmFtZSA9IGdldFRva2VuTmFtZShkZXRzKSB8fCAnYWNjZXNzX3Rva2VuJztcbiAgICAgICAgICAgIGNvbnRhaW5lci50b2tlblVybCA9IChmbG93ID09PSAnYWNjZXNzQ29kZScgPyBkZXRzLnRva2VuVXJsIDogbnVsbCk7XG4gICAgICAgICAgICBzdGF0ZSA9IGNvbnRhaW5lci5PQXV0aFNjaGVtZUtleTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmKGF1dGguZ2V0KCd0eXBlJykgPT09ICdvYXV0aDInICYmIGZsb3cgJiYgKGZsb3cgPT09ICdhcHBsaWNhdGlvbicpKSB7XG4gICAgICAgICAgICBkZXRzID0gYXV0aC5hdHRyaWJ1dGVzO1xuICAgICAgICAgICAgY29udGFpbmVyLnRva2VuTmFtZSA9IGdldFRva2VuTmFtZShkZXRzKSB8fCAnYWNjZXNzX3Rva2VuJztcbiAgICAgICAgICAgIHRoaXMuY2xpZW50Q3JlZGVudGlhbHNGbG93KHNjb3BlcywgZGV0cywgY29udGFpbmVyLk9BdXRoU2NoZW1lS2V5KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmKGF1dGguZ2V0KCd0eXBlJykgPT09ICdvYXV0aDInICYmIGZsb3cgJiYgKGZsb3cgPT09ICdwYXNzd29yZCcpKSB7XG4gICAgICAgICAgICBkZXRzID0gYXV0aC5hdHRyaWJ1dGVzO1xuICAgICAgICAgICAgY29udGFpbmVyLnRva2VuTmFtZSA9IGdldFRva2VuTmFtZShkZXRzKSB8fCAnYWNjZXNzX3Rva2VuJztcbiAgICAgICAgICAgIHRoaXMucGFzc3dvcmRGbG93KHNjb3BlcywgZGV0cywgY29udGFpbmVyLk9BdXRoU2NoZW1lS2V5KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmKGF1dGguZ2V0KCdncmFudFR5cGVzJykpIHtcbiAgICAgICAgICAgIC8vIDEuMiBzdXBwb3J0XG4gICAgICAgICAgICB2YXIgbyA9IGF1dGguZ2V0KCdncmFudFR5cGVzJyk7XG4gICAgICAgICAgICBmb3IodmFyIHQgaW4gbykge1xuICAgICAgICAgICAgICAgIGlmKG8uaGFzT3duUHJvcGVydHkodCkgJiYgdCA9PT0gJ2ltcGxpY2l0Jykge1xuICAgICAgICAgICAgICAgICAgICBkZXRzID0gb1t0XTtcbiAgICAgICAgICAgICAgICAgICAgZXAgPSBkZXRzLmxvZ2luRW5kcG9pbnQudXJsO1xuICAgICAgICAgICAgICAgICAgICB1cmwgPSBkZXRzLmxvZ2luRW5kcG9pbnQudXJsICsgJz9yZXNwb25zZV90eXBlPXRva2VuJztcbiAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyLnRva2VuTmFtZSA9IGdldFRva2VuTmFtZShkZXRzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoby5oYXNPd25Qcm9wZXJ0eSh0KSAmJiB0ID09PSAnYWNjZXNzQ29kZScpIHtcbiAgICAgICAgICAgICAgICAgICAgZGV0cyA9IG9bdF07XG4gICAgICAgICAgICAgICAgICAgIGVwID0gZGV0cy50b2tlblJlcXVlc3RFbmRwb2ludC51cmw7XG4gICAgICAgICAgICAgICAgICAgIHVybCA9IGRldHMudG9rZW5SZXF1ZXN0RW5kcG9pbnQudXJsICsgJz9yZXNwb25zZV90eXBlPWNvZGUnO1xuICAgICAgICAgICAgICAgICAgICBjb250YWluZXIudG9rZW5OYW1lID0gZ2V0VG9rZW5OYW1lKGRldHMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJlZGlyZWN0X3VyaSA9IHJlZGlyZWN0VXJsO1xuXG4gICAgICAgIHVybCArPSAnJnJlZGlyZWN0X3VyaT0nICsgZW5jb2RlVVJJQ29tcG9uZW50KHJlZGlyZWN0VXJsKTtcbiAgICAgICAgdXJsICs9ICcmcmVhbG09JyArIGVuY29kZVVSSUNvbXBvbmVudChyZWFsbSk7XG4gICAgICAgIHVybCArPSAnJmNsaWVudF9pZD0nICsgZW5jb2RlVVJJQ29tcG9uZW50KGNsaWVudElkKTtcbiAgICAgICAgdXJsICs9ICcmc2NvcGU9JyArIGVuY29kZVVSSUNvbXBvbmVudChzY29wZXMuam9pbihzY29wZVNlcGFyYXRvcikpO1xuICAgICAgICB1cmwgKz0gJyZzdGF0ZT0nICsgZW5jb2RlVVJJQ29tcG9uZW50KHN0YXRlKTtcbiAgICAgICAgZm9yICh2YXIga2V5IGluIGFkZGl0aW9uYWxRdWVyeVN0cmluZ1BhcmFtcykge1xuICAgICAgICAgICAgdXJsICs9ICcmJyArIGtleSArICc9JyArIGVuY29kZVVSSUNvbXBvbmVudChhZGRpdGlvbmFsUXVlcnlTdHJpbmdQYXJhbXNba2V5XSk7XG4gICAgICAgIH1cblxuICAgICAgICB3aW5kb3cub3Blbih1cmwpO1xuICAgIH0sXG5cbiAgICAvLyB0YWtlbiBmcm9tIGxpYi9zd2FnZ2VyLW9hdXRoLmpzXG4gICAgY2xpZW50Q3JlZGVudGlhbHNGbG93OiBmdW5jdGlvbiAoc2NvcGVzLCBvYXV0aCwgT0F1dGhTY2hlbWVLZXkpIHtcbiAgICAgICAgdGhpcy5hY2Nlc3NUb2tlblJlcXVlc3Qoc2NvcGVzLCBvYXV0aCwgT0F1dGhTY2hlbWVLZXksICdjbGllbnRfY3JlZGVudGlhbHMnKTtcbiAgICB9LFxuXG4gICAgcGFzc3dvcmRGbG93OiBmdW5jdGlvbiAoc2NvcGVzLCBvYXV0aCwgT0F1dGhTY2hlbWVLZXkpIHtcbiAgICAgICAgdGhpcy5hY2Nlc3NUb2tlblJlcXVlc3Qoc2NvcGVzLCBvYXV0aCwgT0F1dGhTY2hlbWVLZXksICdwYXNzd29yZCcsIHtcbiAgICAgICAgICAgICd1c2VybmFtZSc6IG9hdXRoLnVzZXJuYW1lLFxuICAgICAgICAgICAgJ3Bhc3N3b3JkJzogb2F1dGgucGFzc3dvcmRcbiAgICAgICAgfSk7XG4gICAgfSxcblxuICAgIGFjY2Vzc1Rva2VuUmVxdWVzdDogZnVuY3Rpb24gKHNjb3Blcywgb2F1dGgsIE9BdXRoU2NoZW1lS2V5LCBncmFudFR5cGUsIHBhcmFtcykge1xuICAgICAgICBwYXJhbXMgPSAkLmV4dGVuZCh7fSwge1xuICAgICAgICAgICAgJ3Njb3BlJzogc2NvcGVzLmpvaW4oJyAnKSxcbiAgICAgICAgICAgICdncmFudF90eXBlJzogZ3JhbnRUeXBlXG4gICAgICAgIH0sIHBhcmFtcyk7XG5cbiAgICAgICAgdmFyIGhlYWRlcnM9IHt9O1xuXG4gICAgICAgIHN3aXRjaCAob2F1dGguY2xpZW50QXV0aGVudGljYXRpb25UeXBlKSB7XG4gICAgICAgICAgICBjYXNlICdiYXNpYyc6XG4gICAgICAgICAgICAgICAgaGVhZGVycy5BdXRob3JpemF0aW9uID0gJ0Jhc2ljICcgKyBidG9hKG9hdXRoLmNsaWVudElkICsgJzonICsgb2F1dGguY2xpZW50U2VjcmV0KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ3JlcXVlc3QtYm9keSc6XG4gICAgICAgICAgICAgICAgcGFyYW1zLmNsaWVudF9pZCA9IG9hdXRoLmNsaWVudElkO1xuICAgICAgICAgICAgICAgIHBhcmFtcy5jbGllbnRfc2VjcmV0ID0gb2F1dGguY2xpZW50U2VjcmV0O1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgJC5hamF4KHtcbiAgICAgICAgICAgIHVybCA6IG9hdXRoLnRva2VuVXJsLFxuICAgICAgICAgICAgdHlwZTogJ1BPU1QnLFxuICAgICAgICAgICAgZGF0YTogcGFyYW1zLFxuICAgICAgICAgICAgaGVhZGVyczogaGVhZGVycyxcbiAgICAgICAgICAgIHN1Y2Nlc3M6IGZ1bmN0aW9uIChkYXRhKVxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIG9uT0F1dGhDb21wbGV0ZShkYXRhLCBPQXV0aFNjaGVtZUtleSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZXJyb3I6IGZ1bmN0aW9uICgpXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgb25PQXV0aENvbXBsZXRlKCcnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5Nb2RlbHMuQmFzaWNBdXRoTW9kZWwgPSBCYWNrYm9uZS5Nb2RlbC5leHRlbmQoe1xuICAgIGRlZmF1bHRzOiB7XG4gICAgICAgIHVzZXJuYW1lOiAnJyxcbiAgICAgICAgcGFzc3dvcmQ6ICcnLFxuICAgICAgICB0aXRsZTogJ2Jhc2ljJ1xuICAgIH0sXG5cbiAgICBpbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMub24oJ2NoYW5nZScsIHRoaXMudmFsaWRhdGUpO1xuICAgIH0sXG5cbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdmFsaWQgPSAhIXRoaXMuZ2V0KCdwYXNzd29yZCcpICYmICEhdGhpcy5nZXQoJ3VzZXJuYW1lJyk7XG5cbiAgICAgICAgdGhpcy5zZXQoJ3ZhbGlkJywgdmFsaWQpO1xuXG4gICAgICAgIHJldHVybiB2YWxpZDtcbiAgICB9XG59KTsiLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5WaWV3cy5CYXNpY0F1dGhWaWV3ID0gQmFja2JvbmUuVmlldy5leHRlbmQoe1xuXG4gICAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKG9wdHMpIHtcbiAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0cyB8fCB7fTtcbiAgICAgICAgdGhpcy5yb3V0ZXIgPSB0aGlzLm9wdGlvbnMucm91dGVyO1xuICAgIH0sXG5cbiAgICBldmVudHM6IHtcbiAgICAgICAgJ2NoYW5nZSAuYXV0aF9pbnB1dCc6ICdpbnB1dENoYW5nZSdcbiAgICB9LFxuXG4gICAgc2VsZWN0b3JzOiB7XG4gICAgICAgIHVzZXJuYW1lSW5wdXQ6ICcuYmFzaWNfYXV0aF9fdXNlcm5hbWUnLFxuICAgICAgICBwYXNzd29yZElucHV0OiAnLmJhc2ljX2F1dGhfX3Bhc3N3b3JkJ1xuICAgIH0sXG5cbiAgICBjbHM6IHtcbiAgICAgICAgZXJyb3I6ICdlcnJvcidcbiAgICB9LFxuXG4gICAgdGVtcGxhdGU6IEhhbmRsZWJhcnMudGVtcGxhdGVzLmJhc2ljX2F1dGgsXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uKCl7XG4gICAgICAgICQodGhpcy5lbCkuaHRtbCh0aGlzLnRlbXBsYXRlKHRoaXMubW9kZWwudG9KU09OKCkpKTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuXG4gICAgaW5wdXRDaGFuZ2U6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIHZhciAkZWwgPSAkKGUudGFyZ2V0KTtcbiAgICAgICAgdmFyIHZhbCA9ICRlbC52YWwoKTtcbiAgICAgICAgdmFyIGF0dHIgPSAkZWwucHJvcCgnbmFtZScpO1xuXG4gICAgICAgIGlmICh2YWwpIHtcbiAgICAgICAgICAgICRlbC5yZW1vdmVDbGFzcyh0aGlzLmNscy5lcnJvcik7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLm1vZGVsLnNldChhdHRyLCB2YWwpO1xuICAgIH0sXG5cbiAgICBpc1ZhbGlkOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1vZGVsLnZhbGlkYXRlKCk7XG4gICAgfSxcblxuICAgIGhpZ2hsaWdodEludmFsaWQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKCF0aGlzLm1vZGVsLmdldCgndXNlcm5hbWUnKSkge1xuICAgICAgICAgICAgdGhpcy4kKHRoaXMuc2VsZWN0b3JzLnVzZXJuYW1lSW5wdXQpLmFkZENsYXNzKHRoaXMuY2xzLmVycm9yKTtcbiAgICAgICAgfVxuICAgIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5Td2FnZ2VyVWkuVmlld3MuQ29udGVudFR5cGVWaWV3ID0gQmFja2JvbmUuVmlldy5leHRlbmQoe1xuICBpbml0aWFsaXplOiBmdW5jdGlvbigpIHt9LFxuXG4gIHJlbmRlcjogZnVuY3Rpb24oKXtcbiAgXHR0aGlzLm1vZGVsLmNvbnRlbnRUeXBlSWQgPSAnY3QnICsgTWF0aC5yYW5kb20oKTtcbiAgICAkKHRoaXMuZWwpLmh0bWwoSGFuZGxlYmFycy50ZW1wbGF0ZXMuY29udGVudF90eXBlKHRoaXMubW9kZWwpKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxufSk7IiwiJ3VzZSBzdHJpY3QnO1xuXG5Td2FnZ2VyVWkuVmlld3MuSGVhZGVyVmlldyA9IEJhY2tib25lLlZpZXcuZXh0ZW5kKHtcbiAgZXZlbnRzOiB7XG4gICAgJ2NsaWNrICNzaG93LXBldC1zdG9yZS1pY29uJyAgICA6ICdzaG93UGV0U3RvcmUnLFxuICAgICdjbGljayAjZXhwbG9yZScgICAgICAgICAgICAgICAgOiAnc2hvd0N1c3RvbScsXG4gICAgJ3N1Ym1pdCAjYXBpX3NlbGVjdG9yJyAgICAgICAgICA6ICdzaG93Q3VzdG9tJyxcbiAgICAna2V5dXAgI2lucHV0X2Jhc2VVcmwnICAgICAgICAgIDogJ3Nob3dDdXN0b21PbktleXVwJyxcbiAgICAna2V5dXAgI2lucHV0X2FwaUtleScgICAgICAgICAgIDogJ3Nob3dDdXN0b21PbktleXVwJ1xuICB9LFxuXG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uKCl7fSxcblxuICBzaG93UGV0U3RvcmU6IGZ1bmN0aW9uKCl7XG4gICAgdGhpcy50cmlnZ2VyKCd1cGRhdGUtc3dhZ2dlci11aScsIHtcbiAgICAgIHVybDonaHR0cDovL3BldHN0b3JlLnN3YWdnZXIuaW8vdjIvc3dhZ2dlci5qc29uJ1xuICAgIH0pO1xuICB9LFxuXG4gIHNob3dDdXN0b21PbktleXVwOiBmdW5jdGlvbihlKXtcbiAgICBpZiAoZS5rZXlDb2RlID09PSAxMykge1xuICAgICAgdGhpcy5zaG93Q3VzdG9tKCk7XG4gICAgfVxuICB9LFxuXG4gIHNob3dDdXN0b206IGZ1bmN0aW9uKGUpe1xuICAgIGlmIChlKSB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuXG4gICAgdGhpcy50cmlnZ2VyKCd1cGRhdGUtc3dhZ2dlci11aScsIHtcbiAgICAgIHVybDogJCgnI2lucHV0X2Jhc2VVcmwnKS52YWwoKVxuICAgIH0pO1xuICB9LFxuXG4gIHVwZGF0ZTogZnVuY3Rpb24odXJsLCBhcGlLZXksIHRyaWdnZXIpe1xuICAgIGlmICh0cmlnZ2VyID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRyaWdnZXIgPSBmYWxzZTtcbiAgICB9XG5cbiAgICAkKCcjaW5wdXRfYmFzZVVybCcpLnZhbCh1cmwpO1xuXG4gICAgaWYgKHRyaWdnZXIpIHtcbiAgICAgIHRoaXMudHJpZ2dlcigndXBkYXRlLXN3YWdnZXItdWknLCB7dXJsOnVybH0pO1xuICAgIH1cbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5WaWV3cy5NYWluVmlldyA9IEJhY2tib25lLlZpZXcuZXh0ZW5kKHtcbiAgYXBpc1NvcnRlciA6IHtcbiAgICBhbHBoYSAgIDogZnVuY3Rpb24oYSxiKXsgcmV0dXJuIGEubmFtZS5sb2NhbGVDb21wYXJlKGIubmFtZSk7IH1cbiAgfSxcbiAgb3BlcmF0aW9uc1NvcnRlcnMgOiB7XG4gICAgYWxwaGEgICA6IGZ1bmN0aW9uKGEsYil7IHJldHVybiBhLnBhdGgubG9jYWxlQ29tcGFyZShiLnBhdGgpOyB9LFxuICAgIG1ldGhvZCAgOiBmdW5jdGlvbihhLGIpeyByZXR1cm4gYS5tZXRob2QubG9jYWxlQ29tcGFyZShiLm1ldGhvZCk7IH1cbiAgfSxcbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24ob3B0cyl7XG4gICAgdmFyIHNvcnRlck9wdGlvbiwgc29ydGVyRm4sIGtleSwgdmFsdWU7XG4gICAgb3B0cyA9IG9wdHMgfHwge307XG5cbiAgICB0aGlzLnJvdXRlciA9IG9wdHMucm91dGVyO1xuXG4gICAgLy8gU29ydCBBUElzXG4gICAgaWYgKG9wdHMuc3dhZ2dlck9wdGlvbnMuYXBpc1NvcnRlcikge1xuICAgICAgc29ydGVyT3B0aW9uID0gb3B0cy5zd2FnZ2VyT3B0aW9ucy5hcGlzU29ydGVyO1xuICAgICAgaWYgKF8uaXNGdW5jdGlvbihzb3J0ZXJPcHRpb24pKSB7XG4gICAgICAgIHNvcnRlckZuID0gc29ydGVyT3B0aW9uO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc29ydGVyRm4gPSB0aGlzLmFwaXNTb3J0ZXJbc29ydGVyT3B0aW9uXTtcbiAgICAgIH1cbiAgICAgIGlmIChfLmlzRnVuY3Rpb24oc29ydGVyRm4pKSB7XG4gICAgICAgIHRoaXMubW9kZWwuYXBpc0FycmF5LnNvcnQoc29ydGVyRm4pO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBTb3J0IG9wZXJhdGlvbnMgb2YgZWFjaCBBUElcbiAgICBpZiAob3B0cy5zd2FnZ2VyT3B0aW9ucy5vcGVyYXRpb25zU29ydGVyKSB7XG4gICAgICBzb3J0ZXJPcHRpb24gPSBvcHRzLnN3YWdnZXJPcHRpb25zLm9wZXJhdGlvbnNTb3J0ZXI7XG4gICAgICBpZiAoXy5pc0Z1bmN0aW9uKHNvcnRlck9wdGlvbikpIHtcbiAgICAgICAgc29ydGVyRm4gPSBzb3J0ZXJPcHRpb247XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzb3J0ZXJGbiA9IHRoaXMub3BlcmF0aW9uc1NvcnRlcnNbc29ydGVyT3B0aW9uXTtcbiAgICAgIH1cbiAgICAgIGlmIChfLmlzRnVuY3Rpb24oc29ydGVyRm4pKSB7XG4gICAgICAgIGZvciAoa2V5IGluIHRoaXMubW9kZWwuYXBpc0FycmF5KSB7XG4gICAgICAgICAgdGhpcy5tb2RlbC5hcGlzQXJyYXlba2V5XS5vcGVyYXRpb25zQXJyYXkuc29ydChzb3J0ZXJGbik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBzZXQgdXAgdGhlIFVJIGZvciBpbnB1dFxuICAgIHRoaXMubW9kZWwuYXV0aHMgPSBbXTtcblxuICAgIGZvciAoa2V5IGluIHRoaXMubW9kZWwuc2VjdXJpdHlEZWZpbml0aW9ucykge1xuICAgICAgdmFsdWUgPSB0aGlzLm1vZGVsLnNlY3VyaXR5RGVmaW5pdGlvbnNba2V5XTtcblxuICAgICAgdGhpcy5tb2RlbC5hdXRocy5wdXNoKHtcbiAgICAgICAgbmFtZToga2V5LFxuICAgICAgICB0eXBlOiB2YWx1ZS50eXBlLFxuICAgICAgICB2YWx1ZTogdmFsdWVcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICgndmFsaWRhdG9yVXJsJyBpbiBvcHRzLnN3YWdnZXJPcHRpb25zKSB7XG4gICAgICAvLyBWYWxpZGF0b3IgVVJMIHNwZWNpZmllZCBleHBsaWNpdGx5XG4gICAgICB0aGlzLm1vZGVsLnZhbGlkYXRvclVybCA9IG9wdHMuc3dhZ2dlck9wdGlvbnMudmFsaWRhdG9yVXJsO1xuICAgIH0gZWxzZSBpZiAodGhpcy5tb2RlbC51cmwuaW5kZXhPZignbG9jYWxob3N0JykgPiAwIHx8IHRoaXMubW9kZWwudXJsLmluZGV4T2YoJzEyNy4wLjAuMScpID4gMCkge1xuICAgICAgLy8gTG9jYWxob3N0IG92ZXJyaWRlXG4gICAgICB0aGlzLm1vZGVsLnZhbGlkYXRvclVybCA9IG51bGw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubW9kZWwudmFsaWRhdG9yVXJsID0gJy8vb25saW5lLnN3YWdnZXIuaW8vdmFsaWRhdG9yJztcbiAgICB9XG5cbiAgICAvLyBKU29uRWRpdG9yIHJlcXVpcmVzIHR5cGU9J29iamVjdCcgdG8gYmUgcHJlc2VudCBvbiBkZWZpbmVkIHR5cGVzLCB3ZSBhZGQgaXQgaWYgaXQncyBtaXNzaW5nXG4gICAgLy8gaXMgdGhlcmUgYW55IHZhbGlkIGNhc2Ugd2VyZSBpdCBzaG91bGQgbm90IGJlIGFkZGVkID9cbiAgICB2YXIgZGVmO1xuICAgIGZvcihkZWYgaW4gdGhpcy5tb2RlbC5kZWZpbml0aW9ucyl7XG4gICAgICBpZiAoIXRoaXMubW9kZWwuZGVmaW5pdGlvbnNbZGVmXS50eXBlKXtcbiAgICAgICAgdGhpcy5tb2RlbC5kZWZpbml0aW9uc1tkZWZdLnR5cGUgPSAnb2JqZWN0JztcbiAgICAgIH1cbiAgICB9XG5cbiAgfSxcblxuICByZW5kZXI6IGZ1bmN0aW9uICgpIHtcbiAgICAkKHRoaXMuZWwpLmh0bWwoSGFuZGxlYmFycy50ZW1wbGF0ZXMubWFpbih0aGlzLm1vZGVsKSk7XG4gICAgdGhpcy5pbmZvID0gdGhpcy4kKCcuaW5mbycpWzBdO1xuXG4gICAgaWYgKHRoaXMuaW5mbykge1xuICAgICAgdGhpcy5pbmZvLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5vbkxpbmtDbGljaywgdHJ1ZSk7XG4gICAgfVxuXG4gICAgdGhpcy5tb2RlbC5zZWN1cml0eURlZmluaXRpb25zID0gdGhpcy5tb2RlbC5zZWN1cml0eURlZmluaXRpb25zIHx8IHt9O1xuXG4gICAgLy8gUmVuZGVyIGVhY2ggcmVzb3VyY2VcblxuICAgIHZhciByZXNvdXJjZXMgPSB7fTtcbiAgICB2YXIgY291bnRlciA9IDA7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLm1vZGVsLmFwaXNBcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHJlc291cmNlID0gdGhpcy5tb2RlbC5hcGlzQXJyYXlbaV07XG4gICAgICB2YXIgaWQgPSByZXNvdXJjZS5uYW1lO1xuICAgICAgd2hpbGUgKHR5cGVvZiByZXNvdXJjZXNbaWRdICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBpZCA9IGlkICsgJ18nICsgY291bnRlcjtcbiAgICAgICAgY291bnRlciArPSAxO1xuICAgICAgfVxuICAgICAgcmVzb3VyY2UuaWQgPSBzYW5pdGl6ZUh0bWwoaWQpO1xuICAgICAgcmVzb3VyY2VzW2lkXSA9IHJlc291cmNlO1xuICAgICAgdGhpcy5hZGRSZXNvdXJjZShyZXNvdXJjZSwgdGhpcy5tb2RlbC5hdXRocyk7XG4gICAgfVxuXG4gICAgJCgnLnByb3BXcmFwJykuaG92ZXIoZnVuY3Rpb24gb25Ib3Zlcigpe1xuICAgICAgJCgnLm9wdGlvbnNXcmFwcGVyJywgJCh0aGlzKSkuc2hvdygpO1xuICAgIH0sIGZ1bmN0aW9uIG9mZmhvdmVyKCl7XG4gICAgICAkKCcub3B0aW9uc1dyYXBwZXInLCAkKHRoaXMpKS5oaWRlKCk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG5cbiAgYWRkUmVzb3VyY2U6IGZ1bmN0aW9uKHJlc291cmNlLCBhdXRocyl7XG4gICAgLy8gUmVuZGVyIGEgcmVzb3VyY2UgYW5kIGFkZCBpdCB0byByZXNvdXJjZXMgbGlcbiAgICByZXNvdXJjZS5pZCA9IHJlc291cmNlLmlkLnJlcGxhY2UoL1teYS16QS1aXFxkXS9nLCBmdW5jdGlvbihzdHIpIHsgcmV0dXJuIHN0ci5jaGFyQ29kZUF0KDApOyB9KTtcblxuICAgIC8vIE1ha2UgYWxsIGRlZmluaXRpb25zIGF2YWlsYWJsZSBhdCB0aGUgcm9vdCBvZiB0aGUgcmVzb3VyY2Ugc28gdGhhdCB0aGV5IGNhblxuICAgIC8vIGJlIGxvYWRlZCBieSB0aGUgSlNvbkVkaXRvclxuICAgIHJlc291cmNlLmRlZmluaXRpb25zID0gdGhpcy5tb2RlbC5kZWZpbml0aW9ucztcblxuICAgIHZhciByZXNvdXJjZVZpZXcgPSBuZXcgU3dhZ2dlclVpLlZpZXdzLlJlc291cmNlVmlldyh7XG4gICAgICBtb2RlbDogcmVzb3VyY2UsXG4gICAgICByb3V0ZXI6IHRoaXMucm91dGVyLFxuICAgICAgdGFnTmFtZTogJ2xpJyxcbiAgICAgIGlkOiAncmVzb3VyY2VfJyArIHJlc291cmNlLmlkLFxuICAgICAgY2xhc3NOYW1lOiAncmVzb3VyY2UnLFxuICAgICAgYXV0aHM6IGF1dGhzLFxuICAgICAgc3dhZ2dlck9wdGlvbnM6IHRoaXMub3B0aW9ucy5zd2FnZ2VyT3B0aW9uc1xuICAgIH0pO1xuICAgICQoJyNyZXNvdXJjZXMnLCB0aGlzLmVsKS5hcHBlbmQocmVzb3VyY2VWaWV3LnJlbmRlcigpLmVsKTtcbiAgfSxcblxuICBjbGVhcjogZnVuY3Rpb24oKXtcbiAgICAkKHRoaXMuZWwpLmh0bWwoJycpO1xuICB9LFxuXG4gIG9uTGlua0NsaWNrOiBmdW5jdGlvbiAoZSkge1xuICAgIHZhciBlbCA9IGUudGFyZ2V0O1xuXG4gICAgaWYgKGVsLnRhZ05hbWUgPT09ICdBJyAmJiBlbC5ocmVmICYmICFlbC50YXJnZXQpIHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB3aW5kb3cub3BlbihlbC5ocmVmLCAnX2JsYW5rJyk7XG4gICAgfVxuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcblxuU3dhZ2dlclVpLk1vZGVscy5PYXV0aDJNb2RlbCA9IEJhY2tib25lLk1vZGVsLmV4dGVuZCh7XG4gICAgZGVmYXVsdHM6IHtcbiAgICAgICAgc2NvcGVzOiB7fSxcbiAgICAgICAgaXNQYXNzd29yZEZsb3c6IGZhbHNlLFxuICAgICAgICBjbGllbnRBdXRoZW50aWNhdGlvblR5cGU6ICdub25lJ1xuICAgIH0sXG5cbiAgICBpbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmKHRoaXMuYXR0cmlidXRlcyAmJiB0aGlzLmF0dHJpYnV0ZXMuc2NvcGVzKSB7XG4gICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9IF8uY2xvbmVEZWVwKHRoaXMuYXR0cmlidXRlcyk7XG4gICAgICAgICAgICB2YXIgaSwgc2NvcGVzID0gW107XG4gICAgICAgICAgICBmb3IoaSBpbiBhdHRyaWJ1dGVzLnNjb3Blcykge1xuICAgICAgICAgICAgICAgIHZhciBzY29wZSA9IGF0dHJpYnV0ZXMuc2NvcGVzW2ldO1xuICAgICAgICAgICAgICAgIGlmKHR5cGVvZiBzY29wZS5kZXNjcmlwdGlvbiA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgc2NvcGVzW3Njb3BlXSA9IGF0dHJpYnV0ZXMuc2NvcGVzW2ldO1xuICAgICAgICAgICAgICAgICAgICBzY29wZXMucHVzaChhdHRyaWJ1dGVzLnNjb3Blc1tpXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXR0cmlidXRlcy5zY29wZXMgPSBzY29wZXM7XG4gICAgICAgICAgICB0aGlzLmF0dHJpYnV0ZXMgPSBhdHRyaWJ1dGVzO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuYXR0cmlidXRlcyAmJiB0aGlzLmF0dHJpYnV0ZXMuZmxvdykge1xuICAgICAgICAgICAgdmFyIGZsb3cgPSB0aGlzLmF0dHJpYnV0ZXMuZmxvdztcbiAgICAgICAgICAgIHRoaXMuc2V0KCdpc1Bhc3N3b3JkRmxvdycsIGZsb3cgPT09ICdwYXNzd29yZCcpO1xuICAgICAgICAgICAgdGhpcy5zZXQoJ3JlcXVpcmVDbGllbnRBdXRoZW50aWNhdGlvbicsIGZsb3cgPT09ICdhcHBsaWNhdGlvbicpO1xuICAgICAgICAgICAgdGhpcy5zZXQoJ2NsaWVudEF1dGhlbnRpY2F0aW9uJywgZmxvdyA9PT0gJ3Bhc3N3b3JkJyB8fCBmbG93ID09PSAnYXBwbGljYXRpb24nKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm9uKCdjaGFuZ2UnLCB0aGlzLnZhbGlkYXRlKTtcbiAgICB9LFxuXG4gICAgc2V0U2NvcGVzOiBmdW5jdGlvbiAobmFtZSwgdmFsKSB7XG4gICAgICAgIHZhciBhdXRoID0gXy5leHRlbmQoe30sIHRoaXMuYXR0cmlidXRlcyk7XG4gICAgICAgIHZhciBpbmRleCA9IF8uZmluZEluZGV4KGF1dGguc2NvcGVzLCBmdW5jdGlvbihvKSB7XG4gICAgICAgICAgICByZXR1cm4gby5zY29wZSA9PT0gbmFtZTtcbiAgICAgICAgfSk7XG4gICAgICAgIGF1dGguc2NvcGVzW2luZGV4XS5jaGVja2VkID0gdmFsO1xuXG4gICAgICAgIHRoaXMuc2V0KGF1dGgpO1xuICAgICAgICB0aGlzLnZhbGlkYXRlKCk7XG4gICAgfSxcblxuICAgIHZhbGlkYXRlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgdmFsaWQgPSBmYWxzZTtcbiAgICAgIGlmICh0aGlzLmdldCgnaXNQYXNzd29yZEZsb3cnKSAmJlxuICAgICAgICAgICghdGhpcy5nZXQoJ3VzZXJuYW1lJykpKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5nZXQoJ2NsaWVudEF1dGhlbnRpY2F0aW9uVHlwZScpIGluIFsnYmFzaWMnLCAncmVxdWVzdC1ib2R5J10gJiZcbiAgICAgICAgICAoIXRoaXMuZ2V0KCdjbGllbnRJZCcpKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgdmFyIHNjcCA9IHRoaXMuZ2V0KCdzY29wZXMnKTtcbiAgICAgIHZhciBpZHggPSAgXy5maW5kSW5kZXgoc2NwLCBmdW5jdGlvbiAobykge1xuICAgICAgICAgcmV0dXJuIG8uY2hlY2tlZCA9PT0gdHJ1ZTtcbiAgICAgIH0pO1xuXG4gICAgICBpZihzY3AubGVuZ3RoID4gMCAmJiBpZHggPj0gMCkge1xuICAgICAgICAgIHZhbGlkID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYoc2NwLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHZhbGlkID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5zZXQoJ3ZhbGlkJywgdmFsaWQpO1xuXG4gICAgICByZXR1cm4gdmFsaWQ7XG4gICAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5WaWV3cy5PYXV0aDJWaWV3ID0gQmFja2JvbmUuVmlldy5leHRlbmQoe1xuICAgIGV2ZW50czoge1xuICAgICAgICAnY2hhbmdlIC5vYXV0aC1zY29wZSc6ICdzY29wZUNoYW5nZScsXG4gICAgICAgICdjaGFuZ2UgLm9hdXRoLXVzZXJuYW1lJzogJ3NldFVzZXJuYW1lJyxcbiAgICAgICAgJ2NoYW5nZSAub2F1dGgtcGFzc3dvcmQnOiAnc2V0UGFzc3dvcmQnLFxuICAgICAgICAnY2hhbmdlIC5vYXV0aC1jbGllbnQtYXV0aGVudGljYXRpb24tdHlwZSc6ICdzZXRDbGllbnRBdXRoZW50aWNhdGlvblR5cGUnLFxuICAgICAgICAnY2hhbmdlIC5vYXV0aC1jbGllbnQtaWQnOiAnc2V0Q2xpZW50SWQnLFxuICAgICAgICAnY2hhbmdlIC5vYXV0aC1jbGllbnQtc2VjcmV0JzogJ3NldENsaWVudFNlY3JldCdcbiAgICB9LFxuXG4gICAgdGVtcGxhdGU6IEhhbmRsZWJhcnMudGVtcGxhdGVzLm9hdXRoMixcblxuICAgIGNsczoge1xuICAgICAgICBlcnJvcjogJ2Vycm9yJ1xuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy4kZWwuaHRtbCh0aGlzLnRlbXBsYXRlKHRoaXMubW9kZWwudG9KU09OKCkpKTtcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuXG4gICAgc2NvcGVDaGFuZ2U6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIHZhciB2YWwgPSAkKGUudGFyZ2V0KS5wcm9wKCdjaGVja2VkJyk7XG4gICAgICAgIHZhciBzY29wZSA9ICQoZS50YXJnZXQpLmRhdGEoJ3Njb3BlJyk7XG5cbiAgICAgICAgdGhpcy5tb2RlbC5zZXRTY29wZXMoc2NvcGUsIHZhbCk7XG4gICAgfSxcblxuICAgIHNldFVzZXJuYW1lOiBmdW5jdGlvbiAoZSkge1xuICAgICAgICB2YXIgdmFsPSAkKGUudGFyZ2V0KS52YWwoKTtcbiAgICAgICAgdGhpcy5tb2RlbC5zZXQoJ3VzZXJuYW1lJywgdmFsKTtcbiAgICAgICAgaWYgKHZhbCkge1xuICAgICAgICAgICAgJChlLnRhcmdldCkucmVtb3ZlQ2xhc3ModGhpcy5jbHMuZXJyb3IpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIHNldFBhc3N3b3JkOiBmdW5jdGlvbiAoZSkge1xuICAgICAgICB0aGlzLm1vZGVsLnNldCgncGFzc3dvcmQnLCAkKGUudGFyZ2V0KS52YWwoKSk7XG4gICAgfSxcblxuICAgIHNldENsaWVudEF1dGhlbnRpY2F0aW9uVHlwZTogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgdmFyIHR5cGUgPSAkKGUudGFyZ2V0KS52YWwoKTtcbiAgICAgICAgdmFyICRlbCA9IHRoaXMuJGVsO1xuICAgICAgICB0aGlzLm1vZGVsLnNldCgnY2xpZW50QXV0aGVudGljYXRpb25UeXBlJywgdHlwZSk7XG5cbiAgICAgICAgc3dpdGNoKHR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgJ25vbmUnOlxuICAgICAgICAgICAgICAgICRlbC5maW5kKCcub2F1dGgtY2xpZW50LWF1dGhlbnRpY2F0aW9uJykuaGlkZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnYmFzaWMnOlxuICAgICAgICAgICAgY2FzZSAncmVxdWVzdC1ib2R5JzpcbiAgICAgICAgICAgICAgICAkZWwuZmluZCgnLm9hdXRoLWNsaWVudC1pZCcpLnJlbW92ZUNsYXNzKHRoaXMuY2xzLmVycm9yKTtcbiAgICAgICAgICAgICAgICAkZWwuZmluZCgnLm9hdXRoLWNsaWVudC1hdXRoZW50aWNhdGlvbicpLnNob3coKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBzZXRDbGllbnRJZDogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgdmFyIHZhbCA9ICQoZS50YXJnZXQpLnZhbCgpO1xuICAgICAgICB0aGlzLm1vZGVsLnNldCgnY2xpZW50SWQnLCB2YWwpO1xuICAgICAgICBpZiAodmFsKSB7XG4gICAgICAgICAgICAkKGUudGFyZ2V0KS5yZW1vdmVDbGFzcyh0aGlzLmNscy5lcnJvcik7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgc2V0Q2xpZW50U2VjcmV0OiBmdW5jdGlvbiAoZSkge1xuICAgICAgICB0aGlzLm1vZGVsLnNldCgnY2xpZW50U2VjcmV0JywgJChlLnRhcmdldCkudmFsKCkpO1xuICAgICAgICAkKGUudGFyZ2V0KS5yZW1vdmVDbGFzcygnZXJyb3InKTtcbiAgICB9LFxuXG4gICAgaGlnaGxpZ2h0SW52YWxpZDogZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoIXRoaXMubW9kZWwuZ2V0KCd1c2VybmFtZScpKSB7XG4gICAgICAgICAgICB0aGlzLiRlbC5maW5kKCcub2F1dGgtdXNlcm5hbWUnKS5hZGRDbGFzcyh0aGlzLmNscy5lcnJvcik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMubW9kZWwuZ2V0KCdjbGllbnRJZCcpKSB7XG4gICAgICAgICAgICB0aGlzLiRlbC5maW5kKCcub2F1dGgtY2xpZW50LWlkJykuYWRkQ2xhc3ModGhpcy5jbHMuZXJyb3IpO1xuICAgICAgICB9XG4gICAgfVxufSk7IiwiJ3VzZSBzdHJpY3QnO1xuXG5Td2FnZ2VyVWkuVmlld3MuT3BlcmF0aW9uVmlldyA9IEJhY2tib25lLlZpZXcuZXh0ZW5kKHtcbiAgaW52b2NhdGlvblVybDogbnVsbCxcblxuICBldmVudHM6IHtcbiAgICAnc3VibWl0IC5zYW5kYm94JyAgICAgICAgIDogJ3N1Ym1pdE9wZXJhdGlvbicsXG4gICAgJ2NsaWNrIC5zdWJtaXQnICAgICAgICAgICA6ICdzdWJtaXRPcGVyYXRpb24nLFxuICAgICdjbGljayAucmVzcG9uc2VfaGlkZXInICAgOiAnaGlkZVJlc3BvbnNlJyxcbiAgICAnY2xpY2sgLnRvZ2dsZU9wZXJhdGlvbicgIDogJ3RvZ2dsZU9wZXJhdGlvbkNvbnRlbnQnLFxuICAgICdtb3VzZWVudGVyIC5hcGktaWMnICAgICAgOiAnbW91c2VFbnRlcicsXG4gICAgJ2RibGNsaWNrIC5jdXJsJyAgICAgICAgICA6ICdzZWxlY3RUZXh0JyxcbiAgICAnY2hhbmdlIFtuYW1lPXJlc3BvbnNlQ29udGVudFR5cGVdJyA6ICdzaG93U25pcHBldCdcbiAgfSxcblxuICBpbml0aWFsaXplOiBmdW5jdGlvbihvcHRzKSB7XG4gICAgb3B0cyA9IG9wdHMgfHwge307XG4gICAgdGhpcy5yb3V0ZXIgPSBvcHRzLnJvdXRlcjtcbiAgICB0aGlzLmF1dGhzID0gb3B0cy5hdXRocztcbiAgICB0aGlzLnBhcmVudElkID0gdGhpcy5tb2RlbC5wYXJlbnRJZDtcbiAgICB0aGlzLm5pY2tuYW1lID0gdGhpcy5tb2RlbC5uaWNrbmFtZTtcbiAgICB0aGlzLm1vZGVsLmVuY29kZWRQYXJlbnRJZCA9IGVuY29kZVVSSUNvbXBvbmVudCh0aGlzLnBhcmVudElkKTtcblxuICAgIGlmIChvcHRzLnN3YWdnZXJPcHRpb25zKSB7XG4gICAgICB0aGlzLm1vZGVsLmRlZmF1bHRSZW5kZXJpbmcgPSBvcHRzLnN3YWdnZXJPcHRpb25zLmRlZmF1bHRNb2RlbFJlbmRlcmluZztcblxuICAgICAgaWYgKG9wdHMuc3dhZ2dlck9wdGlvbnMuc2hvd1JlcXVlc3RIZWFkZXJzKSB7XG4gICAgICAgIHRoaXMubW9kZWwuc2hvd1JlcXVlc3RIZWFkZXJzID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKG9wdHMuc3dhZ2dlck9wdGlvbnMuc2hvd09wZXJhdGlvbklkcykge1xuICAgICAgICB0aGlzLm1vZGVsLnNob3dPcGVyYXRpb25JZHMgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfSxcblxuICBzZWxlY3RUZXh0OiBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBkb2MgPSBkb2N1bWVudCxcbiAgICAgICAgdGV4dCA9IGV2ZW50LnRhcmdldC5maXJzdENoaWxkLFxuICAgICAgICByYW5nZSxcbiAgICAgICAgc2VsZWN0aW9uO1xuICAgIGlmIChkb2MuYm9keS5jcmVhdGVUZXh0UmFuZ2UpIHtcbiAgICAgIHJhbmdlID0gZG9jdW1lbnQuYm9keS5jcmVhdGVUZXh0UmFuZ2UoKTtcbiAgICAgIHJhbmdlLm1vdmVUb0VsZW1lbnRUZXh0KHRleHQpO1xuICAgICAgcmFuZ2Uuc2VsZWN0KCk7XG4gICAgfSBlbHNlIGlmICh3aW5kb3cuZ2V0U2VsZWN0aW9uKSB7XG4gICAgICBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgICByYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7XG4gICAgICByYW5nZS5zZWxlY3ROb2RlQ29udGVudHModGV4dCk7XG4gICAgICBzZWxlY3Rpb24ucmVtb3ZlQWxsUmFuZ2VzKCk7XG4gICAgICBzZWxlY3Rpb24uYWRkUmFuZ2UocmFuZ2UpO1xuICAgIH1cbiAgfSxcblxuICBtb3VzZUVudGVyOiBmdW5jdGlvbihlKSB7XG4gICAgdmFyIGVsZW0gPSAkKHRoaXMuZWwpLmZpbmQoJy5jb250ZW50Jyk7XG4gICAgdmFyIHggPSBlLnBhZ2VYO1xuICAgIHZhciB5ID0gZS5wYWdlWTtcbiAgICB2YXIgc2NYID0gJCh3aW5kb3cpLnNjcm9sbExlZnQoKTtcbiAgICB2YXIgc2NZID0gJCh3aW5kb3cpLnNjcm9sbFRvcCgpO1xuICAgIHZhciBzY01heFggPSBzY1ggKyAkKHdpbmRvdykud2lkdGgoKTtcbiAgICB2YXIgc2NNYXhZID0gc2NZICsgJCh3aW5kb3cpLmhlaWdodCgpO1xuICAgIHZhciB3ZCA9IGVsZW0ud2lkdGgoKTtcbiAgICB2YXIgaGdoID0gZWxlbS5oZWlnaHQoKTtcblxuICAgIGlmICh4ICsgd2QgPiBzY01heFgpIHtcbiAgICAgIHggPSBzY01heFggLSB3ZDtcbiAgICB9XG5cbiAgICBpZiAoeCA8IHNjWCkge1xuICAgICAgeCA9IHNjWDtcbiAgICB9XG5cbiAgICBpZiAoeSArIGhnaCA+IHNjTWF4WSkge1xuICAgICAgeSA9IHNjTWF4WSAtIGhnaDtcbiAgICB9XG5cbiAgICBpZiAoeSA8IHNjWSkge1xuICAgICAgeSA9IHNjWTtcbiAgICB9XG5cbiAgICB2YXIgcG9zID0ge307XG4gICAgcG9zLnRvcCA9IHk7XG4gICAgcG9zLmxlZnQgPSB4O1xuICAgIGVsZW0uY3NzKHBvcyk7XG4gIH0sXG5cbiAgLy8gTm90ZTogY29waWVkIGZyb20gQ29mZmVlU2NyaXB0IGNvbXBpbGVkIGZpbGVcbiAgLy8gVE9ETzogcmVmYWN0b3JcbiAgcmVuZGVyOiBmdW5jdGlvbigpIHtcbiAgICB2YXIgYSwgYXV0aCwgYXV0aHMsIGNvZGUsIGNvbnRlbnRUeXBlTW9kZWwsIGlzTWV0aG9kU3VibWlzc2lvblN1cHBvcnRlZCwgaywga2V5LCBsLCBsZW4sIGxlbjEsIGxlbjIsIGxlbjMsIGxlbjQsIG0sIG1vZGVsQXV0aHMsIG4sIG8sIHAsIHBhcmFtLCBxLCByZWYsIHJlZjEsIHJlZjIsIHJlZjMsIHJlZjQsIHJlZjUsIHJlc3BvbnNlQ29udGVudFR5cGVWaWV3LCByZXNwb25zZVNpZ25hdHVyZVZpZXcsIHNjaGVtYSwgc2NoZW1hT2JqLCBzY29wZUluZGV4LCBzaWduYXR1cmVNb2RlbCwgc3RhdHVzQ29kZSwgc3VjY2Vzc1Jlc3BvbnNlLCB0eXBlLCB2LCB2YWx1ZSwgcHJvZHVjZXMsIGlzWE1MLCBpc0pTT047XG4gICAgaXNNZXRob2RTdWJtaXNzaW9uU3VwcG9ydGVkID0galF1ZXJ5LmluQXJyYXkodGhpcy5tb2RlbC5tZXRob2QsIHRoaXMubW9kZWwuc3VwcG9ydGVkU3VibWl0TWV0aG9kcygpKSA+PSAwO1xuICAgIGlmICghaXNNZXRob2RTdWJtaXNzaW9uU3VwcG9ydGVkKSB7XG4gICAgICB0aGlzLm1vZGVsLmlzUmVhZE9ubHkgPSB0cnVlO1xuICAgIH1cbiAgICB0aGlzLm1vZGVsLmRlc2NyaXB0aW9uID0gdGhpcy5tb2RlbC5kZXNjcmlwdGlvbiB8fCB0aGlzLm1vZGVsLm5vdGVzO1xuICAgIHRoaXMubW9kZWwub2F1dGggPSBudWxsO1xuICAgIG1vZGVsQXV0aHMgPSB0aGlzLm1vZGVsLmF1dGhvcml6YXRpb25zIHx8IHRoaXMubW9kZWwuc2VjdXJpdHk7XG4gICAgaWYgKG1vZGVsQXV0aHMpIHtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KG1vZGVsQXV0aHMpKSB7XG4gICAgICAgIGZvciAobCA9IDAsIGxlbiA9IG1vZGVsQXV0aHMubGVuZ3RoOyBsIDwgbGVuOyBsKyspIHtcbiAgICAgICAgICBhdXRocyA9IG1vZGVsQXV0aHNbbF07XG4gICAgICAgICAgZm9yIChrZXkgaW4gYXV0aHMpIHtcbiAgICAgICAgICAgIGZvciAoYSBpbiB0aGlzLmF1dGhzKSB7XG4gICAgICAgICAgICAgIGF1dGggPSB0aGlzLmF1dGhzW2FdO1xuICAgICAgICAgICAgICBpZiAoa2V5ID09PSBhdXRoLm5hbWUpIHtcbiAgICAgICAgICAgICAgICBpZiAoYXV0aC50eXBlID09PSAnb2F1dGgyJykge1xuICAgICAgICAgICAgICAgICAgdGhpcy5tb2RlbC5vYXV0aCA9IHt9O1xuICAgICAgICAgICAgICAgICAgdGhpcy5tb2RlbC5vYXV0aC5zY29wZXMgPSBbXTtcbiAgICAgICAgICAgICAgICAgIHJlZjEgPSBhdXRoLnZhbHVlLnNjb3BlcztcbiAgICAgICAgICAgICAgICAgIGZvciAoayBpbiByZWYxKSB7XG4gICAgICAgICAgICAgICAgICAgIHYgPSByZWYxW2tdO1xuICAgICAgICAgICAgICAgICAgICBzY29wZUluZGV4ID0gYXV0aHNba2V5XS5pbmRleE9mKGspO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2NvcGVJbmRleCA+PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgbyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjb3BlOiBrLFxuICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246IHZcbiAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgIHRoaXMubW9kZWwub2F1dGguc2NvcGVzLnB1c2gobyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZvciAoayBpbiBtb2RlbEF1dGhzKSB7XG4gICAgICAgICAgdiA9IG1vZGVsQXV0aHNba107XG4gICAgICAgICAgaWYgKGsgPT09ICdvYXV0aDInKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5tb2RlbC5vYXV0aCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICB0aGlzLm1vZGVsLm9hdXRoID0ge307XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5tb2RlbC5vYXV0aC5zY29wZXMgPT09IHZvaWQgMCkge1xuICAgICAgICAgICAgICB0aGlzLm1vZGVsLm9hdXRoLnNjb3BlcyA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yIChtID0gMCwgbGVuMSA9IHYubGVuZ3RoOyBtIDwgbGVuMTsgbSsrKSB7XG4gICAgICAgICAgICAgIG8gPSB2W21dO1xuICAgICAgICAgICAgICB0aGlzLm1vZGVsLm9hdXRoLnNjb3Blcy5wdXNoKG8pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAodHlwZW9mIHRoaXMubW9kZWwucmVzcG9uc2VzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhpcy5tb2RlbC5yZXNwb25zZU1lc3NhZ2VzID0gW107XG4gICAgICByZWYyID0gdGhpcy5tb2RlbC5yZXNwb25zZXM7XG4gICAgICBmb3IgKGNvZGUgaW4gcmVmMikge1xuICAgICAgICB2YWx1ZSA9IHJlZjJbY29kZV07XG4gICAgICAgIHNjaGVtYSA9IG51bGw7XG4gICAgICAgIHNjaGVtYU9iaiA9IHRoaXMubW9kZWwucmVzcG9uc2VzW2NvZGVdLnNjaGVtYTtcbiAgICAgICAgaWYgKHNjaGVtYU9iaiAmJiBzY2hlbWFPYmouJHJlZikge1xuICAgICAgICAgIHNjaGVtYSA9IHNjaGVtYU9iai4kcmVmO1xuICAgICAgICAgIGlmIChzY2hlbWEuaW5kZXhPZignIy9kZWZpbml0aW9ucy8nKSAhPT0gLTEpIHtcbiAgICAgICAgICAgIHNjaGVtYSA9IHNjaGVtYS5yZXBsYWNlKC9eLiojXFwvZGVmaW5pdGlvbnNcXC8vLCAnJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMubW9kZWwucmVzcG9uc2VNZXNzYWdlcy5wdXNoKHtcbiAgICAgICAgICBjb2RlOiBjb2RlLFxuICAgICAgICAgIG1lc3NhZ2U6IHZhbHVlLmRlc2NyaXB0aW9uLFxuICAgICAgICAgIHJlc3BvbnNlTW9kZWw6IHNjaGVtYSxcbiAgICAgICAgICBoZWFkZXJzOiB2YWx1ZS5oZWFkZXJzLFxuICAgICAgICAgIHNjaGVtYTogc2NoZW1hT2JqXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAodHlwZW9mIHRoaXMubW9kZWwucmVzcG9uc2VNZXNzYWdlcyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHRoaXMubW9kZWwucmVzcG9uc2VNZXNzYWdlcyA9IFtdO1xuICAgIH1cbiAgICBzaWduYXR1cmVNb2RlbCA9IG51bGw7XG4gICAgcHJvZHVjZXMgPSB0aGlzLm1vZGVsLnByb2R1Y2VzO1xuICAgIGlzWE1MID0gdGhpcy5jb250YWlucyhwcm9kdWNlcywgJ3htbCcpO1xuICAgIGlzSlNPTiA9IGlzWE1MID8gdGhpcy5jb250YWlucyhwcm9kdWNlcywgJ2pzb24nKSA6IHRydWU7XG5cbiAgICBpZiAodGhpcy5tb2RlbC5zdWNjZXNzUmVzcG9uc2UpIHtcbiAgICAgIHN1Y2Nlc3NSZXNwb25zZSA9IHRoaXMubW9kZWwuc3VjY2Vzc1Jlc3BvbnNlO1xuICAgICAgZm9yIChrZXkgaW4gc3VjY2Vzc1Jlc3BvbnNlKSB7XG4gICAgICAgIHZhbHVlID0gc3VjY2Vzc1Jlc3BvbnNlW2tleV07XG4gICAgICAgIHRoaXMubW9kZWwuc3VjY2Vzc0NvZGUgPSBrZXk7XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHR5cGVvZiB2YWx1ZS5jcmVhdGVKU09OU2FtcGxlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgdGhpcy5tb2RlbC5zdWNjZXNzRGVzY3JpcHRpb24gPSB2YWx1ZS5kZXNjcmlwdGlvbjtcbiAgICAgICAgICB0aGlzLm1vZGVsLmhlYWRlcnMgPSB0aGlzLnBhcnNlUmVzcG9uc2VIZWFkZXJzKHZhbHVlLmhlYWRlcnMpO1xuICAgICAgICAgIHNpZ25hdHVyZU1vZGVsID0ge1xuICAgICAgICAgICAgc2FtcGxlSlNPTjogaXNKU09OID8gSlNPTi5zdHJpbmdpZnkoU3dhZ2dlclVpLnBhcnRpYWxzLnNpZ25hdHVyZS5jcmVhdGVKU09OU2FtcGxlKHZhbHVlKSwgdm9pZCAwLCAyKSA6IGZhbHNlLFxuICAgICAgICAgICAgaXNQYXJhbTogZmFsc2UsXG4gICAgICAgICAgICBzYW1wbGVYTUw6IGlzWE1MID8gU3dhZ2dlclVpLnBhcnRpYWxzLnNpZ25hdHVyZS5jcmVhdGVYTUxTYW1wbGUodmFsdWUubmFtZSwgdmFsdWUuZGVmaW5pdGlvbiwgdmFsdWUubW9kZWxzKSA6IGZhbHNlLFxuICAgICAgICAgICAgc2lnbmF0dXJlOiBTd2FnZ2VyVWkucGFydGlhbHMuc2lnbmF0dXJlLmdldE1vZGVsU2lnbmF0dXJlKHZhbHVlLm5hbWUsIHZhbHVlLmRlZmluaXRpb24sIHZhbHVlLm1vZGVscywgdmFsdWUubW9kZWxQcm9wZXJ0eU1hY3JvKVxuICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2lnbmF0dXJlTW9kZWwgPSB7XG4gICAgICAgICAgICBzaWduYXR1cmU6IFN3YWdnZXJVaS5wYXJ0aWFscy5zaWduYXR1cmUuZ2V0UHJpbWl0aXZlU2lnbmF0dXJlKHZhbHVlKVxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHRoaXMubW9kZWwucmVzcG9uc2VDbGFzc1NpZ25hdHVyZSAmJiB0aGlzLm1vZGVsLnJlc3BvbnNlQ2xhc3NTaWduYXR1cmUgIT09ICdzdHJpbmcnKSB7XG4gICAgICBzaWduYXR1cmVNb2RlbCA9IHtcbiAgICAgICAgc2FtcGxlSlNPTjogdGhpcy5tb2RlbC5yZXNwb25zZVNhbXBsZUpTT04sXG4gICAgICAgIGlzUGFyYW06IGZhbHNlLFxuICAgICAgICBzaWduYXR1cmU6IHRoaXMubW9kZWwucmVzcG9uc2VDbGFzc1NpZ25hdHVyZVxuICAgICAgfTtcbiAgICB9XG4gICAgJCh0aGlzLmVsKS5odG1sKEhhbmRsZWJhcnMudGVtcGxhdGVzLm9wZXJhdGlvbih0aGlzLm1vZGVsKSk7XG4gICAgaWYgKHNpZ25hdHVyZU1vZGVsKSB7XG4gICAgICBzaWduYXR1cmVNb2RlbC5kZWZhdWx0UmVuZGVyaW5nID0gdGhpcy5tb2RlbC5kZWZhdWx0UmVuZGVyaW5nO1xuICAgICAgcmVzcG9uc2VTaWduYXR1cmVWaWV3ID0gbmV3IFN3YWdnZXJVaS5WaWV3cy5TaWduYXR1cmVWaWV3KHtcbiAgICAgICAgbW9kZWw6IHNpZ25hdHVyZU1vZGVsLFxuICAgICAgICByb3V0ZXI6IHRoaXMucm91dGVyLFxuICAgICAgICB0YWdOYW1lOiAnZGl2J1xuICAgICAgfSk7XG4gICAgICAkKCcubW9kZWwtc2lnbmF0dXJlJywgJCh0aGlzLmVsKSkuYXBwZW5kKHJlc3BvbnNlU2lnbmF0dXJlVmlldy5yZW5kZXIoKS5lbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubW9kZWwucmVzcG9uc2VDbGFzc1NpZ25hdHVyZSA9ICdzdHJpbmcnO1xuICAgICAgJCgnLm1vZGVsLXNpZ25hdHVyZScsICQodGhpcy5lbCkpLmh0bWwodGhpcy5tb2RlbC50eXBlKTtcbiAgICB9XG4gICAgY29udGVudFR5cGVNb2RlbCA9IHtcbiAgICAgIGlzUGFyYW06IGZhbHNlXG4gICAgfTtcbiAgICBjb250ZW50VHlwZU1vZGVsLmNvbnN1bWVzID0gdGhpcy5tb2RlbC5jb25zdW1lcztcbiAgICBjb250ZW50VHlwZU1vZGVsLnByb2R1Y2VzID0gdGhpcy5tb2RlbC5wcm9kdWNlcztcbiAgICByZWYzID0gdGhpcy5tb2RlbC5wYXJhbWV0ZXJzO1xuICAgIGZvciAobiA9IDAsIGxlbjIgPSByZWYzLmxlbmd0aDsgbiA8IGxlbjI7IG4rKykge1xuICAgICAgcGFyYW0gPSByZWYzW25dO1xuICAgICAgdHlwZSA9IHBhcmFtLnR5cGUgfHwgcGFyYW0uZGF0YVR5cGUgfHwgJyc7XG4gICAgICBpZiAodHlwZW9mIHR5cGUgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHNjaGVtYSA9IHBhcmFtLnNjaGVtYTtcbiAgICAgICAgaWYgKHNjaGVtYSAmJiBzY2hlbWEuJHJlZikge1xuICAgICAgICAgIHJlZiA9IHNjaGVtYS4kcmVmO1xuICAgICAgICAgIGlmIChyZWYuaW5kZXhPZignIy9kZWZpbml0aW9ucy8nKSA9PT0gMCkge1xuICAgICAgICAgICAgdHlwZSA9IHJlZi5zdWJzdHJpbmcoJyMvZGVmaW5pdGlvbnMvJy5sZW5ndGgpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0eXBlID0gcmVmO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHR5cGUgJiYgdHlwZS50b0xvd2VyQ2FzZSgpID09PSAnZmlsZScpIHtcbiAgICAgICAgaWYgKCFjb250ZW50VHlwZU1vZGVsLmNvbnN1bWVzKSB7XG4gICAgICAgICAgY29udGVudFR5cGVNb2RlbC5jb25zdW1lcyA9ICdtdWx0aXBhcnQvZm9ybS1kYXRhJztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcGFyYW0udHlwZSA9IHR5cGU7XG4gICAgfVxuICAgIHJlc3BvbnNlQ29udGVudFR5cGVWaWV3ID0gbmV3IFN3YWdnZXJVaS5WaWV3cy5SZXNwb25zZUNvbnRlbnRUeXBlVmlldyh7XG4gICAgICBtb2RlbDogY29udGVudFR5cGVNb2RlbCxcbiAgICAgIHJvdXRlcjogdGhpcy5yb3V0ZXJcbiAgICB9KTtcbiAgICAkKCcucmVzcG9uc2UtY29udGVudC10eXBlJywgJCh0aGlzLmVsKSkuYXBwZW5kKHJlc3BvbnNlQ29udGVudFR5cGVWaWV3LnJlbmRlcigpLmVsKTtcbiAgICByZWY0ID0gdGhpcy5tb2RlbC5wYXJhbWV0ZXJzO1xuICAgIGZvciAocCA9IDAsIGxlbjMgPSByZWY0Lmxlbmd0aDsgcCA8IGxlbjM7IHArKykge1xuICAgICAgcGFyYW0gPSByZWY0W3BdO1xuICAgICAgdGhpcy5hZGRQYXJhbWV0ZXIocGFyYW0sIGNvbnRlbnRUeXBlTW9kZWwuY29uc3VtZXMpO1xuICAgIH1cbiAgICByZWY1ID0gdGhpcy5tb2RlbC5yZXNwb25zZU1lc3NhZ2VzO1xuICAgIGZvciAocSA9IDAsIGxlbjQgPSByZWY1Lmxlbmd0aDsgcSA8IGxlbjQ7IHErKykge1xuICAgICAgc3RhdHVzQ29kZSA9IHJlZjVbcV07XG4gICAgICBzdGF0dXNDb2RlLmlzWE1MID0gaXNYTUw7XG4gICAgICBzdGF0dXNDb2RlLmlzSlNPTiA9IGlzSlNPTjtcbiAgICAgIGlmICghXy5pc1VuZGVmaW5lZChzdGF0dXNDb2RlLmhlYWRlcnMpKSB7XG4gICAgICAgIHN0YXR1c0NvZGUuaGVhZGVycyA9IHRoaXMucGFyc2VIZWFkZXJzVHlwZShzdGF0dXNDb2RlLmhlYWRlcnMpO1xuICAgICAgfVxuICAgICAgdGhpcy5hZGRTdGF0dXNDb2RlKHN0YXR1c0NvZGUpO1xuICAgIH1cblxuICAgIGlmIChBcnJheS5pc0FycmF5KHRoaXMubW9kZWwuc2VjdXJpdHkpKSB7XG4gICAgICB2YXIgYXV0aHNNb2RlbCA9IFN3YWdnZXJVaS51dGlscy5wYXJzZVNlY3VyaXR5RGVmaW5pdGlvbnModGhpcy5tb2RlbC5zZWN1cml0eSwgdGhpcy5tb2RlbC5wYXJlbnQuc2VjdXJpdHlEZWZpbml0aW9ucyk7XG5cbiAgICAgIGF1dGhzTW9kZWwuaXNMb2dvdXQgPSAhXy5pc0VtcHR5KHRoaXMubW9kZWwuY2xpZW50QXV0aG9yaXphdGlvbnMuYXV0aHopO1xuICAgICAgdGhpcy5hdXRoVmlldyA9IG5ldyBTd2FnZ2VyVWkuVmlld3MuQXV0aEJ1dHRvblZpZXcoe1xuICAgICAgICBkYXRhOiBhdXRoc01vZGVsLFxuICAgICAgICByb3V0ZXI6IHRoaXMucm91dGVyLFxuICAgICAgICBpc09wZXJhdGlvbjogdHJ1ZSxcbiAgICAgICAgbW9kZWw6IHtcbiAgICAgICAgICBzY29wZXM6IGF1dGhzTW9kZWwuc2NvcGVzXG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgdGhpcy4kKCcuYXV0aG9yaXplLXdyYXBwZXInKS5hcHBlbmQodGhpcy5hdXRoVmlldy5yZW5kZXIoKS5lbCk7XG4gICAgfVxuXG4gICAgdGhpcy5zaG93U25pcHBldCgpO1xuICAgIHJldHVybiB0aGlzO1xuICB9LFxuXG4gIHBhcnNlSGVhZGVyc1R5cGU6IGZ1bmN0aW9uIChoZWFkZXJzKSB7XG4gICAgdmFyIG1hcCA9IHtcbiAgICAgICdzdHJpbmcnOiB7XG4gICAgICAgICdkYXRlLXRpbWUnOiAnZGF0ZVRpbWUnLFxuICAgICAgICAnZGF0ZScgICAgIDogJ2RhdGUnXG4gICAgICB9XG4gICAgfTtcblxuICAgIF8uZm9yRWFjaChoZWFkZXJzLCBmdW5jdGlvbiAoaGVhZGVyKSB7XG4gICAgICB2YXIgdmFsdWU7XG4gICAgICBoZWFkZXIgPSBoZWFkZXIgfHwge307XG4gICAgICB2YWx1ZSA9IG1hcFtoZWFkZXIudHlwZV0gJiYgbWFwW2hlYWRlci50eXBlXVtoZWFkZXIuZm9ybWF0XTtcbiAgICAgIGlmICghXy5pc1VuZGVmaW5lZCh2YWx1ZSkpIHtcbiAgICAgICAgaGVhZGVyLnR5cGUgPSB2YWx1ZTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiBoZWFkZXJzO1xuICB9LFxuXG4gIGNvbnRhaW5zOiBmdW5jdGlvbiAocHJvZHVjZXMsIHR5cGUpIHtcbiAgICByZXR1cm4gcHJvZHVjZXMuZmlsdGVyKGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgIGlmICh2YWwuaW5kZXhPZih0eXBlKSA+IC0xKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH0pLmxlbmd0aDtcbiAgfSxcblxuICBwYXJzZVJlc3BvbnNlSGVhZGVyczogZnVuY3Rpb24gKGRhdGEpIHtcbiAgICB2YXIgSEVBREVSU19TRVBBUkFUT1IgPSAnOyAnO1xuICAgIHZhciBoZWFkZXJzID0gXy5jbG9uZShkYXRhKTtcblxuICAgIF8uZm9yRWFjaChoZWFkZXJzLCBmdW5jdGlvbiAoaGVhZGVyKSB7XG4gICAgICB2YXIgb3RoZXIgPSBbXTtcbiAgICAgIF8uZm9yRWFjaChoZWFkZXIsIGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG4gICAgICAgIHZhciBwcm9wZXJ0aWVzID0gWyd0eXBlJywgJ2Rlc2NyaXB0aW9uJ107XG4gICAgICAgIGlmIChwcm9wZXJ0aWVzLmluZGV4T2Yoa2V5LnRvTG93ZXJDYXNlKCkpID09PSAtMSkge1xuICAgICAgICAgIG90aGVyLnB1c2goa2V5ICsgJzogJyArIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIG90aGVyLmpvaW4oSEVBREVSU19TRVBBUkFUT1IpO1xuICAgICAgaGVhZGVyLm90aGVyID0gb3RoZXI7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gaGVhZGVycztcbiAgfSxcblxuICBhZGRQYXJhbWV0ZXI6IGZ1bmN0aW9uKHBhcmFtLCBjb25zdW1lcykge1xuICAgIC8vIFJlbmRlciBhIHBhcmFtZXRlclxuICAgIHBhcmFtLmNvbnN1bWVzID0gY29uc3VtZXM7XG4gICAgcGFyYW0uZGVmYXVsdFJlbmRlcmluZyA9IHRoaXMubW9kZWwuZGVmYXVsdFJlbmRlcmluZztcblxuICAgIC8vIENvcHkgdGhpcyBwYXJhbSBKU09OIHNwZWMgc28gdGhhdCBpdCB3aWxsIGJlIGF2YWlsYWJsZSBmb3IgSnNvbkVkaXRvclxuICAgIGlmKHBhcmFtLnNjaGVtYSl7XG4gICAgICAkLmV4dGVuZCh0cnVlLCBwYXJhbS5zY2hlbWEsIHRoaXMubW9kZWwuZGVmaW5pdGlvbnNbcGFyYW0udHlwZV0pO1xuICAgICAgcGFyYW0uc2NoZW1hLmRlZmluaXRpb25zID0gdGhpcy5tb2RlbC5kZWZpbml0aW9ucztcbiAgICAgIC8vIFRoaXMgaXMgcmVxdWlyZWQgZm9yIEpzb25FZGl0b3IgdG8gZGlzcGxheSB0aGUgcm9vdCBwcm9wZXJseVxuICAgICAgaWYoIXBhcmFtLnNjaGVtYS50eXBlKXtcbiAgICAgICAgcGFyYW0uc2NoZW1hLnR5cGUgPSAnb2JqZWN0JztcbiAgICAgIH1cbiAgICAgIC8vIFRoaXMgaXMgdGhlIHRpdGxlIHRoYXQgd2lsbCBiZSB1c2VkIGJ5IEpzb25FZGl0b3IgZm9yIHRoZSByb290XG4gICAgICAvLyBTaW5jZSB3ZSBhbHJlYWR5IGRpc3BsYXkgdGhlIHBhcmFtZXRlcidzIG5hbWUgaW4gdGhlIFBhcmFtZXRlciBjb2x1bW5cbiAgICAgIC8vIFdlIHNldCB0aGlzIHRvIHNwYWNlLCB3ZSBjYW4ndCBzZXQgaXQgdG8gbnVsbCBvciBzcGFjZSBvdGhlcndpc2UgSnNvbkVkaXRvclxuICAgICAgLy8gd2lsbCByZXBsYWNlIGl0IHdpdGggdGhlIHRleHQgXCJyb290XCIgd2hpY2ggd29uJ3QgbG9vayBnb29kIG9uIHNjcmVlblxuICAgICAgaWYoIXBhcmFtLnNjaGVtYS50aXRsZSl7XG4gICAgICAgIHBhcmFtLnNjaGVtYS50aXRsZSA9ICcgJztcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgcGFyYW1WaWV3ID0gbmV3IFN3YWdnZXJVaS5WaWV3cy5QYXJhbWV0ZXJWaWV3KHtcbiAgICAgIG1vZGVsOiBwYXJhbSxcbiAgICAgIHRhZ05hbWU6ICd0cicsXG4gICAgICByZWFkT25seTogdGhpcy5tb2RlbC5pc1JlYWRPbmx5LFxuICAgICAgc3dhZ2dlck9wdGlvbnM6IHRoaXMub3B0aW9ucy5zd2FnZ2VyT3B0aW9uc1xuICAgIH0pO1xuICAgICQoJy5vcGVyYXRpb24tcGFyYW1zJywgJCh0aGlzLmVsKSkuYXBwZW5kKHBhcmFtVmlldy5yZW5kZXIoKS5lbCk7XG4gIH0sXG5cbiAgYWRkU3RhdHVzQ29kZTogZnVuY3Rpb24oc3RhdHVzQ29kZSkge1xuICAgIC8vIFJlbmRlciBzdGF0dXMgY29kZXNcbiAgICBzdGF0dXNDb2RlLmRlZmF1bHRSZW5kZXJpbmcgPSB0aGlzLm1vZGVsLmRlZmF1bHRSZW5kZXJpbmc7XG4gICAgdmFyIHN0YXR1c0NvZGVWaWV3ID0gbmV3IFN3YWdnZXJVaS5WaWV3cy5TdGF0dXNDb2RlVmlldyh7XG4gICAgICBtb2RlbDogc3RhdHVzQ29kZSxcbiAgICAgIHRhZ05hbWU6ICd0cicsXG4gICAgICByb3V0ZXI6IHRoaXMucm91dGVyXG4gICAgfSk7XG4gICAgJCgnLm9wZXJhdGlvbi1zdGF0dXMnLCAkKHRoaXMuZWwpKS5hcHBlbmQoc3RhdHVzQ29kZVZpZXcucmVuZGVyKCkuZWwpO1xuICB9LFxuXG4gIC8vIE5vdGU6IGNvcGllZCBmcm9tIENvZmZlZVNjcmlwdCBjb21waWxlZCBmaWxlXG4gIC8vIFRPRE86IHJlZGFjdG9yXG4gIHN1Ym1pdE9wZXJhdGlvbjogZnVuY3Rpb24oZSkge1xuICAgIHZhciBlcnJvcl9mcmVlLCBmb3JtLCBpc0ZpbGVVcGxvYWQsIG1hcCwgb3B0cztcbiAgICBpZiAoZSAhPT0gbnVsbCkge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbiAgICBmb3JtID0gJCgnLnNhbmRib3gnLCAkKHRoaXMuZWwpKTtcbiAgICBlcnJvcl9mcmVlID0gdHJ1ZTtcbiAgICBmb3JtLmZpbmQoJ2lucHV0LnJlcXVpcmVkJykuZWFjaChmdW5jdGlvbigpIHtcbiAgICAgICQodGhpcykucmVtb3ZlQ2xhc3MoJ2Vycm9yJyk7XG4gICAgICBpZiAoalF1ZXJ5LnRyaW0oJCh0aGlzKS52YWwoKSkgPT09ICcnKSB7XG4gICAgICAgICQodGhpcykuYWRkQ2xhc3MoJ2Vycm9yJyk7XG4gICAgICAgICQodGhpcykud2lnZ2xlKHtcbiAgICAgICAgICBjYWxsYmFjazogKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICQoX3RoaXMpLmZvY3VzKCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0pKHRoaXMpXG4gICAgICAgIH0pO1xuICAgICAgICBlcnJvcl9mcmVlID0gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG4gICAgZm9ybS5maW5kKCd0ZXh0YXJlYS5yZXF1aXJlZDp2aXNpYmxlJykuZWFjaChmdW5jdGlvbigpIHtcbiAgICAgICQodGhpcykucmVtb3ZlQ2xhc3MoJ2Vycm9yJyk7XG4gICAgICBpZiAoalF1ZXJ5LnRyaW0oJCh0aGlzKS52YWwoKSkgPT09ICcnKSB7XG4gICAgICAgICQodGhpcykuYWRkQ2xhc3MoJ2Vycm9yJyk7XG4gICAgICAgICQodGhpcykud2lnZ2xlKHtcbiAgICAgICAgICBjYWxsYmFjazogKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgIHJldHVybiAkKF90aGlzKS5mb2N1cygpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9KSh0aGlzKVxuICAgICAgICB9KTtcbiAgICAgICAgZXJyb3JfZnJlZSA9IGZhbHNlO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGZvcm0uZmluZCgnc2VsZWN0LnJlcXVpcmVkJykuZWFjaChmdW5jdGlvbigpIHtcbiAgICAgICQodGhpcykucmVtb3ZlQ2xhc3MoJ2Vycm9yJyk7XG4gICAgICBpZiAodGhpcy5zZWxlY3RlZEluZGV4ID09PSAtMSkge1xuICAgICAgICAkKHRoaXMpLmFkZENsYXNzKCdlcnJvcicpO1xuICAgICAgICAkKHRoaXMpLndpZ2dsZSh7XG4gICAgICAgICAgY2FsbGJhY2s6IChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAkKF90aGlzKS5mb2N1cygpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9KSh0aGlzKVxuICAgICAgICB9KTtcbiAgICAgICAgZXJyb3JfZnJlZSA9IGZhbHNlO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGlmIChlcnJvcl9mcmVlKSB7XG4gICAgICBtYXAgPSB0aGlzLmdldElucHV0TWFwKGZvcm0pO1xuICAgICAgaXNGaWxlVXBsb2FkID0gdGhpcy5pc0ZpbGVVcGxvYWQoZm9ybSk7XG4gICAgICBvcHRzID0ge1xuICAgICAgICBwYXJlbnQ6IHRoaXNcbiAgICAgIH07XG4gICAgICBpZiAodGhpcy5vcHRpb25zLnN3YWdnZXJPcHRpb25zKSB7XG4gICAgICAgIGZvcih2YXIga2V5IGluIHRoaXMub3B0aW9ucy5zd2FnZ2VyT3B0aW9ucykge1xuICAgICAgICAgIG9wdHNba2V5XSA9IHRoaXMub3B0aW9ucy5zd2FnZ2VyT3B0aW9uc1trZXldO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHZhciBwaTtcbiAgICAgIGZvcihwaSA9IDA7IHBpIDwgdGhpcy5tb2RlbC5wYXJhbWV0ZXJzLmxlbmd0aDsgcGkrKyl7XG4gICAgICAgIHZhciBwID0gdGhpcy5tb2RlbC5wYXJhbWV0ZXJzW3BpXTtcbiAgICAgICAgaWYoIHAuanNvbkVkaXRvciAmJiBwLmpzb25FZGl0b3IuaXNFbmFibGVkKCkpe1xuICAgICAgICAgIHZhciBqc29uID0gcC5qc29uRWRpdG9yLmdldFZhbHVlKCk7XG4gICAgICAgICAgbWFwW3AubmFtZV0gPSBKU09OLnN0cmluZ2lmeShqc29uKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBvcHRzLnJlc3BvbnNlQ29udGVudFR5cGUgPSAkKCdkaXYgc2VsZWN0W25hbWU9cmVzcG9uc2VDb250ZW50VHlwZV0nLCAkKHRoaXMuZWwpKS52YWwoKTtcbiAgICAgIG9wdHMucmVxdWVzdENvbnRlbnRUeXBlID0gJCgnZGl2IHNlbGVjdFtuYW1lPXBhcmFtZXRlckNvbnRlbnRUeXBlXScsICQodGhpcy5lbCkpLnZhbCgpO1xuICAgICAgJCgnLnJlc3BvbnNlX3Rocm9iYmVyJywgJCh0aGlzLmVsKSkuc2hvdygpO1xuICAgICAgaWYgKGlzRmlsZVVwbG9hZCkge1xuICAgICAgICAkKCcucmVxdWVzdF91cmwnLCAkKHRoaXMuZWwpKS5odG1sKCc8cHJlPjwvcHJlPicpO1xuICAgICAgICAkKCcucmVxdWVzdF91cmwgcHJlJywgJCh0aGlzLmVsKSkudGV4dCh0aGlzLmludm9jYXRpb25VcmwpO1xuXG4gICAgICAgIG9wdHMudXNlSlF1ZXJ5ID0gdHJ1ZTtcbiAgICAgICAgbWFwLnBhcmFtZXRlckNvbnRlbnRUeXBlID0gJ211bHRpcGFydC9mb3JtLWRhdGEnO1xuICAgICAgICB0aGlzLm1hcCA9IG1hcDtcbiAgICAgICAgcmV0dXJuIHRoaXMubW9kZWwuZXhlY3V0ZShtYXAsIG9wdHMsIHRoaXMuc2hvd0NvbXBsZXRlU3RhdHVzLCB0aGlzLnNob3dFcnJvclN0YXR1cywgdGhpcyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLm1hcCA9IG1hcDtcbiAgICAgICAgcmV0dXJuIHRoaXMubW9kZWwuZXhlY3V0ZShtYXAsIG9wdHMsIHRoaXMuc2hvd0NvbXBsZXRlU3RhdHVzLCB0aGlzLnNob3dFcnJvclN0YXR1cywgdGhpcyk7XG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIGdldElucHV0TWFwOiBmdW5jdGlvbiAoZm9ybSkge1xuICAgIHZhciBtYXAsIHJlZjEsIGwsIGxlbiwgbywgcmVmMiwgbSwgbGVuMSwgdmFsLCByZWYzLCBuLCBsZW4yO1xuICAgIG1hcCA9IHt9O1xuICAgIHJlZjEgPSBmb3JtLmZpbmQoJ2lucHV0Jyk7XG4gICAgZm9yIChsID0gMCwgbGVuID0gcmVmMS5sZW5ndGg7IGwgPCBsZW47IGwrKykge1xuICAgICAgbyA9IHJlZjFbbF07XG4gICAgICBpZiAoKG8udmFsdWUgIT09IG51bGwpICYmIGpRdWVyeS50cmltKG8udmFsdWUpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgbWFwW28ubmFtZV0gPSBvLnZhbHVlO1xuICAgICAgfVxuICAgICAgaWYgKG8udHlwZSA9PT0gJ2ZpbGUnKSB7XG4gICAgICAgIG1hcFtvLm5hbWVdID0gby5maWxlc1swXTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmVmMiA9IGZvcm0uZmluZCgndGV4dGFyZWEnKTtcbiAgICBmb3IgKG0gPSAwLCBsZW4xID0gcmVmMi5sZW5ndGg7IG0gPCBsZW4xOyBtKyspIHtcbiAgICAgIG8gPSByZWYyW21dO1xuICAgICAgdmFsID0gdGhpcy5nZXRUZXh0QXJlYVZhbHVlKG8pO1xuICAgICAgaWYgKCh2YWwgIT09IG51bGwpICYmIGpRdWVyeS50cmltKHZhbCkubGVuZ3RoID4gMCkge1xuICAgICAgICBtYXBbby5uYW1lXSA9IHZhbDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmVmMyA9IGZvcm0uZmluZCgnc2VsZWN0Jyk7XG4gICAgZm9yIChuID0gMCwgbGVuMiA9IHJlZjMubGVuZ3RoOyBuIDwgbGVuMjsgbisrKSB7XG4gICAgICBvID0gcmVmM1tuXTtcbiAgICAgIHZhbCA9IHRoaXMuZ2V0U2VsZWN0ZWRWYWx1ZShvKTtcbiAgICAgIGlmICgodmFsICE9PSBudWxsKSAmJiBqUXVlcnkudHJpbSh2YWwpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgbWFwW28ubmFtZV0gPSB2YWw7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBtYXA7XG4gIH0sXG5cbiAgaXNGaWxlVXBsb2FkOiBmdW5jdGlvbiAoZm9ybSkge1xuICAgIHZhciByZWYxLCBsLCBsZW4sIG87XG4gICAgdmFyIGlzRmlsZVVwbG9hZCA9IGZhbHNlO1xuICAgIHJlZjEgPSBmb3JtLmZpbmQoJ2lucHV0Jyk7XG4gICAgZm9yIChsID0gMCwgbGVuID0gcmVmMS5sZW5ndGg7IGwgPCBsZW47IGwrKykge1xuICAgICAgbyA9IHJlZjFbbF07XG4gICAgICBpZiAoby50eXBlID09PSAnZmlsZScpIHtcbiAgICAgICAgaXNGaWxlVXBsb2FkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGlzRmlsZVVwbG9hZDtcbiAgfSxcblxuICBzdWNjZXNzOiBmdW5jdGlvbihyZXNwb25zZSwgcGFyZW50KSB7XG4gICAgcGFyZW50LnNob3dDb21wbGV0ZVN0YXR1cyhyZXNwb25zZSk7XG4gIH0sXG5cbiAgLy8gd3JhcHMgYSBqcXVlcnkgcmVzcG9uc2UgYXMgYSBzaHJlZCByZXNwb25zZVxuICB3cmFwOiBmdW5jdGlvbihkYXRhKSB7XG4gICAgdmFyIGgsIGhlYWRlckFycmF5LCBoZWFkZXJzLCBpLCBsLCBsZW4sIG87XG4gICAgaGVhZGVycyA9IHt9O1xuICAgIGhlYWRlckFycmF5ID0gZGF0YS5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKS5zcGxpdCgnXFxyJyk7XG4gICAgZm9yIChsID0gMCwgbGVuID0gaGVhZGVyQXJyYXkubGVuZ3RoOyBsIDwgbGVuOyBsKyspIHtcbiAgICAgIGkgPSBoZWFkZXJBcnJheVtsXTtcbiAgICAgIGggPSBpLm1hdGNoKC9eKFteOl0qPyk6KC4qKSQvKTtcbiAgICAgIGlmICghaCkge1xuICAgICAgICBoID0gW107XG4gICAgICB9XG4gICAgICBoLnNoaWZ0KCk7XG4gICAgICBpZiAoaFswXSAhPT0gdm9pZCAwICYmIGhbMV0gIT09IHZvaWQgMCkge1xuICAgICAgICBoZWFkZXJzW2hbMF0udHJpbSgpXSA9IGhbMV0udHJpbSgpO1xuICAgICAgfVxuICAgIH1cbiAgICBvID0ge307XG4gICAgby5jb250ZW50ID0ge307XG4gICAgby5jb250ZW50LmRhdGEgPSBkYXRhLnJlc3BvbnNlVGV4dDtcbiAgICBvLmhlYWRlcnMgPSBoZWFkZXJzO1xuICAgIG8ucmVxdWVzdCA9IHt9O1xuICAgIG8ucmVxdWVzdC51cmwgPSB0aGlzLmludm9jYXRpb25Vcmw7XG4gICAgby5zdGF0dXMgPSBkYXRhLnN0YXR1cztcbiAgICByZXR1cm4gbztcbiAgfSxcblxuICBnZXRTZWxlY3RlZFZhbHVlOiBmdW5jdGlvbihzZWxlY3QpIHtcbiAgICBpZiAoIXNlbGVjdC5tdWx0aXBsZSkge1xuICAgICAgcmV0dXJuIHNlbGVjdC52YWx1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIG9wdGlvbnMgPSBbXTtcbiAgICAgIGZvciAodmFyIGwgPSAwLCBsZW4gPSBzZWxlY3Qub3B0aW9ucy5sZW5ndGg7IGwgPCBsZW47IGwrKykge1xuICAgICAgICB2YXIgb3B0ID0gc2VsZWN0Lm9wdGlvbnNbbF07XG4gICAgICAgIGlmIChvcHQuc2VsZWN0ZWQpIHtcbiAgICAgICAgICBvcHRpb25zLnB1c2gob3B0LnZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG9wdGlvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICByZXR1cm4gb3B0aW9ucztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICAvLyBoYW5kbGVyIGZvciBoaWRlIHJlc3BvbnNlIGxpbmtcbiAgaGlkZVJlc3BvbnNlOiBmdW5jdGlvbihlKSB7XG4gICAgaWYgKGUpIHsgZS5wcmV2ZW50RGVmYXVsdCgpOyB9XG4gICAgJCgnLnJlc3BvbnNlJywgJCh0aGlzLmVsKSkuc2xpZGVVcCgpO1xuICAgICQoJy5yZXNwb25zZV9oaWRlcicsICQodGhpcy5lbCkpLmZhZGVPdXQoKTtcbiAgfSxcblxuICAvLyBTaG93IHJlc3BvbnNlIGZyb20gc2VydmVyXG4gIHNob3dSZXNwb25zZTogZnVuY3Rpb24ocmVzcG9uc2UpIHtcbiAgICB2YXIgcHJldHR5SnNvbiA9IEpTT04uc3RyaW5naWZ5KHJlc3BvbnNlLCBudWxsLCAnXFx0JykucmVwbGFjZSgvXFxuL2csICc8YnI+Jyk7XG4gICAgJCgnLnJlc3BvbnNlX2JvZHknLCAkKHRoaXMuZWwpKS5odG1sKF8uZXNjYXBlKHByZXR0eUpzb24pKTtcbiAgfSxcblxuICAvLyBTaG93IGVycm9yIGZyb20gc2VydmVyXG4gIHNob3dFcnJvclN0YXR1czogZnVuY3Rpb24oZGF0YSwgcGFyZW50KSB7XG4gICAgcGFyZW50LnNob3dTdGF0dXMoZGF0YSk7XG4gIH0sXG5cbiAgLy8gc2hvdyB0aGUgc3RhdHVzIGNvZGVzXG4gIHNob3dDb21wbGV0ZVN0YXR1czogZnVuY3Rpb24oZGF0YSwgcGFyZW50KXtcbiAgICBwYXJlbnQuc2hvd1N0YXR1cyhkYXRhKTtcbiAgfSxcblxuICAvLyBBZGFwdGVkIGZyb20gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMjg5MzI1OS80NTQwMDRcbiAgLy8gTm90ZTogZGlyZWN0bHkgcG9ydGVkIGZyb20gQ29mZmVlU2NyaXB0XG4gIC8vIFRPRE86IENsZWFudXAgQ29mZmVlU2NyaXB0IGFydGlmYWN0c1xuICBmb3JtYXRYbWw6IGZ1bmN0aW9uKHhtbCkge1xuICAgIHZhciBjb250ZXhwLCBmbiwgZm9ybWF0dGVkLCBpbmRlbnQsIGwsIGxhc3RUeXBlLCBsZW4sIGxpbmVzLCBsbiwgcGFkLCByZWcsIHRyYW5zaXRpb25zLCB3c2V4cDtcbiAgICByZWcgPSAvKD4pKDwpKFxcLyopL2c7XG4gICAgd3NleHAgPSAvWyBdKiguKilbIF0rXFxuL2c7XG4gICAgY29udGV4cCA9IC8oPC4rPikoLitcXG4pL2c7XG4gICAgeG1sID0geG1sLnJlcGxhY2UoL1xcclxcbi9nLCAnXFxuJykucmVwbGFjZShyZWcsICckMVxcbiQyJDMnKS5yZXBsYWNlKHdzZXhwLCAnJDFcXG4nKS5yZXBsYWNlKGNvbnRleHAsICckMVxcbiQyJyk7XG4gICAgcGFkID0gMDtcbiAgICBmb3JtYXR0ZWQgPSAnJztcbiAgICBsaW5lcyA9IHhtbC5zcGxpdCgnXFxuJyk7XG4gICAgaW5kZW50ID0gMDtcbiAgICBsYXN0VHlwZSA9ICdvdGhlcic7XG4gICAgdHJhbnNpdGlvbnMgPSB7XG4gICAgICAnc2luZ2xlLT5zaW5nbGUnOiAwLFxuICAgICAgJ3NpbmdsZS0+Y2xvc2luZyc6IC0xLFxuICAgICAgJ3NpbmdsZS0+b3BlbmluZyc6IDAsXG4gICAgICAnc2luZ2xlLT5vdGhlcic6IDAsXG4gICAgICAnY2xvc2luZy0+c2luZ2xlJzogMCxcbiAgICAgICdjbG9zaW5nLT5jbG9zaW5nJzogLTEsXG4gICAgICAnY2xvc2luZy0+b3BlbmluZyc6IDAsXG4gICAgICAnY2xvc2luZy0+b3RoZXInOiAwLFxuICAgICAgJ29wZW5pbmctPnNpbmdsZSc6IDEsXG4gICAgICAnb3BlbmluZy0+Y2xvc2luZyc6IDAsXG4gICAgICAnb3BlbmluZy0+b3BlbmluZyc6IDEsXG4gICAgICAnb3BlbmluZy0+b3RoZXInOiAxLFxuICAgICAgJ290aGVyLT5zaW5nbGUnOiAwLFxuICAgICAgJ290aGVyLT5jbG9zaW5nJzogLTEsXG4gICAgICAnb3RoZXItPm9wZW5pbmcnOiAwLFxuICAgICAgJ290aGVyLT5vdGhlcic6IDBcbiAgICB9O1xuICAgIGZuID0gZnVuY3Rpb24obG4pIHtcbiAgICAgIHZhciBmcm9tVG8sIGosIGtleSwgcGFkZGluZywgdHlwZSwgdHlwZXMsIHZhbHVlO1xuICAgICAgdHlwZXMgPSB7XG4gICAgICAgIHNpbmdsZTogQm9vbGVhbihsbi5tYXRjaCgvPC4rXFwvPi8pKSxcbiAgICAgICAgY2xvc2luZzogQm9vbGVhbihsbi5tYXRjaCgvPFxcLy4rPi8pKSxcbiAgICAgICAgb3BlbmluZzogQm9vbGVhbihsbi5tYXRjaCgvPFteIT9dLio+LykpXG4gICAgICB9O1xuICAgICAgdHlwZSA9ICgoZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciByZXN1bHRzO1xuICAgICAgICByZXN1bHRzID0gW107XG4gICAgICAgIGZvciAoa2V5IGluIHR5cGVzKSB7XG4gICAgICAgICAgdmFsdWUgPSB0eXBlc1trZXldO1xuICAgICAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICAgICAgcmVzdWx0cy5wdXNoKGtleSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHRzO1xuICAgICAgfSkoKSlbMF07XG4gICAgICB0eXBlID0gdHlwZSA9PT0gdm9pZCAwID8gJ290aGVyJyA6IHR5cGU7XG4gICAgICBmcm9tVG8gPSBsYXN0VHlwZSArICctPicgKyB0eXBlO1xuICAgICAgbGFzdFR5cGUgPSB0eXBlO1xuICAgICAgcGFkZGluZyA9ICcnO1xuICAgICAgaW5kZW50ICs9IHRyYW5zaXRpb25zW2Zyb21Ub107XG4gICAgICBwYWRkaW5nID0gKChmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIG0sIHJlZjEsIHJlc3VsdHM7XG4gICAgICAgIHJlc3VsdHMgPSBbXTtcbiAgICAgICAgZm9yIChqID0gbSA9IDAsIHJlZjEgPSBpbmRlbnQ7IDAgPD0gcmVmMSA/IG0gPCByZWYxIDogbSA+IHJlZjE7IGogPSAwIDw9IHJlZjEgPyArK20gOiAtLW0pIHtcbiAgICAgICAgICByZXN1bHRzLnB1c2goJyAgJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdHM7XG4gICAgICB9KSgpKS5qb2luKCcnKTtcbiAgICAgIGlmIChmcm9tVG8gPT09ICdvcGVuaW5nLT5jbG9zaW5nJykge1xuICAgICAgICBmb3JtYXR0ZWQgPSBmb3JtYXR0ZWQuc3Vic3RyKDAsIGZvcm1hdHRlZC5sZW5ndGggLSAxKSArIGxuICsgJ1xcbic7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3JtYXR0ZWQgKz0gcGFkZGluZyArIGxuICsgJ1xcbic7XG4gICAgICB9XG4gICAgfTtcbiAgICBmb3IgKGwgPSAwLCBsZW4gPSBsaW5lcy5sZW5ndGg7IGwgPCBsZW47IGwrKykge1xuICAgICAgbG4gPSBsaW5lc1tsXTtcbiAgICAgIGZuKGxuKTtcbiAgICB9XG4gICAgcmV0dXJuIGZvcm1hdHRlZDtcbiAgfSxcblxuICAvLyBwdXRzIHRoZSByZXNwb25zZSBkYXRhIGluIFVJXG4gIHNob3dTdGF0dXM6IGZ1bmN0aW9uKHJlc3BvbnNlKSB7XG4gICAgdmFyIHVybCwgY29udGVudDtcbiAgICBpZiAocmVzcG9uc2UuY29udGVudCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb250ZW50ID0gcmVzcG9uc2UuZGF0YTtcbiAgICAgIHVybCA9IHJlc3BvbnNlLnVybDtcbiAgICB9IGVsc2Uge1xuICAgICAgY29udGVudCA9IHJlc3BvbnNlLmNvbnRlbnQuZGF0YTtcbiAgICAgIHVybCA9IHJlc3BvbnNlLnJlcXVlc3QudXJsO1xuICAgIH1cbiAgICB2YXIgaGVhZGVycyA9IHJlc3BvbnNlLmhlYWRlcnM7XG4gICAgaWYodHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBjb250ZW50ID0galF1ZXJ5LnRyaW0oY29udGVudCk7XG4gICAgfVxuXG4gICAgLy8gaWYgc2VydmVyIGlzIG5pY2UsIGFuZCBzZW5kcyBjb250ZW50LXR5cGUgYmFjaywgd2UgY2FuIHVzZSBpdFxuICAgIHZhciBjb250ZW50VHlwZSA9IG51bGw7XG4gICAgaWYgKGhlYWRlcnMpIHtcbiAgICAgIGNvbnRlbnRUeXBlID0gaGVhZGVyc1snQ29udGVudC1UeXBlJ10gfHwgaGVhZGVyc1snY29udGVudC10eXBlJ107XG4gICAgICBpZiAoY29udGVudFR5cGUpIHtcbiAgICAgICAgY29udGVudFR5cGUgPSBjb250ZW50VHlwZS5zcGxpdCgnOycpWzBdLnRyaW0oKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAkKCcucmVzcG9uc2VfYm9keScsICQodGhpcy5lbCkpLnJlbW92ZUNsYXNzKCdqc29uJyk7XG4gICAgJCgnLnJlc3BvbnNlX2JvZHknLCAkKHRoaXMuZWwpKS5yZW1vdmVDbGFzcygneG1sJyk7XG5cbiAgICB2YXIgc3VwcG9ydHNBdWRpb1BsYXliYWNrID0gZnVuY3Rpb24oY29udGVudFR5cGUpe1xuICAgICAgdmFyIGF1ZGlvRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2F1ZGlvJyk7XG4gICAgICByZXR1cm4gISEoYXVkaW9FbGVtZW50LmNhblBsYXlUeXBlICYmIGF1ZGlvRWxlbWVudC5jYW5QbGF5VHlwZShjb250ZW50VHlwZSkucmVwbGFjZSgvbm8vLCAnJykpO1xuICAgIH07XG5cbiAgICB2YXIgcHJlO1xuICAgIHZhciBjb2RlO1xuICAgIHZhciBza2lwSGlnaGxpZ2h0ID0gZmFsc2U7XG4gICAgaWYgKCFjb250ZW50KSB7XG4gICAgICBjb2RlID0gJCgnPGNvZGUgLz4nKS50ZXh0KCdubyBjb250ZW50Jyk7XG4gICAgICBwcmUgPSAkKCc8cHJlIGNsYXNzPVwianNvblwiIC8+JykuYXBwZW5kKGNvZGUpO1xuXG4gICAgICAvLyBKU09OXG4gICAgfSBlbHNlIGlmIChcbiAgICAgICAgY29udGVudFR5cGUgPT09ICdhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0nIHx8XG4gICAgICAgIGhlYWRlcnNbJ0NvbnRlbnQtRGlzcG9zaXRpb24nXSAmJiAoL2F0dGFjaG1lbnQvKS50ZXN0KGhlYWRlcnNbJ0NvbnRlbnQtRGlzcG9zaXRpb24nXSkgfHxcbiAgICAgICAgaGVhZGVyc1snY29udGVudC1kaXNwb3NpdGlvbiddICYmICgvYXR0YWNobWVudC8pLnRlc3QoaGVhZGVyc1snY29udGVudC1kaXNwb3NpdGlvbiddKSB8fFxuICAgICAgICBoZWFkZXJzWydDb250ZW50LURlc2NyaXB0aW9uJ10gJiYgKC9GaWxlIFRyYW5zZmVyLykudGVzdChoZWFkZXJzWydDb250ZW50LURlc2NyaXB0aW9uJ10pIHx8XG4gICAgICAgIGhlYWRlcnNbJ2NvbnRlbnQtZGVzY3JpcHRpb24nXSAmJiAoL0ZpbGUgVHJhbnNmZXIvKS50ZXN0KGhlYWRlcnNbJ2NvbnRlbnQtZGVzY3JpcHRpb24nXSkpIHtcblxuICAgICAgaWYgKCdCbG9iJyBpbiB3aW5kb3cpIHtcbiAgICAgICAgdmFyIHR5cGUgPSBjb250ZW50VHlwZSB8fCAndGV4dC9odG1sJztcbiAgICAgICAgdmFyIGEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7XG4gICAgICAgIHZhciBocmVmO1xuXG4gICAgICAgIGlmKHt9LnRvU3RyaW5nLmFwcGx5KGNvbnRlbnQpID09PSAnW29iamVjdCBCbG9iXScpIHtcbiAgICAgICAgICBocmVmID0gd2luZG93LlVSTC5jcmVhdGVPYmplY3RVUkwoY29udGVudCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgdmFyIGJpbmFyeURhdGEgPSBbXTtcbiAgICAgICAgICBiaW5hcnlEYXRhLnB1c2goY29udGVudCk7XG4gICAgICAgICAgaHJlZiA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKG5ldyBCbG9iKGJpbmFyeURhdGEsIHt0eXBlOiB0eXBlfSkpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBmaWxlTmFtZSA9IHJlc3BvbnNlLnVybC5zdWJzdHIocmVzcG9uc2UudXJsLmxhc3RJbmRleE9mKCcvJykgKyAxKTtcbiAgICAgICAgdmFyIGRvd25sb2FkID0gW3R5cGUsIGZpbGVOYW1lLCBocmVmXS5qb2luKCc6Jyk7XG5cbiAgICAgICAgLy8gVXNlIGZpbGVuYW1lIGZyb20gcmVzcG9uc2UgaGVhZGVyXG4gICAgICAgIHZhciBkaXNwb3NpdGlvbiA9IGhlYWRlcnNbJ2NvbnRlbnQtZGlzcG9zaXRpb24nXSB8fCBoZWFkZXJzWydDb250ZW50LURpc3Bvc2l0aW9uJ107XG4gICAgICAgIGlmKHR5cGVvZiBkaXNwb3NpdGlvbiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICB2YXIgcmVzcG9uc2VGaWxlbmFtZSA9IC9maWxlbmFtZT0oW147XSopOz8vLmV4ZWMoZGlzcG9zaXRpb24pO1xuICAgICAgICAgIGlmKHJlc3BvbnNlRmlsZW5hbWUgIT09IG51bGwgJiYgcmVzcG9uc2VGaWxlbmFtZS5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICBkb3dubG9hZCA9IHJlc3BvbnNlRmlsZW5hbWVbMV07XG4gICAgICAgICAgICBmaWxlTmFtZSA9IGRvd25sb2FkO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGEuc2V0QXR0cmlidXRlKCdocmVmJywgaHJlZik7XG4gICAgICAgIGEuc2V0QXR0cmlidXRlKCdkb3dubG9hZCcsIGRvd25sb2FkKTtcbiAgICAgICAgYS5pbm5lclRleHQgPSAnRG93bmxvYWQgJyArIGZpbGVOYW1lO1xuXG4gICAgICAgIHByZSA9ICQoJzxkaXYvPicpLmFwcGVuZChhKTtcbiAgICAgICAgc2tpcEhpZ2hsaWdodCA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwcmUgPSAkKCc8cHJlIGNsYXNzPVwianNvblwiIC8+JykuYXBwZW5kKCdEb3dubG9hZCBoZWFkZXJzIGRldGVjdGVkIGJ1dCB5b3VyIGJyb3dzZXIgZG9lcyBub3Qgc3VwcG9ydCBkb3dubG9hZGluZyBiaW5hcnkgdmlhIFhIUiAoQmxvYikuJyk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChjb250ZW50VHlwZSA9PT0gJ2FwcGxpY2F0aW9uL2pzb24nIHx8IC9cXCtqc29uJC8udGVzdChjb250ZW50VHlwZSkpIHtcbiAgICAgIHZhciBqc29uID0gbnVsbDtcbiAgICAgIHRyeSB7XG4gICAgICAgIGpzb24gPSBKU09OLnN0cmluZ2lmeShKU09OLnBhcnNlKGNvbnRlbnQpLCBudWxsLCAnICAnKTtcbiAgICAgIH0gY2F0Y2ggKF9lcnJvcikge1xuICAgICAgICBqc29uID0gJ2NhblxcJ3QgcGFyc2UgSlNPTi4gIFJhdyByZXN1bHQ6XFxuXFxuJyArIGNvbnRlbnQ7XG4gICAgICB9XG4gICAgICBjb2RlID0gJCgnPGNvZGUgLz4nKS50ZXh0KGpzb24pO1xuICAgICAgcHJlID0gJCgnPHByZSBjbGFzcz1cImpzb25cIiAvPicpLmFwcGVuZChjb2RlKTtcblxuICAgICAgLy8gWE1MXG4gICAgfSBlbHNlIGlmIChjb250ZW50VHlwZSA9PT0gJ2FwcGxpY2F0aW9uL3htbCcgfHwgL1xcK3htbCQvLnRlc3QoY29udGVudFR5cGUpKSB7XG4gICAgICBjb2RlID0gJCgnPGNvZGUgLz4nKS50ZXh0KHRoaXMuZm9ybWF0WG1sKGNvbnRlbnQpKTtcbiAgICAgIHByZSA9ICQoJzxwcmUgY2xhc3M9XCJ4bWxcIiAvPicpLmFwcGVuZChjb2RlKTtcblxuICAgICAgLy8gSFRNTFxuICAgIH0gZWxzZSBpZiAoY29udGVudFR5cGUgPT09ICd0ZXh0L2h0bWwnKSB7XG4gICAgICBjb2RlID0gJCgnPGNvZGUgLz4nKS5odG1sKF8uZXNjYXBlKGNvbnRlbnQpKTtcbiAgICAgIHByZSA9ICQoJzxwcmUgY2xhc3M9XCJ4bWxcIiAvPicpLmFwcGVuZChjb2RlKTtcblxuICAgICAgLy8gUGxhaW4gVGV4dFxuICAgIH0gZWxzZSBpZiAoL3RleHRcXC9wbGFpbi8udGVzdChjb250ZW50VHlwZSkpIHtcbiAgICAgIGNvZGUgPSAkKCc8Y29kZSAvPicpLnRleHQoY29udGVudCk7XG4gICAgICBwcmUgPSAkKCc8cHJlIGNsYXNzPVwicGxhaW5cIiAvPicpLmFwcGVuZChjb2RlKTtcblxuICAgICAgLy8gSW1hZ2VcbiAgICB9IGVsc2UgaWYgKC9eaW1hZ2VcXC8vLnRlc3QoY29udGVudFR5cGUpKSB7XG4gICAgICB2YXIgdXJsQ3JlYXRvciA9IHdpbmRvdy5VUkwgfHwgd2luZG93LndlYmtpdFVSTDtcbiAgICAgIHZhciBpbWFnZVVybCA9IHVybENyZWF0b3IuY3JlYXRlT2JqZWN0VVJMKGNvbnRlbnQpO1xuXG4gICAgICBwcmUgPSAkKCc8aW1nPicpLmF0dHIoICdzcmMnLCBpbWFnZVVybCk7XG4gICAgICAvLyBBdWRpb1xuICAgIH0gZWxzZSBpZiAoL15hdWRpb1xcLy8udGVzdChjb250ZW50VHlwZSkgJiYgc3VwcG9ydHNBdWRpb1BsYXliYWNrKGNvbnRlbnRUeXBlKSkge1xuICAgICAgcHJlID0gJCgnPGF1ZGlvIGNvbnRyb2xzPicpLmFwcGVuZCgkKCc8c291cmNlPicpLmF0dHIoJ3NyYycsIHVybCkuYXR0cigndHlwZScsIGNvbnRlbnRUeXBlKSk7XG4gICAgfSBlbHNlIGlmKGhlYWRlcnMubG9jYXRpb24gfHwgaGVhZGVycy5Mb2NhdGlvbikge1xuICAgICAgLy8gTG9jYXRpb24gaGVhZGVyIGJhc2VkIHJlZGlyZWN0IGRvd25sb2FkXG4gICAgICB3aW5kb3cubG9jYXRpb24gPSByZXNwb25zZS51cmw7XG5cbiAgICAgIC8vIEFueXRoaW5nIGVsc2UgKENPUlMpXG4gICAgfSBlbHNlIHtcbiAgICAgIGNvZGUgPSAkKCc8Y29kZSAvPicpLnRleHQoY29udGVudCk7XG4gICAgICBwcmUgPSAkKCc8cHJlIGNsYXNzPVwianNvblwiIC8+JykuYXBwZW5kKGNvZGUpO1xuICAgIH1cbiAgICB2YXIgcmVzcG9uc2VfYm9keSA9IHByZTtcbiAgICAkKCcucmVxdWVzdF91cmwnLCAkKHRoaXMuZWwpKS5odG1sKCc8cHJlPjwvcHJlPicpO1xuICAgICQoJy5yZXF1ZXN0X3VybCBwcmUnLCAkKHRoaXMuZWwpKS50ZXh0KHVybCk7XG4gICAgJCgnLnJlc3BvbnNlX2NvZGUnLCAkKHRoaXMuZWwpKS5odG1sKCc8cHJlPicgKyByZXNwb25zZS5zdGF0dXMgKyAnPC9wcmU+Jyk7XG4gICAgJCgnLnJlc3BvbnNlX2JvZHknLCAkKHRoaXMuZWwpKS5odG1sKHJlc3BvbnNlX2JvZHkpO1xuICAgICQoJy5yZXNwb25zZV9oZWFkZXJzJywgJCh0aGlzLmVsKSkuaHRtbCgnPHByZT4nICsgXy5lc2NhcGUoSlNPTi5zdHJpbmdpZnkocmVzcG9uc2UuaGVhZGVycywgbnVsbCwgJyAgJykpLnJlcGxhY2UoL1xcbi9nLCAnPGJyPicpICsgJzwvcHJlPicpO1xuICAgICQoJy5yZXNwb25zZScsICQodGhpcy5lbCkpLnNsaWRlRG93bigpO1xuICAgICQoJy5yZXNwb25zZV9oaWRlcicsICQodGhpcy5lbCkpLnNob3coKTtcbiAgICAkKCcucmVzcG9uc2VfdGhyb2JiZXInLCAkKHRoaXMuZWwpKS5oaWRlKCk7XG5cblxuICAgIC8vIGFkZHMgY3VybCBvdXRwdXRcbiAgICB2YXIgY3VybENvbW1hbmQgPSB0aGlzLm1vZGVsLmFzQ3VybCh0aGlzLm1hcCwge3Jlc3BvbnNlQ29udGVudFR5cGU6IGNvbnRlbnRUeXBlfSk7XG4gICAgY3VybENvbW1hbmQgPSBjdXJsQ29tbWFuZC5yZXBsYWNlKCchJywgJyYjMzM7Jyk7XG4gICAgJCggJ2Rpdi5jdXJsJywgJCh0aGlzLmVsKSkuaHRtbCgnPHByZT4nICsgXy5lc2NhcGUoY3VybENvbW1hbmQpICsgJzwvcHJlPicpO1xuXG4gICAgLy8gb25seSBoaWdobGlnaHQgdGhlIHJlc3BvbnNlIGlmIHJlc3BvbnNlIGlzIGxlc3MgdGhhbiB0aHJlc2hvbGQsIGRlZmF1bHQgc3RhdGUgaXMgaGlnaGxpZ2h0IHJlc3BvbnNlXG4gICAgdmFyIG9wdHMgPSB0aGlzLm9wdGlvbnMuc3dhZ2dlck9wdGlvbnM7XG5cbiAgICBpZiAob3B0cy5zaG93UmVxdWVzdEhlYWRlcnMpIHtcbiAgICAgIHZhciBmb3JtID0gJCgnLnNhbmRib3gnLCAkKHRoaXMuZWwpKSxcbiAgICAgICAgICBtYXAgPSB0aGlzLmdldElucHV0TWFwKGZvcm0pLFxuICAgICAgICAgIHJlcXVlc3RIZWFkZXJzID0gdGhpcy5tb2RlbC5nZXRIZWFkZXJQYXJhbXMobWFwKTtcbiAgICAgIGRlbGV0ZSByZXF1ZXN0SGVhZGVyc1snQ29udGVudC1UeXBlJ107XG4gICAgICAkKCcucmVxdWVzdF9oZWFkZXJzJywgJCh0aGlzLmVsKSkuaHRtbCgnPHByZT4nICsgXy5lc2NhcGUoSlNPTi5zdHJpbmdpZnkocmVxdWVzdEhlYWRlcnMsIG51bGwsICcgICcpKS5yZXBsYWNlKC9cXG4vZywgJzxicj4nKSArICc8L3ByZT4nKTtcbiAgICB9XG5cbiAgICAvLyBDYWxsIHVzZXItZGVmaW5lZCBob29rXG4gICAgaWYgKG9wdHMucmVzcG9uc2VIb29rcyAmJiBvcHRzLnJlc3BvbnNlSG9va3NbdGhpcy5uaWNrbmFtZV0pIHtcbiAgICAgIG9wdHMucmVzcG9uc2VIb29rc1t0aGlzLm5pY2tuYW1lXShyZXNwb25zZSwgdGhpcyk7XG4gICAgfVxuXG4gICAgdmFyIHJlc3BvbnNlX2JvZHlfZWwgPSAkKCcucmVzcG9uc2VfYm9keScsICQodGhpcy5lbCkpWzBdO1xuICAgIC8vIG9ubHkgaGlnaGxpZ2h0IHRoZSByZXNwb25zZSBpZiByZXNwb25zZSBpcyBsZXNzIHRoYW4gdGhyZXNob2xkLCBkZWZhdWx0IHN0YXRlIGlzIGhpZ2hsaWdodCByZXNwb25zZVxuICAgIGlmIChvcHRzLmhpZ2hsaWdodFNpemVUaHJlc2hvbGQgJiYgdHlwZW9mIHJlc3BvbnNlLmRhdGEgIT09ICd1bmRlZmluZWQnICYmIHJlc3BvbnNlLmRhdGEubGVuZ3RoID4gb3B0cy5oaWdobGlnaHRTaXplVGhyZXNob2xkIHx8IHNraXBIaWdobGlnaHQpIHtcbiAgICAgIHJldHVybiByZXNwb25zZV9ib2R5X2VsO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gaGxqcy5oaWdobGlnaHRCbG9jayhyZXNwb25zZV9ib2R5X2VsKTtcbiAgICB9XG4gIH0sXG5cbiAgdG9nZ2xlT3BlcmF0aW9uQ29udGVudDogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgdmFyIGVsZW0gPSAkKCcjJyArIERvY3MuZXNjYXBlUmVzb3VyY2VOYW1lKHRoaXMucGFyZW50SWQgKyAnXycgKyB0aGlzLm5pY2tuYW1lICsgJ19jb250ZW50JykpO1xuICAgIGlmIChlbGVtLmlzKCc6dmlzaWJsZScpKXtcbiAgICAgICQuYmJxLnB1c2hTdGF0ZSgnIy8nLCAyKTtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBEb2NzLmNvbGxhcHNlT3BlcmF0aW9uKGVsZW0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBEb2NzLmV4cGFuZE9wZXJhdGlvbihlbGVtKTtcbiAgICB9XG4gIH0sXG5cbiAgZ2V0VGV4dEFyZWFWYWx1ZTogZnVuY3Rpb24odGV4dEFyZWEpIHtcbiAgICB2YXIgcGFyYW0sIHBhcnNlZCwgcmVzdWx0LCBpO1xuICAgIGlmICh0ZXh0QXJlYS52YWx1ZSA9PT0gbnVsbCB8fCBqUXVlcnkudHJpbSh0ZXh0QXJlYS52YWx1ZSkubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcGFyYW0gPSB0aGlzLmdldFBhcmFtQnlOYW1lKHRleHRBcmVhLm5hbWUpO1xuICAgIGlmIChwYXJhbSAmJiBwYXJhbS50eXBlICYmIHBhcmFtLnR5cGUudG9Mb3dlckNhc2UoKSA9PT0gJ2FycmF5Jykge1xuICAgICAgcGFyc2VkID0gdGV4dEFyZWEudmFsdWUuc3BsaXQoJ1xcbicpO1xuICAgICAgcmVzdWx0ID0gW107XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgcGFyc2VkLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChwYXJzZWRbaV0gIT09IG51bGwgJiYgalF1ZXJ5LnRyaW0ocGFyc2VkW2ldKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgcmVzdWx0LnB1c2gocGFyc2VkW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdC5sZW5ndGggPiAwID8gcmVzdWx0IDogbnVsbDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRleHRBcmVhLnZhbHVlO1xuICAgIH1cbiAgfSxcblxuICBzaG93U25pcHBldDogZnVuY3Rpb24gKCkge1xuICAgIHZhciBjb250ZW50VHlwZUVsID0gdGhpcy4kKCdbbmFtZT1yZXNwb25zZUNvbnRlbnRUeXBlXScpO1xuICAgIHZhciB4bWxTbmlwcGV0RWwgPSB0aGlzLiQoJy5vcGVyYXRpb24tc3RhdHVzIC5zbmlwcGV0X3htbCwgLnJlc3BvbnNlLWNsYXNzIC5zbmlwcGV0X3htbCcpO1xuICAgIHZhciBqc29uU25pcHBldEVsID0gdGhpcy4kKCcub3BlcmF0aW9uLXN0YXR1cyAuc25pcHBldF9qc29uLCAucmVzcG9uc2UtY2xhc3MgLnNuaXBwZXRfanNvbicpO1xuICAgIHZhciBjb250ZW50VHlwZTtcblxuICAgIGlmICghY29udGVudFR5cGVFbC5sZW5ndGgpIHsgcmV0dXJuOyB9XG4gICAgY29udGVudFR5cGUgPSBjb250ZW50VHlwZUVsLnZhbCgpO1xuXG4gICAgaWYgKGNvbnRlbnRUeXBlLmluZGV4T2YoJ3htbCcpID4gLTEpIHtcbiAgICAgIHhtbFNuaXBwZXRFbC5zaG93KCk7XG4gICAgICBqc29uU25pcHBldEVsLmhpZGUoKTtcbiAgICB9IGVsc2Uge1xuICAgICAganNvblNuaXBwZXRFbC5zaG93KCk7XG4gICAgICB4bWxTbmlwcGV0RWwuaGlkZSgpO1xuICAgIH1cbiAgfSxcblxuICBnZXRQYXJhbUJ5TmFtZTogZnVuY3Rpb24obmFtZSkge1xuICAgIHZhciBpO1xuICAgIGlmICh0aGlzLm1vZGVsLnBhcmFtZXRlcnMpIHtcbiAgICAgIGZvcihpID0gMDsgaSA8IHRoaXMubW9kZWwucGFyYW1ldGVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAodGhpcy5tb2RlbC5wYXJhbWV0ZXJzW2ldLm5hbWUgPT09IG5hbWUpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5tb2RlbC5wYXJhbWV0ZXJzW2ldO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5Td2FnZ2VyVWkuVmlld3MuUGFyYW1ldGVyQ29udGVudFR5cGVWaWV3ID0gQmFja2JvbmUuVmlldy5leHRlbmQoe1xuICBpbml0aWFsaXplOiBmdW5jdGlvbiAgKCkge30sXG5cbiAgcmVuZGVyOiBmdW5jdGlvbigpe1xuICAgIHRoaXMubW9kZWwucGFyYW1ldGVyQ29udGVudFR5cGVJZCA9ICdwY3QnICsgTWF0aC5yYW5kb20oKTtcbiAgICAkKHRoaXMuZWwpLmh0bWwoSGFuZGxlYmFycy50ZW1wbGF0ZXMucGFyYW1ldGVyX2NvbnRlbnRfdHlwZSh0aGlzLm1vZGVsKSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxufSk7IiwiJ3VzZSBzdHJpY3QnO1xuXG5Td2FnZ2VyVWkuVmlld3MuUGFyYW1ldGVyVmlldyA9IEJhY2tib25lLlZpZXcuZXh0ZW5kKHtcbiAgZXZlbnRzOiB7XG4gICAgJ2NoYW5nZSBbbmFtZT1wYXJhbWV0ZXJDb250ZW50VHlwZV0nIDogJ3RvZ2dsZVBhcmFtZXRlclNuaXBwZXQnXG4gIH0sXG5cbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oKXtcbiAgICBIYW5kbGViYXJzLnJlZ2lzdGVySGVscGVyKCdpc0FycmF5JywgZnVuY3Rpb24ocGFyYW0sIG9wdHMpIHtcbiAgICAgIHZhciBwYXJhbVR5cGUgPSBwYXJhbS50eXBlICYmIHBhcmFtLnR5cGUudG9Mb3dlckNhc2UoKTtcbiAgICAgIGlmIChwYXJhbVR5cGUgPT09ICdhcnJheScgfHwgcGFyYW0uYWxsb3dNdWx0aXBsZSkge1xuICAgICAgICByZXR1cm4gb3B0cy5mbih0aGlzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBvcHRzLmludmVyc2UodGhpcyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0sXG5cbiAgcmVuZGVyOiBmdW5jdGlvbigpIHtcbiAgICB2YXIgdHlwZSA9IHRoaXMubW9kZWwudHlwZSB8fCB0aGlzLm1vZGVsLmRhdGFUeXBlO1xuICAgIHZhciBtb2RlbFR5cGUgPSB0aGlzLm1vZGVsLm1vZGVsU2lnbmF0dXJlLnR5cGU7XG4gICAgdmFyIG1vZGVsRGVmaW5pdGlvbnMgPSB0aGlzLm1vZGVsLm1vZGVsU2lnbmF0dXJlLmRlZmluaXRpb25zO1xuICAgIHZhciBzY2hlbWEgPSB0aGlzLm1vZGVsLnNjaGVtYSB8fCB7fTtcbiAgICB2YXIgY29uc3VtZXMgPSB0aGlzLm1vZGVsLmNvbnN1bWVzIHx8IFtdO1xuICAgIHZhciBzYW1wbGVKU09OLCBzaWduYXR1cmVWaWV3O1xuXG4gICAgaWYgKHR5cGVvZiB0eXBlID09PSAndW5kZWZpbmVkJykge1xuICAgICAgaWYgKHNjaGVtYS4kcmVmKSB7XG4gICAgICAgIHZhciByZWYgPSBzY2hlbWEuJHJlZjtcbiAgICAgICAgaWYgKHJlZi5pbmRleE9mKCcjL2RlZmluaXRpb25zLycpID09PSAwKSB7XG4gICAgICAgICAgdHlwZSA9IHJlZi5zdWJzdHJpbmcoJyMvZGVmaW5pdGlvbnMvJy5sZW5ndGgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHR5cGUgPSByZWY7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLm1vZGVsLnR5cGUgPSB0eXBlO1xuICAgIHRoaXMubW9kZWwucGFyYW1UeXBlID0gdGhpcy5tb2RlbC5pbiB8fCB0aGlzLm1vZGVsLnBhcmFtVHlwZTtcbiAgICB0aGlzLm1vZGVsLmlzQm9keSA9IHRoaXMubW9kZWwucGFyYW1UeXBlID09PSAnYm9keScgfHwgdGhpcy5tb2RlbC5pbiA9PT0gJ2JvZHknO1xuICAgIHRoaXMubW9kZWwuaXNGaWxlID0gdHlwZSAmJiB0eXBlLnRvTG93ZXJDYXNlKCkgPT09ICdmaWxlJztcblxuICAgIC8vIEFsbG93IGZvciBkZWZhdWx0ID09PSBmYWxzZVxuICAgIGlmKHR5cGVvZiB0aGlzLm1vZGVsLmRlZmF1bHQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB0aGlzLm1vZGVsLmRlZmF1bHQgPSB0aGlzLm1vZGVsLmRlZmF1bHRWYWx1ZTtcbiAgICB9XG5cbiAgICB0aGlzLm1vZGVsLmhhc0RlZmF1bHQgPSAodHlwZW9mIHRoaXMubW9kZWwuZGVmYXVsdCAhPT0gJ3VuZGVmaW5lZCcpO1xuICAgIHRoaXMubW9kZWwudmFsdWVJZCA9ICdtJyArIHRoaXMubW9kZWwubmFtZSArIE1hdGgucmFuZG9tKCk7XG5cbiAgICBpZiAodGhpcy5tb2RlbC5hbGxvd2FibGVWYWx1ZXMpIHtcbiAgICAgIHRoaXMubW9kZWwuaXNMaXN0ID0gdHJ1ZTtcbiAgICB9XG5cbiAgICB2YXIgaXNYTUwgPSB0aGlzLmNvbnRhaW5zKGNvbnN1bWVzLCAneG1sJyk7XG4gICAgdmFyIGlzSlNPTiA9IGlzWE1MID8gdGhpcy5jb250YWlucyhjb25zdW1lcywgJ2pzb24nKSA6IHRydWU7XG4gICAgc2FtcGxlSlNPTiA9IFN3YWdnZXJVaS5wYXJ0aWFscy5zaWduYXR1cmUuY3JlYXRlUGFyYW1ldGVySlNPTlNhbXBsZShtb2RlbFR5cGUsIG1vZGVsRGVmaW5pdGlvbnMpO1xuXG4gICAgdmFyIHRlbXBsYXRlID0gdGhpcy50ZW1wbGF0ZSgpO1xuICAgICQodGhpcy5lbCkuaHRtbCh0ZW1wbGF0ZSh0aGlzLm1vZGVsKSk7XG5cbiAgICB2YXIgc2lnbmF0dXJlTW9kZWwgPSB7XG4gICAgICBzYW1wbGVKU09OOiBpc0pTT04gPyBzYW1wbGVKU09OIDogZmFsc2UsXG4gICAgICBzYW1wbGVYTUw6IHNhbXBsZUpTT04gJiYgaXNYTUwgPyBTd2FnZ2VyVWkucGFydGlhbHMuc2lnbmF0dXJlLmNyZWF0ZVhNTFNhbXBsZSgnJywgc2NoZW1hLCBtb2RlbERlZmluaXRpb25zLCB0cnVlKSA6IGZhbHNlLFxuICAgICAgaXNQYXJhbTogdHJ1ZSxcbiAgICAgIHNpZ25hdHVyZTogU3dhZ2dlclVpLnBhcnRpYWxzLnNpZ25hdHVyZS5nZXRQYXJhbWV0ZXJNb2RlbFNpZ25hdHVyZShtb2RlbFR5cGUsIG1vZGVsRGVmaW5pdGlvbnMpLFxuICAgICAgZGVmYXVsdFJlbmRlcmluZzogdGhpcy5tb2RlbC5kZWZhdWx0UmVuZGVyaW5nXG4gICAgfTtcblxuICAgIGlmIChzYW1wbGVKU09OKSB7XG4gICAgICBzaWduYXR1cmVWaWV3ID0gbmV3IFN3YWdnZXJVaS5WaWV3cy5TaWduYXR1cmVWaWV3KHttb2RlbDogc2lnbmF0dXJlTW9kZWwsIHRhZ05hbWU6ICdkaXYnfSk7XG4gICAgICAkKCcubW9kZWwtc2lnbmF0dXJlJywgJCh0aGlzLmVsKSkuYXBwZW5kKHNpZ25hdHVyZVZpZXcucmVuZGVyKCkuZWwpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICQoJy5tb2RlbC1zaWduYXR1cmUnLCAkKHRoaXMuZWwpKS5odG1sKHRoaXMubW9kZWwuc2lnbmF0dXJlKTtcbiAgICB9XG5cbiAgICB2YXIgaXNQYXJhbSA9IGZhbHNlO1xuXG4gICAgaWYoIHRoaXMub3B0aW9ucy5zd2FnZ2VyT3B0aW9ucy5qc29uRWRpdG9yICYmIHRoaXMubW9kZWwuaXNCb2R5ICYmIHRoaXMubW9kZWwuc2NoZW1hKXtcbiAgICAgIHZhciAkc2VsZiA9ICQodGhpcy5lbCk7XG4gICAgICB0aGlzLm1vZGVsLmpzb25FZGl0b3IgPVxuICAgICAgICAvKiBnbG9iYWwgSlNPTkVkaXRvciAqL1xuICAgICAgICBuZXcgSlNPTkVkaXRvcigkKCcuZWRpdG9yX2hvbGRlcicsICRzZWxmKVswXSxcbiAgICAgICAgICAgICAgICAgICAgICAge3NjaGVtYTogdGhpcy5tb2RlbC5zY2hlbWEsIHN0YXJ0dmFsIDogdGhpcy5tb2RlbC5kZWZhdWx0LFxuICAgICAgICAgICAgICAgICAgICAgICAgYWpheDp0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgZGlzYWJsZV9wcm9wZXJ0aWVzOnRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNhYmxlX2VkaXRfanNvbjp0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgaWNvbmxpYjogJ3N3YWdnZXInIH0pO1xuICAgICAgLy8gVGhpcyBpcyBzbyB0aGF0IHRoZSBzaWduYXR1cmUgY2FuIHNlbmQgYmFjayB0aGUgc2FtcGxlIHRvIHRoZSBqc29uIGVkaXRvclxuICAgICAgLy8gVE9ETzogU2lnbmF0dXJlVmlldyBzaG91bGQgZXhwb3NlIGFuIGV2ZW50IFwib25TYW1wbGVDbGlja2VkXCIgaW5zdGVhZFxuICAgICAgc2lnbmF0dXJlTW9kZWwuanNvbkVkaXRvciA9IHRoaXMubW9kZWwuanNvbkVkaXRvcjtcbiAgICAgICQoJy5ib2R5LXRleHRhcmVhJywgJHNlbGYpLmhpZGUoKTtcbiAgICAgICQoJy5lZGl0b3JfaG9sZGVyJywgJHNlbGYpLnNob3coKTtcbiAgICAgICQoJy5wYXJhbWV0ZXItY29udGVudC10eXBlJywgJHNlbGYpXG4gICAgICAgIC5jaGFuZ2UoZnVuY3Rpb24oZSl7XG4gICAgICAgICAgICBpZihlLnRhcmdldC52YWx1ZSA9PT0gJ2FwcGxpY2F0aW9uL3htbCcpe1xuICAgICAgICAgICAgICAkKCcuYm9keS10ZXh0YXJlYScsICRzZWxmKS5zaG93KCk7XG4gICAgICAgICAgICAgICQoJy5lZGl0b3JfaG9sZGVyJywgJHNlbGYpLmhpZGUoKTtcbiAgICAgICAgICAgICAgdGhpcy5tb2RlbC5qc29uRWRpdG9yLmRpc2FibGUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAkKCcuYm9keS10ZXh0YXJlYScsICRzZWxmKS5oaWRlKCk7XG4gICAgICAgICAgICAgICQoJy5lZGl0b3JfaG9sZGVyJywgJHNlbGYpLnNob3coKTtcbiAgICAgICAgICAgICAgdGhpcy5tb2RlbC5qc29uRWRpdG9yLmVuYWJsZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cblxuXG4gICAgaWYgKHRoaXMubW9kZWwuaXNCb2R5KSB7XG4gICAgICBpc1BhcmFtID0gdHJ1ZTtcbiAgICB9XG5cbiAgICB2YXIgY29udGVudFR5cGVNb2RlbCA9IHtcbiAgICAgIGlzUGFyYW06IGlzUGFyYW1cbiAgICB9O1xuXG4gICAgY29udGVudFR5cGVNb2RlbC5jb25zdW1lcyA9IHRoaXMubW9kZWwuY29uc3VtZXM7XG5cbiAgICBpZiAoaXNQYXJhbSkge1xuICAgICAgdmFyIHBhcmFtZXRlckNvbnRlbnRUeXBlVmlldyA9IG5ldyBTd2FnZ2VyVWkuVmlld3MuUGFyYW1ldGVyQ29udGVudFR5cGVWaWV3KHttb2RlbDogY29udGVudFR5cGVNb2RlbH0pO1xuICAgICAgJCgnLnBhcmFtZXRlci1jb250ZW50LXR5cGUnLCAkKHRoaXMuZWwpKS5hcHBlbmQocGFyYW1ldGVyQ29udGVudFR5cGVWaWV3LnJlbmRlcigpLmVsKTtcbiAgICAgIHRoaXMudG9nZ2xlUGFyYW1ldGVyU25pcHBldCgpO1xuICAgIH1cblxuICAgIGVsc2Uge1xuICAgICAgdmFyIHJlc3BvbnNlQ29udGVudFR5cGVWaWV3ID0gbmV3IFN3YWdnZXJVaS5WaWV3cy5SZXNwb25zZUNvbnRlbnRUeXBlVmlldyh7bW9kZWw6IGNvbnRlbnRUeXBlTW9kZWx9KTtcbiAgICAgICQoJy5yZXNwb25zZS1jb250ZW50LXR5cGUnLCAkKHRoaXMuZWwpKS5hcHBlbmQocmVzcG9uc2VDb250ZW50VHlwZVZpZXcucmVuZGVyKCkuZWwpO1xuICAgICAgdGhpcy50b2dnbGVSZXNwb25zZVNuaXBwZXQoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfSxcblxuICBjb250YWluczogZnVuY3Rpb24gKGNvbnN1bWVzLCB0eXBlKSB7XG4gICAgcmV0dXJuIGNvbnN1bWVzLmZpbHRlcihmdW5jdGlvbiAodmFsKSB7XG4gICAgICBpZiAodmFsLmluZGV4T2YodHlwZSkgPiAtMSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9KS5sZW5ndGg7XG4gIH0sXG5cbiAgdG9nZ2xlUGFyYW1ldGVyU25pcHBldDogZnVuY3Rpb24gKCkge1xuICAgIHZhciBjb250ZW50VHlwZSA9IHRoaXMuJCgnW25hbWU9cGFyYW1ldGVyQ29udGVudFR5cGVdJykudmFsKCk7XG5cbiAgICB0aGlzLnRvZ2dsZVNuaXBwZXQoY29udGVudFR5cGUpO1xuICB9LFxuXG4gIHRvZ2dsZVJlc3BvbnNlU25pcHBldDogZnVuY3Rpb24gKCkge1xuICAgIHZhciBjb250ZW50RWwgPSB0aGlzLiQoJ1tuYW1lPXJlc3BvbnNlQ29udGVudFR5cGVdJyk7XG5cbiAgICBpZiAoIWNvbnRlbnRFbC5sZW5ndGgpIHsgcmV0dXJuOyB9XG5cbiAgICB0aGlzLnRvZ2dsZVNuaXBwZXQoY29udGVudEVsLnZhbCgpKTtcbiAgfSxcblxuICB0b2dnbGVTbmlwcGV0OiBmdW5jdGlvbiAodHlwZSkge1xuICAgIHR5cGUgPSB0eXBlIHx8ICcnO1xuICAgIGlmICh0eXBlLmluZGV4T2YoJ3htbCcpID4gLTEpIHtcbiAgICAgIHRoaXMuJCgnLnNuaXBwZXRfeG1sJykuc2hvdygpO1xuICAgICAgdGhpcy4kKCcuc25pcHBldF9qc29uJykuaGlkZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLiQoJy5zbmlwcGV0X2pzb24nKS5zaG93KCk7XG4gICAgICB0aGlzLiQoJy5zbmlwcGV0X3htbCcpLmhpZGUoKTtcbiAgICB9XG4gIH0sXG5cbiAgLy8gUmV0dXJuIGFuIGFwcHJvcHJpYXRlIHRlbXBsYXRlIGJhc2VkIG9uIGlmIHRoZSBwYXJhbWV0ZXIgaXMgYSBsaXN0LCByZWFkb25seSwgcmVxdWlyZWRcbiAgdGVtcGxhdGU6IGZ1bmN0aW9uKCl7XG4gICAgaWYgKHRoaXMubW9kZWwuaXNMaXN0KSB7XG4gICAgICByZXR1cm4gSGFuZGxlYmFycy50ZW1wbGF0ZXMucGFyYW1fbGlzdDtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHRoaXMub3B0aW9ucy5yZWFkT25seSkge1xuICAgICAgICBpZiAodGhpcy5tb2RlbC5yZXF1aXJlZCkge1xuICAgICAgICAgIHJldHVybiBIYW5kbGViYXJzLnRlbXBsYXRlcy5wYXJhbV9yZWFkb25seV9yZXF1aXJlZDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gSGFuZGxlYmFycy50ZW1wbGF0ZXMucGFyYW1fcmVhZG9ubHk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh0aGlzLm1vZGVsLnJlcXVpcmVkKSB7XG4gICAgICAgICAgcmV0dXJuIEhhbmRsZWJhcnMudGVtcGxhdGVzLnBhcmFtX3JlcXVpcmVkO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBIYW5kbGViYXJzLnRlbXBsYXRlcy5wYXJhbTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cbi8qIGpzaGludCAtVzEyMiAqL1xuU3dhZ2dlclVpLnBhcnRpYWxzLnNpZ25hdHVyZSA9IChmdW5jdGlvbiAoKSB7XG4gIC8vIGNvcHktcGFzdGVkIGZyb20gc3dhZ2dlci1qc1xuICB2YXIgcmVzb2x2ZVNjaGVtYSA9IGZ1bmN0aW9uIChzY2hlbWEpIHtcbiAgICBpZiAoXy5pc1BsYWluT2JqZWN0KHNjaGVtYS5zY2hlbWEpKSB7XG4gICAgICBzY2hlbWEgPSByZXNvbHZlU2NoZW1hKHNjaGVtYS5zY2hlbWEpO1xuICAgIH1cblxuICAgIHJldHVybiBzY2hlbWE7XG4gIH07XG5cbiAgLy8gY29weS1wYXN0ZWQgZnJvbSBzd2FnZ2VyLWpzXG4gIHZhciBzaW1wbGVSZWYgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIGlmICh0eXBlb2YgbmFtZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGlmIChuYW1lLmluZGV4T2YoJyMvZGVmaW5pdGlvbnMvJykgPT09IDApIHtcbiAgICAgIHJldHVybiBuYW1lLnN1YnN0cmluZygnIy9kZWZpbml0aW9ucy8nLmxlbmd0aCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBuYW1lO1xuICAgIH1cbiAgfTtcblxuICAvLyBjb3B5LXBhc3RlZCBmcm9tIHN3YWdnZXItanNcbiAgdmFyIGdldElubGluZU1vZGVsID0gZnVuY3Rpb24oaW5saW5lU3RyKSB7XG4gICAgaWYoL15JbmxpbmUgTW9kZWwgXFxkKyQvLnRlc3QoaW5saW5lU3RyKSAmJiB0aGlzLmlubGluZU1vZGVscykge1xuICAgICAgdmFyIGlkID0gcGFyc2VJbnQoaW5saW5lU3RyLnN1YnN0cignSW5saW5lIE1vZGVsJy5sZW5ndGgpLnRyaW0oKSwxMCk7IC8vXG4gICAgICB2YXIgbW9kZWwgPSB0aGlzLmlubGluZU1vZGVsc1tpZF07XG4gICAgICByZXR1cm4gbW9kZWw7XG4gICAgfVxuICAgIC8vIEknbSByZXR1cm5pbmcgbnVsbCBoZXJlLCBzaG91bGQgSSByYXRoZXIgdGhyb3cgYW4gZXJyb3I/XG4gICAgcmV0dXJuIG51bGw7XG4gIH07XG5cbiAgLy8gY29weS1wYXN0ZWQgZnJvbSBzd2FnZ2VyLWpzXG4gIHZhciBmb3JtYXRYbWwgPSBmdW5jdGlvbih4bWwpIHtcbiAgICB2YXIgY29udGV4cCwgZm4sIGZvcm1hdHRlZCwgaW5kZW50LCBsLCBsYXN0VHlwZSwgbGVuLCBsaW5lcywgbG4sIHBhZCwgcmVnLCB0cmFuc2l0aW9ucywgd3NleHA7XG4gICAgcmVnID0gLyg+KSg8KShcXC8qKS9nO1xuICAgIHdzZXhwID0gL1sgXSooLiopWyBdK1xcbi9nO1xuICAgIGNvbnRleHAgPSAvKDwuKz4pKC4rXFxuKS9nO1xuICAgIHhtbCA9IHhtbC5yZXBsYWNlKHJlZywgJyQxXFxuJDIkMycpLnJlcGxhY2Uod3NleHAsICckMVxcbicpLnJlcGxhY2UoY29udGV4cCwgJyQxXFxuJDInKTtcbiAgICBwYWQgPSAwO1xuICAgIGZvcm1hdHRlZCA9ICcnO1xuICAgIGxpbmVzID0geG1sLnNwbGl0KCdcXG4nKTtcbiAgICBpbmRlbnQgPSAwO1xuICAgIGxhc3RUeXBlID0gJ290aGVyJztcbiAgICB0cmFuc2l0aW9ucyA9IHtcbiAgICAgICdzaW5nbGUtPnNpbmdsZSc6IDAsXG4gICAgICAnc2luZ2xlLT5jbG9zaW5nJzogLTEsXG4gICAgICAnc2luZ2xlLT5vcGVuaW5nJzogMCxcbiAgICAgICdzaW5nbGUtPm90aGVyJzogMCxcbiAgICAgICdjbG9zaW5nLT5zaW5nbGUnOiAwLFxuICAgICAgJ2Nsb3NpbmctPmNsb3NpbmcnOiAtMSxcbiAgICAgICdjbG9zaW5nLT5vcGVuaW5nJzogMCxcbiAgICAgICdjbG9zaW5nLT5vdGhlcic6IDAsXG4gICAgICAnb3BlbmluZy0+c2luZ2xlJzogMSxcbiAgICAgICdvcGVuaW5nLT5jbG9zaW5nJzogMCxcbiAgICAgICdvcGVuaW5nLT5vcGVuaW5nJzogMSxcbiAgICAgICdvcGVuaW5nLT5vdGhlcic6IDEsXG4gICAgICAnb3RoZXItPnNpbmdsZSc6IDAsXG4gICAgICAnb3RoZXItPmNsb3NpbmcnOiAtMSxcbiAgICAgICdvdGhlci0+b3BlbmluZyc6IDAsXG4gICAgICAnb3RoZXItPm90aGVyJzogMFxuICAgIH07XG4gICAgZm4gPSBmdW5jdGlvbihsbikge1xuICAgICAgdmFyIGZyb21Ubywgaiwga2V5LCBwYWRkaW5nLCB0eXBlLCB0eXBlcywgdmFsdWU7XG4gICAgICB0eXBlcyA9IHtcbiAgICAgICAgc2luZ2xlOiBCb29sZWFuKGxuLm1hdGNoKC88LitcXC8+LykpLFxuICAgICAgICBjbG9zaW5nOiBCb29sZWFuKGxuLm1hdGNoKC88XFwvLis+LykpLFxuICAgICAgICBvcGVuaW5nOiBCb29sZWFuKGxuLm1hdGNoKC88W14hP10uKj4vKSlcbiAgICAgIH07XG4gICAgICB0eXBlID0gKChmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIHJlc3VsdHM7XG4gICAgICAgIHJlc3VsdHMgPSBbXTtcbiAgICAgICAgZm9yIChrZXkgaW4gdHlwZXMpIHtcbiAgICAgICAgICB2YWx1ZSA9IHR5cGVzW2tleV07XG4gICAgICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgICAgICByZXN1bHRzLnB1c2goa2V5KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdHM7XG4gICAgICB9KSgpKVswXTtcbiAgICAgIHR5cGUgPSB0eXBlID09PSB2b2lkIDAgPyAnb3RoZXInIDogdHlwZTtcbiAgICAgIGZyb21UbyA9IGxhc3RUeXBlICsgJy0+JyArIHR5cGU7XG4gICAgICBsYXN0VHlwZSA9IHR5cGU7XG4gICAgICBwYWRkaW5nID0gJyc7XG4gICAgICBpbmRlbnQgKz0gdHJhbnNpdGlvbnNbZnJvbVRvXTtcbiAgICAgIHBhZGRpbmcgPSAoKGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgbSwgcmVmMSwgcmVzdWx0cztcbiAgICAgICAgcmVzdWx0cyA9IFtdO1xuICAgICAgICBmb3IgKGogPSBtID0gMCwgcmVmMSA9IGluZGVudDsgMCA8PSByZWYxID8gbSA8IHJlZjEgOiBtID4gcmVmMTsgaiA9IDAgPD0gcmVmMSA/ICsrbSA6IC0tbSkge1xuICAgICAgICAgIHJlc3VsdHMucHVzaCgnICAnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0cztcbiAgICAgIH0pKCkpLmpvaW4oJycpO1xuICAgICAgaWYgKGZyb21UbyA9PT0gJ29wZW5pbmctPmNsb3NpbmcnKSB7XG4gICAgICAgIGZvcm1hdHRlZCA9IGZvcm1hdHRlZC5zdWJzdHIoMCwgZm9ybWF0dGVkLmxlbmd0aCAtIDEpICsgbG4gKyAnXFxuJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZvcm1hdHRlZCArPSBwYWRkaW5nICsgbG4gKyAnXFxuJztcbiAgICAgIH1cbiAgICB9O1xuICAgIGZvciAobCA9IDAsIGxlbiA9IGxpbmVzLmxlbmd0aDsgbCA8IGxlbjsgbCsrKSB7XG4gICAgICBsbiA9IGxpbmVzW2xdO1xuICAgICAgZm4obG4pO1xuICAgIH1cbiAgICByZXR1cm4gZm9ybWF0dGVkO1xuICB9O1xuXG4gIC8vIGNvcHktcGFzdGVkIGZyb20gc3dhZ2dlci1qc1xuICB2YXIgZ2V0TW9kZWxTaWduYXR1cmUgPSBmdW5jdGlvbiAobmFtZSwgc2NoZW1hLCBtb2RlbHMsIG1vZGVsUHJvcGVydHlNYWNybykge1xuICAgIHZhciBzdHJvbmdPcGVuID0gJzxzcGFuIGNsYXNzPVwic3Ryb25nXCI+JztcbiAgICB2YXIgc3Ryb25nQ2xvc2UgPSAnPC9zcGFuPic7XG5cbiAgICB2YXIgb3B0aW9uSHRtbCA9IGZ1bmN0aW9uIChsYWJlbCwgdmFsdWUpIHtcbiAgICAgIHJldHVybiAnPHRyPjx0ZCBjbGFzcz1cIm9wdGlvbk5hbWVcIj4nICsgbGFiZWwgKyAnOjwvdGQ+PHRkPicgKyB2YWx1ZSArICc8L3RkPjwvdHI+JztcbiAgICB9O1xuXG5cbiAgICAvLyBBbGxvdyBmb3IgaWdub3JpbmcgdGhlICduYW1lJyBhcmd1bWVudC4uLi4gc2hpZnRpbmcgdGhlIHJlc3RcbiAgICBpZihfLmlzT2JqZWN0KGFyZ3VtZW50c1swXSkpIHtcbiAgICAgIG5hbWUgPSB2b2lkIDA7XG4gICAgICBzY2hlbWEgPSBhcmd1bWVudHNbMF07XG4gICAgICBtb2RlbHMgPSBhcmd1bWVudHNbMV07XG4gICAgICBtb2RlbFByb3BlcnR5TWFjcm8gPSBhcmd1bWVudHNbMl07XG4gICAgfVxuXG4gICAgbW9kZWxzID0gbW9kZWxzIHx8IHt9O1xuXG4gICAgLy8gUmVzb2x2ZSB0aGUgc2NoZW1hIChIYW5kbGUgbmVzdGVkIHNjaGVtYXMpXG4gICAgc2NoZW1hID0gcmVzb2x2ZVNjaGVtYShzY2hlbWEpO1xuXG4gICAgLy8gUmV0dXJuIGZvciBlbXB0eSBvYmplY3RcbiAgICBpZihfLmlzRW1wdHkoc2NoZW1hKSkge1xuICAgICAgcmV0dXJuIHN0cm9uZ09wZW4gKyAnRW1wdHknICsgc3Ryb25nQ2xvc2U7XG4gICAgfVxuXG4gICAgLy8gRGVyZWZlcmVuY2UgJHJlZiBmcm9tICdtb2RlbHMnXG4gICAgaWYodHlwZW9mIHNjaGVtYS4kcmVmID09PSAnc3RyaW5nJykge1xuICAgICAgbmFtZSA9IHNpbXBsZVJlZihzY2hlbWEuJHJlZik7XG4gICAgICBzY2hlbWEgPSBtb2RlbHNbbmFtZV07XG4gICAgICBpZih0eXBlb2Ygc2NoZW1hID09PSAndW5kZWZpbmVkJylcbiAgICAgIHtcbiAgICAgICAgcmV0dXJuIHN0cm9uZ09wZW4gKyBuYW1lICsgJyBpcyBub3QgZGVmaW5lZCEnICsgc3Ryb25nQ2xvc2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYodHlwZW9mIG5hbWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICBuYW1lID0gc2NoZW1hLnRpdGxlIHx8ICdJbmxpbmUgTW9kZWwnO1xuICAgIH1cblxuICAgIC8vIElmIHdlIGFyZSBhIE1vZGVsIG9iamVjdC4uLiBhZGp1c3QgYWNjb3JkaW5nbHlcbiAgICBpZihzY2hlbWEuZGVmaW5pdGlvbikge1xuICAgICAgc2NoZW1hID0gc2NoZW1hLmRlZmluaXRpb247XG4gICAgfVxuXG4gICAgaWYodHlwZW9mIG1vZGVsUHJvcGVydHlNYWNybyAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgbW9kZWxQcm9wZXJ0eU1hY3JvID0gZnVuY3Rpb24ocHJvcCl7XG4gICAgICAgIHJldHVybiAocHJvcCB8fCB7fSkuZGVmYXVsdDtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgdmFyIHJlZmVyZW5jZXMgPSB7fTtcbiAgICB2YXIgc2Vlbk1vZGVscyA9IFtdO1xuICAgIHZhciBpbmxpbmVNb2RlbHMgPSAwO1xuXG4gICAgLy8gR2VuZXJhdGUgY3VycmVudCBIVE1MXG4gICAgdmFyIGh0bWwgPSBwcm9jZXNzTW9kZWwoc2NoZW1hLCBuYW1lKTtcblxuICAgIC8vIEdlbmVyYXRlIHJlZmVyZW5jZXMgSFRNTFxuICAgIHdoaWxlIChfLmtleXMocmVmZXJlbmNlcykubGVuZ3RoID4gMCkge1xuICAgICAgLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuICAgICAgXy5mb3JFYWNoKHJlZmVyZW5jZXMsIGZ1bmN0aW9uIChzY2hlbWEsIG5hbWUpIHtcbiAgICAgICAgdmFyIHNlZW5Nb2RlbCA9IF8uaW5kZXhPZihzZWVuTW9kZWxzLCBuYW1lKSA+IC0xO1xuXG4gICAgICAgIGRlbGV0ZSByZWZlcmVuY2VzW25hbWVdO1xuXG4gICAgICAgIGlmICghc2Vlbk1vZGVsKSB7XG4gICAgICAgICAgc2Vlbk1vZGVscy5wdXNoKG5hbWUpO1xuXG4gICAgICAgICAgaHRtbCArPSAnPGJyIC8+JyArIHByb2Nlc3NNb2RlbChzY2hlbWEsIG5hbWUpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIC8qIGpzaGludCBpZ25vcmU6ZW5kICovXG4gICAgfVxuXG4gICAgcmV0dXJuIGh0bWw7XG5cblxuICAgIGZ1bmN0aW9uIGFkZFJlZmVyZW5jZShzY2hlbWEsIG5hbWUsIHNraXBSZWYpIHtcbiAgICAgIHZhciBtb2RlbE5hbWUgPSBuYW1lO1xuICAgICAgdmFyIG1vZGVsO1xuXG4gICAgICBpZiAoc2NoZW1hLiRyZWYpIHtcbiAgICAgICAgbW9kZWxOYW1lID0gc2NoZW1hLnRpdGxlIHx8IHNpbXBsZVJlZihzY2hlbWEuJHJlZik7XG4gICAgICAgIG1vZGVsID0gbW9kZWxzW3NpbXBsZVJlZihzY2hlbWEuJHJlZildO1xuICAgICAgfSBlbHNlIGlmIChfLmlzVW5kZWZpbmVkKG5hbWUpKSB7XG4gICAgICAgIG1vZGVsTmFtZSA9IHNjaGVtYS50aXRsZSB8fCAnSW5saW5lIE1vZGVsICcgKyAoKytpbmxpbmVNb2RlbHMpO1xuICAgICAgICBtb2RlbCA9IHtkZWZpbml0aW9uOiBzY2hlbWF9O1xuICAgICAgfVxuXG4gICAgICBpZiAoc2tpcFJlZiAhPT0gdHJ1ZSkge1xuICAgICAgICByZWZlcmVuY2VzW21vZGVsTmFtZV0gPSBfLmlzVW5kZWZpbmVkKG1vZGVsKSA/IHt9IDogbW9kZWwuZGVmaW5pdGlvbjtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG1vZGVsTmFtZTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwcmltaXRpdmVUb0hUTUwoc2NoZW1hKSB7XG4gICAgICB2YXIgaHRtbCA9ICc8c3BhbiBjbGFzcz1cInByb3BUeXBlXCI+JztcbiAgICAgIHZhciB0eXBlID0gc2NoZW1hLnR5cGUgfHwgJ29iamVjdCc7XG5cbiAgICAgIGlmIChzY2hlbWEuJHJlZikge1xuICAgICAgICBodG1sICs9IGFkZFJlZmVyZW5jZShzY2hlbWEsIHNpbXBsZVJlZihzY2hlbWEuJHJlZikpO1xuICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnb2JqZWN0Jykge1xuICAgICAgICBpZiAoIV8uaXNVbmRlZmluZWQoc2NoZW1hLnByb3BlcnRpZXMpKSB7XG4gICAgICAgICAgaHRtbCArPSBhZGRSZWZlcmVuY2Uoc2NoZW1hKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBodG1sICs9ICdvYmplY3QnO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdhcnJheScpIHtcbiAgICAgICAgaHRtbCArPSAnQXJyYXlbJztcblxuICAgICAgICBpZiAoXy5pc0FycmF5KHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgICBodG1sICs9IF8ubWFwKHNjaGVtYS5pdGVtcywgYWRkUmVmZXJlbmNlKS5qb2luKCcsJyk7XG4gICAgICAgIH0gZWxzZSBpZiAoXy5pc1BsYWluT2JqZWN0KHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgICBpZiAoXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMuJHJlZikpIHtcbiAgICAgICAgICAgIGlmICghXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMudHlwZSkgJiYgXy5pbmRleE9mKFsnYXJyYXknLCAnb2JqZWN0J10sIHNjaGVtYS5pdGVtcy50eXBlKSA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgaHRtbCArPSBzY2hlbWEuaXRlbXMudHlwZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGh0bWwgKz0gYWRkUmVmZXJlbmNlKHNjaGVtYS5pdGVtcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGh0bWwgKz0gYWRkUmVmZXJlbmNlKHNjaGVtYS5pdGVtcywgc2ltcGxlUmVmKHNjaGVtYS5pdGVtcy4kcmVmKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUubG9nKCdBcnJheSB0eXBlXFwncyBcXCdpdGVtc1xcJyBzY2hlbWEgaXMgbm90IGFuIGFycmF5IG9yIGFuIG9iamVjdCwgY2Fubm90IHByb2Nlc3MnKTtcbiAgICAgICAgICBodG1sICs9ICdvYmplY3QnO1xuICAgICAgICB9XG5cbiAgICAgICAgaHRtbCArPSAnXSc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBodG1sICs9IHNjaGVtYS50eXBlO1xuICAgICAgfVxuXG4gICAgICBodG1sICs9ICc8L3NwYW4+JztcblxuICAgICAgcmV0dXJuIGh0bWw7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcHJpbWl0aXZlVG9PcHRpb25zSFRNTChzY2hlbWEsIGh0bWwpIHtcbiAgICAgIHZhciBvcHRpb25zID0gJyc7XG4gICAgICB2YXIgdHlwZSA9IHNjaGVtYS50eXBlIHx8ICdvYmplY3QnO1xuICAgICAgdmFyIGlzQXJyYXkgPSB0eXBlID09PSAnYXJyYXknO1xuXG4gICAgICBpZiAoIV8uaXNVbmRlZmluZWQoc2NoZW1hLmRlc2NyaXB0aW9uKSkge1xuICAgICAgICBodG1sICs9ICc6ICcgKyAnPHNwYW4gY2xhc3M9XCJwcm9wRGVzY1wiPicgKyBzY2hlbWEuZGVzY3JpcHRpb24gKyAnPC9zcGFuPic7XG4gICAgICB9XG5cbiAgICAgIGlmIChzY2hlbWEuZW51bSkge1xuICAgICAgICBodG1sICs9ICcgPSA8c3BhbiBjbGFzcz1cInByb3BWYWxzXCI+W1xcJycgKyBzY2hlbWEuZW51bS5qb2luKCdcXCcsIFxcJycpICsgJ1xcJ108L3NwYW4+JztcbiAgICAgIH1cblxuICAgICAgaWYgKGlzQXJyYXkpIHtcbiAgICAgICAgaWYgKF8uaXNQbGFpbk9iamVjdChzY2hlbWEuaXRlbXMpICYmICFfLmlzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcy50eXBlKSkge1xuICAgICAgICAgIHR5cGUgPSBzY2hlbWEuaXRlbXMudHlwZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0eXBlID0gJ29iamVjdCc7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKCFfLmlzVW5kZWZpbmVkKHNjaGVtYS5kZWZhdWx0KSkge1xuICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ0RlZmF1bHQnLCBzY2hlbWEuZGVmYXVsdCk7XG4gICAgICB9XG5cbiAgICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgY2FzZSAnc3RyaW5nJzpcbiAgICAgICAgaWYgKHNjaGVtYS5taW5MZW5ndGgpIHtcbiAgICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ01pbi4gTGVuZ3RoJywgc2NoZW1hLm1pbkxlbmd0aCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc2NoZW1hLm1heExlbmd0aCkge1xuICAgICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnTWF4LiBMZW5ndGgnLCBzY2hlbWEubWF4TGVuZ3RoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzY2hlbWEucGF0dGVybikge1xuICAgICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnUmVnLiBFeHAuJywgc2NoZW1hLnBhdHRlcm4pO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnaW50ZWdlcic6XG4gICAgICBjYXNlICdudW1iZXInOlxuICAgICAgICBpZiAoc2NoZW1hLm1pbmltdW0pIHtcbiAgICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ01pbi4gVmFsdWUnLCBzY2hlbWEubWluaW11bSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc2NoZW1hLmV4Y2x1c2l2ZU1pbmltdW0pIHtcbiAgICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ0V4Y2x1c2l2ZSBNaW4uJywgJ3RydWUnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzY2hlbWEubWF4aW11bSkge1xuICAgICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnTWF4LiBWYWx1ZScsIHNjaGVtYS5tYXhpbXVtKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzY2hlbWEuZXhjbHVzaXZlTWF4aW11bSkge1xuICAgICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnRXhjbHVzaXZlIE1heC4nLCAndHJ1ZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNjaGVtYS5tdWx0aXBsZU9mKSB7XG4gICAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdNdWx0aXBsZSBPZicsIHNjaGVtYS5tdWx0aXBsZU9mKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNBcnJheSkge1xuICAgICAgICBpZiAoc2NoZW1hLm1pbkl0ZW1zKSB7XG4gICAgICAgICAgb3B0aW9ucyArPSBvcHRpb25IdG1sKCdNaW4uIEl0ZW1zJywgc2NoZW1hLm1pbkl0ZW1zKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzY2hlbWEubWF4SXRlbXMpIHtcbiAgICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ01heC4gSXRlbXMnLCBzY2hlbWEubWF4SXRlbXMpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNjaGVtYS51bmlxdWVJdGVtcykge1xuICAgICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnVW5pcXVlIEl0ZW1zJywgJ3RydWUnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzY2hlbWEuY29sbGVjdGlvbkZvcm1hdCkge1xuICAgICAgICAgIG9wdGlvbnMgKz0gb3B0aW9uSHRtbCgnQ29sbC4gRm9ybWF0Jywgc2NoZW1hLmNvbGxlY3Rpb25Gb3JtYXQpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChfLmlzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgaWYgKF8uaXNBcnJheShzY2hlbWEuZW51bSkpIHtcbiAgICAgICAgICB2YXIgZW51bVN0cmluZztcblxuICAgICAgICAgIGlmICh0eXBlID09PSAnbnVtYmVyJyB8fCB0eXBlID09PSAnaW50ZWdlcicpIHtcbiAgICAgICAgICAgIGVudW1TdHJpbmcgPSBzY2hlbWEuZW51bS5qb2luKCcsICcpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBlbnVtU3RyaW5nID0gJ1wiJyArIHNjaGVtYS5lbnVtLmpvaW4oJ1wiLCBcIicpICsgJ1wiJztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBvcHRpb25zICs9IG9wdGlvbkh0bWwoJ0VudW0nLCBlbnVtU3RyaW5nKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAob3B0aW9ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGh0bWwgPSAnPHNwYW4gY2xhc3M9XCJwcm9wV3JhcFwiPicgKyBodG1sICsgJzx0YWJsZSBjbGFzcz1cIm9wdGlvbnNXcmFwcGVyXCI+PHRyPjx0aCBjb2xzcGFuPVwiMlwiPicgKyB0eXBlICsgJzwvdGg+PC90cj4nICsgb3B0aW9ucyArICc8L3RhYmxlPjwvc3Bhbj4nO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gaHRtbDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwcm9jZXNzTW9kZWwoc2NoZW1hLCBuYW1lKSB7XG4gICAgICB2YXIgdHlwZSA9IHNjaGVtYS50eXBlIHx8ICdvYmplY3QnO1xuICAgICAgdmFyIGlzQXJyYXkgPSBzY2hlbWEudHlwZSA9PT0gJ2FycmF5JztcbiAgICAgIHZhciBodG1sID0gc3Ryb25nT3BlbiArIG5hbWUgKyAnICcgKyAoaXNBcnJheSA/ICdbJyA6ICd7JykgKyBzdHJvbmdDbG9zZTtcbiAgICAgIHZhciBjb250ZW50cztcblxuICAgICAgaWYgKG5hbWUpIHtcbiAgICAgICAgc2Vlbk1vZGVscy5wdXNoKG5hbWUpO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNBcnJheSkge1xuICAgICAgICBpZiAoXy5pc0FycmF5KHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgICBodG1sICs9ICc8ZGl2PicgKyBfLm1hcChzY2hlbWEuaXRlbXMsIGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgICB2YXIgdHlwZSA9IGl0ZW0udHlwZSB8fCAnb2JqZWN0JztcblxuICAgICAgICAgICAgaWYgKF8uaXNVbmRlZmluZWQoaXRlbS4kcmVmKSkge1xuICAgICAgICAgICAgICBpZiAoXy5pbmRleE9mKFsnYXJyYXknLCAnb2JqZWN0J10sIHR5cGUpID4gLTEpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZSA9PT0gJ29iamVjdCcgJiYgXy5pc1VuZGVmaW5lZChpdGVtLnByb3BlcnRpZXMpKSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gJ29iamVjdCc7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBhZGRSZWZlcmVuY2UoaXRlbSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBwcmltaXRpdmVUb09wdGlvbnNIVE1MKGl0ZW0sIHR5cGUpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXR1cm4gYWRkUmVmZXJlbmNlKGl0ZW0sIHNpbXBsZVJlZihpdGVtLiRyZWYpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KS5qb2luKCcsPC9kaXY+PGRpdj4nKTtcbiAgICAgICAgfSBlbHNlIGlmIChfLmlzUGxhaW5PYmplY3Qoc2NoZW1hLml0ZW1zKSkge1xuICAgICAgICAgIGlmIChfLmlzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcy4kcmVmKSkge1xuICAgICAgICAgICAgaWYgKF8uaW5kZXhPZihbJ2FycmF5JywgJ29iamVjdCddLCBzY2hlbWEuaXRlbXMudHlwZSB8fCAnb2JqZWN0JykgPiAtMSkge1xuICAgICAgICAgICAgICBpZiAoKF8uaXNVbmRlZmluZWQoc2NoZW1hLml0ZW1zLnR5cGUpIHx8IHNjaGVtYS5pdGVtcy50eXBlID09PSAnb2JqZWN0JykgJiYgXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMucHJvcGVydGllcykpIHtcbiAgICAgICAgICAgICAgICBodG1sICs9ICc8ZGl2Pm9iamVjdDwvZGl2Pic7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaHRtbCArPSAnPGRpdj4nICsgYWRkUmVmZXJlbmNlKHNjaGVtYS5pdGVtcykgKyAnPC9kaXY+JztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgaHRtbCArPSAnPGRpdj4nICsgcHJpbWl0aXZlVG9PcHRpb25zSFRNTChzY2hlbWEuaXRlbXMsIHNjaGVtYS5pdGVtcy50eXBlKSArICc8L2Rpdj4nO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBodG1sICs9ICc8ZGl2PicgKyBhZGRSZWZlcmVuY2Uoc2NoZW1hLml0ZW1zLCBzaW1wbGVSZWYoc2NoZW1hLml0ZW1zLiRyZWYpKSArICc8L2Rpdj4nO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zb2xlLmxvZygnQXJyYXkgdHlwZVxcJ3MgXFwnaXRlbXNcXCcgcHJvcGVydHkgaXMgbm90IGFuIGFycmF5IG9yIGFuIG9iamVjdCwgY2Fubm90IHByb2Nlc3MnKTtcbiAgICAgICAgICBodG1sICs9ICc8ZGl2Pm9iamVjdDwvZGl2Pic7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChzY2hlbWEuJHJlZikge1xuICAgICAgICAgIGh0bWwgKz0gJzxkaXY+JyArIGFkZFJlZmVyZW5jZShzY2hlbWEsIG5hbWUpICsgJzwvZGl2Pic7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICBpZiAoXy5pc1BsYWluT2JqZWN0KHNjaGVtYS5wcm9wZXJ0aWVzKSkge1xuICAgICAgICAgICAgY29udGVudHMgPSBfLm1hcChzY2hlbWEucHJvcGVydGllcywgZnVuY3Rpb24gKHByb3BlcnR5LCBuYW1lKSB7XG4gICAgICAgICAgICAgIHZhciBwcm9wZXJ0eUlzUmVxdWlyZWQgPSAoXy5pbmRleE9mKHNjaGVtYS5yZXF1aXJlZCwgbmFtZSkgPj0gMCk7XG4gICAgICAgICAgICAgIHZhciBjUHJvcGVydHkgPSBfLmNsb25lRGVlcChwcm9wZXJ0eSk7XG5cbiAgICAgICAgICAgICAgdmFyIHJlcXVpcmVkQ2xhc3MgPSBwcm9wZXJ0eUlzUmVxdWlyZWQgPyAncmVxdWlyZWQnIDogJyc7XG4gICAgICAgICAgICAgIHZhciBodG1sID0gJzxzcGFuIGNsYXNzPVwicHJvcE5hbWUgJyArIHJlcXVpcmVkQ2xhc3MgKyAnXCI+JyArIG5hbWUgKyAnPC9zcGFuPiAoJztcbiAgICAgICAgICAgICAgdmFyIG1vZGVsO1xuXG4gICAgICAgICAgICAgIC8vIEFsbG93IG1hY3JvIHRvIHNldCB0aGUgZGVmYXVsdCB2YWx1ZVxuICAgICAgICAgICAgICBjUHJvcGVydHkuZGVmYXVsdCA9IG1vZGVsUHJvcGVydHlNYWNybyhjUHJvcGVydHkpO1xuXG4gICAgICAgICAgICAgIC8vIFJlc29sdmUgdGhlIHNjaGVtYSAoSGFuZGxlIG5lc3RlZCBzY2hlbWFzKVxuICAgICAgICAgICAgICBjUHJvcGVydHkgPSByZXNvbHZlU2NoZW1hKGNQcm9wZXJ0eSk7XG5cbiAgICAgICAgICAgICAgLy8gV2UgbmVlZCB0byBoYW5kbGUgcHJvcGVydHkgcmVmZXJlbmNlcyB0byBwcmltaXRpdmVzIChJc3N1ZSAzMzkpXG4gICAgICAgICAgICAgIGlmICghXy5pc1VuZGVmaW5lZChjUHJvcGVydHkuJHJlZikpIHtcbiAgICAgICAgICAgICAgICBtb2RlbCA9IG1vZGVsc1tzaW1wbGVSZWYoY1Byb3BlcnR5LiRyZWYpXTtcblxuICAgICAgICAgICAgICAgIGlmICghXy5pc1VuZGVmaW5lZChtb2RlbCkgJiYgXy5pbmRleE9mKFt1bmRlZmluZWQsICdhcnJheScsICdvYmplY3QnXSwgbW9kZWwuZGVmaW5pdGlvbi50eXBlKSA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgIC8vIFVzZSByZWZlcmVuY2VkIHNjaGVtYVxuICAgICAgICAgICAgICAgICAgY1Byb3BlcnR5ID0gcmVzb2x2ZVNjaGVtYShtb2RlbC5kZWZpbml0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBodG1sICs9IHByaW1pdGl2ZVRvSFRNTChjUHJvcGVydHkpO1xuXG4gICAgICAgICAgICAgIGlmKCFwcm9wZXJ0eUlzUmVxdWlyZWQpIHtcbiAgICAgICAgICAgICAgICBodG1sICs9ICcsIDxzcGFuIGNsYXNzPVwicHJvcE9wdEtleVwiPm9wdGlvbmFsPC9zcGFuPic7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBpZihwcm9wZXJ0eS5yZWFkT25seSkge1xuICAgICAgICAgICAgICAgICAgaHRtbCArPSAnLCA8c3BhbiBjbGFzcz1cInByb3BSZWFkT25seVwiPnJlYWQgb25seTwvc3Bhbj4nO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgaHRtbCArPSAnKSc7XG5cbiAgICAgICAgICAgICAgcmV0dXJuICc8ZGl2JyArIChwcm9wZXJ0eS5yZWFkT25seSA/ICcgY2xhc3M9XCJyZWFkT25seVwiJyA6ICcnKSArICc+JyArIHByaW1pdGl2ZVRvT3B0aW9uc0hUTUwoY1Byb3BlcnR5LCBodG1sKTtcbiAgICAgICAgICAgIH0pLmpvaW4oJyw8L2Rpdj4nKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoY29udGVudHMpIHtcbiAgICAgICAgICAgIGh0bWwgKz0gY29udGVudHMgKyAnPC9kaXY+JztcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaHRtbCArPSAnPGRpdj4nICsgcHJpbWl0aXZlVG9PcHRpb25zSFRNTChzY2hlbWEsIHR5cGUpICsgJzwvZGl2Pic7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGh0bWwgKyBzdHJvbmdPcGVuICsgKGlzQXJyYXkgPyAnXScgOiAnfScpICsgc3Ryb25nQ2xvc2U7XG4gICAgfVxuXG4gIH07XG5cbiAgLy8gY29weS1wYXN0ZWQgZnJvbSBzd2FnZ2VyLWpzXG4gIHZhciBzY2hlbWFUb0pTT04gPSBmdW5jdGlvbiAoc2NoZW1hLCBtb2RlbHMsIG1vZGVsc1RvSWdub3JlLCBtb2RlbFByb3BlcnR5TWFjcm8pIHtcbiAgICAvLyBSZXNvbHZlIHRoZSBzY2hlbWEgKEhhbmRsZSBuZXN0ZWQgc2NoZW1hcylcbiAgICBzY2hlbWEgPSByZXNvbHZlU2NoZW1hKHNjaGVtYSk7XG5cbiAgICBpZih0eXBlb2YgbW9kZWxQcm9wZXJ0eU1hY3JvICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICBtb2RlbFByb3BlcnR5TWFjcm8gPSBmdW5jdGlvbihwcm9wKXtcbiAgICAgICAgcmV0dXJuIChwcm9wIHx8IHt9KS5kZWZhdWx0O1xuICAgICAgfTtcbiAgICB9XG5cbiAgICBtb2RlbHNUb0lnbm9yZT0gbW9kZWxzVG9JZ25vcmUgfHwge307XG5cbiAgICB2YXIgdHlwZSA9IHNjaGVtYS50eXBlIHx8ICdvYmplY3QnO1xuICAgIHZhciBmb3JtYXQgPSBzY2hlbWEuZm9ybWF0O1xuICAgIHZhciBtb2RlbDtcbiAgICB2YXIgb3V0cHV0O1xuXG4gICAgaWYgKCFfLmlzVW5kZWZpbmVkKHNjaGVtYS5leGFtcGxlKSkge1xuICAgICAgb3V0cHV0ID0gc2NoZW1hLmV4YW1wbGU7XG4gICAgfSBlbHNlIGlmIChfLmlzVW5kZWZpbmVkKHNjaGVtYS5pdGVtcykgJiYgXy5pc0FycmF5KHNjaGVtYS5lbnVtKSkge1xuICAgICAgb3V0cHV0ID0gc2NoZW1hLmVudW1bMF07XG4gICAgfVxuXG4gICAgaWYgKF8uaXNVbmRlZmluZWQob3V0cHV0KSkge1xuICAgICAgaWYgKHNjaGVtYS4kcmVmKSB7XG4gICAgICAgIG1vZGVsID0gbW9kZWxzW3NpbXBsZVJlZihzY2hlbWEuJHJlZildO1xuXG4gICAgICAgIGlmICghXy5pc1VuZGVmaW5lZChtb2RlbCkpIHtcbiAgICAgICAgICBpZiAoXy5pc1VuZGVmaW5lZChtb2RlbHNUb0lnbm9yZVttb2RlbC5uYW1lXSkpIHtcbiAgICAgICAgICAgIG1vZGVsc1RvSWdub3JlW21vZGVsLm5hbWVdID0gbW9kZWw7XG4gICAgICAgICAgICBvdXRwdXQgPSBzY2hlbWFUb0pTT04obW9kZWwuZGVmaW5pdGlvbiwgbW9kZWxzLCBtb2RlbHNUb0lnbm9yZSwgbW9kZWxQcm9wZXJ0eU1hY3JvKTtcbiAgICAgICAgICAgIGRlbGV0ZSBtb2RlbHNUb0lnbm9yZVttb2RlbC5uYW1lXTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKG1vZGVsLnR5cGUgPT09ICdhcnJheScpIHtcbiAgICAgICAgICAgICAgb3V0cHV0ID0gW107XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBvdXRwdXQgPSB7fTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoIV8uaXNVbmRlZmluZWQoc2NoZW1hLmRlZmF1bHQpKSB7XG4gICAgICAgIG91dHB1dCA9IHNjaGVtYS5kZWZhdWx0O1xuICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgICBpZiAoZm9ybWF0ID09PSAnZGF0ZS10aW1lJykge1xuICAgICAgICAgIG91dHB1dCA9IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKTtcbiAgICAgICAgfSBlbHNlIGlmIChmb3JtYXQgPT09ICdkYXRlJykge1xuICAgICAgICAgIG91dHB1dCA9IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKS5zcGxpdCgnVCcpWzBdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG91dHB1dCA9ICdzdHJpbmcnO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdpbnRlZ2VyJykge1xuICAgICAgICBvdXRwdXQgPSAwO1xuICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJykge1xuICAgICAgICBvdXRwdXQgPSAwLjA7XG4gICAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdib29sZWFuJykge1xuICAgICAgICBvdXRwdXQgPSB0cnVlO1xuICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnb2JqZWN0Jykge1xuICAgICAgICBvdXRwdXQgPSB7fTtcblxuICAgICAgICBfLmZvckVhY2goc2NoZW1hLnByb3BlcnRpZXMsIGZ1bmN0aW9uIChwcm9wZXJ0eSwgbmFtZSkge1xuICAgICAgICAgIHZhciBjUHJvcGVydHkgPSBfLmNsb25lRGVlcChwcm9wZXJ0eSk7XG5cbiAgICAgICAgICAvLyBBbGxvdyBtYWNybyB0byBzZXQgdGhlIGRlZmF1bHQgdmFsdWVcbiAgICAgICAgICBjUHJvcGVydHkuZGVmYXVsdCA9IG1vZGVsUHJvcGVydHlNYWNybyhwcm9wZXJ0eSk7XG5cbiAgICAgICAgICBvdXRwdXRbbmFtZV0gPSBzY2hlbWFUb0pTT04oY1Byb3BlcnR5LCBtb2RlbHMsIG1vZGVsc1RvSWdub3JlLCBtb2RlbFByb3BlcnR5TWFjcm8pO1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2FycmF5Jykge1xuICAgICAgICBvdXRwdXQgPSBbXTtcblxuICAgICAgICBpZiAoXy5pc0FycmF5KHNjaGVtYS5pdGVtcykpIHtcbiAgICAgICAgICBfLmZvckVhY2goc2NoZW1hLml0ZW1zLCBmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgICAgb3V0cHV0LnB1c2goc2NoZW1hVG9KU09OKGl0ZW0sIG1vZGVscywgbW9kZWxzVG9JZ25vcmUsIG1vZGVsUHJvcGVydHlNYWNybykpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKF8uaXNQbGFpbk9iamVjdChzY2hlbWEuaXRlbXMpKSB7XG4gICAgICAgICAgb3V0cHV0LnB1c2goc2NoZW1hVG9KU09OKHNjaGVtYS5pdGVtcywgbW9kZWxzLCBtb2RlbHNUb0lnbm9yZSwgbW9kZWxQcm9wZXJ0eU1hY3JvKSk7XG4gICAgICAgIH0gZWxzZSBpZiAoXy5pc1VuZGVmaW5lZChzY2hlbWEuaXRlbXMpKSB7XG4gICAgICAgICAgb3V0cHV0LnB1c2goe30pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUubG9nKCdBcnJheSB0eXBlXFwncyBcXCdpdGVtc1xcJyBwcm9wZXJ0eSBpcyBub3QgYW4gYXJyYXkgb3IgYW4gb2JqZWN0LCBjYW5ub3QgcHJvY2VzcycpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG91dHB1dDtcbiAgfTtcblxuICAvLyBjb3B5LXBhc3RlZCBmcm9tIHN3YWdnZXItanNcbiAgdmFyIGNyZWF0ZUpTT05TYW1wbGUgPSBmdW5jdGlvbiAodmFsdWUsIG1vZGVsc1RvSWdub3JlKSB7XG4gICAgbW9kZWxzVG9JZ25vcmUgPSBtb2RlbHNUb0lnbm9yZSB8fCB7fTtcblxuICAgIG1vZGVsc1RvSWdub3JlW3ZhbHVlLm5hbWVdID0gdmFsdWU7XG5cbiAgICAvLyBSZXNwb25zZSBzdXBwb3J0XG4gICAgaWYgKHZhbHVlLmV4YW1wbGVzICYmIF8uaXNQbGFpbk9iamVjdCh2YWx1ZS5leGFtcGxlcykpIHtcbiAgICAgIHZhbHVlID0gXy5jbG9uZURlZXAodmFsdWUpO1xuICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyh2YWx1ZS5leGFtcGxlcyk7XG5cbiAgICAgIF8uZm9yRWFjaChrZXlzLCBmdW5jdGlvbihrZXkpIHtcbiAgICAgICAgaWYoa2V5LmluZGV4T2YoJ2FwcGxpY2F0aW9uL2pzb24nKSA9PT0gMCkge1xuICAgICAgICAgIHZhciBleGFtcGxlID0gdmFsdWUuZXhhbXBsZXNba2V5XTtcbiAgICAgICAgICBpZiAoXy5pc1N0cmluZyhleGFtcGxlKSkge1xuICAgICAgICAgICAgZXhhbXBsZSA9IGpzeWFtbC5zYWZlTG9hZChleGFtcGxlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdmFsdWUuZGVmaW5pdGlvbi5leGFtcGxlID0gZXhhbXBsZTtcbiAgICAgICAgICByZXR1cm4gc2NoZW1hVG9KU09OKHZhbHVlLmRlZmluaXRpb24sIGV4YW1wbGUsIG1vZGVsc1RvSWdub3JlLCB2YWx1ZS5tb2RlbFByb3BlcnR5TWFjcm8pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAodmFsdWUuZXhhbXBsZXMpIHtcbiAgICAgIHZhbHVlID0gXy5jbG9uZURlZXAodmFsdWUpO1xuICAgICAgdmFyIGV4YW1wbGUgPSB2YWx1ZS5leGFtcGxlcztcbiAgICAgIGlmIChfLmlzU3RyaW5nKGV4YW1wbGUpKSB7XG4gICAgICAgIGV4YW1wbGUgPSBqc3lhbWwuc2FmZUxvYWQoZXhhbXBsZSk7XG4gICAgICB9XG4gICAgICB2YWx1ZS5kZWZpbml0aW9uLmV4YW1wbGUgPSBleGFtcGxlO1xuICAgICAgcmV0dXJuIHNjaGVtYVRvSlNPTih2YWx1ZS5kZWZpbml0aW9uLCBleGFtcGxlLCBtb2RlbHNUb0lnbm9yZSwgdmFsdWUubW9kZWxQcm9wZXJ0eU1hY3JvKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc2NoZW1hVG9KU09OKHZhbHVlLmRlZmluaXRpb24sIHZhbHVlLm1vZGVscywgbW9kZWxzVG9JZ25vcmUsIHZhbHVlLm1vZGVsUHJvcGVydHlNYWNybyk7XG4gIH07XG5cbiAgLy8gY29weS1wYXN0ZWQgZnJvbSBzd2FnZ2VyLWpzXG4gIHZhciBnZXRQYXJhbWV0ZXJNb2RlbFNpZ25hdHVyZSA9IGZ1bmN0aW9uICh0eXBlLCBkZWZpbml0aW9ucykge1xuICAgICAgdmFyIGlzUHJpbWl0aXZlLCBsaXN0VHlwZTtcblxuICAgICAgaWYgKHR5cGUgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICBsaXN0VHlwZSA9IHRydWU7XG4gICAgICAgIHR5cGUgPSB0eXBlWzBdO1xuICAgICAgfVxuXG4gICAgICAvLyBDb252ZXJ0IHVuZGVmaW5lZCB0byBzdHJpbmcgb2YgJ3VuZGVmaW5lZCdcbiAgICAgIGlmICh0eXBlb2YgdHlwZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgdHlwZSA9ICd1bmRlZmluZWQnO1xuICAgICAgICBpc1ByaW1pdGl2ZSA9IHRydWU7XG5cbiAgICAgIH0gZWxzZSBpZiAoZGVmaW5pdGlvbnNbdHlwZV0pe1xuICAgICAgICAvLyBhIG1vZGVsIGRlZiBleGlzdHM/XG4gICAgICAgIHR5cGUgPSBkZWZpbml0aW9uc1t0eXBlXTsgLyogTW9kZWwgKi9cbiAgICAgICAgaXNQcmltaXRpdmUgPSBmYWxzZTtcblxuICAgICAgfSBlbHNlIGlmIChnZXRJbmxpbmVNb2RlbCh0eXBlKSkge1xuICAgICAgICB0eXBlID0gZ2V0SW5saW5lTW9kZWwodHlwZSk7IC8qIE1vZGVsICovXG4gICAgICAgIGlzUHJpbWl0aXZlID0gZmFsc2U7XG5cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFdlIGRlZmF1bHQgdG8gcHJpbWl0aXZlXG4gICAgICAgIGlzUHJpbWl0aXZlID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzUHJpbWl0aXZlKSB7XG4gICAgICAgIGlmIChsaXN0VHlwZSkge1xuICAgICAgICAgIHJldHVybiAnQXJyYXlbJyArIHR5cGUgKyAnXSc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHR5cGUudG9TdHJpbmcoKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGxpc3RUeXBlKSB7XG4gICAgICAgICAgcmV0dXJuICdBcnJheVsnICsgZ2V0TW9kZWxTaWduYXR1cmUodHlwZS5uYW1lLCB0eXBlLmRlZmluaXRpb24sIHR5cGUubW9kZWxzLCB0eXBlLm1vZGVsUHJvcGVydHlNYWNybykgKyAnXSc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIGdldE1vZGVsU2lnbmF0dXJlKHR5cGUubmFtZSwgdHlwZS5kZWZpbml0aW9uLCB0eXBlLm1vZGVscywgdHlwZS5tb2RlbFByb3BlcnR5TWFjcm8pO1xuICAgICAgICB9XG4gICAgICB9XG4gIH07XG5cbiAgLy8gY29weS1wYXN0ZWQgZnJvbSBzd2FnZ2VyLWpzXG4gIHZhciBjcmVhdGVQYXJhbWV0ZXJKU09OU2FtcGxlID0gZnVuY3Rpb24gKHR5cGUsIG1vZGVscykge1xuICAgIHZhciBsaXN0VHlwZSwgc2FtcGxlSnNvbiwgaW5uZXJUeXBlO1xuICAgIG1vZGVscyA9IG1vZGVscyB8fCB7fTtcblxuICAgIGxpc3RUeXBlID0gKHR5cGUgaW5zdGFuY2VvZiBBcnJheSk7XG4gICAgaW5uZXJUeXBlID0gbGlzdFR5cGUgPyB0eXBlWzBdIDogdHlwZTtcblxuICAgIGlmKG1vZGVsc1tpbm5lclR5cGVdKSB7XG4gICAgICBzYW1wbGVKc29uID0gY3JlYXRlSlNPTlNhbXBsZShtb2RlbHNbaW5uZXJUeXBlXSk7XG4gICAgfSBlbHNlIGlmIChnZXRJbmxpbmVNb2RlbChpbm5lclR5cGUpKXtcbiAgICAgIHNhbXBsZUpzb24gPSBjcmVhdGVKU09OU2FtcGxlKGdldElubGluZU1vZGVsKGlubmVyVHlwZSkpOyAvLyBtYXkgcmV0dXJuIG51bGwsIGlmIHR5cGUgaXNuJ3QgY29ycmVjdFxuICAgIH1cblxuXG4gICAgaWYgKHNhbXBsZUpzb24pIHtcbiAgICAgIHNhbXBsZUpzb24gPSBsaXN0VHlwZSA/IFtzYW1wbGVKc29uXSA6IHNhbXBsZUpzb247XG5cbiAgICAgIGlmICh0eXBlb2Ygc2FtcGxlSnNvbiA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIHNhbXBsZUpzb247XG4gICAgICB9IGVsc2UgaWYgKF8uaXNPYmplY3Qoc2FtcGxlSnNvbikpIHtcbiAgICAgICAgdmFyIHQgPSBzYW1wbGVKc29uO1xuXG4gICAgICAgIGlmIChzYW1wbGVKc29uIGluc3RhbmNlb2YgQXJyYXkgJiYgc2FtcGxlSnNvbi5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgdCA9IHNhbXBsZUpzb25bMF07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodC5ub2RlTmFtZSAmJiB0eXBlb2YgdCA9PT0gJ05vZGUnKSB7XG4gICAgICAgICAgdmFyIHhtbFN0cmluZyA9IG5ldyBYTUxTZXJpYWxpemVyKCkuc2VyaWFsaXplVG9TdHJpbmcodCk7XG5cbiAgICAgICAgICByZXR1cm4gZm9ybWF0WG1sKHhtbFN0cmluZyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHNhbXBsZUpzb24sIG51bGwsIDIpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gc2FtcGxlSnNvbjtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgdmFyIHdyYXBUYWcgPSBmdW5jdGlvbiAobmFtZSwgdmFsdWUsIGF0dHJzKSB7XG4gICAgdmFyIHN0ciwgYXR0cmlidXRlcztcblxuICAgIGF0dHJzID0gYXR0cnMgfHwgW107XG5cbiAgICBhdHRyaWJ1dGVzID0gYXR0cnMubWFwKGZ1bmN0aW9uIChhdHRyKSB7XG4gICAgICByZXR1cm4gJyAnICsgYXR0ci5uYW1lICsgJz1cIicgKyBhdHRyLnZhbHVlICsgJ1wiJztcbiAgICB9KS5qb2luKCcnKTtcblxuICAgIGlmICghbmFtZSkge1xuICAgICAgcmV0dXJuIGdldEVycm9yTWVzc2FnZSgnTm9kZSBuYW1lIGlzIG5vdCBwcm92aWRlZCcpO1xuICAgIH1cblxuICAgIHN0ciA9IFtcbiAgICAgICc8JywgbmFtZSxcbiAgICAgIGF0dHJpYnV0ZXMsXG4gICAgICAnPicsXG4gICAgICB2YWx1ZSxcbiAgICAgICc8LycsIG5hbWUsICc+J1xuICAgIF07XG5cbiAgICByZXR1cm4gc3RyLmpvaW4oJycpO1xuICB9O1xuXG4gIC8vIENvbW1lbnRpbmcgdGhpcyBmdW50aW9uIGFzIHRoZSBuYW1lcyBhcmUgbm93IGRldGVybWluZWQgYmVmb3JlaGFuZCBhbmQgdGhlIHByZWZpeCBwYXJ0IGlzIGV4cG9zZWQgYXMgYSBzZXBhcmF0ZSBmdW5jdGlvbiB8IGh0dHBzOi8vZ2l0aHViLmNvbS9zd2FnZ2VyLWFwaS9zd2FnZ2VyLXVpL2lzc3Vlcy8yNTc3XG4gLyoqIHZhciBnZXROYW1lID0gZnVuY3Rpb24gKG5hbWUsIHhtbCkge1xuICAgIHZhciByZXN1bHQgPSBuYW1lIHx8ICcnO1xuXG4gICAgeG1sID0geG1sIHx8IHt9O1xuXG4gICAgaWYgKHhtbC5uYW1lKSB7XG4gICAgICByZXN1bHQgPSB4bWwubmFtZTtcbiAgICB9XG5cbiAgICBpZiAoeG1sLnByZWZpeCkge1xuICAgICAgcmVzdWx0ID0geG1sLnByZWZpeCArICc6JyArIHJlc3VsdDtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuICAqL1xuICBcbiAgdmFyIGdldFByZWZpeCA9IGZ1bmN0aW9uIChuYW1lLCB4bWwpIHtcbiAgICB2YXIgcmVzdWx0ID0gbmFtZSB8fCAnJztcblxuICAgIHhtbCA9IHhtbCB8fCB7fTtcblxuICAgIGlmICh4bWwucHJlZml4KSB7XG4gICAgICByZXN1bHQgPSB4bWwucHJlZml4ICsgJzonICsgcmVzdWx0O1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG5cbiAgdmFyIGdldE5hbWVzcGFjZSA9IGZ1bmN0aW9uICh4bWwpIHtcbiAgICB2YXIgbmFtZXNwYWNlID0gJyc7XG4gICAgdmFyIG5hbWUgPSAneG1sbnMnO1xuXG4gICAgeG1sID0geG1sIHx8IHt9O1xuXG4gICAgaWYgKHhtbC5uYW1lc3BhY2UpIHtcbiAgICAgIG5hbWVzcGFjZSA9IHhtbC5uYW1lc3BhY2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBuYW1lc3BhY2U7XG4gICAgfVxuXG4gICAgaWYgKHhtbC5wcmVmaXgpIHtcbiAgICAgIG5hbWUgKz0gJzonICsgeG1sLnByZWZpeDtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgbmFtZTogbmFtZSxcbiAgICAgIHZhbHVlOiBuYW1lc3BhY2VcbiAgICB9O1xuICB9O1xuXG4gIHZhciBjcmVhdGVBcnJheVhNTCA9IGZ1bmN0aW9uIChkZXNjcmlwdG9yKSB7XG4gICAgdmFyIG5hbWUgPSBkZXNjcmlwdG9yLm5hbWU7XG4gICAgdmFyIGNvbmZpZyA9IGRlc2NyaXB0b3IuY29uZmlnO1xuICAgIHZhciBkZWZpbml0aW9uID0gZGVzY3JpcHRvci5kZWZpbml0aW9uO1xuICAgIHZhciBtb2RlbHMgPSBkZXNjcmlwdG9yLm1vZGVscztcbiAgICB2YXIgdmFsdWU7XG4gICAgdmFyIGl0ZW1zID0gZGVmaW5pdGlvbi5pdGVtcztcbiAgICB2YXIgeG1sID0gZGVmaW5pdGlvbi54bWwgfHwge307XG4gICAgdmFyIG5hbWVzcGFjZSA9IGdldE5hbWVzcGFjZSh4bWwpO1xuICAgIHZhciBhdHRyaWJ1dGVzID0gW107XG5cbiAgICBpZiAoIWl0ZW1zKSB7IHJldHVybiBnZXRFcnJvck1lc3NhZ2UoKTsgfVxuICAgIHZhciBrZXkgPSBuYW1lO1xuICAgIC8vIElmIHRoZXJlIGlzIGEgbmFtZSBzcGVjaWZpZWQgZm9yIHRoZSBhcnJheSBlbGVtZW50cywgdXNlIHRoYXQgZm9yIHRoZSBhcnJheSBlbGVtZW50cyBuYW1lIHwgaHR0cHM6Ly9naXRodWIuY29tL3N3YWdnZXItYXBpL3N3YWdnZXItdWkvaXNzdWVzLzI1NzdcbiAgICBpZihpdGVtcy54bWwgJiYgaXRlbXMueG1sLm5hbWUpIHtcbiAgICAgICAga2V5ID0gaXRlbXMueG1sLm5hbWU7XG4gICAgfVxuICAgIHZhbHVlID0gY3JlYXRlU2NoZW1hWE1MKGtleSwgaXRlbXMsIG1vZGVscywgY29uZmlnKTtcbiAgICBpZiAobmFtZXNwYWNlKSB7XG4gICAgICBhdHRyaWJ1dGVzLnB1c2gobmFtZXNwYWNlKTtcbiAgICB9XG5cbiAgICBpZiAoeG1sLndyYXBwZWQpIHtcbiAgICAgIHZhbHVlID0gd3JhcFRhZyhuYW1lLCB2YWx1ZSwgYXR0cmlidXRlcyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlO1xuICB9O1xuXG4gIHZhciBnZXRQcmltaXRpdmVTaWduYXR1cmUgPSBmdW5jdGlvbiAoc2NoZW1hKSB7XG4gICAgdmFyIHR5cGUsIGl0ZW1zO1xuXG4gICAgc2NoZW1hID0gc2NoZW1hIHx8IHt9O1xuICAgIGl0ZW1zID0gc2NoZW1hLml0ZW1zIHx8IHt9O1xuICAgIHR5cGUgPSBzY2hlbWEudHlwZSB8fCAnJztcblxuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgY2FzZSAnb2JqZWN0JzogcmV0dXJuICdPYmplY3QgaXMgbm90IGEgcHJpbWl0aXZlJztcbiAgICAgIGNhc2UgJ2FycmF5JyA6IHJldHVybiAnQXJyYXlbJyArIChpdGVtcy5mb3JtYXQgfHwgaXRlbXMudHlwZSkgKyAnXSc7XG4gICAgICBkZWZhdWx0OiByZXR1cm4gc2NoZW1hLmZvcm1hdCB8fCB0eXBlO1xuICAgIH1cbiAgfTtcblxuICB2YXIgY3JlYXRlUHJpbWl0aXZlWE1MID0gZnVuY3Rpb24gKGRlc2NyaXB0b3IpIHtcbiAgICB2YXIgbmFtZSA9IGRlc2NyaXB0b3IubmFtZTtcbiAgICB2YXIgZGVmaW5pdGlvbiA9IGRlc2NyaXB0b3IuZGVmaW5pdGlvbjtcbiAgICB2YXIgcHJpbWl0aXZlc01hcCA9IHtcbiAgICAgICdzdHJpbmcnOiB7XG4gICAgICAgICdkYXRlJzogbmV3IERhdGUoMSkudG9JU09TdHJpbmcoKS5zcGxpdCgnVCcpWzBdLFxuICAgICAgICAnZGF0ZS10aW1lJyA6IG5ldyBEYXRlKDEpLnRvSVNPU3RyaW5nKCksXG4gICAgICAgICdkZWZhdWx0JzogJ3N0cmluZydcbiAgICAgIH0sXG4gICAgICAnaW50ZWdlcic6IHtcbiAgICAgICAgJ2RlZmF1bHQnOiAxXG4gICAgICB9LFxuICAgICAgJ251bWJlcic6IHtcbiAgICAgICAgJ2RlZmF1bHQnOiAxLjFcbiAgICAgIH0sXG4gICAgICAnYm9vbGVhbic6IHtcbiAgICAgICAgJ2RlZmF1bHQnOiB0cnVlXG4gICAgICB9XG4gICAgfTtcbiAgICB2YXIgdHlwZSA9IGRlZmluaXRpb24udHlwZTtcbiAgICB2YXIgZm9ybWF0ID0gZGVmaW5pdGlvbi5mb3JtYXQ7XG4gICAgdmFyIHhtbCA9IGRlZmluaXRpb24ueG1sIHx8IHt9O1xuICAgIHZhciBuYW1lc3BhY2UgPSBnZXROYW1lc3BhY2UoeG1sKTtcbiAgICB2YXIgYXR0cmlidXRlcyA9IFtdO1xuICAgIHZhciB2YWx1ZTtcblxuICAgIGlmIChfLmtleXMocHJpbWl0aXZlc01hcCkuaW5kZXhPZih0eXBlKSA8IDApIHsgcmV0dXJuIGdldEVycm9yTWVzc2FnZSgpOyB9XG5cbiAgICBpZiAoXy5pc0FycmF5KGRlZmluaXRpb24uZW51bSkpe1xuICAgICAgdmFsdWUgPSBkZWZpbml0aW9uLmVudW1bMF07XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhbHVlID0gZGVmaW5pdGlvbi5leGFtcGxlIHx8IHByaW1pdGl2ZXNNYXBbdHlwZV1bZm9ybWF0XSB8fCBwcmltaXRpdmVzTWFwW3R5cGVdLmRlZmF1bHQ7XG4gICAgfVxuXG4gICAgaWYgKHhtbC5hdHRyaWJ1dGUpIHtcbiAgICAgIHJldHVybiB7bmFtZTogbmFtZSwgdmFsdWU6IHZhbHVlfTtcbiAgICB9XG5cbiAgICBpZiAobmFtZXNwYWNlKSB7XG4gICAgICBhdHRyaWJ1dGVzLnB1c2gobmFtZXNwYWNlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gd3JhcFRhZyhuYW1lLCB2YWx1ZSwgYXR0cmlidXRlcyk7XG4gIH07XG5cbiAgZnVuY3Rpb24gY3JlYXRlT2JqZWN0WE1MIChkZXNjcmlwdG9yKSB7XG4gICAgdmFyIG5hbWUgPSBkZXNjcmlwdG9yLm5hbWU7XG4gICAgdmFyIGRlZmluaXRpb24gPSBkZXNjcmlwdG9yLmRlZmluaXRpb247XG4gICAgdmFyIGNvbmZpZyA9IGRlc2NyaXB0b3IuY29uZmlnO1xuICAgIHZhciBtb2RlbHMgPSBkZXNjcmlwdG9yLm1vZGVscztcbiAgICB2YXIgaXNQYXJhbSA9IGRlc2NyaXB0b3IuY29uZmlnLmlzUGFyYW07XG4gICAgdmFyIHNlcmlhbGl6ZWRQcm9wZXJ0aWVzO1xuICAgIHZhciBhdHRycyA9IFtdO1xuICAgIHZhciBwcm9wZXJ0aWVzID0gZGVmaW5pdGlvbi5wcm9wZXJ0aWVzO1xuICAgIHZhciBhZGRpdGlvbmFsUHJvcGVydGllcyA9IGRlZmluaXRpb24uYWRkaXRpb25hbFByb3BlcnRpZXM7XG4gICAgdmFyIHhtbCA9IGRlZmluaXRpb24ueG1sO1xuICAgIHZhciBuYW1lc3BhY2UgPSBnZXROYW1lc3BhY2UoeG1sKTtcblxuICAgIGlmIChuYW1lc3BhY2UpIHtcbiAgICAgIGF0dHJzLnB1c2gobmFtZXNwYWNlKTtcbiAgICB9ICAgXG5cbiAgICBpZiAoIXByb3BlcnRpZXMgJiYgIWFkZGl0aW9uYWxQcm9wZXJ0aWVzKSB7IHJldHVybiBnZXRFcnJvck1lc3NhZ2UoKTsgfVxuXG4gICAgcHJvcGVydGllcyA9IHByb3BlcnRpZXMgfHwge307XG5cbiAgICBzZXJpYWxpemVkUHJvcGVydGllcyA9IF8ubWFwKHByb3BlcnRpZXMsIGZ1bmN0aW9uIChwcm9wLCBrZXkpIHtcbiAgICAgIHZhciB4bWwsIHJlc3VsdDtcblxuICAgICAgaWYgKGlzUGFyYW0gJiYgcHJvcC5yZWFkT25seSkge1xuICAgICAgICByZXR1cm4gJyc7XG4gICAgICB9XG5cbiAgICAgIHhtbCA9IHByb3AueG1sIHx8IHt9O1xuICAgICAgcmVzdWx0ID0gY3JlYXRlU2NoZW1hWE1MKGtleSwgcHJvcCwgbW9kZWxzLCBjb25maWcpO1xuXG4gICAgICBpZiAoeG1sLmF0dHJpYnV0ZSkge1xuICAgICAgICBhdHRycy5wdXNoKHJlc3VsdCk7XG4gICAgICAgIHJldHVybiAnJztcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9KS5qb2luKCcnKTtcblxuICAgIGlmIChhZGRpdGlvbmFsUHJvcGVydGllcykge1xuICAgICAgc2VyaWFsaXplZFByb3BlcnRpZXMgKz0gJzwhLS0gYWRkaXRpb25hbCBlbGVtZW50cyBhbGxvd2VkIC0tPic7XG4gICAgfVxuXG4gICAgcmV0dXJuIHdyYXBUYWcobmFtZSwgc2VyaWFsaXplZFByb3BlcnRpZXMsIGF0dHJzKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldEluZmluaXRlTG9vcE1lc3NhZ2UgKG5hbWUsIGxvb3BUbykge1xuICAgIHJldHVybiB3cmFwVGFnKG5hbWUsICc8IS0tIEluZmluaXRlIGxvb3AgJHJlZjonICsgbG9vcFRvICsgJyAtLT4nKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldEVycm9yTWVzc2FnZSAoZGV0YWlscykge1xuICAgIGRldGFpbHMgPSBkZXRhaWxzID8gJzogJyArIGRldGFpbHMgOiAnJztcbiAgICByZXR1cm4gJzwhLS0gaW52YWxpZCBYTUwnICsgZGV0YWlscyArICcgLS0+JztcbiAgfVxuXG4gIGZ1bmN0aW9uIGNyZWF0ZVNjaGVtYVhNTCAobmFtZSwgZGVmaW5pdGlvbiwgbW9kZWxzLCBjb25maWcpIHtcbiAgICB2YXIgJHJlZiA9IF8uaXNPYmplY3QoZGVmaW5pdGlvbikgPyBkZWZpbml0aW9uLiRyZWYgOiBudWxsO1xuICAgIHZhciBvdXRwdXQsIGluZGV4O1xuICAgIGNvbmZpZyA9IGNvbmZpZyB8fCB7fTtcbiAgICBjb25maWcubW9kZWxzVG9JZ25vcmUgPSBjb25maWcubW9kZWxzVG9JZ25vcmUgfHwgW107XG4gICBcbiAgICB2YXIgZGVzY3JpcHRvciA9IF8uaXNTdHJpbmcoJHJlZikgPyBnZXREZXNjcmlwdG9yQnlSZWYoJHJlZiwgbmFtZSwgbW9kZWxzLCBjb25maWcpXG4gICAgICAgIDogZ2V0RGVzY3JpcHRvcihuYW1lLCBkZWZpbml0aW9uLCBtb2RlbHMsIGNvbmZpZyk7XG4gICAgXG4gICAgaWYgKCFkZXNjcmlwdG9yKSB7XG4gICAgICByZXR1cm4gZ2V0RXJyb3JNZXNzYWdlKCk7XG4gICAgfVxuXG4gICAgc3dpdGNoIChkZXNjcmlwdG9yLnR5cGUpIHtcbiAgICAgIGNhc2UgJ2FycmF5JzpcbiAgICAgICAgb3V0cHV0ID0gY3JlYXRlQXJyYXlYTUwoZGVzY3JpcHRvcik7IGJyZWFrO1xuICAgICAgY2FzZSAnb2JqZWN0JzpcbiAgICAgICAgb3V0cHV0ID0gY3JlYXRlT2JqZWN0WE1MKGRlc2NyaXB0b3IpOyBicmVhaztcbiAgICAgIGNhc2UgJ2xvb3AnOlxuICAgICAgICBvdXRwdXQgPSBnZXRJbmZpbml0ZUxvb3BNZXNzYWdlKGRlc2NyaXB0b3IubmFtZSwgZGVzY3JpcHRvci5jb25maWcubG9vcFRvKTsgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBvdXRwdXQgPSBjcmVhdGVQcmltaXRpdmVYTUwoZGVzY3JpcHRvcik7XG4gICAgfVxuXG4gICAgaWYgKCRyZWYgJiYgZGVzY3JpcHRvci50eXBlICE9PSAnbG9vcCcpIHtcbiAgICAgIGluZGV4ID0gY29uZmlnLm1vZGVsc1RvSWdub3JlLmluZGV4T2YoJHJlZik7XG4gICAgICBpZiAoaW5kZXggPiAtMSkge1xuICAgICAgICBjb25maWcubW9kZWxzVG9JZ25vcmUuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gb3V0cHV0O1xuICB9XG5cbiAgZnVuY3Rpb24gRGVzY3JpcHRvciAobmFtZSwgdHlwZSwgZGVmaW5pdGlvbiwgbW9kZWxzLCBjb25maWcpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigpO1xuICAgIH1cbiAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZyB8fCB7fTtcbiAgICB0aGlzLmNvbmZpZy5tb2RlbHNUb0lnbm9yZSA9IHRoaXMuY29uZmlnLm1vZGVsc1RvSWdub3JlIHx8IFtdO1xuICAgIC8vIG5hbWUgaXMgYWxyZWFkeSBzZXQgYnkgZ2V0RGVzY3JpcHRvckJ5UmVmIG9yIGdldERlc2NyaXB0b3IgZnVuY3Rpb24gZGVwZW5kaW5nIG9uIHRoZSB0eXBlLiBPbmx5IHByZWZpeCwgaWYgcHJlc2VudCBpcyBuZWVkZWQgdG8gYmUgc2V0IGhlcmUgfCBodHRwczovL2dpdGh1Yi5jb20vc3dhZ2dlci1hcGkvc3dhZ2dlci11aS9pc3N1ZXMvMjU3N1xuICAgIHRoaXMubmFtZSA9IGdldFByZWZpeChuYW1lLCBkZWZpbml0aW9uLnhtbCk7XG4gICAgdGhpcy5kZWZpbml0aW9uID0gZGVmaW5pdGlvbjtcbiAgICB0aGlzLm1vZGVscyA9IG1vZGVscztcbiAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0RGVzY3JpcHRvckJ5UmVmKCRyZWYsIG5hbWUsIG1vZGVscywgY29uZmlnKSB7XG4gICAgdmFyIG1vZGVsVHlwZSA9IHNpbXBsZVJlZigkcmVmKTtcbiAgICB2YXIgbW9kZWwgPSBtb2RlbHNbbW9kZWxUeXBlXSB8fCB7fTtcbiAgICB2YXIgdHlwZSA9IG1vZGVsLmRlZmluaXRpb24gJiYgbW9kZWwuZGVmaW5pdGlvbi50eXBlID8gbW9kZWwuZGVmaW5pdGlvbi50eXBlIDogJ29iamVjdCc7XG4gICAgLy8gSWYgbW9kZWwgZGVmaW5pdGlvbiB4bWwgbmFtZSBpcyBwcmVzZW50LCB0aGVuIHRoYXQgd2lsbCBiZSBwcmVmZXJyZWQgb3ZlciBtb2RlbCBuYW1lLiBUaGlzIGlzIHRoZSBjYXNlIG9mIHByZWZlcnJpbmcgWG1sRWxlbWVudCBuYW1lIG92ZXIgWG1sUm9vdEVsZW1lbnQgbmFtZSBpZiBYbWxFbGVtZW50IG5hbWUgaXMgcHJvdmlkZWQgfCBodHRwczovL2dpdGh1Yi5jb20vc3dhZ2dlci1hcGkvc3dhZ2dlci11aS9pc3N1ZXMvMjU3N1xuICAgIGlmKG1vZGVsLmRlZmluaXRpb24gJiYgbW9kZWwuZGVmaW5pdGlvbi54bWwgJiYgbW9kZWwuZGVmaW5pdGlvbi54bWwubmFtZSkge1xuICAgICAgICBuYW1lID0gbmFtZSB8fCBtb2RlbC5kZWZpbml0aW9uLnhtbC5uYW1lIHx8IG1vZGVsLm5hbWU7XG4gICAgfVxuICAgIC8vIGVsc2Ugb25seSBtb2RlbCBuYW1lIHdpbGwgYmUgY29uc2lkZXJlZCBmb3IgZGV0ZXJtaW5hdGlvbiB8IGh0dHBzOi8vZ2l0aHViLmNvbS9zd2FnZ2VyLWFwaS9zd2FnZ2VyLXVpL2lzc3Vlcy8yNTc3XG4gICAgZWxzZSB7XG4gICAgICAgIG5hbWUgPSBuYW1lIHx8IG1vZGVsLm5hbWU7XG4gICAgfVxuICAgIFxuICAgIGlmIChjb25maWcubW9kZWxzVG9JZ25vcmUuaW5kZXhPZigkcmVmKSA+IC0xKSB7XG4gICAgICB0eXBlID0gJ2xvb3AnO1xuICAgICAgY29uZmlnLmxvb3BUbyA9IG1vZGVsVHlwZTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uZmlnLm1vZGVsc1RvSWdub3JlLnB1c2goJHJlZik7XG4gICAgfVxuXG4gICAgaWYgKCFtb2RlbC5kZWZpbml0aW9uKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBEZXNjcmlwdG9yKG5hbWUsIHR5cGUsIG1vZGVsLmRlZmluaXRpb24sIG1vZGVscywgY29uZmlnKTsgICAgXG4gIH1cblxuICBmdW5jdGlvbiBnZXREZXNjcmlwdG9yIChuYW1lLCBkZWZpbml0aW9uLCBtb2RlbHMsIGNvbmZpZyl7XG4gICAgdmFyIHR5cGUgPSBkZWZpbml0aW9uLnR5cGUgfHwgJ29iamVjdCc7XG4gICAgLy8gSWYgZGVmaW5pdGlvbiB4bWwgbmFtZSBpcyBwcmVzZW50LCB0aGVuIHRoYXQgd2lsbCBiZSBwcmVmZXJyZWQgb3ZlciBuYW1lIHwgaHR0cHM6Ly9naXRodWIuY29tL3N3YWdnZXItYXBpL3N3YWdnZXItdWkvaXNzdWVzLzI1NzdcbiAgICBpZihkZWZpbml0aW9uLnhtbCAmJiBkZWZpbml0aW9uLnhtbC5uYW1lKSB7XG4gICAgICAgIG5hbWUgPSBkZWZpbml0aW9uLnhtbC5uYW1lIHx8IG5hbWU7XG4gICAgfVxuICAgIGlmICghZGVmaW5pdGlvbikge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBEZXNjcmlwdG9yKG5hbWUsIHR5cGUsIGRlZmluaXRpb24sIG1vZGVscywgY29uZmlnKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNyZWF0ZVhNTFNhbXBsZSAobmFtZSwgZGVmaW5pdGlvbiwgbW9kZWxzLCBpc1BhcmFtKSB7XG4gICAgdmFyIHByb2xvZyA9ICc8P3htbCB2ZXJzaW9uPVwiMS4wXCI/Pic7XG5cbiAgICByZXR1cm4gZm9ybWF0WG1sKHByb2xvZyArIGNyZWF0ZVNjaGVtYVhNTChuYW1lLCBkZWZpbml0aW9uLCBtb2RlbHMsIHsgaXNQYXJhbTogaXNQYXJhbSB9ICkpO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICAgIGdldE1vZGVsU2lnbmF0dXJlOiBnZXRNb2RlbFNpZ25hdHVyZSxcbiAgICAgIGNyZWF0ZUpTT05TYW1wbGU6IGNyZWF0ZUpTT05TYW1wbGUsXG4gICAgICBnZXRQYXJhbWV0ZXJNb2RlbFNpZ25hdHVyZTogZ2V0UGFyYW1ldGVyTW9kZWxTaWduYXR1cmUsXG4gICAgICBjcmVhdGVQYXJhbWV0ZXJKU09OU2FtcGxlOiBjcmVhdGVQYXJhbWV0ZXJKU09OU2FtcGxlLFxuICAgICAgY3JlYXRlU2NoZW1hWE1MOiBjcmVhdGVTY2hlbWFYTUwsXG4gICAgICBjcmVhdGVYTUxTYW1wbGU6IGNyZWF0ZVhNTFNhbXBsZSxcbiAgICAgIGdldFByaW1pdGl2ZVNpZ25hdHVyZTogZ2V0UHJpbWl0aXZlU2lnbmF0dXJlXG4gIH07XG5cbn0pKCk7XG4iLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5WaWV3cy5Qb3B1cFZpZXcgPSBCYWNrYm9uZS5WaWV3LmV4dGVuZCh7XG4gICAgZXZlbnRzOiB7XG4gICAgICAgICdjbGljayAuYXBpLXBvcHVwLWNhbmNlbCc6ICdjYW5jZWxDbGljaydcbiAgICB9LFxuXG4gICAgdGVtcGxhdGU6IEhhbmRsZWJhcnMudGVtcGxhdGVzLnBvcHVwLFxuICAgIGNsYXNzTmFtZTogJ2FwaS1wb3B1cC1kaWFsb2cnLFxuXG4gICAgc2VsZWN0b3JzOiB7XG4gICAgICAgIGNvbnRlbnQ6ICcuYXBpLXBvcHVwLWNvbnRlbnQnLFxuICAgICAgICBtYWluICAgOiAnI3N3YWdnZXItdWktY29udGFpbmVyJ1xuICAgIH0sXG5cbiAgICBpbml0aWFsaXplOiBmdW5jdGlvbigpe1xuICAgICAgICB0aGlzLiRlbC5odG1sKHRoaXMudGVtcGxhdGUodGhpcy5tb2RlbCkpO1xuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy4kKHRoaXMuc2VsZWN0b3JzLmNvbnRlbnQpLmFwcGVuZCh0aGlzLm1vZGVsLmNvbnRlbnQpO1xuICAgICAgICAkKHRoaXMuc2VsZWN0b3JzLm1haW4pLmZpcnN0KCkuYXBwZW5kKHRoaXMuZWwpO1xuICAgICAgICB0aGlzLnNob3dQb3B1cCgpO1xuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICBzaG93UG9wdXA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy4kZWwuc2hvdygpO1xuICAgIH0sXG5cbiAgICBjYW5jZWxDbGljazogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnJlbW92ZSgpO1xuICAgIH1cblxufSk7XG4iLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5WaWV3cy5SZXNvdXJjZVZpZXcgPSBCYWNrYm9uZS5WaWV3LmV4dGVuZCh7XG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uKG9wdHMpIHtcbiAgICBvcHRzID0gb3B0cyB8fCB7fTtcbiAgICB0aGlzLnJvdXRlciA9IG9wdHMucm91dGVyO1xuICAgIHRoaXMuYXV0aHMgPSBvcHRzLmF1dGhzO1xuICAgIGlmICgnJyA9PT0gdGhpcy5tb2RlbC5kZXNjcmlwdGlvbikge1xuICAgICAgdGhpcy5tb2RlbC5kZXNjcmlwdGlvbiA9IG51bGw7XG4gICAgfVxuICAgIGlmICh0aGlzLm1vZGVsLmRlc2NyaXB0aW9uKSB7XG4gICAgICB0aGlzLm1vZGVsLnN1bW1hcnkgPSB0aGlzLm1vZGVsLmRlc2NyaXB0aW9uO1xuICAgIH1cbiAgICB0aGlzLm51bWJlciA9IDA7XG4gIH0sXG5cbiAgcmVuZGVyOiBmdW5jdGlvbigpe1xuICAgIHZhciBtZXRob2RzID0ge307XG5cblxuICAgICQodGhpcy5lbCkuaHRtbChIYW5kbGViYXJzLnRlbXBsYXRlcy5yZXNvdXJjZSh0aGlzLm1vZGVsKSk7XG5cbiAgICAvLyBSZW5kZXIgZWFjaCBvcGVyYXRpb25cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubW9kZWwub3BlcmF0aW9uc0FycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgb3BlcmF0aW9uID0gdGhpcy5tb2RlbC5vcGVyYXRpb25zQXJyYXlbaV07XG4gICAgICB2YXIgY291bnRlciA9IDA7XG4gICAgICB2YXIgaWQgPSBvcGVyYXRpb24ubmlja25hbWU7XG5cbiAgICAgIHdoaWxlICh0eXBlb2YgbWV0aG9kc1tpZF0gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGlkID0gaWQgKyAnXycgKyBjb3VudGVyO1xuICAgICAgICBjb3VudGVyICs9IDE7XG4gICAgICB9XG5cbiAgICAgIG1ldGhvZHNbaWRdID0gb3BlcmF0aW9uO1xuXG4gICAgICBvcGVyYXRpb24ubmlja25hbWUgPSBpZDtcbiAgICAgIG9wZXJhdGlvbi5wYXJlbnRJZCA9IHRoaXMubW9kZWwuaWQ7XG4gICAgICBvcGVyYXRpb24uZGVmaW5pdGlvbnMgPSB0aGlzLm1vZGVsLmRlZmluaXRpb25zOyAvLyBtYWtlIEpzb24gU2NoZW1hIGF2YWlsYWJsZSBmb3IgSlNvbkVkaXRvciBpbiB0aGlzIG9wZXJhdGlvblxuICAgICAgdGhpcy5hZGRPcGVyYXRpb24ob3BlcmF0aW9uKTtcbiAgICB9XG5cbiAgICAkKCcudG9nZ2xlRW5kcG9pbnRMaXN0JywgdGhpcy5lbCkuY2xpY2sodGhpcy5jYWxsRG9jcy5iaW5kKHRoaXMsICd0b2dnbGVFbmRwb2ludExpc3RGb3JSZXNvdXJjZScpKTtcbiAgICAkKCcuY29sbGFwc2VSZXNvdXJjZScsIHRoaXMuZWwpLmNsaWNrKHRoaXMuY2FsbERvY3MuYmluZCh0aGlzLCAnY29sbGFwc2VPcGVyYXRpb25zRm9yUmVzb3VyY2UnKSk7XG4gICAgJCgnLmV4cGFuZFJlc291cmNlJywgdGhpcy5lbCkuY2xpY2sodGhpcy5jYWxsRG9jcy5iaW5kKHRoaXMsICdleHBhbmRPcGVyYXRpb25zRm9yUmVzb3VyY2UnKSk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfSxcblxuICBhZGRPcGVyYXRpb246IGZ1bmN0aW9uKG9wZXJhdGlvbikge1xuXG4gICAgb3BlcmF0aW9uLm51bWJlciA9IHRoaXMubnVtYmVyO1xuXG4gICAgLy8gUmVuZGVyIGFuIG9wZXJhdGlvbiBhbmQgYWRkIGl0IHRvIG9wZXJhdGlvbnMgbGlcbiAgICB2YXIgb3BlcmF0aW9uVmlldyA9IG5ldyBTd2FnZ2VyVWkuVmlld3MuT3BlcmF0aW9uVmlldyh7XG4gICAgICBtb2RlbDogb3BlcmF0aW9uLFxuICAgICAgcm91dGVyOiB0aGlzLnJvdXRlcixcbiAgICAgIHRhZ05hbWU6ICdsaScsXG4gICAgICBjbGFzc05hbWU6ICdlbmRwb2ludCcsXG4gICAgICBzd2FnZ2VyT3B0aW9uczogdGhpcy5vcHRpb25zLnN3YWdnZXJPcHRpb25zLFxuICAgICAgYXV0aHM6IHRoaXMuYXV0aHNcbiAgICB9KTtcblxuICAgICQoJy5lbmRwb2ludHMnLCAkKHRoaXMuZWwpKS5hcHBlbmQob3BlcmF0aW9uVmlldy5yZW5kZXIoKS5lbCk7XG5cbiAgICB0aGlzLm51bWJlcisrO1xuXG4gIH0sXG4gIC8vIEdlbmVyaWMgRXZlbnQgaGFuZGxlciAoYERvY3NgIGlzIGdsb2JhbClcblxuXG4gIGNhbGxEb2NzOiBmdW5jdGlvbihmbk5hbWUsIGUpIHtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgRG9jc1tmbk5hbWVdKGUuY3VycmVudFRhcmdldC5nZXRBdHRyaWJ1dGUoJ2RhdGEtaWQnKSk7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5Td2FnZ2VyVWkuVmlld3MuUmVzcG9uc2VDb250ZW50VHlwZVZpZXcgPSBCYWNrYm9uZS5WaWV3LmV4dGVuZCh7XG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uKCl7fSxcblxuICByZW5kZXI6IGZ1bmN0aW9uKCl7XG4gICAgdGhpcy5tb2RlbC5yZXNwb25zZUNvbnRlbnRUeXBlSWQgPSAncmN0JyArIE1hdGgucmFuZG9tKCk7XG4gICAgJCh0aGlzLmVsKS5odG1sKEhhbmRsZWJhcnMudGVtcGxhdGVzLnJlc3BvbnNlX2NvbnRlbnRfdHlwZSh0aGlzLm1vZGVsKSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbn0pOyIsIid1c2Ugc3RyaWN0JztcblxuU3dhZ2dlclVpLlZpZXdzLlNpZ25hdHVyZVZpZXcgPSBCYWNrYm9uZS5WaWV3LmV4dGVuZCh7XG4gIGV2ZW50czoge1xuICAgICdjbGljayBhLmRlc2NyaXB0aW9uLWxpbmsnICAgICAgIDogJ3N3aXRjaFRvRGVzY3JpcHRpb24nLFxuICAgICdjbGljayBhLnNuaXBwZXQtbGluaycgICAgICAgICAgIDogJ3N3aXRjaFRvU25pcHBldCcsXG4gICAgJ21vdXNlZG93biAuc25pcHBldF9qc29uJyAgICAgICAgICA6ICdqc29uU25pcHBldE1vdXNlRG93bicsXG4gICAgJ21vdXNlZG93biAuc25pcHBldF94bWwnICAgICAgICAgIDogJ3htbFNuaXBwZXRNb3VzZURvd24nXG4gIH0sXG5cbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKCkge1xuICB9LFxuXG4gIHJlbmRlcjogZnVuY3Rpb24oKXtcblxuICAgICQodGhpcy5lbCkuaHRtbChIYW5kbGViYXJzLnRlbXBsYXRlcy5zaWduYXR1cmUodGhpcy5tb2RlbCkpO1xuXG4gICAgaWYgKHRoaXMubW9kZWwuZGVmYXVsdFJlbmRlcmluZyA9PT0gJ21vZGVsJykge1xuICAgICAgdGhpcy5zd2l0Y2hUb0Rlc2NyaXB0aW9uKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc3dpdGNoVG9TbmlwcGV0KCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG5cbiAgLy8gaGFuZGxlciBmb3Igc2hvdyBzaWduYXR1cmVcbiAgc3dpdGNoVG9EZXNjcmlwdGlvbjogZnVuY3Rpb24oZSl7XG4gICAgaWYgKGUpIHsgZS5wcmV2ZW50RGVmYXVsdCgpOyB9XG5cbiAgICAkKCcuc25pcHBldCcsICQodGhpcy5lbCkpLmhpZGUoKTtcbiAgICAkKCcuZGVzY3JpcHRpb24nLCAkKHRoaXMuZWwpKS5zaG93KCk7XG4gICAgJCgnLmRlc2NyaXB0aW9uLWxpbmsnLCAkKHRoaXMuZWwpKS5hZGRDbGFzcygnc2VsZWN0ZWQnKTtcbiAgICAkKCcuc25pcHBldC1saW5rJywgJCh0aGlzLmVsKSkucmVtb3ZlQ2xhc3MoJ3NlbGVjdGVkJyk7XG4gIH0sXG5cbiAgLy8gaGFuZGxlciBmb3Igc2hvdyBzYW1wbGVcbiAgc3dpdGNoVG9TbmlwcGV0OiBmdW5jdGlvbihlKXtcbiAgICBpZiAoZSkgeyBlLnByZXZlbnREZWZhdWx0KCk7IH1cblxuICAgICQoJy5zbmlwcGV0JywgJCh0aGlzLmVsKSkuc2hvdygpO1xuICAgICQoJy5kZXNjcmlwdGlvbicsICQodGhpcy5lbCkpLmhpZGUoKTtcbiAgICAkKCcuc25pcHBldC1saW5rJywgJCh0aGlzLmVsKSkuYWRkQ2xhc3MoJ3NlbGVjdGVkJyk7XG4gICAgJCgnLmRlc2NyaXB0aW9uLWxpbmsnLCAkKHRoaXMuZWwpKS5yZW1vdmVDbGFzcygnc2VsZWN0ZWQnKTtcbiAgfSxcblxuICAvLyBoYW5kbGVyIGZvciBzbmlwcGV0IHRvIHRleHQgYXJlYVxuICBzbmlwcGV0VG9UZXh0QXJlYTogZnVuY3Rpb24odmFsKSB7XG4gICAgdmFyIHRleHRBcmVhID0gJCgndGV4dGFyZWEnLCAkKHRoaXMuZWwucGFyZW50Tm9kZS5wYXJlbnROb2RlLnBhcmVudE5vZGUpKTtcblxuICAgIC8vIEZpeCBmb3IgYnVnIGluIElFIDEwLzExIHdoaWNoIGNhdXNlcyBwbGFjZWhvbGRlciB0ZXh0IHRvIGJlIGNvcGllZCB0byBcInZhbHVlXCJcbiAgICBpZiAoJC50cmltKHRleHRBcmVhLnZhbCgpKSA9PT0gJycgfHwgdGV4dEFyZWEucHJvcCgncGxhY2Vob2xkZXInKSA9PT0gdGV4dEFyZWEudmFsKCkpIHtcbiAgICAgIHRleHRBcmVhLnZhbCh2YWwpO1xuICAgICAgLy8gVE9ETyBtb3ZlIHRoaXMgY29kZSBvdXRzaWRlIG9mIHRoZSB2aWV3IGFuZCBleHBvc2UgYW4gZXZlbnQgaW5zdGVhZFxuICAgICAgaWYoIHRoaXMubW9kZWwuanNvbkVkaXRvciAmJiB0aGlzLm1vZGVsLmpzb25FZGl0b3IuaXNFbmFibGVkKCkpe1xuICAgICAgICB0aGlzLm1vZGVsLmpzb25FZGl0b3Iuc2V0VmFsdWUoSlNPTi5wYXJzZSh0aGlzLm1vZGVsLnNhbXBsZUpTT04pKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sXG5cbiAganNvblNuaXBwZXRNb3VzZURvd246IGZ1bmN0aW9uIChlKSB7XG4gICAgaWYgKHRoaXMubW9kZWwuaXNQYXJhbSkge1xuICAgICAgaWYgKGUpIHsgZS5wcmV2ZW50RGVmYXVsdCgpOyB9XG5cbiAgICAgIHRoaXMuc25pcHBldFRvVGV4dEFyZWEodGhpcy5tb2RlbC5zYW1wbGVKU09OKTtcbiAgICB9XG4gIH0sXG5cbiAgeG1sU25pcHBldE1vdXNlRG93bjogZnVuY3Rpb24gKGUpIHtcbiAgICBpZiAodGhpcy5tb2RlbC5pc1BhcmFtKSB7XG4gICAgICBpZiAoZSkgeyBlLnByZXZlbnREZWZhdWx0KCk7IH1cblxuICAgICAgdGhpcy5zbmlwcGV0VG9UZXh0QXJlYSh0aGlzLm1vZGVsLnNhbXBsZVhNTCk7XG4gICAgfVxuICB9XG59KTsiLCIndXNlIHN0cmljdCc7XG5cblN3YWdnZXJVaS5WaWV3cy5TdGF0dXNDb2RlVmlldyA9IEJhY2tib25lLlZpZXcuZXh0ZW5kKHtcbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24gKG9wdHMpIHtcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRzIHx8IHt9O1xuICAgIHRoaXMucm91dGVyID0gdGhpcy5vcHRpb25zLnJvdXRlcjtcbiAgfSxcblxuICByZW5kZXI6IGZ1bmN0aW9uKCl7XG4gICAgdmFyIHJlc3BvbnNlTW9kZWwsIHJlc3BvbnNlTW9kZWxWaWV3O1xuICAgIHZhciB2YWx1ZSA9IHRoaXMucm91dGVyLmFwaS5tb2RlbHNbdGhpcy5tb2RlbC5yZXNwb25zZU1vZGVsXTtcbiAgICAkKHRoaXMuZWwpLmh0bWwoSGFuZGxlYmFycy50ZW1wbGF0ZXMuc3RhdHVzX2NvZGUodGhpcy5tb2RlbCkpO1xuXG4gICAgaWYgKHRoaXMucm91dGVyLmFwaS5tb2RlbHMuaGFzT3duUHJvcGVydHkodGhpcy5tb2RlbC5yZXNwb25zZU1vZGVsKSkge1xuICAgICAgcmVzcG9uc2VNb2RlbCA9IHtcbiAgICAgICAgc2FtcGxlSlNPTjogSlNPTi5zdHJpbmdpZnkoU3dhZ2dlclVpLnBhcnRpYWxzLnNpZ25hdHVyZS5jcmVhdGVKU09OU2FtcGxlKHZhbHVlKSwgdm9pZCAwLCAyKSxcbiAgICAgICAgc2FtcGxlWE1MOiB0aGlzLm1vZGVsLmlzWE1MID8gU3dhZ2dlclVpLnBhcnRpYWxzLnNpZ25hdHVyZS5jcmVhdGVYTUxTYW1wbGUoJycsIHRoaXMubW9kZWwuc2NoZW1hLCB0aGlzLnJvdXRlci5hcGkubW9kZWxzKSA6IGZhbHNlLFxuICAgICAgICBpc1BhcmFtOiBmYWxzZSxcbiAgICAgICAgc2lnbmF0dXJlOiBTd2FnZ2VyVWkucGFydGlhbHMuc2lnbmF0dXJlLmdldE1vZGVsU2lnbmF0dXJlKHRoaXMubW9kZWwucmVzcG9uc2VNb2RlbCwgdmFsdWUsIHRoaXMucm91dGVyLmFwaS5tb2RlbHMpLFxuICAgICAgICBkZWZhdWx0UmVuZGVyaW5nOiB0aGlzLm1vZGVsLmRlZmF1bHRSZW5kZXJpbmdcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3BvbnNlTW9kZWwgPSB7XG4gICAgICAgIHNpZ25hdHVyZTogU3dhZ2dlclVpLnBhcnRpYWxzLnNpZ25hdHVyZS5nZXRQcmltaXRpdmVTaWduYXR1cmUodGhpcy5tb2RlbC5zY2hlbWEpXG4gICAgICB9O1xuICAgIH1cblxuICAgIHJlc3BvbnNlTW9kZWxWaWV3ID0gbmV3IFN3YWdnZXJVaS5WaWV3cy5TaWduYXR1cmVWaWV3KHttb2RlbDogcmVzcG9uc2VNb2RlbCwgdGFnTmFtZTogJ2Rpdid9KTtcbiAgICAkKCcubW9kZWwtc2lnbmF0dXJlJywgdGhpcy4kZWwpLmFwcGVuZChyZXNwb25zZU1vZGVsVmlldy5yZW5kZXIoKS5lbCk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbn0pOyJdfQ==
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/swagger-ui.min.js b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/swagger-ui.min.js
new file mode 100644 (file)
index 0000000..bb417af
--- /dev/null
@@ -0,0 +1,15 @@
+(function(){function e(){e.history=e.history||[],e.history.push(arguments),this.console&&console.log(Array.prototype.slice.call(arguments)[0])}!function(){var e=Handlebars.template,t=Handlebars.templates=Handlebars.templates||{};t.apikey_auth=e({1:function(e,t,n,r,i){var a;return'                <span class="key_auth__value">'+(null!=(a=(n.sanitize||t&&t.sanitize||n.helperMissing).call(null!=t?t:{},null!=t?t.value:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</span>\n"},3:function(e,t,n,r,i){return'                <input placeholder="api_key" class="auth_input input_apiKey_entry" name="apiKey" type="text"/>\n'},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return'<div class="key_input_container">\n    <h3 class="auth__title">Api key authorization</h3>\n    <div class="auth__description">'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.description:t,{name:"sanitize",hash:{},data:i}))?a:"")+'</div>\n    <div>\n        <div class="key_auth__field">\n            <span class="key_auth__label">name:</span>\n            <span class="key_auth__value">'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.name:t,{name:"escape",hash:{},data:i}))?a:"")+'</span>\n        </div>\n        <div class="key_auth__field">\n            <span class="key_auth__label">in:</span>\n            <span class="key_auth__value">'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t["in"]:t,{name:"escape",hash:{},data:i}))?a:"")+'</span>\n        </div>\n        <div class="key_auth__field">\n            <span class="key_auth__label">value:</span>\n'+(null!=(a=n["if"].call(o,null!=t?t.isLogout:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.program(3,i,0),data:i}))?a:"")+"        </div>\n    </div>\n</div>\n"},useData:!0}),t.auth_button=e({compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){return"<a class='authorize__btn' href=\"#\" data-sw-translate>Authorize</a>\n"},useData:!0}),t.auth_button_operation=e({1:function(e,t,n,r,i){return"        authorize__btn_operation_login\n"},3:function(e,t,n,r,i){return"        authorize__btn_operation_logout\n"},5:function(e,t,n,r,i){var a;return'        <ul class="authorize-scopes">\n'+(null!=(a=n.each.call(null!=t?t:{},null!=t?t.scopes:t,{name:"each",hash:{},fn:e.program(6,i,0),inverse:e.noop,data:i}))?a:"")+"        </ul>\n"},6:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return'                <li class="authorize__scope" title="'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.description:t,{name:"escape",hash:{},data:i}))?a:"")+'">'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.scope:t,{name:"escape",hash:{},data:i}))?a:"")+"</li>\n"},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{};return'<div class="authorize__btn authorize__btn_operation\n'+(null!=(a=n["if"].call(o,null!=t?t.isLogout:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.program(3,i,0),data:i}))?a:"")+'">\n'+(null!=(a=n["if"].call(o,null!=t?t.scopes:t,{name:"if",hash:{},fn:e.program(5,i,0),inverse:e.noop,data:i}))?a:"")+"</div>\n"},useData:!0}),t.auth_view=e({1:function(e,t,n,r,i){return'            <button type="button" class="auth__button auth_submit__button" data-sw-translate>Authorize</button>\n'},3:function(e,t,n,r,i){return'            <button type="button" class="auth__button auth_logout__button" data-sw-translate>Logout</button>\n'},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{};return'<div class="auth_container">\n\n    <div class="auth_inner"></div>\n    <div class="auth_submit">\n'+(null!=(a=n.unless.call(o,null!=t?t.isLogout:t,{name:"unless",hash:{},fn:e.program(1,i,0),inverse:e.noop,data:i}))?a:"")+(null!=(a=n["if"].call(o,null!=t?t.isAuthorized:t,{name:"if",hash:{},fn:e.program(3,i,0),inverse:e.noop,data:i}))?a:"")+"    </div>\n\n</div>\n"},useData:!0}),t.basic_auth=e({1:function(e,t,n,r,i){return" - authorized"},3:function(e,t,n,r,i){var a;return'                <span class="basic_auth__value">'+(null!=(a=(n.escape||t&&t.escape||n.helperMissing).call(null!=t?t:{},null!=t?t.username:t,{name:"escape",hash:{},data:i}))?a:"")+"</span>\n"},5:function(e,t,n,r,i){return'                <input required placeholder="username" class="basic_auth__username auth_input" name="username" type="text"/>\n'},7:function(e,t,n,r,i){return'            <div class="auth_label">\n                <span class="basic_auth__label" data-sw-translate>password:</span>\n                <input required placeholder="password" class="basic_auth__password auth_input" name="password" type="password"/></label>\n            </div>\n'},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{};return"<div class='basic_auth_container'>\n    <h3 class=\"auth__title\">Basic authentication"+(null!=(a=n["if"].call(o,null!=t?t.isLogout:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.noop,data:i}))?a:"")+'</h3>\n    <form class="basic_input_container">\n        <div class="auth__description">'+(null!=(a=(n.sanitize||t&&t.sanitize||n.helperMissing).call(o,null!=t?t.description:t,{name:"sanitize",hash:{},data:i}))?a:"")+'</div>\n        <div class="auth_label">\n            <span class="basic_auth__label" data-sw-translate>username:</span>\n'+(null!=(a=n["if"].call(o,null!=t?t.isLogout:t,{name:"if",hash:{},fn:e.program(3,i,0),inverse:e.program(5,i,0),data:i}))?a:"")+"        </div>\n"+(null!=(a=n.unless.call(o,null!=t?t.isLogout:t,{name:"unless",hash:{},fn:e.program(7,i,0),inverse:e.noop,data:i}))?a:"")+"    </form>\n</div>\n"},useData:!0}),t.content_type=e({1:function(e,t,n,r,i){var a;return null!=(a=n.each.call(null!=t?t:{},null!=t?t.produces:t,{name:"each",hash:{},fn:e.program(2,i,0),inverse:e.noop,data:i}))?a:""},2:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return'\t<option value="'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,t,{name:"sanitize",hash:{},data:i}))?a:"")+'">'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,t,{name:"sanitize",hash:{},data:i}))?a:"")+"</option>\n"},4:function(e,t,n,r,i){return'  <option value="application/json">application/json</option>\n'},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return'<label data-sw-translate for="'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.contentTypeId:t,{name:"escape",hash:{},data:i}))?a:"")+'">Response Content Type</label>\n<select name="contentType" id="'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.contentTypeId:t,{name:"escape",hash:{},data:i}))?a:"")+'">\n'+(null!=(a=n["if"].call(o,null!=t?t.produces:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.program(4,i,0),data:i}))?a:"")+"</select>\n"},useData:!0}),t.main=e({1:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return'  <div class="info_title">'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=(a=null!=t?t.info:t)?a.title:a,{name:"sanitize",hash:{},data:i}))?a:"")+'</div>\n  <div class="info_description markdown">'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=(a=null!=t?t.info:t)?a.description:a,{name:"sanitize",hash:{},data:i}))?a:"")+"</div>\n"+(null!=(a=n["if"].call(o,null!=t?t.externalDocs:t,{name:"if",hash:{},fn:e.program(2,i,0),inverse:e.noop,data:i}))?a:"")+"  "+(null!=(a=n["if"].call(o,null!=(a=null!=t?t.info:t)?a.termsOfServiceUrl:a,{name:"if",hash:{},fn:e.program(4,i,0),inverse:e.noop,data:i}))?a:"")+"\n  "+(null!=(a=n["if"].call(o,null!=(a=null!=(a=null!=t?t.info:t)?a.contact:a)?a.name:a,{name:"if",hash:{},fn:e.program(6,i,0),inverse:e.noop,data:i}))?a:"")+"\n  "+(null!=(a=n["if"].call(o,null!=(a=null!=(a=null!=t?t.info:t)?a.contact:a)?a.url:a,{name:"if",hash:{},fn:e.program(8,i,0),inverse:e.noop,data:i}))?a:"")+"\n  "+(null!=(a=n["if"].call(o,null!=(a=null!=(a=null!=t?t.info:t)?a.contact:a)?a.email:a,{name:"if",hash:{},fn:e.program(10,i,0),inverse:e.noop,data:i}))?a:"")+"\n  "+(null!=(a=n["if"].call(o,null!=(a=null!=t?t.info:t)?a.license:a,{name:"if",hash:{},fn:e.program(12,i,0),inverse:e.noop,data:i}))?a:"")+"\n"},2:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"  <p>"+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=(a=null!=t?t.externalDocs:t)?a.description:a,{name:"sanitize",hash:{},data:i}))?a:"")+'</p>\n  <a href="'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=(a=null!=t?t.externalDocs:t)?a.url:a,{name:"escape",hash:{},data:i}))?a:"")+'" target="_blank">'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=(a=null!=t?t.externalDocs:t)?a.url:a,{name:"escape",hash:{},data:i}))?a:"")+"</a>\n"},4:function(e,t,n,r,i){var a;return'<div class="info_tos"><a target="_blank" href="'+(null!=(a=(n.escape||t&&t.escape||n.helperMissing).call(null!=t?t:{},null!=(a=null!=t?t.info:t)?a.termsOfServiceUrl:a,{name:"escape",hash:{},data:i}))?a:"")+'" data-sw-translate>Terms of service</a></div>'},6:function(e,t,n,r,i){var a;return"<div><div class='info_name' style=\"display: inline\" data-sw-translate>Created by </div> "+(null!=(a=(n.escape||t&&t.escape||n.helperMissing).call(null!=t?t:{},null!=(a=null!=(a=null!=t?t.info:t)?a.contact:a)?a.name:a,{name:"escape",hash:{},data:i}))?a:"")+"</div>"},8:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"<div class='info_url' data-sw-translate>See more at <a href=\""+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=(a=null!=(a=null!=t?t.info:t)?a.contact:a)?a.url:a,{name:"escape",hash:{},data:i}))?a:"")+'">'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=(a=null!=(a=null!=t?t.info:t)?a.contact:a)?a.url:a,{name:"escape",hash:{},data:i}))?a:"")+"</a></div>"},10:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return'<div class=\'info_email\'><a target="_parent" href="mailto:'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=(a=null!=(a=null!=t?t.info:t)?a.contact:a)?a.email:a,{name:"escape",hash:{},data:i}))?a:"")+"?subject="+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=(a=null!=t?t.info:t)?a.title:a,{name:"escape",hash:{},data:i}))?a:"")+'" data-sw-translate>Contact the developer</a></div>'},12:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"<div class='info_license'><a target=\"_blank\" href='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=(a=null!=(a=null!=t?t.info:t)?a.license:a)?a.url:a,{name:"escape",hash:{},data:i}))?a:"")+"'>"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=(a=null!=(a=null!=t?t.info:t)?a.license:a)?a.name:a,{name:"escape",hash:{},data:i}))?a:"")+"</a></div>"},14:function(e,t,n,r,i){var a;return'  , <span style="font-variant: small-caps" data-sw-translate>api version</span>: '+(null!=(a=(n.escape||t&&t.escape||n.helperMissing).call(null!=t?t:{},null!=(a=null!=t?t.info:t)?a.version:a,{name:"escape",hash:{},data:i}))?a:"")+"\n    "},16:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return'    <span style="float:right"><a target="_blank" href="'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.validatorUrl:t,{name:"escape",hash:{},data:i}))?a:"")+"/debug?url="+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.url:t,{name:"escape",hash:{},data:i}))?a:"")+'"><img id="validator" src="'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.validatorUrl:t,{name:"escape",hash:{},data:i}))?a:"")+"?url="+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.url:t,{name:"escape",hash:{},data:i}))?a:"")+'"></a>\n    </span>\n'},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{};return"<div class='info' id='api_info'>\n"+(null!=(a=n["if"].call(o,null!=t?t.info:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.noop,data:i}))?a:"")+"</div>\n<div class='container' id='resources_container'>\n  <div class='authorize-wrapper'></div>\n\n  <ul id='resources'></ul>\n\n  <div class=\"footer\">\n    <h4 style=\"color: #999\">[ <span style=\"font-variant: small-caps\">base url</span>: "+(null!=(a=(n.escape||t&&t.escape||n.helperMissing).call(o,null!=t?t.basePath:t,{name:"escape",hash:{},data:i}))?a:"")+"\n"+(null!=(a=n["if"].call(o,null!=(a=null!=t?t.info:t)?a.version:a,{name:"if",hash:{},fn:e.program(14,i,0),inverse:e.noop,data:i}))?a:"")+"]\n"+(null!=(a=n["if"].call(o,null!=t?t.validatorUrl:t,{name:"if",hash:{},fn:e.program(16,i,0),inverse:e.noop,data:i}))?a:"")+"    </h4>\n    </div>\n</div>\n"},useData:!0}),t.oauth2=e({1:function(e,t,n,r,i){var a;return"<p>Authorization URL: "+(null!=(a=(n.sanitize||t&&t.sanitize||n.helperMissing).call(null!=t?t:{},null!=t?t.authorizationUrl:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</p>"},3:function(e,t,n,r,i){var a;return"<p>Token URL: "+(null!=(a=(n.sanitize||t&&t.sanitize||n.helperMissing).call(null!=t?t:{},null!=t?t.tokenUrl:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</p>"},5:function(e,t,n,r,i){return'        <p>Please input username and password for password flow authorization</p>\n        <fieldset>\n            <div><label>Username: <input class="oauth-username" type="text" name="username"></label></div>\n            <div><label>Password: <input class="oauth-password" type="password" name="password"></label></div>\n        </fieldset>\n'},7:function(e,t,n,r,i){var a;return"        <p>Setup client authentication."+(null!=(a=n["if"].call(null!=t?t:{},null!=t?t.requireClientAuthenticaiton:t,{name:"if",hash:{},fn:e.program(8,i,0),inverse:e.noop,data:i}))?a:"")+'</p>\n        <fieldset>\n            <div><label>Type:\n                <select class="oauth-client-authentication-type" name="client-authentication-type">\n                    <option value="none" selected>None or other</option>\n                    <option value="basic">Basic auth</option>\n                    <option value="request-body">Request body</option>\n                </select>\n            </label></div>\n            <div class="oauth-client-authentication" hidden>\n                <div><label>ClientId: <input class="oauth-client-id" type="text" name="client-id"></label></div>\n                <div><label>Secret: <input class="oauth-client-secret" type="text" name="client-secret"></label></div>\n            </div>\n        </fieldset>\n'},8:function(e,t,n,r,i){return"(Required)"},10:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return'            <li>\n                <input class="oauth-scope" type="checkbox" data-scope="'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.scope:t,{name:"escape",hash:{},data:i}))?a:"")+'" oauthtype="'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.OAuthSchemeKey:t,{name:"escape",hash:{},data:i}))?a:"")+'"/>\n                <label>'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.scope:t,{name:"escape",hash:{},data:i}))?a:"")+'</label><br/>\n                <span class="api-scope-desc">'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.description:t,{name:"escape",hash:{},data:i}))?a:"")+"\n"+(null!=(a=n["if"].call(o,null!=t?t.OAuthSchemeKey:t,{name:"if",hash:{},fn:e.program(11,i,0),inverse:e.noop,data:i}))?a:"")+"                </span>\n            </li>\n"},11:function(e,t,n,r,i){var a;return"                        ("+(null!=(a=(n.escape||t&&t.escape||n.helperMissing).call(null!=t?t:{},null!=t?t.OAuthSchemeKey:t,{name:"escape",hash:{},data:i}))?a:"")+")\n"},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return'<div>\n    <h3 class="auth__title">OAuth2.0</h3>\n    <p>'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.description:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</p>\n    "+(null!=(a=n["if"].call(o,null!=t?t.authorizationUrl:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.noop,data:i}))?a:"")+"\n    "+(null!=(a=n["if"].call(o,null!=t?t.tokenUrl:t,{name:"if",hash:{},fn:e.program(3,i,0),inverse:e.noop,data:i}))?a:"")+"\n    <p>flow: "+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.flow:t,{name:"escape",hash:{},data:i}))?a:"")+"</p>\n"+(null!=(a=n["if"].call(o,null!=t?t.isPasswordFlow:t,{name:"if",hash:{},fn:e.program(5,i,0),inverse:e.noop,data:i}))?a:"")+(null!=(a=n["if"].call(o,null!=t?t.clientAuthentication:t,{name:"if",hash:{},fn:e.program(7,i,0),inverse:e.noop,data:i}))?a:"")+"    <p><strong> "+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.appName:t,{name:"escape",hash:{},data:i}))?a:"")+' </strong> API requires the following scopes. Select which ones you want to grant to Swagger UI.</p>\n    <p>Scopes are used to grant an application different levels of access to data on behalf of the end user. Each API may declare one or more scopes.\n        <a href="#">Learn how to use</a>\n    </p>\n    <ul class="api-popup-scopes">\n'+(null!=(a=n.each.call(o,null!=t?t.scopes:t,{name:"each",hash:{},fn:e.program(10,i,0),inverse:e.noop,data:i}))?a:"")+"    </ul>\n</div>"},useData:!0}),t.operation=e({1:function(e,t,n,r,i){return"deprecated"},3:function(e,t,n,r,i){return"            <h4><span data-sw-translate>Warning: Deprecated</span></h4>\n"},5:function(e,t,n,r,i){var a;return'        <h4><span data-sw-translate>Implementation Notes</span></h4>\n        <div class="markdown">'+(null!=(a=(n.sanitize||t&&t.sanitize||n.helperMissing).call(null!=t?t:{},null!=t?t.description:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</div>\n"},7:function(e,t,n,r,i){return"            <div class='authorize-wrapper authorize-wrapper_operation'></div>\n"},9:function(e,t,n,r,i){var a,o=null!=t?t:{};return'          <div class="response-class">\n            <h4><span data-sw-translate>Response Class</span> (<span data-sw-translate>Status</span> '+(null!=(a=(n.escape||t&&t.escape||n.helperMissing).call(o,null!=t?t.successCode:t,{name:"escape",hash:{},data:i}))?a:"")+")</h4>\n              "+(null!=(a=n["if"].call(o,null!=t?t.successDescription:t,{name:"if",hash:{},fn:e.program(10,i,0),inverse:e.noop,data:i}))?a:"")+'\n            <p><span class="model-signature" /></p>\n            <br/>\n            <div class="response-content-type" />\n            </div>\n'},10:function(e,t,n,r,i){var a;return'<div class="markdown">'+(null!=(a=(n.sanitize||t&&t.sanitize||n.helperMissing).call(null!=t?t:{},null!=t?t.successDescription:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</div>"},12:function(e,t,n,r,i){var a;return'          <h4 data-sw-translate>Headers</h4>\n          <table class="headers">\n            <thead>\n              <tr>\n                <th style="width: 100px; max-width: 100px" data-sw-translate>Header</th>\n                <th style="width: 310px; max-width: 310px" data-sw-translate>Description</th>\n                <th style="width: 200px; max-width: 200px" data-sw-translate>Type</th>\n                <th style="width: 320px; max-width: 320px" data-sw-translate>Other</th>\n              </tr>\n            </thead>\n            <tbody>\n'+(null!=(a=n.each.call(null!=t?t:{},null!=t?t.headers:t,{name:"each",hash:{},fn:e.program(13,i,0),inverse:e.noop,data:i}))?a:"")+"            </tbody>\n          </table>\n"},13:function(e,t,n,r,i){var a,o,s=null!=t?t:{},l=n.helperMissing;return"              <tr>\n                <td>"+e.escapeExpression((o=null!=(o=n.key||i&&i.key)?o:l,"function"==typeof o?o.call(s,{name:"key",hash:{},data:i}):o))+"</td>\n                <td>"+(null!=(a=(n.sanitize||t&&t.sanitize||l).call(s,null!=t?t.description:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</td>\n                <td>"+(null!=(a=(n.escape||t&&t.escape||l).call(s,null!=t?t.type:t,{name:"escape",hash:{},data:i}))?a:"")+"</td>\n                <td>"+(null!=(a=(n.escape||t&&t.escape||l).call(s,null!=t?t.other:t,{name:"escape",hash:{},data:i}))?a:"")+"</td>\n              </tr>\n"},15:function(e,t,n,r,i){return'          <h4 data-sw-translate>Parameters</h4>\n          <table class=\'fullwidth parameters\'>\n          <thead>\n            <tr>\n            <th style="width: 100px; max-width: 100px" data-sw-translate>Parameter</th>\n            <th style="width: 310px; max-width: 310px" data-sw-translate>Value</th>\n            <th style="width: 200px; max-width: 200px" data-sw-translate>Description</th>\n            <th style="width: 100px; max-width: 100px" data-sw-translate>Parameter Type</th>\n            <th style="width: 220px; max-width: 230px" data-sw-translate>Data Type</th>\n            </tr>\n          </thead>\n          <tbody class="operation-params">\n\n          </tbody>\n          </table>\n'},17:function(e,t,n,r,i){return"          <div style='margin:0;padding:0;display:inline'></div>\n          <h4 data-sw-translate>Response Messages</h4>\n          <table class='fullwidth response-messages'>\n            <thead>\n            <tr>\n              <th data-sw-translate>HTTP Status Code</th>\n              <th data-sw-translate>Reason</th>\n              <th data-sw-translate>Response Model</th>\n              <th data-sw-translate>Headers</th>\n            </tr>\n            </thead>\n            <tbody class=\"operation-status\">\n            </tbody>\n          </table>\n"},19:function(e,t,n,r,i){return""},21:function(e,t,n,r,i){return"          <div class='sandbox_header'>\n            <input class='submit' type='submit' value='Try it out!' data-sw-translate/>\n            <a href='#' class='response_hider' style='display:none' data-sw-translate>Hide Response</a>\n            <span class='response_throbber' style='display:none'></span>\n          </div>\n"},23:function(e,t,n,r,i){return"          <h4 data-sw-translate>Request Headers</h4>\n          <div class='block request_headers'></div>\n"},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing,l=e.escapeExpression;return"  <ul class='operations' >\n    <li class='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.method:t,{name:"escape",hash:{},data:i}))?a:"")+" operation' id='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.parentId:t,{name:"escape",hash:{},data:i}))?a:"")+"_"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.nickname:t,{name:"escape",hash:{},data:i}))?a:"")+"'>\n      <div class='heading'>\n        <h3>\n          <span class='http_method'>\n          <a href='#!/"+l((n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.encodedParentId:t,{name:"sanitize",hash:{},data:i}))+"/"+l((n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.nickname:t,{name:"sanitize",hash:{},data:i}))+'\' class="toggleOperation">'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.method:t,{name:"escape",hash:{},data:i}))?a:"")+"</a>\n          </span>\n          <span class='path'>\n          <a href='#!/"+l((n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.encodedParentId:t,{name:"sanitize",hash:{},data:i}))+"/"+l((n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.nickname:t,{name:"sanitize",hash:{},data:i}))+"' class=\"toggleOperation "+(null!=(a=n["if"].call(o,null!=t?t.deprecated:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.noop,data:i}))?a:"")+'">'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.path:t,{name:"escape",hash:{},data:i}))?a:"")+"</a>\n          </span>\n        </h3>\n        <ul class='options'>\n          <li>\n          <a href='#!/"+l((n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.encodedParentId:t,{name:"sanitize",hash:{},data:i}))+"/"+l((n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.nickname:t,{name:"sanitize",hash:{},data:i}))+'\' class="toggleOperation"><span class="markdown">'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.summary:t,{name:"escape",hash:{},data:i}))?a:"")+"</span></a>\n          </li>\n        </ul>\n      </div>\n      <div class='content' id='"+l((n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.encodedParentId:t,{name:"sanitize",hash:{},data:i}))+"_"+l((n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.nickname:t,{name:"sanitize",hash:{},data:i}))+"_content' style='display:none'>\n"+(null!=(a=n["if"].call(o,null!=t?t.deprecated:t,{name:"if",hash:{},fn:e.program(3,i,0),inverse:e.noop,data:i}))?a:"")+(null!=(a=n["if"].call(o,null!=t?t.description:t,{name:"if",hash:{},fn:e.program(5,i,0),inverse:e.noop,data:i}))?a:"")+(null!=(a=n["if"].call(o,null!=t?t.security:t,{name:"if",hash:{},fn:e.program(7,i,0),inverse:e.noop,data:i}))?a:"")+(null!=(a=n["if"].call(o,null!=t?t.type:t,{name:"if",hash:{},fn:e.program(9,i,0),inverse:e.noop,data:i}))?a:"")+"\n"+(null!=(a=n["if"].call(o,null!=t?t.headers:t,{name:"if",hash:{},fn:e.program(12,i,0),inverse:e.noop,data:i}))?a:"")+"\n        <form accept-charset='UTF-8' class='sandbox'>\n          <div style='margin:0;padding:0;display:inline'></div>\n"+(null!=(a=n["if"].call(o,null!=t?t.parameters:t,{name:"if",hash:{},fn:e.program(15,i,0),inverse:e.noop,data:i}))?a:"")+(null!=(a=n["if"].call(o,null!=t?t.responseMessages:t,{name:"if",hash:{},fn:e.program(17,i,0),inverse:e.noop,data:i}))?a:"")+(null!=(a=n["if"].call(o,null!=t?t.isReadOnly:t,{name:"if",hash:{},fn:e.program(19,i,0),inverse:e.program(21,i,0),data:i}))?a:"")+"        </form>\n        <div class='response' style='display:none'>\n          <h4 class='curl'>Curl</h4>\n          <div class='block curl'></div>\n          <h4 data-sw-translate>Request URL</h4>\n          <div class='block request_url'></div>\n"+(null!=(a=n["if"].call(o,null!=t?t.showRequestHeaders:t,{name:"if",hash:{},fn:e.program(23,i,0),inverse:e.noop,data:i}))?a:"")+"          <h4 data-sw-translate>Response Body</h4>\n          <div class='block response_body'></div>\n          <h4 data-sw-translate>Response Code</h4>\n          <div class='block response_code'></div>\n          <h4 data-sw-translate>Response Headers</h4>\n          <div class='block response_headers'></div>\n        </div>\n      </div>\n    </li>\n  </ul>\n"},useData:!0}),t.param=e({1:function(e,t,n,r,i){var a;return null!=(a=n["if"].call(null!=t?t:{},null!=t?t.isFile:t,{name:"if",hash:{},fn:e.program(2,i,0),inverse:e.program(4,i,0),data:i}))?a:""},2:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return'\t\t\t<input type="file" name=\''+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.name:t,{name:"escape",hash:{},data:i}))?a:"")+"' id='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+'\'/>\n\t\t\t<div class="parameter-content-type" />\n'},4:function(e,t,n,r,i){var a;return null!=(a=n["if"].call(null!=t?t:{},null!=t?t["default"]:t,{name:"if",hash:{},fn:e.program(5,i,0),inverse:e.program(7,i,0),data:i}))?a:""},5:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"\t\t\t\t<div class=\"editor_holder\"></div>\n\t\t\t\t<textarea class='body-textarea' name='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.name:t,{name:"escape",hash:{},data:i}))?a:"")+"' id='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+"'>"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t["default"]:t,{name:"escape",hash:{},data:i}))?a:"")+'</textarea>\n        <br />\n        <div class="parameter-content-type" />\n'},7:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"\t\t\t\t<textarea class='body-textarea' name='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.name:t,{name:"escape",hash:{},data:i}))?a:"")+"' id='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+'\'></textarea>\n\t\t\t\t<div class="editor_holder"></div>\n\t\t\t\t<br />\n\t\t\t\t<div class="parameter-content-type" />\n'},9:function(e,t,n,r,i){var a;return null!=(a=n["if"].call(null!=t?t:{},null!=t?t.isFile:t,{name:"if",hash:{},fn:e.program(2,i,0),inverse:e.program(10,i,0),data:i}))?a:""},10:function(e,t,n,r,i){var a;return null!=(a=(n.renderTextParam||t&&t.renderTextParam||n.helperMissing).call(null!=t?t:{},t,{name:"renderTextParam",hash:{},fn:e.program(11,i,0),inverse:e.noop,data:i}))?a:""},11:function(e,t,n,r,i){return""},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"<td class='code'><label for='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+"'>"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.name:t,{name:"escape",hash:{},data:i}))?a:"")+"</label></td>\n<td>\n\n"+(null!=(a=n["if"].call(o,null!=t?t.isBody:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.program(9,i,0),data:i}))?a:"")+'\n</td>\n<td class="markdown">'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.description:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</td>\n<td>"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.paramType:t,{name:"escape",hash:{},data:i}))?a:"")+'</td>\n<td>\n\t<span class="model-signature"></span>\n</td>\n'},useData:!0}),t.param_list=e({1:function(e,t,n,r,i){return" required"},3:function(e,t,n,r,i){return' multiple="multiple"'},5:function(e,t,n,r,i){return" required "},7:function(e,t,n,r,i){var a;return"      <option "+(null!=(a=n.unless.call(null!=t?t:{},null!=t?t.hasDefault:t,{name:"unless",hash:{},fn:e.program(8,i,0),inverse:e.noop,data:i}))?a:"")+" value=''></option>\n"},8:function(e,t,n,r,i){return'  selected="" '},10:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"\n      <option "+(null!=(a=n["if"].call(o,null!=t?t.isDefault:t,{name:"if",hash:{},fn:e.program(11,i,0),inverse:e.noop,data:i}))?a:"")+"  value='"+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.value:t,{name:"sanitize",hash:{},data:i}))?a:"")+"'> "+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.value:t,{name:"sanitize",hash:{},data:i}))?a:"")+" "+(null!=(a=n["if"].call(o,null!=t?t.isDefault:t,{name:"if",hash:{},fn:e.program(13,i,0),inverse:e.noop,data:i}))?a:"")+" </option>\n\n"},11:function(e,t,n,r,i){return' selected=""  '},13:function(e,t,n,r,i){return" (default) "},15:function(e,t,n,r,i){return"<strong>"},17:function(e,t,n,r,i){return"</strong>"},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o,s=null!=t?t:{},l=n.helperMissing;return"<td class='code"+(null!=(a=n["if"].call(s,null!=t?t.required:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.noop,data:i}))?a:"")+"'><label for='"+(null!=(a=(n.escape||t&&t.escape||l).call(s,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+"'>"+(null!=(a=(n.sanitize||t&&t.sanitize||l).call(s,null!=t?t.name:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</label></td>\n<td>\n  <select "+(null!=(a=(n.isArray||t&&t.isArray||l).call(s,t,{name:"isArray",hash:{},fn:e.program(3,i,0),inverse:e.noop,data:i}))?a:"")+' class="parameter '+(null!=(a=n["if"].call(s,null!=t?t.required:t,{name:"if",hash:{},fn:e.program(5,i,0),inverse:e.noop,data:i}))?a:"")+'" name="'+(null!=(a=(n.sanitize||t&&t.sanitize||l).call(s,null!=t?t.name:t,{name:"sanitize",hash:{},data:i}))?a:"")+'" id="'+(null!=(a=(n.escape||t&&t.escape||l).call(s,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+'">\n\n'+(null!=(a=n.unless.call(s,null!=t?t.required:t,{name:"unless",hash:{},fn:e.program(7,i,0),inverse:e.noop,data:i}))?a:"")+"\n"+(null!=(a=n.each.call(s,null!=(a=null!=t?t.allowableValues:t)?a.descriptiveValues:a,{name:"each",hash:{},fn:e.program(10,i,0),inverse:e.noop,data:i}))?a:"")+'\n  </select>\n</td>\n<td class="markdown">'+(null!=(a=n["if"].call(s,null!=t?t.required:t,{name:"if",hash:{},fn:e.program(15,i,0),inverse:e.noop,data:i}))?a:"")+(null!=(o=null!=(o=n.description||(null!=t?t.description:t))?o:l,a="function"==typeof o?o.call(s,{name:"description",hash:{},data:i}):o)?a:"")+(null!=(a=n["if"].call(s,null!=t?t.required:t,{name:"if",hash:{},fn:e.program(17,i,0),inverse:e.noop,data:i}))?a:"")+"</td>\n<td>"+(null!=(a=(n.escape||t&&t.escape||l).call(s,null!=t?t.paramType:t,{name:"escape",hash:{},data:i}))?a:"")+'</td>\n<td><span class="model-signature"></span></td>\n'},useData:!0}),t.param_readonly=e({1:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"        <textarea class='body-textarea' readonly='readonly' name='"+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.name:t,{name:"sanitize",hash:{},data:i}))?a:"")+"' id='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+"'>"+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t["default"]:t,{name:"sanitize",hash:{},data:i}))?a:"")+'</textarea>\n        <div class="parameter-content-type" />\n'},3:function(e,t,n,r,i){
+var a;return null!=(a=n["if"].call(null!=t?t:{},null!=t?t["default"]:t,{name:"if",hash:{},fn:e.program(4,i,0),inverse:e.program(6,i,0),data:i}))?a:""},4:function(e,t,n,r,i){var a;return"            "+(null!=(a=(n.sanitize||t&&t.sanitize||n.helperMissing).call(null!=t?t:{},null!=t?t["default"]:t,{name:"sanitize",hash:{},data:i}))?a:"")+"\n"},6:function(e,t,n,r,i){return"            (empty)\n"},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"<td class='code'><label for='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+"'>"+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.name:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</label></td>\n<td>\n"+(null!=(a=n["if"].call(o,null!=t?t.isBody:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.program(3,i,0),data:i}))?a:"")+'</td>\n<td class="markdown">'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.description:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</td>\n<td>"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.paramType:t,{name:"escape",hash:{},data:i}))?a:"")+'</td>\n<td><span class="model-signature"></span></td>\n'},useData:!0}),t.param_readonly_required=e({1:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"        <textarea class='body-textarea' readonly='readonly' placeholder='(required)' name='"+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.name:t,{name:"sanitize",hash:{},data:i}))?a:"")+"' id='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+"'>"+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t["default"]:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</textarea>\n"},3:function(e,t,n,r,i){var a;return null!=(a=n["if"].call(null!=t?t:{},null!=t?t["default"]:t,{name:"if",hash:{},fn:e.program(4,i,0),inverse:e.program(6,i,0),data:i}))?a:""},4:function(e,t,n,r,i){var a;return"            "+(null!=(a=(n.sanitize||t&&t.sanitize||n.helperMissing).call(null!=t?t:{},null!=t?t["default"]:t,{name:"sanitize",hash:{},data:i}))?a:"")+"\n"},6:function(e,t,n,r,i){return"            (empty)\n"},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"<td class='code required'><label for='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+"'>"+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.name:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</label></td>\n<td>\n"+(null!=(a=n["if"].call(o,null!=t?t.isBody:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.program(3,i,0),data:i}))?a:"")+'</td>\n<td class="markdown">'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.description:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</td>\n<td>"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.paramType:t,{name:"escape",hash:{},data:i}))?a:"")+'</td>\n<td><span class="model-signature"></span></td>\n'},useData:!0}),t.param_required=e({1:function(e,t,n,r,i){var a;return null!=(a=n["if"].call(null!=t?t:{},null!=t?t.isFile:t,{name:"if",hash:{},fn:e.program(2,i,0),inverse:e.program(4,i,0),data:i}))?a:""},2:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return'\t\t\t<input type="file" name=\''+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.name:t,{name:"escape",hash:{},data:i}))?a:"")+"' id='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+"'/>\n"},4:function(e,t,n,r,i){var a;return null!=(a=n["if"].call(null!=t?t:{},null!=t?t["default"]:t,{name:"if",hash:{},fn:e.program(5,i,0),inverse:e.program(7,i,0),data:i}))?a:""},5:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"\t\t\t\t<div class=\"editor_holder\"></div>\n\t\t\t\t<textarea class='body-textarea required' placeholder='(required)' name='"+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.name:t,{name:"sanitize",hash:{},data:i}))?a:"")+"' id=\""+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+'">'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t["default"]:t,{name:"sanitize",hash:{},data:i}))?a:"")+'</textarea>\n        <br />\n        <div class="parameter-content-type" />\n'},7:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"\t\t\t\t<textarea class='body-textarea required' placeholder='(required)' name='"+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.name:t,{name:"sanitize",hash:{},data:i}))?a:"")+"' id='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+'\'></textarea>\n\t\t\t\t<div class="editor_holder"></div>\n\t\t\t\t<br />\n\t\t\t\t<div class="parameter-content-type" />\n'},9:function(e,t,n,r,i){var a;return null!=(a=n["if"].call(null!=t?t:{},null!=t?t.isFile:t,{name:"if",hash:{},fn:e.program(10,i,0),inverse:e.program(12,i,0),data:i}))?a:""},10:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"\t\t\t<input class='parameter required' type='file' name='"+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.name:t,{name:"sanitize",hash:{},data:i}))?a:"")+"' id='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+"'/>\n"},12:function(e,t,n,r,i){var a;return null!=(a=(n.renderTextParam||t&&t.renderTextParam||n.helperMissing).call(null!=t?t:{},t,{name:"renderTextParam",hash:{},fn:e.program(13,i,0),inverse:e.noop,data:i}))?a:""},13:function(e,t,n,r,i){return""},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"<td class='code required'><label for='"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.valueId:t,{name:"escape",hash:{},data:i}))?a:"")+"'>"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.name:t,{name:"escape",hash:{},data:i}))?a:"")+"</label></td>\n<td>\n"+(null!=(a=n["if"].call(o,null!=t?t.isBody:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.program(9,i,0),data:i}))?a:"")+'</td>\n<td>\n\t<strong><span class="markdown">'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,null!=t?t.description:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</span></strong>\n</td>\n<td>"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.paramType:t,{name:"escape",hash:{},data:i}))?a:"")+'</td>\n<td><span class="model-signature"></span></td>\n'},useData:!0}),t.parameter_content_type=e({1:function(e,t,n,r,i){var a;return null!=(a=n.each.call(null!=t?t:{},null!=t?t.consumes:t,{name:"each",hash:{},fn:e.program(2,i,0),inverse:e.noop,data:i}))?a:""},2:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return'  <option value="'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,t,{name:"sanitize",hash:{},data:i}))?a:"")+'">'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,t,{name:"sanitize",hash:{},data:i}))?a:"")+"</option>\n"},4:function(e,t,n,r,i){return'  <option value="application/json">application/json</option>\n'},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o,s=null!=t?t:{},l=n.helperMissing;return'<label for="'+e.escapeExpression((o=null!=(o=n.parameterContentTypeId||(null!=t?t.parameterContentTypeId:t))?o:l,"function"==typeof o?o.call(s,{name:"parameterContentTypeId",hash:{},data:i}):o))+'" data-sw-translate>Parameter content type:</label>\n<select name="parameterContentType" id="'+(null!=(a=(n.sanitize||t&&t.sanitize||l).call(s,null!=t?t.parameterContentTypeId:t,{name:"sanitize",hash:{},data:i}))?a:"")+'">\n'+(null!=(a=n["if"].call(s,null!=t?t.consumes:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.program(4,i,0),data:i}))?a:"")+"</select>\n"},useData:!0}),t.popup=e({compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a;return'<div class="api-popup-dialog-wrapper">\n    <div class="api-popup-title">'+e.escapeExpression((a=null!=(a=n.title||(null!=t?t.title:t))?a:n.helperMissing,"function"==typeof a?a.call(null!=t?t:{},{name:"title",hash:{},data:i}):a))+'</div>\n    <div class="api-popup-content"></div>\n    <p class="error-msg"></p>\n    <div class="api-popup-actions">\n        <button class="api-popup-cancel api-button gray" type="button">Cancel</button>\n    </div>\n</div>\n<div class="api-popup-dialog-shadow"></div>'},useData:!0}),t.resource=e({1:function(e,t,n,r,i){return" : "},3:function(e,t,n,r,i){var a;return"    <li>\n      <a href='"+(null!=(a=(n.sanitize||t&&t.sanitize||n.helperMissing).call(null!=t?t:{},null!=t?t.url:t,{name:"sanitize",hash:{},data:i}))?a:"")+"' data-sw-translate>Raw</a>\n    </li>\n"},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o,s,l=null!=t?t:{},u=n.helperMissing,c="<div class='heading'>\n  <h2>\n    <a href='#!/"+(null!=(a=(n.sanitize||t&&t.sanitize||u).call(l,null!=t?t.id:t,{name:"sanitize",hash:{},data:i}))?a:"")+'\' class="toggleEndpointList" data-id="'+(null!=(a=(n.sanitize||t&&t.sanitize||u).call(l,null!=t?t.id:t,{name:"sanitize",hash:{},data:i}))?a:"")+'">'+(null!=(a=(n.sanitize||t&&t.sanitize||u).call(l,null!=t?t.name:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</a> ";return o=null!=(o=n.summary||(null!=t?t.summary:t))?o:u,s={name:"summary",hash:{},fn:e.program(1,i,0),inverse:e.noop,data:i},a="function"==typeof o?o.call(l,s):o,n.summary||(a=n.blockHelperMissing.call(t,a,s)),null!=a&&(c+=a),c+(null!=(a=(n.sanitize||t&&t.sanitize||u).call(l,null!=t?t.summary:t,{name:"sanitize",hash:{},data:i}))?a:"")+"\n  </h2>\n  <ul class='options'>\n    <li>\n      <a href='#!/"+(null!=(a=(n.sanitize||t&&t.sanitize||u).call(l,null!=t?t.id:t,{name:"sanitize",hash:{},data:i}))?a:"")+"' id='endpointListTogger_"+(null!=(a=(n.sanitize||t&&t.sanitize||u).call(l,null!=t?t.id:t,{name:"sanitize",hash:{},data:i}))?a:"")+'\' class="toggleEndpointList" data-id="'+(null!=(a=(n.sanitize||t&&t.sanitize||u).call(l,null!=t?t.id:t,{name:"sanitize",hash:{},data:i}))?a:"")+'" data-sw-translate>Show/Hide</a>\n    </li>\n    <li>\n      <a href=\'#\' class="collapseResource" data-id="'+(null!=(a=(n.sanitize||t&&t.sanitize||u).call(l,null!=t?t.id:t,{name:"sanitize",hash:{},data:i}))?a:"")+'" data-sw-translate>\n        List Operations\n      </a>\n    </li>\n    <li>\n      <a href=\'#\' class="expandResource" data-id="'+(null!=(a=(n.sanitize||t&&t.sanitize||u).call(l,null!=t?t.id:t,{name:"sanitize",hash:{},data:i}))?a:"")+'" data-sw-translate>\n        Expand Operations\n      </a>\n    </li>\n'+(null!=(a=n["if"].call(l,null!=t?t.url:t,{name:"if",hash:{},fn:e.program(3,i,0),inverse:e.noop,data:i}))?a:"")+"  </ul>\n</div>\n<ul class='endpoints' id='"+(null!=(a=(n.sanitize||t&&t.sanitize||u).call(l,null!=t?t.id:t,{name:"sanitize",hash:{},data:i}))?a:"")+"_endpoint_list' style='display:none'>\n\n</ul>\n"},useData:!0}),t.response_content_type=e({1:function(e,t,n,r,i){var a;return null!=(a=n.each.call(null!=t?t:{},null!=t?t.produces:t,{name:"each",hash:{},fn:e.program(2,i,0),inverse:e.noop,data:i}))?a:""},2:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return'  <option value="'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,t,{name:"sanitize",hash:{},data:i}))?a:"")+'">'+(null!=(a=(n.sanitize||t&&t.sanitize||s).call(o,t,{name:"sanitize",hash:{},data:i}))?a:"")+"</option>\n"},4:function(e,t,n,r,i){return'  <option value="application/json">application/json</option>\n'},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o,s=null!=t?t:{},l=n.helperMissing,u="function",c=e.escapeExpression;return'<label data-sw-translate for="'+c((o=null!=(o=n.responseContentTypeId||(null!=t?t.responseContentTypeId:t))?o:l,typeof o===u?o.call(s,{name:"responseContentTypeId",hash:{},data:i}):o))+'">Response Content Type</label>\n<select name="responseContentType" id="'+c((o=null!=(o=n.responseContentTypeId||(null!=t?t.responseContentTypeId:t))?o:l,typeof o===u?o.call(s,{name:"responseContentTypeId",hash:{},data:i}):o))+'">\n'+(null!=(a=n["if"].call(s,null!=t?t.produces:t,{name:"if",hash:{},fn:e.program(1,i,0),inverse:e.program(4,i,0),data:i}))?a:"")+"</select>\n"},useData:!0}),t.signature=e({1:function(e,t,n,r,i){var a,o=null!=t?t:{};return'\n<div>\n<ul class="signature-nav">\n  <li><a class="description-link" href="#" data-sw-translate>Model</a></li>\n  <li><a class="snippet-link" href="#" data-sw-translate>Example Value</a></li>\n</ul>\n<div>\n\n<div class="signature-container">\n  <div class="description">\n      '+e.escapeExpression((n.sanitize||t&&t.sanitize||n.helperMissing).call(o,null!=t?t.signature:t,{name:"sanitize",hash:{},data:i}))+'\n  </div>\n\n  <div class="snippet">\n'+(null!=(a=n["if"].call(o,null!=t?t.sampleJSON:t,{name:"if",hash:{},fn:e.program(2,i,0),inverse:e.noop,data:i}))?a:"")+(null!=(a=n["if"].call(o,null!=t?t.sampleXML:t,{name:"if",hash:{},fn:e.program(5,i,0),inverse:e.noop,data:i}))?a:"")+"  </div>\n</div>\n"},2:function(e,t,n,r,i){var a,o=null!=t?t:{};return'      <div class="snippet_json">\n        <pre><code>'+(null!=(a=(n.escape||t&&t.escape||n.helperMissing).call(o,null!=t?t.sampleJSON:t,{name:"escape",hash:{},data:i}))?a:"")+"</code></pre>\n        "+(null!=(a=n["if"].call(o,null!=t?t.isParam:t,{name:"if",hash:{},fn:e.program(3,i,0),inverse:e.noop,data:i}))?a:"")+"\n      </div>\n"},3:function(e,t,n,r,i){return'<small class="notice" data-sw-translate></small>'},5:function(e,t,n,r,i){var a,o=null!=t?t:{};return'    <div class="snippet_xml">\n      <pre><code>'+(null!=(a=(n.escape||t&&t.escape||n.helperMissing).call(o,null!=t?t.sampleXML:t,{name:"escape",hash:{},data:i}))?a:"")+"</code></pre>\n      "+(null!=(a=n["if"].call(o,null!=t?t.isParam:t,{name:"if",hash:{},fn:e.program(3,i,0),inverse:e.noop,data:i}))?a:"")+"\n    </div>\n"},7:function(e,t,n,r,i){var a;return"    "+(null!=(a=(n.escape||t&&t.escape||n.helperMissing).call(null!=t?t:{},null!=t?t.signature:t,{name:"escape",hash:{},data:i}))?a:"")+"\n"},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a;return null!=(a=(n.ifCond||t&&t.ifCond||n.helperMissing).call(null!=t?t:{},null!=t?t.sampleJSON:t,"||",null!=t?t.sampleXML:t,{name:"ifCond",hash:{},fn:e.program(1,i,0),inverse:e.program(7,i,0),data:i}))?a:""},useData:!0}),t.status_code=e({1:function(e,t,n,r,i){var a,o,s=null!=t?t:{},l=n.helperMissing;return"      <tr>\n        <td>"+e.escapeExpression((o=null!=(o=n.key||i&&i.key)?o:l,"function"==typeof o?o.call(s,{name:"key",hash:{},data:i}):o))+"</td>\n        <td>"+(null!=(a=(n.sanitize||t&&t.sanitize||l).call(s,null!=t?t.description:t,{name:"sanitize",hash:{},data:i}))?a:"")+"</td>\n        <td>"+(null!=(a=(n.escape||t&&t.escape||l).call(s,null!=t?t.type:t,{name:"escape",hash:{},data:i}))?a:"")+"</td>\n      </tr>\n"},compiler:[7,">= 4.0.0"],main:function(e,t,n,r,i){var a,o=null!=t?t:{},s=n.helperMissing;return"<td width='15%' class='code'>"+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.code:t,{name:"escape",hash:{},data:i}))?a:"")+'</td>\n<td class="markdown">'+(null!=(a=(n.escape||t&&t.escape||s).call(o,null!=t?t.message:t,{name:"escape",hash:{},data:i}))?a:"")+'</td>\n<td width=\'50%\'><span class="model-signature" /></td>\n<td class="headers">\n  <table>\n    <tbody>\n'+(null!=(a=n.each.call(o,null!=t?t.headers:t,{name:"each",hash:{},fn:e.program(1,i,0),inverse:e.noop,data:i}))?a:"")+"    </tbody>\n  </table>\n</td>"},useData:!0})}(),$(function(){$.fn.vAlign=function(){return this.each(function(){var e=$(this).height(),t=$(this).parent().height(),n=(t-e)/2;$(this).css("margin-top",n)})},$.fn.stretchFormtasticInputWidthToParent=function(){return this.each(function(){var e=$(this).closest("form").innerWidth(),t=parseInt($(this).closest("form").css("padding-left"),10)+parseInt($(this).closest("form").css("padding-right"),10),n=parseInt($(this).css("padding-left"),10)+parseInt($(this).css("padding-right"),10);$(this).css("width",e-t-n)})},$("form.formtastic li.string input, form.formtastic textarea").stretchFormtasticInputWidthToParent(),$("ul.downplayed li div.content p").vAlign(),$("form.sandbox").submit(function(){var e=!0;return $(this).find("input.required").each(function(){$(this).removeClass("error"),""===$(this).val()&&($(this).addClass("error"),$(this).wiggle(),e=!1)}),e})}),Function.prototype.bind&&console&&"object"==typeof console.log&&["log","info","warn","error","assert","dir","clear","profile","profileEnd"].forEach(function(e){console[e]=this.bind(console[e],console)},Function.prototype.call),window.Docs={shebang:function(){var e=$.param.fragment().split("/");switch(e.shift(),e.length){case 1:if(e[0].length>0){var t="resource_"+e[0];Docs.expandEndpointListForResource(e[0]),$("#"+t).slideto({highlight:!1})}break;case 2:Docs.expandEndpointListForResource(e[0]),$("#"+t).slideto({highlight:!1});var n=e.join("_"),r=n+"_content";Docs.expandOperation($("#"+r)),$("#"+n).slideto({highlight:!1})}},toggleEndpointListForResource:function(e){var t=$("li#resource_"+Docs.escapeResourceName(e)+" ul.endpoints");t.is(":visible")?($.bbq.pushState("#/",2),Docs.collapseEndpointListForResource(e)):($.bbq.pushState("#/"+e,2),Docs.expandEndpointListForResource(e))},expandEndpointListForResource:function(e){var e=Docs.escapeResourceName(e);if(""==e)return void $(".resource ul.endpoints").slideDown();$("li#resource_"+e).addClass("active");var t=$("li#resource_"+e+" ul.endpoints");t.slideDown()},collapseEndpointListForResource:function(e){var e=Docs.escapeResourceName(e);if(""==e)return void $(".resource ul.endpoints").slideUp();$("li#resource_"+e).removeClass("active");var t=$("li#resource_"+e+" ul.endpoints");t.slideUp()},expandOperationsForResource:function(e){return Docs.expandEndpointListForResource(e),""==e?void $(".resource ul.endpoints li.operation div.content").slideDown():void $("li#resource_"+Docs.escapeResourceName(e)+" li.operation div.content").each(function(){Docs.expandOperation($(this))})},collapseOperationsForResource:function(e){return Docs.expandEndpointListForResource(e),""==e?void $(".resource ul.endpoints li.operation div.content").slideUp():void $("li#resource_"+Docs.escapeResourceName(e)+" li.operation div.content").each(function(){Docs.collapseOperation($(this))})},escapeResourceName:function(e){return e.replace(/[!"#$%&'()*+,.\/:;<=>?@\[\\\]\^`{|}~]/g,"\\$&")},expandOperation:function(e){e.slideDown()},collapseOperation:function(e){e.slideUp()}},function(e,t){"use strict";"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():e.returnExports=t()}(this,function(){var e,t,n=Array,r=n.prototype,i=Object,a=i.prototype,o=Function,s=o.prototype,l=String,u=l.prototype,c=Number,p=c.prototype,h=r.slice,f=r.splice,d=r.push,m=r.unshift,g=r.concat,y=r.join,v=s.call,b=s.apply,w=Math.max,_=Math.min,x=a.toString,A="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag,S=Function.prototype.toString,j=/^\s*class /,E=function(e){try{var t=S.call(e),n=t.replace(/\/\/.*\n/g,""),r=n.replace(/\/\*[.\s\S]*\*\//g,""),i=r.replace(/\n/gm," ").replace(/ {2}/g," ");return j.test(i)}catch(a){return!1}},O=function(e){try{return!E(e)&&(S.call(e),!0)}catch(t){return!1}},k="[object Function]",T="[object GeneratorFunction]",e=function(e){if(!e)return!1;if("function"!=typeof e&&"object"!=typeof e)return!1;if(A)return O(e);if(E(e))return!1;var t=x.call(e);return t===k||t===T},C=RegExp.prototype.exec,I=function(e){try{return C.call(e),!0}catch(t){return!1}},D="[object RegExp]";t=function(e){return"object"==typeof e&&(A?I(e):x.call(e)===D)};var L,M=String.prototype.valueOf,R=function(e){try{return M.call(e),!0}catch(t){return!1}},U="[object String]";L=function(e){return"string"==typeof e||"object"==typeof e&&(A?R(e):x.call(e)===U)};var P=i.defineProperty&&function(){try{var e={};i.defineProperty(e,"x",{enumerable:!1,value:e});for(var t in e)return!1;return e.x===e}catch(n){return!1}}(),q=function(e){var t;return t=P?function(e,t,n,r){!r&&t in e||i.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:!0,value:n})}:function(e,t,n,r){!r&&t in e||(e[t]=n)},function(n,r,i){for(var a in r)e.call(r,a)&&t(n,a,r[a],i)}}(a.hasOwnProperty),B=function(e){var t=typeof e;return null===e||"object"!==t&&"function"!==t},z=c.isNaN||function(e){return e!==e},N={ToInteger:function(e){var t=+e;return z(t)?t=0:0!==t&&t!==1/0&&t!==-(1/0)&&(t=(t>0||-1)*Math.floor(Math.abs(t))),t},ToPrimitive:function(t){var n,r,i;if(B(t))return t;if(r=t.valueOf,e(r)&&(n=r.call(t),B(n)))return n;if(i=t.toString,e(i)&&(n=i.call(t),B(n)))return n;throw new TypeError},ToObject:function(e){if(null==e)throw new TypeError("can't convert "+e+" to object");return i(e)},ToUint32:function(e){return e>>>0}},$=function(){};q(s,{bind:function(t){var n=this;if(!e(n))throw new TypeError("Function.prototype.bind called on incompatible "+n);for(var r,a=h.call(arguments,1),s=function(){if(this instanceof r){var e=b.call(n,this,g.call(a,h.call(arguments)));return i(e)===e?e:this}return b.call(n,t,g.call(a,h.call(arguments)))},l=w(0,n.length-a.length),u=[],c=0;c<l;c++)d.call(u,"$"+c);return r=o("binder","return function ("+y.call(u,",")+"){ return binder.apply(this, arguments); }")(s),n.prototype&&($.prototype=n.prototype,r.prototype=new $,$.prototype=null),r}});var F=v.bind(a.hasOwnProperty),V=v.bind(a.toString),H=v.bind(h),Y=b.bind(h),J=v.bind(u.slice),W=v.bind(u.split),Q=v.bind(u.indexOf),G=v.bind(d),K=v.bind(a.propertyIsEnumerable),X=v.bind(r.sort),Z=n.isArray||function(e){return"[object Array]"===V(e)},ee=1!==[].unshift(0);q(r,{unshift:function(){return m.apply(this,arguments),this.length}},ee),q(n,{isArray:Z});var te=i("a"),ne="a"!==te[0]||!(0 in te),re=function(e){var t=!0,n=!0,r=!1;if(e)try{e.call("foo",function(e,n,r){"object"!=typeof r&&(t=!1)}),e.call([1],function(){"use strict";n="string"==typeof this},"x")}catch(i){r=!0}return!!e&&!r&&t&&n};q(r,{forEach:function(t){var n,r=N.ToObject(this),i=ne&&L(this)?W(this,""):r,a=-1,o=N.ToUint32(i.length);if(arguments.length>1&&(n=arguments[1]),!e(t))throw new TypeError("Array.prototype.forEach callback must be a function");for(;++a<o;)a in i&&("undefined"==typeof n?t(i[a],a,r):t.call(n,i[a],a,r))}},!re(r.forEach)),q(r,{map:function(t){var r,i=N.ToObject(this),a=ne&&L(this)?W(this,""):i,o=N.ToUint32(a.length),s=n(o);if(arguments.length>1&&(r=arguments[1]),!e(t))throw new TypeError("Array.prototype.map callback must be a function");for(var l=0;l<o;l++)l in a&&("undefined"==typeof r?s[l]=t(a[l],l,i):s[l]=t.call(r,a[l],l,i));return s}},!re(r.map)),q(r,{filter:function(t){var n,r,i=N.ToObject(this),a=ne&&L(this)?W(this,""):i,o=N.ToUint32(a.length),s=[];if(arguments.length>1&&(r=arguments[1]),!e(t))throw new TypeError("Array.prototype.filter callback must be a function");for(var l=0;l<o;l++)l in a&&(n=a[l],("undefined"==typeof r?t(n,l,i):t.call(r,n,l,i))&&G(s,n));return s}},!re(r.filter)),q(r,{every:function(t){var n,r=N.ToObject(this),i=ne&&L(this)?W(this,""):r,a=N.ToUint32(i.length);if(arguments.length>1&&(n=arguments[1]),!e(t))throw new TypeError("Array.prototype.every callback must be a function");for(var o=0;o<a;o++)if(o in i&&!("undefined"==typeof n?t(i[o],o,r):t.call(n,i[o],o,r)))return!1;return!0}},!re(r.every)),q(r,{some:function(t){var n,r=N.ToObject(this),i=ne&&L(this)?W(this,""):r,a=N.ToUint32(i.length);if(arguments.length>1&&(n=arguments[1]),!e(t))throw new TypeError("Array.prototype.some callback must be a function");for(var o=0;o<a;o++)if(o in i&&("undefined"==typeof n?t(i[o],o,r):t.call(n,i[o],o,r)))return!0;return!1}},!re(r.some));var ie=!1;r.reduce&&(ie="object"==typeof r.reduce.call("es5",function(e,t,n,r){return r})),q(r,{reduce:function(t){var n=N.ToObject(this),r=ne&&L(this)?W(this,""):n,i=N.ToUint32(r.length);if(!e(t))throw new TypeError("Array.prototype.reduce callback must be a function");if(0===i&&1===arguments.length)throw new TypeError("reduce of empty array with no initial value");var a,o=0;if(arguments.length>=2)a=arguments[1];else for(;;){if(o in r){a=r[o++];break}if(++o>=i)throw new TypeError("reduce of empty array with no initial value")}for(;o<i;o++)o in r&&(a=t(a,r[o],o,n));return a}},!ie);var ae=!1;r.reduceRight&&(ae="object"==typeof r.reduceRight.call("es5",function(e,t,n,r){return r})),q(r,{reduceRight:function(t){var n=N.ToObject(this),r=ne&&L(this)?W(this,""):n,i=N.ToUint32(r.length);if(!e(t))throw new TypeError("Array.prototype.reduceRight callback must be a function");if(0===i&&1===arguments.length)throw new TypeError("reduceRight of empty array with no initial value");var a,o=i-1;if(arguments.length>=2)a=arguments[1];else for(;;){if(o in r){a=r[o--];break}if(--o<0)throw new TypeError("reduceRight of empty array with no initial value")}if(o<0)return a;do o in r&&(a=t(a,r[o],o,n));while(o--);return a}},!ae);var oe=r.indexOf&&[0,1].indexOf(1,2)!==-1;q(r,{indexOf:function(e){var t=ne&&L(this)?W(this,""):N.ToObject(this),n=N.ToUint32(t.length);if(0===n)return-1;var r=0;for(arguments.length>1&&(r=N.ToInteger(arguments[1])),r=r>=0?r:w(0,n+r);r<n;r++)if(r in t&&t[r]===e)return r;return-1}},oe);var se=r.lastIndexOf&&[0,1].lastIndexOf(0,-3)!==-1;q(r,{lastIndexOf:function(e){var t=ne&&L(this)?W(this,""):N.ToObject(this),n=N.ToUint32(t.length);if(0===n)return-1;var r=n-1;for(arguments.length>1&&(r=_(r,N.ToInteger(arguments[1]))),r=r>=0?r:n-Math.abs(r);r>=0;r--)if(r in t&&e===t[r])return r;return-1}},se);var le=function(){var e=[1,2],t=e.splice();return 2===e.length&&Z(t)&&0===t.length}();q(r,{splice:function(e,t){return 0===arguments.length?[]:f.apply(this,arguments)}},!le);var ue=function(){var e={};return r.splice.call(e,0,0,1),1===e.length}();q(r,{splice:function(e,t){if(0===arguments.length)return[];var n=arguments;return this.length=w(N.ToInteger(this.length),0),arguments.length>0&&"number"!=typeof t&&(n=H(arguments),n.length<2?G(n,this.length-e):n[1]=N.ToInteger(t)),f.apply(this,n)}},!ue);var ce=function(){var e=new n(1e5);return e[8]="x",e.splice(1,1),7===e.indexOf("x")}(),pe=function(){var e=256,t=[];return t[e]="a",t.splice(e+1,0,"b"),"a"===t[e]}();q(r,{splice:function(e,t){for(var n,r=N.ToObject(this),i=[],a=N.ToUint32(r.length),o=N.ToInteger(e),s=o<0?w(a+o,0):_(o,a),u=_(w(N.ToInteger(t),0),a-s),c=0;c<u;)n=l(s+c),F(r,n)&&(i[c]=r[n]),c+=1;var p,h=H(arguments,2),f=h.length;if(f<u){c=s;for(var d=a-u;c<d;)n=l(c+u),p=l(c+f),F(r,n)?r[p]=r[n]:delete r[p],c+=1;c=a;for(var m=a-u+f;c>m;)delete r[c-1],c-=1}else if(f>u)for(c=a-u;c>s;)n=l(c+u-1),p=l(c+f-1),F(r,n)?r[p]=r[n]:delete r[p],c-=1;c=s;for(var g=0;g<h.length;++g)r[c]=h[g],c+=1;return r.length=a-u+f,i}},!ce||!pe);var he,fe=r.join;try{he="1,2,3"!==Array.prototype.join.call("123",",")}catch(de){he=!0}he&&q(r,{join:function(e){var t="undefined"==typeof e?",":e;return fe.call(L(this)?W(this,""):this,t)}},he);var me="1,2"!==[1,2].join(void 0);me&&q(r,{join:function(e){var t="undefined"==typeof e?",":e;return fe.call(this,t)}},me);var ge=function(e){for(var t=N.ToObject(this),n=N.ToUint32(t.length),r=0;r<arguments.length;)t[n+r]=arguments[r],r+=1;return t.length=n+r,n+r},ye=function(){var e={},t=Array.prototype.push.call(e,void 0);return 1!==t||1!==e.length||"undefined"!=typeof e[0]||!F(e,0)}();q(r,{push:function(e){return Z(this)?d.apply(this,arguments):ge.apply(this,arguments)}},ye);var ve=function(){var e=[],t=e.push(void 0);return 1!==t||1!==e.length||"undefined"!=typeof e[0]||!F(e,0)}();q(r,{push:ge},ve),q(r,{slice:function(e,t){var n=L(this)?W(this,""):this;return Y(n,arguments)}},ne);var be=function(){try{return[1,2].sort(null),[1,2].sort({}),!0}catch(e){}return!1}(),we=function(){try{return[1,2].sort(/a/),!1}catch(e){}return!0}(),_e=function(){try{return[1,2].sort(void 0),!0}catch(e){}return!1}();q(r,{sort:function(t){if("undefined"==typeof t)return X(this);if(!e(t))throw new TypeError("Array.prototype.sort callback must be a function");return X(this,t)}},be||!_e||!we);var xe=!K({toString:null},"toString"),Ae=K(function(){},"prototype"),Se=!F("x","0"),je=function(e){var t=e.constructor;return t&&t.prototype===e},Ee={$window:!0,$console:!0,$parent:!0,$self:!0,$frame:!0,$frames:!0,$frameElement:!0,$webkitIndexedDB:!0,$webkitStorageInfo:!0,$external:!0},Oe=function(){if("undefined"==typeof window)return!1;for(var e in window)try{!Ee["$"+e]&&F(window,e)&&null!==window[e]&&"object"==typeof window[e]&&je(window[e])}catch(t){return!0}return!1}(),ke=function(e){if("undefined"==typeof window||!Oe)return je(e);try{return je(e)}catch(t){return!1}},Te=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],Ce=Te.length,Ie=function(e){return"[object Arguments]"===V(e)},De=function(t){return null!==t&&"object"==typeof t&&"number"==typeof t.length&&t.length>=0&&!Z(t)&&e(t.callee)},Le=Ie(arguments)?Ie:De;q(i,{keys:function(t){var n=e(t),r=Le(t),i=null!==t&&"object"==typeof t,a=i&&L(t);if(!i&&!n&&!r)throw new TypeError("Object.keys called on a non-object");var o=[],s=Ae&&n;if(a&&Se||r)for(var u=0;u<t.length;++u)G(o,l(u));if(!r)for(var c in t)s&&"prototype"===c||!F(t,c)||G(o,l(c));if(xe)for(var p=ke(t),h=0;h<Ce;h++){var f=Te[h];p&&"constructor"===f||!F(t,f)||G(o,f)}return o}});var Me=i.keys&&function(){return 2===i.keys(arguments).length}(1,2),Re=i.keys&&function(){var e=i.keys(arguments);return 1!==arguments.length||1!==e.length||1!==e[0]}(1),Ue=i.keys;q(i,{keys:function(e){return Ue(Le(e)?H(e):e)}},!Me||Re);var Pe,qe,Be=0!==new Date((-0xc782b5b342b24)).getUTCMonth(),ze=new Date((-0x55d318d56a724)),Ne=new Date(14496624e5),$e="Mon, 01 Jan -45875 11:59:59 GMT"!==ze.toUTCString(),Fe=ze.getTimezoneOffset();Fe<-720?(Pe="Tue Jan 02 -45875"!==ze.toDateString(),qe=!/^Thu Dec 10 2015 \d\d:\d\d:\d\d GMT[-\+]\d\d\d\d(?: |$)/.test(Ne.toString())):(Pe="Mon Jan 01 -45875"!==ze.toDateString(),qe=!/^Wed Dec 09 2015 \d\d:\d\d:\d\d GMT[-\+]\d\d\d\d(?: |$)/.test(Ne.toString()));var Ve=v.bind(Date.prototype.getFullYear),He=v.bind(Date.prototype.getMonth),Ye=v.bind(Date.prototype.getDate),Je=v.bind(Date.prototype.getUTCFullYear),We=v.bind(Date.prototype.getUTCMonth),Qe=v.bind(Date.prototype.getUTCDate),Ge=v.bind(Date.prototype.getUTCDay),Ke=v.bind(Date.prototype.getUTCHours),Xe=v.bind(Date.prototype.getUTCMinutes),Ze=v.bind(Date.prototype.getUTCSeconds),et=v.bind(Date.prototype.getUTCMilliseconds),tt=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],nt=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],rt=function(e,t){return Ye(new Date(t,e,0))};q(Date.prototype,{getFullYear:function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var e=Ve(this);return e<0&&He(this)>11?e+1:e},getMonth:function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var e=Ve(this),t=He(this);return e<0&&t>11?0:t},getDate:function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var e=Ve(this),t=He(this),n=Ye(this);if(e<0&&t>11){if(12===t)return n;var r=rt(0,e+1);return r-n+1}return n},getUTCFullYear:function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var e=Je(this);return e<0&&We(this)>11?e+1:e},getUTCMonth:function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var e=Je(this),t=We(this);return e<0&&t>11?0:t},getUTCDate:function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var e=Je(this),t=We(this),n=Qe(this);if(e<0&&t>11){if(12===t)return n;var r=rt(0,e+1);return r-n+1}return n}},Be),q(Date.prototype,{toUTCString:function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var e=Ge(this),t=Qe(this),n=We(this),r=Je(this),i=Ke(this),a=Xe(this),o=Ze(this);return tt[e]+", "+(t<10?"0"+t:t)+" "+nt[n]+" "+r+" "+(i<10?"0"+i:i)+":"+(a<10?"0"+a:a)+":"+(o<10?"0"+o:o)+" GMT"}},Be||$e),q(Date.prototype,{toDateString:function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var e=this.getDay(),t=this.getDate(),n=this.getMonth(),r=this.getFullYear();return tt[e]+" "+nt[n]+" "+(t<10?"0"+t:t)+" "+r}},Be||Pe),(Be||qe)&&(Date.prototype.toString=function(){if(!(this&&this instanceof Date))throw new TypeError("this is not a Date object.");var e=this.getDay(),t=this.getDate(),n=this.getMonth(),r=this.getFullYear(),i=this.getHours(),a=this.getMinutes(),o=this.getSeconds(),s=this.getTimezoneOffset(),l=Math.floor(Math.abs(s)/60),u=Math.floor(Math.abs(s)%60);
+return tt[e]+" "+nt[n]+" "+(t<10?"0"+t:t)+" "+r+" "+(i<10?"0"+i:i)+":"+(a<10?"0"+a:a)+":"+(o<10?"0"+o:o)+" GMT"+(s>0?"-":"+")+(l<10?"0"+l:l)+(u<10?"0"+u:u)},P&&i.defineProperty(Date.prototype,"toString",{configurable:!0,enumerable:!1,writable:!0}));var it=-621987552e5,at="-000001",ot=Date.prototype.toISOString&&new Date(it).toISOString().indexOf(at)===-1,st=Date.prototype.toISOString&&"1969-12-31T23:59:59.999Z"!==new Date((-1)).toISOString(),lt=v.bind(Date.prototype.getTime);q(Date.prototype,{toISOString:function(){if(!isFinite(this)||!isFinite(lt(this)))throw new RangeError("Date.prototype.toISOString called on non-finite value.");var e=Je(this),t=We(this);e+=Math.floor(t/12),t=(t%12+12)%12;var n=[t+1,Qe(this),Ke(this),Xe(this),Ze(this)];e=(e<0?"-":e>9999?"+":"")+J("00000"+Math.abs(e),0<=e&&e<=9999?-4:-6);for(var r=0;r<n.length;++r)n[r]=J("00"+n[r],-2);return e+"-"+H(n,0,2).join("-")+"T"+H(n,2).join(":")+"."+J("000"+et(this),-3)+"Z"}},ot||st);var ut=function(){try{return Date.prototype.toJSON&&null===new Date(NaN).toJSON()&&new Date(it).toJSON().indexOf(at)!==-1&&Date.prototype.toJSON.call({toISOString:function(){return!0}})}catch(e){return!1}}();ut||(Date.prototype.toJSON=function(t){var n=i(this),r=N.ToPrimitive(n);if("number"==typeof r&&!isFinite(r))return null;var a=n.toISOString;if(!e(a))throw new TypeError("toISOString property is not callable");return a.call(n)});var ct=1e15===Date.parse("+033658-09-27T01:46:40.000Z"),pt=!isNaN(Date.parse("2012-04-04T24:00:00.500Z"))||!isNaN(Date.parse("2012-11-31T23:59:59.000Z"))||!isNaN(Date.parse("2012-12-31T23:59:60.000Z")),ht=isNaN(Date.parse("2000-01-01T00:00:00.000Z"));if(ht||pt||!ct){var ft=Math.pow(2,31)-1,dt=z(new Date(1970,0,1,0,0,0,ft+1).getTime());Date=function(e){var t=function(n,r,i,a,o,s,u){var c,p=arguments.length;if(this instanceof e){var h=s,f=u;if(dt&&p>=7&&u>ft){var d=Math.floor(u/ft)*ft,m=Math.floor(d/1e3);h+=m,f-=1e3*m}c=1===p&&l(n)===n?new e(t.parse(n)):p>=7?new e(n,r,i,a,o,h,f):p>=6?new e(n,r,i,a,o,h):p>=5?new e(n,r,i,a,o):p>=4?new e(n,r,i,a):p>=3?new e(n,r,i):p>=2?new e(n,r):p>=1?new e(n instanceof e?+n:n):new e}else c=e.apply(this,arguments);return B(c)||q(c,{constructor:t},!0),c},n=new RegExp("^(\\d{4}|[+-]\\d{6})(?:-(\\d{2})(?:-(\\d{2})(?:T(\\d{2}):(\\d{2})(?::(\\d{2})(?:(\\.\\d{1,}))?)?(Z|(?:([-+])(\\d{2}):(\\d{2})))?)?)?)?$"),r=[0,31,59,90,120,151,181,212,243,273,304,334,365],i=function(e,t){var n=t>1?1:0;return r[t]+Math.floor((e-1969+n)/4)-Math.floor((e-1901+n)/100)+Math.floor((e-1601+n)/400)+365*(e-1970)},a=function(t){var n=0,r=t;if(dt&&r>ft){var i=Math.floor(r/ft)*ft,a=Math.floor(i/1e3);n+=a,r-=1e3*a}return c(new e(1970,0,1,0,0,n,r))};for(var o in e)F(e,o)&&(t[o]=e[o]);q(t,{now:e.now,UTC:e.UTC},!0),t.prototype=e.prototype,q(t.prototype,{constructor:t},!0);var s=function(t){var r=n.exec(t);if(r){var o,s=c(r[1]),l=c(r[2]||1)-1,u=c(r[3]||1)-1,p=c(r[4]||0),h=c(r[5]||0),f=c(r[6]||0),d=Math.floor(1e3*c(r[7]||0)),m=Boolean(r[4]&&!r[8]),g="-"===r[9]?1:-1,y=c(r[10]||0),v=c(r[11]||0),b=h>0||f>0||d>0;return p<(b?24:25)&&h<60&&f<60&&d<1e3&&l>-1&&l<12&&y<24&&v<60&&u>-1&&u<i(s,l+1)-i(s,l)&&(o=60*(24*(i(s,l)+u)+p+y*g),o=1e3*(60*(o+h+v*g)+f)+d,m&&(o=a(o)),-864e13<=o&&o<=864e13)?o:NaN}return e.parse.apply(this,arguments)};return q(t,{parse:s}),t}(Date)}Date.now||(Date.now=function(){return(new Date).getTime()});var mt=p.toFixed&&("0.000"!==8e-5.toFixed(3)||"1"!==.9.toFixed(0)||"1.25"!==1.255.toFixed(2)||"1000000000000000128"!==(0xde0b6b3a7640080).toFixed(0)),gt={base:1e7,size:6,data:[0,0,0,0,0,0],multiply:function(e,t){for(var n=-1,r=t;++n<gt.size;)r+=e*gt.data[n],gt.data[n]=r%gt.base,r=Math.floor(r/gt.base)},divide:function(e){for(var t=gt.size,n=0;--t>=0;)n+=gt.data[t],gt.data[t]=Math.floor(n/e),n=n%e*gt.base},numToString:function(){for(var e=gt.size,t="";--e>=0;)if(""!==t||0===e||0!==gt.data[e]){var n=l(gt.data[e]);""===t?t=n:t+=J("0000000",0,7-n.length)+n}return t},pow:function Ut(e,t,n){return 0===t?n:t%2===1?Ut(e,t-1,n*e):Ut(e*e,t/2,n)},log:function(e){for(var t=0,n=e;n>=4096;)t+=12,n/=4096;for(;n>=2;)t+=1,n/=2;return t}},yt=function(e){var t,n,r,i,a,o,s,u;if(t=c(e),t=z(t)?0:Math.floor(t),t<0||t>20)throw new RangeError("Number.toFixed called with invalid number of decimals");if(n=c(this),z(n))return"NaN";if(n<=-1e21||n>=1e21)return l(n);if(r="",n<0&&(r="-",n=-n),i="0",n>1e-21)if(a=gt.log(n*gt.pow(2,69,1))-69,o=a<0?n*gt.pow(2,-a,1):n/gt.pow(2,a,1),o*=4503599627370496,a=52-a,a>0){for(gt.multiply(0,o),s=t;s>=7;)gt.multiply(1e7,0),s-=7;for(gt.multiply(gt.pow(10,s,1),0),s=a-1;s>=23;)gt.divide(1<<23),s-=23;gt.divide(1<<s),gt.multiply(1,1),gt.divide(2),i=gt.numToString()}else gt.multiply(0,o),gt.multiply(1<<-a,0),i=gt.numToString()+J("0.00000000000000000000",2,2+t);return t>0?(u=i.length,i=u<=t?r+J("0.0000000000000000000",0,t-u+2)+i:r+J(i,0,u-t)+"."+J(i,u-t)):i=r+i,i};q(p,{toFixed:yt},mt);var vt=function(){try{return"1"===1..toPrecision(void 0)}catch(e){return!0}}(),bt=p.toPrecision;q(p,{toPrecision:function(e){return"undefined"==typeof e?bt.call(this):bt.call(this,e)}},vt),2!=="ab".split(/(?:ab)*/).length||4!==".".split(/(.?)(.?)/).length||"t"==="tesst".split(/(s)*/)[1]||4!=="test".split(/(?:)/,-1).length||"".split(/.?/).length||".".split(/()()/).length>1?!function(){var e="undefined"==typeof/()??/.exec("")[1],n=Math.pow(2,32)-1;u.split=function(r,i){var a=String(this);if("undefined"==typeof r&&0===i)return[];if(!t(r))return W(this,r,i);var o,s,l,u,c=[],p=(r.ignoreCase?"i":"")+(r.multiline?"m":"")+(r.unicode?"u":"")+(r.sticky?"y":""),h=0,f=new RegExp(r.source,p+"g");e||(o=new RegExp("^"+f.source+"$(?!\\s)",p));var m="undefined"==typeof i?n:N.ToUint32(i);for(s=f.exec(a);s&&(l=s.index+s[0].length,!(l>h&&(G(c,J(a,h,s.index)),!e&&s.length>1&&s[0].replace(o,function(){for(var e=1;e<arguments.length-2;e++)"undefined"==typeof arguments[e]&&(s[e]=void 0)}),s.length>1&&s.index<a.length&&d.apply(c,H(s,1)),u=s[0].length,h=l,c.length>=m)));)f.lastIndex===s.index&&f.lastIndex++,s=f.exec(a);return h===a.length?!u&&f.test("")||G(c,""):G(c,J(a,h)),c.length>m?H(c,0,m):c}}():"0".split(void 0,0).length&&(u.split=function(e,t){return"undefined"==typeof e&&0===t?[]:W(this,e,t)});var wt=u.replace,_t=function(){var e=[];return"x".replace(/x(.)?/g,function(t,n){G(e,n)}),1===e.length&&"undefined"==typeof e[0]}();_t||(u.replace=function(n,r){var i=e(r),a=t(n)&&/\)[*?]/.test(n.source);if(i&&a){var o=function(e){var t=arguments.length,i=n.lastIndex;n.lastIndex=0;var a=n.exec(e)||[];return n.lastIndex=i,G(a,arguments[t-2],arguments[t-1]),r.apply(this,a)};return wt.call(this,n,o)}return wt.call(this,n,r)});var xt=u.substr,At="".substr&&"b"!=="0b".substr(-1);q(u,{substr:function(e,t){var n=e;return e<0&&(n=w(this.length+e,0)),xt.call(this,n,t)}},At);var St="\t\n\x0B\f\r   ᠎              \u2028\u2029\ufeff",jt="​",Et="["+St+"]",Ot=new RegExp("^"+Et+Et+"*"),kt=new RegExp(Et+Et+"*$"),Tt=u.trim&&(St.trim()||!jt.trim());q(u,{trim:function(){if("undefined"==typeof this||null===this)throw new TypeError("can't convert "+this+" to object");return l(this).replace(Ot,"").replace(kt,"")}},Tt);var Ct=v.bind(String.prototype.trim),It=u.lastIndexOf&&"abcあい".lastIndexOf("あい",2)!==-1;q(u,{lastIndexOf:function(e){if("undefined"==typeof this||null===this)throw new TypeError("can't convert "+this+" to object");for(var t=l(this),n=l(e),r=arguments.length>1?c(arguments[1]):NaN,i=z(r)?1/0:N.ToInteger(r),a=_(w(i,0),t.length),o=n.length,s=a+o;s>0;){s=w(0,s-o);var u=Q(J(t,s,a+o),n);if(u!==-1)return s+u}return-1}},It);var Dt=u.lastIndexOf;if(q(u,{lastIndexOf:function(e){return Dt.apply(this,arguments)}},1!==u.lastIndexOf.length),8===parseInt(St+"08")&&22===parseInt(St+"0x16")||(parseInt=function(e){var t=/^[\-+]?0[xX]/;return function(n,r){var i=Ct(String(n)),a=c(r)||(t.test(i)?16:10);return e(i,a)}}(parseInt)),1/parseFloat("-0")!==-(1/0)&&(parseFloat=function(e){return function(t){var n=Ct(String(t)),r=e(n);return 0===r&&"-"===J(n,0,1)?-0:r}}(parseFloat)),"RangeError: test"!==String(new RangeError("test"))){var Lt=function(){if("undefined"==typeof this||null===this)throw new TypeError("can't convert "+this+" to object");var e=this.name;"undefined"==typeof e?e="Error":"string"!=typeof e&&(e=l(e));var t=this.message;return"undefined"==typeof t?t="":"string"!=typeof t&&(t=l(t)),e?t?e+": "+t:e:t};Error.prototype.toString=Lt}if(P){var Mt=function(e,t){if(K(e,t)){var n=Object.getOwnPropertyDescriptor(e,t);n.configurable&&(n.enumerable=!1,Object.defineProperty(e,t,n))}};Mt(Error.prototype,"message"),""!==Error.prototype.message&&(Error.prototype.message=""),Mt(Error.prototype,"name")}if("/a/gim"!==String(/a/gim)){var Rt=function(){var e="/"+this.source+"/";return this.global&&(e+="g"),this.ignoreCase&&(e+="i"),this.multiline&&(e+="m"),e};RegExp.prototype.toString=Rt}}),Handlebars.registerHelper("sanitize",function(e){var t;return void 0===e?"":(t=sanitizeHtml(e,{allowedTags:["div","span","b","i","em","strong","a","br","table","tbody","tr","th","td"],allowedAttributes:{div:["class"],span:["class"],table:["class"],td:["class"],th:["colspan"],a:["href"]}}),new Handlebars.SafeString(t))}),Handlebars.registerHelper("renderTextParam",function(e){var t,n="text",r="",i=e.type||e.schema&&e.schema.type||"",a="array"===i.toLowerCase()||e.allowMultiple,o=a&&Array.isArray(e["default"])?e["default"].join("\n"):e["default"],s=Handlebars.Utils.escapeExpression(e.name),l=Handlebars.Utils.escapeExpression(e.valueId);i=Handlebars.Utils.escapeExpression(i);var u=Object.keys(e).filter(function(e){return null!==e.match(/^X-data-/i)}).reduce(function(t,n){return t+=" "+n.substring(2,n.length)+"='"+e[n]+"'"},"");if(e.format&&"password"===e.format&&(n="password"),l&&(r=" id='"+l+"'"),o=o?sanitizeHtml(o):"",a)t="<textarea class='body-textarea"+(e.required?" required":"")+"' name='"+s+"'"+r+u,t+=" placeholder='Provide multiple values in new lines"+(e.required?" (at least one required).":".")+"'>",t+=o+"</textarea>";else{var c="parameter";e.required&&(c+=" required"),t="<input class='"+c+"' minlength='"+(e.required?1:0)+"'",t+=" name='"+s+"' placeholder='"+(e.required?"(required)":"")+"'"+r+u,t+=" type='"+n+"' value='"+o+"'/>"}return new Handlebars.SafeString(t)}),Handlebars.registerHelper("ifCond",function(e,t,n,r){switch(t){case"==":return e==n?r.fn(this):r.inverse(this);case"===":return e===n?r.fn(this):r.inverse(this);case"<":return e<n?r.fn(this):r.inverse(this);case"<=":return e<=n?r.fn(this):r.inverse(this);case">":return e>n?r.fn(this):r.inverse(this);case">=":return e>=n?r.fn(this):r.inverse(this);case"&&":return e&&n?r.fn(this):r.inverse(this);case"||":return e||n?r.fn(this):r.inverse(this);default:return r.inverse(this)}}),Handlebars.registerHelper("escape",function(e){var t=Handlebars.Utils.escapeExpression(e);return new Handlebars.SafeString(t)}),function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.sanitizeHtml=e()}}(function(){return function e(t,n,r){function i(o,s){if(!n[o]){if(!t[o]){var l="function"==typeof require&&require;if(!s&&l)return l(o,!0);if(a)return a(o,!0);var u=new Error("Cannot find module '"+o+"'");throw u.code="MODULE_NOT_FOUND",u}var c=n[o]={exports:{}};t[o][0].call(c.exports,function(e){var n=t[o][1][e];return i(n?n:e)},c,c.exports,e,t,n,r)}return n[o].exports}for(var a="function"==typeof require&&require,o=0;o<r.length;o++)i(r[o]);return i}({1:[function(e,t,n){function r(e,t){e&&Object.keys(e).forEach(function(n){t(e[n],n)})}function i(e,t){return{}.hasOwnProperty.call(e,t)}function a(e,t,n){function c(e,t){var n=this;this.tag=e,this.attribs=t||{},this.tagPosition=d.length,this.text="",this.updateParentNodeText=function(){if(x.length){var e=x[x.length-1];e.text+=n.text}}}function p(e){return"string"!=typeof e&&(e+=""),e.replace(/\&/g,"&amp;").replace(/</g,"&lt;").replace(/\>/g,"&gt;").replace(/\"/g,"&quot;")}function h(e,n){n=n.replace(/[\x00-\x20]+/g,""),n=n.replace(/<\!\-\-.*?\-\-\>/g,"");var r=n.match(/^([a-zA-Z]+)\:/);if(!r)return!1;var a=r[1].toLowerCase();return i(t.allowedSchemesByTag,e)?t.allowedSchemesByTag[e].indexOf(a)===-1:!t.allowedSchemes||t.allowedSchemes.indexOf(a)===-1}function f(e,t){return t?(e=e.split(/\s+/),e.filter(function(e){return t.indexOf(e)!==-1}).join(" ")):e}var d="";t?(t=s(a.defaults,t),t.parser?t.parser=s(u,t.parser):t.parser=u):(t=a.defaults,t.parser=u);var m,g,y=t.nonTextTags||["script","style","textarea"];t.allowedAttributes&&(m={},g={},r(t.allowedAttributes,function(e,t){m[t]=[];var n=[];e.forEach(function(e){e.indexOf("*")>=0?n.push(l(e).replace(/\\\*/g,".*")):m[t].push(e)}),g[t]=new RegExp("^("+n.join("|")+")$")}));var v={};r(t.allowedClasses,function(e,t){m&&(i(m,t)||(m[t]=[]),m[t].push("class")),v[t]=e});var b,w={};r(t.transformTags,function(e,t){var n;"function"==typeof e?n=e:"string"==typeof e&&(n=a.simpleTransform(e)),"*"===t?b=n:w[t]=n});var _=0,x=[],A={},S={},j=!1,E=0,O=new o.Parser({onopentag:function(e,n){if(j)return void E++;var a=new c(e,n);x.push(a);var o,s=!1,l=!!a.text;i(w,e)&&(o=w[e](e,n),a.attribs=n=o.attribs,void 0!==o.text&&(a.innerText=o.text),e!==o.tagName&&(a.name=e=o.tagName,S[_]=o.tagName)),b&&(o=b(e,n),a.attribs=n=o.attribs,e!==o.tagName&&(a.name=e=o.tagName,S[_]=o.tagName)),t.allowedTags&&t.allowedTags.indexOf(e)===-1&&(s=!0,y.indexOf(e)!==-1&&(j=!0,E=1),A[_]=!0),_++,s||(d+="<"+e,(!m||i(m,e)||m["*"])&&r(n,function(t,n){if(!m||i(m,e)&&m[e].indexOf(n)!==-1||m["*"]&&m["*"].indexOf(n)!==-1||i(g,e)&&g[e].test(n)||g["*"]&&g["*"].test(n)){if(("href"===n||"src"===n)&&h(e,t))return void delete a.attribs[n];if("class"===n&&(t=f(t,v[e]),!t.length))return void delete a.attribs[n];d+=" "+n,t.length&&(d+='="'+p(t)+'"')}else delete a.attribs[n]}),t.selfClosing.indexOf(e)!==-1?d+=" />":(d+=">",!a.innerText||l||t.textFilter||(d+=a.innerText)))},ontext:function(e){if(!j){var n,r=x[x.length-1];if(r&&(n=r.tag,e=void 0!==r.innerText?r.innerText:e),"script"===n||"style"===n)d+=e;else{var i=p(e);d+=t.textFilter?t.textFilter(i):i}if(x.length){var a=x[x.length-1];a.text+=e}}},onclosetag:function(e){if(j){if(E--,E)return;j=!1}var n=x.pop();if(n){if(j=!1,_--,A[_])return delete A[_],void n.updateParentNodeText();if(S[_]&&(e=S[_],delete S[_]),t.exclusiveFilter&&t.exclusiveFilter(n))return void(d=d.substr(0,n.tagPosition));n.updateParentNodeText(),t.selfClosing.indexOf(e)===-1&&(d+="</"+e+">")}}},t.parser);return O.write(e),O.end(),d}var o=e("htmlparser2"),s=e("xtend"),l=e("regexp-quote");t.exports=a;var u={decodeEntities:!0};a.defaults={allowedTags:["h3","h4","h5","h6","blockquote","p","a","ul","ol","nl","li","b","i","strong","em","strike","code","hr","br","div","table","thead","caption","tbody","tr","th","td","pre"],allowedAttributes:{a:["href","name","target"],img:["src"]},selfClosing:["img","br","hr","area","base","basefont","input","link","meta"],allowedSchemes:["http","https","ftp","mailto"],allowedSchemesByTag:{}},a.simpleTransform=function(e,t,n){return n=void 0===n||n,t=t||{},function(r,i){var a;if(n)for(a in t)i[a]=t[a];else i=t;return{tagName:e,attribs:i}}}},{htmlparser2:36,"regexp-quote":54,xtend:58}],2:[function(e,t,n){"use strict";function r(){for(var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",t=0,n=e.length;t<n;++t)l[t]=e[t],u[e.charCodeAt(t)]=t;u["-".charCodeAt(0)]=62,u["_".charCodeAt(0)]=63}function i(e){var t,n,r,i,a,o,s=e.length;if(s%4>0)throw new Error("Invalid string. Length must be a multiple of 4");a="="===e[s-2]?2:"="===e[s-1]?1:0,o=new c(3*s/4-a),r=a>0?s-4:s;var l=0;for(t=0,n=0;t<r;t+=4,n+=3)i=u[e.charCodeAt(t)]<<18|u[e.charCodeAt(t+1)]<<12|u[e.charCodeAt(t+2)]<<6|u[e.charCodeAt(t+3)],o[l++]=i>>16&255,o[l++]=i>>8&255,o[l++]=255&i;return 2===a?(i=u[e.charCodeAt(t)]<<2|u[e.charCodeAt(t+1)]>>4,o[l++]=255&i):1===a&&(i=u[e.charCodeAt(t)]<<10|u[e.charCodeAt(t+1)]<<4|u[e.charCodeAt(t+2)]>>2,o[l++]=i>>8&255,o[l++]=255&i),o}function a(e){return l[e>>18&63]+l[e>>12&63]+l[e>>6&63]+l[63&e]}function o(e,t,n){for(var r,i=[],o=t;o<n;o+=3)r=(e[o]<<16)+(e[o+1]<<8)+e[o+2],i.push(a(r));return i.join("")}function s(e){for(var t,n=e.length,r=n%3,i="",a=[],s=16383,u=0,c=n-r;u<c;u+=s)a.push(o(e,u,u+s>c?c:u+s));return 1===r?(t=e[n-1],i+=l[t>>2],i+=l[t<<4&63],i+="=="):2===r&&(t=(e[n-2]<<8)+e[n-1],i+=l[t>>10],i+=l[t>>4&63],i+=l[t<<2&63],i+="="),a.push(i),a.join("")}n.toByteArray=i,n.fromByteArray=s;var l=[],u=[],c="undefined"!=typeof Uint8Array?Uint8Array:Array;r()},{}],3:[function(e,t,n){},{}],4:[function(e,t,n){(function(t){"use strict";var r=e("buffer"),i=r.Buffer,a=r.SlowBuffer,o=r.kMaxLength||2147483647;n.alloc=function(e,t,n){if("function"==typeof i.alloc)return i.alloc(e,t,n);if("number"==typeof n)throw new TypeError("encoding must not be number");if("number"!=typeof e)throw new TypeError("size must be a number");if(e>o)throw new RangeError("size is too large");var r=n,a=t;void 0===a&&(r=void 0,a=0);var s=new i(e);if("string"==typeof a)for(var l=new i(a,r),u=l.length,c=-1;++c<e;)s[c]=l[c%u];else s.fill(a);return s},n.allocUnsafe=function(e){if("function"==typeof i.allocUnsafe)return i.allocUnsafe(e);if("number"!=typeof e)throw new TypeError("size must be a number");if(e>o)throw new RangeError("size is too large");return new i(e)},n.from=function(e,n,r){if("function"==typeof i.from&&(!t.Uint8Array||Uint8Array.from!==i.from))return i.from(e,n,r);if("number"==typeof e)throw new TypeError('"value" argument must not be a number');if("string"==typeof e)return new i(e,n);if("undefined"!=typeof ArrayBuffer&&e instanceof ArrayBuffer){var a=n;if(1===arguments.length)return new i(e);"undefined"==typeof a&&(a=0);var o=r;if("undefined"==typeof o&&(o=e.byteLength-a),a>=e.byteLength)throw new RangeError("'offset' is out of bounds");if(o>e.byteLength-a)throw new RangeError("'length' is out of bounds");return new i(e.slice(a,a+o))}if(i.isBuffer(e)){var s=new i(e.length);return e.copy(s,0,0,e.length),s}if(e){if(Array.isArray(e)||"undefined"!=typeof ArrayBuffer&&e.buffer instanceof ArrayBuffer||"length"in e)return new i(e);if("Buffer"===e.type&&Array.isArray(e.data))return new i(e.data)}throw new TypeError("First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.")},n.allocUnsafeSlow=function(e){if("function"==typeof i.allocUnsafeSlow)return i.allocUnsafeSlow(e);if("number"!=typeof e)throw new TypeError("size must be a number");if(e>=o)throw new RangeError("size is too large");return new a(e)}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{buffer:5}],5:[function(e,t,n){(function(t){"use strict";function r(){try{var e=new Uint8Array(1);return e.__proto__={__proto__:Uint8Array.prototype,foo:function(){return 42}},42===e.foo()&&"function"==typeof e.subarray&&0===e.subarray(1,1).byteLength}catch(t){return!1}}function i(){return o.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function a(e,t){if(i()<t)throw new RangeError("Invalid typed array length");return o.TYPED_ARRAY_SUPPORT?(e=new Uint8Array(t),e.__proto__=o.prototype):(null===e&&(e=new o(t)),e.length=t),e}function o(e,t,n){if(!(o.TYPED_ARRAY_SUPPORT||this instanceof o))return new o(e,t,n);if("number"==typeof e){if("string"==typeof t)throw new Error("If encoding is specified then the first argument must be a string");return c(this,e)}return s(this,e,t,n)}function s(e,t,n,r){if("number"==typeof t)throw new TypeError('"value" argument must not be a number');return"undefined"!=typeof ArrayBuffer&&t instanceof ArrayBuffer?f(e,t,n,r):"string"==typeof t?p(e,t,n):d(e,t)}function l(e){if("number"!=typeof e)throw new TypeError('"size" argument must be a number');if(e<0)throw new RangeError('"size" argument must not be negative')}function u(e,t,n,r){return l(t),t<=0?a(e,t):void 0!==n?"string"==typeof r?a(e,t).fill(n,r):a(e,t).fill(n):a(e,t)}function c(e,t){if(l(t),e=a(e,t<0?0:0|m(t)),!o.TYPED_ARRAY_SUPPORT)for(var n=0;n<t;++n)e[n]=0;return e}function p(e,t,n){if("string"==typeof n&&""!==n||(n="utf8"),!o.isEncoding(n))throw new TypeError('"encoding" must be a valid string encoding');var r=0|y(t,n);e=a(e,r);var i=e.write(t,n);return i!==r&&(e=e.slice(0,i)),e}function h(e,t){var n=t.length<0?0:0|m(t.length);e=a(e,n);for(var r=0;r<n;r+=1)e[r]=255&t[r];return e}function f(e,t,n,r){if(t.byteLength,n<0||t.byteLength<n)throw new RangeError("'offset' is out of bounds");if(t.byteLength<n+(r||0))throw new RangeError("'length' is out of bounds");return t=void 0===n&&void 0===r?new Uint8Array(t):void 0===r?new Uint8Array(t,n):new Uint8Array(t,n,r),o.TYPED_ARRAY_SUPPORT?(e=t,e.__proto__=o.prototype):e=h(e,t),e}function d(e,t){if(o.isBuffer(t)){var n=0|m(t.length);return e=a(e,n),0===e.length?e:(t.copy(e,0,0,n),e)}if(t){if("undefined"!=typeof ArrayBuffer&&t.buffer instanceof ArrayBuffer||"length"in t)return"number"!=typeof t.length||G(t.length)?a(e,0):h(e,t);if("Buffer"===t.type&&Z(t.data))return h(e,t.data)}throw new TypeError("First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.")}function m(e){if(e>=i())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+i().toString(16)+" bytes");return 0|e}function g(e){return+e!=e&&(e=0),o.alloc(+e)}function y(e,t){if(o.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return H(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return W(e).length;default:if(r)return H(e).length;t=(""+t).toLowerCase(),r=!0}}function v(e,t,n){var r=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if(n>>>=0,t>>>=0,n<=t)return"";for(e||(e="utf8");;)switch(e){case"hex":return L(this,t,n);case"utf8":case"utf-8":return T(this,t,n);case"ascii":return I(this,t,n);case"latin1":case"binary":return D(this,t,n);case"base64":return k(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return M(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}function b(e,t,n){var r=e[t];e[t]=e[n],e[n]=r}function w(e,t,n,r,i){if(0===e.length)return-1;if("string"==typeof n?(r=n,n=0):n>2147483647?n=2147483647:n<-2147483648&&(n=-2147483648),n=+n,isNaN(n)&&(n=i?0:e.length-1),n<0&&(n=e.length+n),n>=e.length){if(i)return-1;n=e.length-1}else if(n<0){if(!i)return-1;n=0}if("string"==typeof t&&(t=o.from(t,r)),o.isBuffer(t))return 0===t.length?-1:_(e,t,n,r,i);if("number"==typeof t)return t=255&t,o.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(e,t,n):Uint8Array.prototype.lastIndexOf.call(e,t,n):_(e,[t],n,r,i);throw new TypeError("val must be string, number or Buffer")}function _(e,t,n,r,i){function a(e,t){return 1===o?e[t]:e.readUInt16BE(t*o)}var o=1,s=e.length,l=t.length;if(void 0!==r&&(r=String(r).toLowerCase(),"ucs2"===r||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;o=2,s/=2,l/=2,n/=2}var u;if(i){var c=-1;for(u=n;u<s;u++)if(a(e,u)===a(t,c===-1?0:u-c)){if(c===-1&&(c=u),u-c+1===l)return c*o}else c!==-1&&(u-=u-c),c=-1}else for(n+l>s&&(n=s-l),u=n;u>=0;u--){for(var p=!0,h=0;h<l;h++)if(a(e,u+h)!==a(t,h)){p=!1;break}if(p)return u}return-1}function x(e,t,n,r){n=Number(n)||0;var i=e.length-n;r?(r=Number(r),r>i&&(r=i)):r=i;var a=t.length;if(a%2!==0)throw new TypeError("Invalid hex string");r>a/2&&(r=a/2);for(var o=0;o<r;++o){var s=parseInt(t.substr(2*o,2),16);if(isNaN(s))return o;e[n+o]=s}return o}function A(e,t,n,r){return Q(H(t,e.length-n),e,n,r)}function S(e,t,n,r){return Q(Y(t),e,n,r)}function j(e,t,n,r){return S(e,t,n,r)}function E(e,t,n,r){return Q(W(t),e,n,r)}function O(e,t,n,r){return Q(J(t,e.length-n),e,n,r)}function k(e,t,n){return 0===t&&n===e.length?K.fromByteArray(e):K.fromByteArray(e.slice(t,n))}function T(e,t,n){n=Math.min(e.length,n);for(var r=[],i=t;i<n;){var a=e[i],o=null,s=a>239?4:a>223?3:a>191?2:1;if(i+s<=n){var l,u,c,p;switch(s){case 1:a<128&&(o=a);break;case 2:l=e[i+1],128===(192&l)&&(p=(31&a)<<6|63&l,p>127&&(o=p));break;case 3:l=e[i+1],u=e[i+2],128===(192&l)&&128===(192&u)&&(p=(15&a)<<12|(63&l)<<6|63&u,p>2047&&(p<55296||p>57343)&&(o=p));break;case 4:l=e[i+1],u=e[i+2],c=e[i+3],128===(192&l)&&128===(192&u)&&128===(192&c)&&(p=(15&a)<<18|(63&l)<<12|(63&u)<<6|63&c,p>65535&&p<1114112&&(o=p))}}null===o?(o=65533,s=1):o>65535&&(o-=65536,r.push(o>>>10&1023|55296),o=56320|1023&o),r.push(o),i+=s}return C(r)}function C(e){var t=e.length;if(t<=ee)return String.fromCharCode.apply(String,e);for(var n="",r=0;r<t;)n+=String.fromCharCode.apply(String,e.slice(r,r+=ee));return n}function I(e,t,n){var r="";n=Math.min(e.length,n);for(var i=t;i<n;++i)r+=String.fromCharCode(127&e[i]);return r}function D(e,t,n){var r="";n=Math.min(e.length,n);for(var i=t;i<n;++i)r+=String.fromCharCode(e[i]);return r}function L(e,t,n){var r=e.length;(!t||t<0)&&(t=0),(!n||n<0||n>r)&&(n=r);for(var i="",a=t;a<n;++a)i+=V(e[a]);return i}function M(e,t,n){for(var r=e.slice(t,n),i="",a=0;a<r.length;a+=2)i+=String.fromCharCode(r[a]+256*r[a+1]);return i}function R(e,t,n){if(e%1!==0||e<0)throw new RangeError("offset is not uint");if(e+t>n)throw new RangeError("Trying to access beyond buffer length")}function U(e,t,n,r,i,a){if(!o.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>i||t<a)throw new RangeError('"value" argument is out of bounds');if(n+r>e.length)throw new RangeError("Index out of range")}function P(e,t,n,r){t<0&&(t=65535+t+1);for(var i=0,a=Math.min(e.length-n,2);i<a;++i)e[n+i]=(t&255<<8*(r?i:1-i))>>>8*(r?i:1-i)}function q(e,t,n,r){t<0&&(t=4294967295+t+1);for(var i=0,a=Math.min(e.length-n,4);i<a;++i)e[n+i]=t>>>8*(r?i:3-i)&255}function B(e,t,n,r,i,a){if(n+r>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function z(e,t,n,r,i){return i||B(e,t,n,4,3.4028234663852886e38,-3.4028234663852886e38),X.write(e,t,n,r,23,4),n+4}function N(e,t,n,r,i){return i||B(e,t,n,8,1.7976931348623157e308,-1.7976931348623157e308),X.write(e,t,n,r,52,8),n+8}function $(e){if(e=F(e).replace(te,""),e.length<2)return"";for(;e.length%4!==0;)e+="=";return e}function F(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}function V(e){return e<16?"0"+e.toString(16):e.toString(16)}function H(e,t){t=t||1/0;for(var n,r=e.length,i=null,a=[],o=0;o<r;++o){if(n=e.charCodeAt(o),n>55295&&n<57344){if(!i){if(n>56319){(t-=3)>-1&&a.push(239,191,189);continue}if(o+1===r){(t-=3)>-1&&a.push(239,191,189);continue}i=n;continue}if(n<56320){(t-=3)>-1&&a.push(239,191,189),i=n;continue}n=(i-55296<<10|n-56320)+65536}else i&&(t-=3)>-1&&a.push(239,191,189);if(i=null,n<128){if((t-=1)<0)break;a.push(n)}else if(n<2048){if((t-=2)<0)break;a.push(n>>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;a.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;a.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return a}function Y(e){for(var t=[],n=0;n<e.length;++n)t.push(255&e.charCodeAt(n));return t}function J(e,t){for(var n,r,i,a=[],o=0;o<e.length&&!((t-=2)<0);++o)n=e.charCodeAt(o),r=n>>8,i=n%256,a.push(i),a.push(r);return a}function W(e){return K.toByteArray($(e))}function Q(e,t,n,r){for(var i=0;i<r&&!(i+n>=t.length||i>=e.length);++i)t[i+n]=e[i];return i}function G(e){return e!==e}var K=e("base64-js"),X=e("ieee754"),Z=e("isarray");n.Buffer=o,n.SlowBuffer=g,n.INSPECT_MAX_BYTES=50,o.TYPED_ARRAY_SUPPORT=void 0!==t.TYPED_ARRAY_SUPPORT?t.TYPED_ARRAY_SUPPORT:r(),n.kMaxLength=i(),o.poolSize=8192,o._augment=function(e){return e.__proto__=o.prototype,e},o.from=function(e,t,n){return s(null,e,t,n)},o.TYPED_ARRAY_SUPPORT&&(o.prototype.__proto__=Uint8Array.prototype,o.__proto__=Uint8Array,"undefined"!=typeof Symbol&&Symbol.species&&o[Symbol.species]===o&&Object.defineProperty(o,Symbol.species,{value:null,configurable:!0})),o.alloc=function(e,t,n){return u(null,e,t,n)},o.allocUnsafe=function(e){return c(null,e)},o.allocUnsafeSlow=function(e){return c(null,e)},o.isBuffer=function(e){return!(null==e||!e._isBuffer)},o.compare=function(e,t){if(!o.isBuffer(e)||!o.isBuffer(t))throw new TypeError("Arguments must be Buffers");if(e===t)return 0;for(var n=e.length,r=t.length,i=0,a=Math.min(n,r);i<a;++i)if(e[i]!==t[i]){n=e[i],r=t[i];break}return n<r?-1:r<n?1:0},o.isEncoding=function(e){switch(String(e).toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"latin1":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return!0;default:return!1}},o.concat=function(e,t){if(!Z(e))throw new TypeError('"list" argument must be an Array of Buffers');if(0===e.length)return o.alloc(0);var n;if(void 0===t)for(t=0,n=0;n<e.length;++n)t+=e[n].length;var r=o.allocUnsafe(t),i=0;for(n=0;n<e.length;++n){var a=e[n];if(!o.isBuffer(a))throw new TypeError('"list" argument must be an Array of Buffers');a.copy(r,i),i+=a.length}return r},o.byteLength=y,o.prototype._isBuffer=!0,o.prototype.swap16=function(){var e=this.length;if(e%2!==0)throw new RangeError("Buffer size must be a multiple of 16-bits");for(var t=0;t<e;t+=2)b(this,t,t+1);return this},o.prototype.swap32=function(){var e=this.length;if(e%4!==0)throw new RangeError("Buffer size must be a multiple of 32-bits");for(var t=0;t<e;t+=4)b(this,t,t+3),b(this,t+1,t+2);return this},o.prototype.swap64=function(){var e=this.length;if(e%8!==0)throw new RangeError("Buffer size must be a multiple of 64-bits");for(var t=0;t<e;t+=8)b(this,t,t+7),b(this,t+1,t+6),b(this,t+2,t+5),b(this,t+3,t+4);return this},o.prototype.toString=function(){var e=0|this.length;return 0===e?"":0===arguments.length?T(this,0,e):v.apply(this,arguments)},o.prototype.equals=function(e){if(!o.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e||0===o.compare(this,e)},o.prototype.inspect=function(){var e="",t=n.INSPECT_MAX_BYTES;return this.length>0&&(e=this.toString("hex",0,t).match(/.{2}/g).join(" "),this.length>t&&(e+=" ... ")),"<Buffer "+e+">"},o.prototype.compare=function(e,t,n,r,i){if(!o.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===r&&(r=0),void 0===i&&(i=this.length),t<0||n>e.length||r<0||i>this.length)throw new RangeError("out of range index");if(r>=i&&t>=n)return 0;if(r>=i)return-1;if(t>=n)return 1;if(t>>>=0,n>>>=0,r>>>=0,i>>>=0,this===e)return 0;for(var a=i-r,s=n-t,l=Math.min(a,s),u=this.slice(r,i),c=e.slice(t,n),p=0;p<l;++p)if(u[p]!==c[p]){a=u[p],s=c[p];break}return a<s?-1:s<a?1:0},o.prototype.includes=function(e,t,n){return this.indexOf(e,t,n)!==-1},o.prototype.indexOf=function(e,t,n){return w(this,e,t,n,!0)},o.prototype.lastIndexOf=function(e,t,n){return w(this,e,t,n,!1)},o.prototype.write=function(e,t,n,r){if(void 0===t)r="utf8",n=this.length,t=0;else if(void 0===n&&"string"==typeof t)r=t,n=this.length,t=0;else{if(!isFinite(t))throw new Error("Buffer.write(string, encoding, offset[, length]) is no longer supported");t=0|t,isFinite(n)?(n=0|n,void 0===r&&(r="utf8")):(r=n,n=void 0)}var i=this.length-t;if((void 0===n||n>i)&&(n=i),e.length>0&&(n<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");r||(r="utf8");for(var a=!1;;)switch(r){case"hex":return x(this,e,t,n);case"utf8":case"utf-8":return A(this,e,t,n);case"ascii":return S(this,e,t,n);case"latin1":case"binary":return j(this,e,t,n);case"base64":return E(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return O(this,e,t,n);default:if(a)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),a=!0}},o.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var ee=4096;o.prototype.slice=function(e,t){var n=this.length;e=~~e,t=void 0===t?n:~~t,e<0?(e+=n,e<0&&(e=0)):e>n&&(e=n),t<0?(t+=n,t<0&&(t=0)):t>n&&(t=n),
+t<e&&(t=e);var r;if(o.TYPED_ARRAY_SUPPORT)r=this.subarray(e,t),r.__proto__=o.prototype;else{var i=t-e;r=new o(i,(void 0));for(var a=0;a<i;++a)r[a]=this[a+e]}return r},o.prototype.readUIntLE=function(e,t,n){e=0|e,t=0|t,n||R(e,t,this.length);for(var r=this[e],i=1,a=0;++a<t&&(i*=256);)r+=this[e+a]*i;return r},o.prototype.readUIntBE=function(e,t,n){e=0|e,t=0|t,n||R(e,t,this.length);for(var r=this[e+--t],i=1;t>0&&(i*=256);)r+=this[e+--t]*i;return r},o.prototype.readUInt8=function(e,t){return t||R(e,1,this.length),this[e]},o.prototype.readUInt16LE=function(e,t){return t||R(e,2,this.length),this[e]|this[e+1]<<8},o.prototype.readUInt16BE=function(e,t){return t||R(e,2,this.length),this[e]<<8|this[e+1]},o.prototype.readUInt32LE=function(e,t){return t||R(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},o.prototype.readUInt32BE=function(e,t){return t||R(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},o.prototype.readIntLE=function(e,t,n){e=0|e,t=0|t,n||R(e,t,this.length);for(var r=this[e],i=1,a=0;++a<t&&(i*=256);)r+=this[e+a]*i;return i*=128,r>=i&&(r-=Math.pow(2,8*t)),r},o.prototype.readIntBE=function(e,t,n){e=0|e,t=0|t,n||R(e,t,this.length);for(var r=t,i=1,a=this[e+--r];r>0&&(i*=256);)a+=this[e+--r]*i;return i*=128,a>=i&&(a-=Math.pow(2,8*t)),a},o.prototype.readInt8=function(e,t){return t||R(e,1,this.length),128&this[e]?(255-this[e]+1)*-1:this[e]},o.prototype.readInt16LE=function(e,t){t||R(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},o.prototype.readInt16BE=function(e,t){t||R(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},o.prototype.readInt32LE=function(e,t){return t||R(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},o.prototype.readInt32BE=function(e,t){return t||R(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},o.prototype.readFloatLE=function(e,t){return t||R(e,4,this.length),X.read(this,e,!0,23,4)},o.prototype.readFloatBE=function(e,t){return t||R(e,4,this.length),X.read(this,e,!1,23,4)},o.prototype.readDoubleLE=function(e,t){return t||R(e,8,this.length),X.read(this,e,!0,52,8)},o.prototype.readDoubleBE=function(e,t){return t||R(e,8,this.length),X.read(this,e,!1,52,8)},o.prototype.writeUIntLE=function(e,t,n,r){if(e=+e,t=0|t,n=0|n,!r){var i=Math.pow(2,8*n)-1;U(this,e,t,n,i,0)}var a=1,o=0;for(this[t]=255&e;++o<n&&(a*=256);)this[t+o]=e/a&255;return t+n},o.prototype.writeUIntBE=function(e,t,n,r){if(e=+e,t=0|t,n=0|n,!r){var i=Math.pow(2,8*n)-1;U(this,e,t,n,i,0)}var a=n-1,o=1;for(this[t+a]=255&e;--a>=0&&(o*=256);)this[t+a]=e/o&255;return t+n},o.prototype.writeUInt8=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,1,255,0),o.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=255&e,t+1},o.prototype.writeUInt16LE=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,2,65535,0),o.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):P(this,e,t,!0),t+2},o.prototype.writeUInt16BE=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,2,65535,0),o.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):P(this,e,t,!1),t+2},o.prototype.writeUInt32LE=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,4,4294967295,0),o.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):q(this,e,t,!0),t+4},o.prototype.writeUInt32BE=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,4,4294967295,0),o.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):q(this,e,t,!1),t+4},o.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t=0|t,!r){var i=Math.pow(2,8*n-1);U(this,e,t,n,i-1,-i)}var a=0,o=1,s=0;for(this[t]=255&e;++a<n&&(o*=256);)e<0&&0===s&&0!==this[t+a-1]&&(s=1),this[t+a]=(e/o>>0)-s&255;return t+n},o.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t=0|t,!r){var i=Math.pow(2,8*n-1);U(this,e,t,n,i-1,-i)}var a=n-1,o=1,s=0;for(this[t+a]=255&e;--a>=0&&(o*=256);)e<0&&0===s&&0!==this[t+a+1]&&(s=1),this[t+a]=(e/o>>0)-s&255;return t+n},o.prototype.writeInt8=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,1,127,-128),o.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=255&e,t+1},o.prototype.writeInt16LE=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,2,32767,-32768),o.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):P(this,e,t,!0),t+2},o.prototype.writeInt16BE=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,2,32767,-32768),o.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):P(this,e,t,!1),t+2},o.prototype.writeInt32LE=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,4,2147483647,-2147483648),o.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):q(this,e,t,!0),t+4},o.prototype.writeInt32BE=function(e,t,n){return e=+e,t=0|t,n||U(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),o.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):q(this,e,t,!1),t+4},o.prototype.writeFloatLE=function(e,t,n){return z(this,e,t,!0,n)},o.prototype.writeFloatBE=function(e,t,n){return z(this,e,t,!1,n)},o.prototype.writeDoubleLE=function(e,t,n){return N(this,e,t,!0,n)},o.prototype.writeDoubleBE=function(e,t,n){return N(this,e,t,!1,n)},o.prototype.copy=function(e,t,n,r){if(n||(n=0),r||0===r||(r=this.length),t>=e.length&&(t=e.length),t||(t=0),r>0&&r<n&&(r=n),r===n)return 0;if(0===e.length||0===this.length)return 0;if(t<0)throw new RangeError("targetStart out of bounds");if(n<0||n>=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t<r-n&&(r=e.length-t+n);var i,a=r-n;if(this===e&&n<t&&t<r)for(i=a-1;i>=0;--i)e[i+t]=this[i+n];else if(a<1e3||!o.TYPED_ARRAY_SUPPORT)for(i=0;i<a;++i)e[i+t]=this[i+n];else Uint8Array.prototype.set.call(e,this.subarray(n,n+a),t);return a},o.prototype.fill=function(e,t,n,r){if("string"==typeof e){if("string"==typeof t?(r=t,t=0,n=this.length):"string"==typeof n&&(r=n,n=this.length),1===e.length){var i=e.charCodeAt(0);i<256&&(e=i)}if(void 0!==r&&"string"!=typeof r)throw new TypeError("encoding must be a string");if("string"==typeof r&&!o.isEncoding(r))throw new TypeError("Unknown encoding: "+r)}else"number"==typeof e&&(e=255&e);if(t<0||this.length<t||this.length<n)throw new RangeError("Out of range index");if(n<=t)return this;t>>>=0,n=void 0===n?this.length:n>>>0,e||(e=0);var a;if("number"==typeof e)for(a=t;a<n;++a)this[a]=e;else{var s=o.isBuffer(e)?e:H(new o(e,r).toString()),l=s.length;for(a=0;a<n-t;++a)this[a+t]=s[a%l]}return this};var te=/[^+\/0-9A-Za-z-_]/g}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"base64-js":2,ieee754:37,isarray:40}],6:[function(e,t,n){(function(e){function t(e){return Array.isArray?Array.isArray(e):"[object Array]"===g(e)}function r(e){return"boolean"==typeof e}function i(e){return null===e}function a(e){return null==e}function o(e){return"number"==typeof e}function s(e){return"string"==typeof e}function l(e){return"symbol"==typeof e}function u(e){return void 0===e}function c(e){return"[object RegExp]"===g(e)}function p(e){return"object"==typeof e&&null!==e}function h(e){return"[object Date]"===g(e)}function f(e){return"[object Error]"===g(e)||e instanceof Error}function d(e){return"function"==typeof e}function m(e){return null===e||"boolean"==typeof e||"number"==typeof e||"string"==typeof e||"symbol"==typeof e||"undefined"==typeof e}function g(e){return Object.prototype.toString.call(e)}n.isArray=t,n.isBoolean=r,n.isNull=i,n.isNullOrUndefined=a,n.isNumber=o,n.isString=s,n.isSymbol=l,n.isUndefined=u,n.isRegExp=c,n.isObject=p,n.isDate=h,n.isError=f,n.isFunction=d,n.isPrimitive=m,n.isBuffer=e.isBuffer}).call(this,{isBuffer:e("../../is-buffer/index.js")})},{"../../is-buffer/index.js":39}],7:[function(e,t,n){function r(e,t){if(e){var n,r="";for(var i in e)n=e[i],r&&(r+=" "),r+=!n&&p[i]?i:i+'="'+(t.decodeEntities?c.encodeXML(n):n)+'"';return r}}function i(e,t){"svg"===e.name&&(t={decodeEntities:t.decodeEntities,xmlMode:!0});var n="<"+e.name,i=r(e.attribs,t);return i&&(n+=" "+i),!t.xmlMode||e.children&&0!==e.children.length?(n+=">",e.children&&(n+=d(e.children,t)),f[e.name]&&!t.xmlMode||(n+="</"+e.name+">")):n+="/>",n}function a(e){return"<"+e.data+">"}function o(e,t){var n=e.data||"";return!t.decodeEntities||e.parent&&e.parent.name in h||(n=c.encodeXML(n)),n}function s(e){return"<![CDATA["+e.children[0].data+"]]>"}function l(e){return"<!--"+e.data+"-->"}var u=e("domelementtype"),c=e("entities"),p={__proto__:null,allowfullscreen:!0,async:!0,autofocus:!0,autoplay:!0,checked:!0,controls:!0,"default":!0,defer:!0,disabled:!0,hidden:!0,ismap:!0,loop:!0,multiple:!0,muted:!0,open:!0,readonly:!0,required:!0,reversed:!0,scoped:!0,seamless:!0,selected:!0,typemustmatch:!0},h={__proto__:null,style:!0,script:!0,xmp:!0,iframe:!0,noembed:!0,noframes:!0,plaintext:!0,noscript:!0},f={__proto__:null,area:!0,base:!0,basefont:!0,br:!0,col:!0,command:!0,embed:!0,frame:!0,hr:!0,img:!0,input:!0,isindex:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0},d=t.exports=function(e,t){Array.isArray(e)||e.cheerio||(e=[e]),t=t||{};for(var n="",r=0;r<e.length;r++){var c=e[r];n+="root"===c.type?d(c.children,t):u.isTag(c)?i(c,t):c.type===u.Directive?a(c):c.type===u.Comment?l(c):c.type===u.CDATA?s(c):o(c,t)}return n}},{domelementtype:8,entities:20}],8:[function(e,t,n){t.exports={Text:"text",Directive:"directive",Comment:"comment",Script:"script",Style:"style",Tag:"tag",CDATA:"cdata",isTag:function(e){return"tag"===e.type||"script"===e.type||"style"===e.type}}},{}],9:[function(e,t,n){t.exports={Text:"text",Directive:"directive",Comment:"comment",Script:"script",Style:"style",Tag:"tag",CDATA:"cdata",Doctype:"doctype",isTag:function(e){return"tag"===e.type||"script"===e.type||"style"===e.type}}},{}],10:[function(e,t,n){function r(e,t,n){"object"==typeof e?(n=t,t=e,e=null):"function"==typeof t&&(n=t,t=l),this._callback=e,this._options=t||l,this._elementCB=n,this.dom=[],this._done=!1,this._tagStack=[],this._parser=this._parser||null}var i=e("domelementtype"),a=/\s+/g,o=e("./lib/node"),s=e("./lib/element"),l={normalizeWhitespace:!1,withStartIndices:!1};r.prototype.onparserinit=function(e){this._parser=e},r.prototype.onreset=function(){r.call(this,this._callback,this._options,this._elementCB)},r.prototype.onend=function(){this._done||(this._done=!0,this._parser=null,this._handleCallback(null))},r.prototype._handleCallback=r.prototype.onerror=function(e){if("function"==typeof this._callback)this._callback(e,this.dom);else if(e)throw e},r.prototype.onclosetag=function(){var e=this._tagStack.pop();this._elementCB&&this._elementCB(e)},r.prototype._addDomElement=function(e){var t=this._tagStack[this._tagStack.length-1],n=t?t.children:this.dom,r=n[n.length-1];e.next=null,this._options.withStartIndices&&(e.startIndex=this._parser.startIndex),this._options.withDomLvl1&&(e.__proto__="tag"===e.type?s:o),r?(e.prev=r,r.next=e):e.prev=null,n.push(e),e.parent=t||null},r.prototype.onopentag=function(e,t){var n={type:"script"===e?i.Script:"style"===e?i.Style:i.Tag,name:e,attribs:t,children:[]};this._addDomElement(n),this._tagStack.push(n)},r.prototype.ontext=function(e){var t,n=this._options.normalizeWhitespace||this._options.ignoreWhitespace;!this._tagStack.length&&this.dom.length&&(t=this.dom[this.dom.length-1]).type===i.Text?n?t.data=(t.data+e).replace(a," "):t.data+=e:this._tagStack.length&&(t=this._tagStack[this._tagStack.length-1])&&(t=t.children[t.children.length-1])&&t.type===i.Text?n?t.data=(t.data+e).replace(a," "):t.data+=e:(n&&(e=e.replace(a," ")),this._addDomElement({data:e,type:i.Text}))},r.prototype.oncomment=function(e){var t=this._tagStack[this._tagStack.length-1];if(t&&t.type===i.Comment)return void(t.data+=e);var n={data:e,type:i.Comment};this._addDomElement(n),this._tagStack.push(n)},r.prototype.oncdatastart=function(){var e={children:[{data:"",type:i.Text}],type:i.CDATA};this._addDomElement(e),this._tagStack.push(e)},r.prototype.oncommentend=r.prototype.oncdataend=function(){this._tagStack.pop()},r.prototype.onprocessinginstruction=function(e,t){this._addDomElement({name:e,data:t,type:i.Directive})},t.exports=r},{"./lib/element":11,"./lib/node":12,domelementtype:9}],11:[function(e,t,n){var r=e("./node"),i=t.exports=Object.create(r),a={tagName:"name"};Object.keys(a).forEach(function(e){var t=a[e];Object.defineProperty(i,e,{get:function(){return this[t]||null},set:function(e){return this[t]=e,e}})})},{"./node":12}],12:[function(e,t,n){var r=t.exports={get firstChild(){var e=this.children;return e&&e[0]||null},get lastChild(){var e=this.children;return e&&e[e.length-1]||null},get nodeType(){return a[this.type]||a.element}},i={tagName:"name",childNodes:"children",parentNode:"parent",previousSibling:"prev",nextSibling:"next",nodeValue:"data"},a={element:1,text:3,cdata:4,comment:8};Object.keys(i).forEach(function(e){var t=i[e];Object.defineProperty(r,e,{get:function(){return this[t]||null},set:function(e){return this[t]=e,e}})})},{}],13:[function(e,t,n){var r=t.exports;[e("./lib/stringify"),e("./lib/traversal"),e("./lib/manipulation"),e("./lib/querying"),e("./lib/legacy"),e("./lib/helpers")].forEach(function(e){Object.keys(e).forEach(function(t){r[t]=e[t].bind(r)})})},{"./lib/helpers":14,"./lib/legacy":15,"./lib/manipulation":16,"./lib/querying":17,"./lib/stringify":18,"./lib/traversal":19}],14:[function(e,t,n){n.removeSubsets=function(e){for(var t,n,r,i=e.length;--i>-1;){for(t=n=e[i],e[i]=null,r=!0;n;){if(e.indexOf(n)>-1){r=!1,e.splice(i,1);break}n=n.parent}r&&(e[i]=t)}return e};var r={DISCONNECTED:1,PRECEDING:2,FOLLOWING:4,CONTAINS:8,CONTAINED_BY:16},i=n.compareDocumentPosition=function(e,t){var n,i,a,o,s,l,u=[],c=[];if(e===t)return 0;for(n=e;n;)u.unshift(n),n=n.parent;for(n=t;n;)c.unshift(n),n=n.parent;for(l=0;u[l]===c[l];)l++;return 0===l?r.DISCONNECTED:(i=u[l-1],a=i.children,o=u[l],s=c[l],a.indexOf(o)>a.indexOf(s)?i===t?r.FOLLOWING|r.CONTAINED_BY:r.FOLLOWING:i===e?r.PRECEDING|r.CONTAINS:r.PRECEDING)};n.uniqueSort=function(e){var t,n,a=e.length;for(e=e.slice();--a>-1;)t=e[a],n=e.indexOf(t),n>-1&&n<a&&e.splice(a,1);return e.sort(function(e,t){var n=i(e,t);return n&r.PRECEDING?-1:n&r.FOLLOWING?1:0}),e}},{}],15:[function(e,t,n){function r(e,t){return"function"==typeof t?function(n){return n.attribs&&t(n.attribs[e])}:function(n){return n.attribs&&n.attribs[e]===t}}function i(e,t){return function(n){return e(n)||t(n)}}var a=e("domelementtype"),o=n.isTag=a.isTag;n.testElement=function(e,t){for(var n in e)if(e.hasOwnProperty(n)){if("tag_name"===n){if(!o(t)||!e.tag_name(t.name))return!1}else if("tag_type"===n){if(!e.tag_type(t.type))return!1}else if("tag_contains"===n){if(o(t)||!e.tag_contains(t.data))return!1}else if(!t.attribs||!e[n](t.attribs[n]))return!1}else;return!0};var s={tag_name:function(e){return"function"==typeof e?function(t){return o(t)&&e(t.name)}:"*"===e?o:function(t){return o(t)&&t.name===e}},tag_type:function(e){return"function"==typeof e?function(t){return e(t.type)}:function(t){return t.type===e}},tag_contains:function(e){return"function"==typeof e?function(t){return!o(t)&&e(t.data)}:function(t){return!o(t)&&t.data===e}}};n.getElements=function(e,t,n,a){var o=Object.keys(e).map(function(t){var n=e[t];return t in s?s[t](n):r(t,n)});return 0===o.length?[]:this.filter(o.reduce(i),t,n,a)},n.getElementById=function(e,t,n){return Array.isArray(t)||(t=[t]),this.findOne(r("id",e),t,n!==!1)},n.getElementsByTagName=function(e,t,n,r){return this.filter(s.tag_name(e),t,n,r)},n.getElementsByTagType=function(e,t,n,r){return this.filter(s.tag_type(e),t,n,r)}},{domelementtype:9}],16:[function(e,t,n){n.removeElement=function(e){if(e.prev&&(e.prev.next=e.next),e.next&&(e.next.prev=e.prev),e.parent){var t=e.parent.children;t.splice(t.lastIndexOf(e),1)}},n.replaceElement=function(e,t){var n=t.prev=e.prev;n&&(n.next=t);var r=t.next=e.next;r&&(r.prev=t);var i=t.parent=e.parent;if(i){var a=i.children;a[a.lastIndexOf(e)]=t}},n.appendChild=function(e,t){if(t.parent=e,1!==e.children.push(t)){var n=e.children[e.children.length-2];n.next=t,t.prev=n,t.next=null}},n.append=function(e,t){var n=e.parent,r=e.next;if(t.next=r,t.prev=e,e.next=t,t.parent=n,r){if(r.prev=t,n){var i=n.children;i.splice(i.lastIndexOf(r),0,t)}}else n&&n.children.push(t)},n.prepend=function(e,t){var n=e.parent;if(n){var r=n.children;r.splice(r.lastIndexOf(e),0,t)}e.prev&&(e.prev.next=t),t.parent=n,t.prev=e.prev,t.next=e,e.prev=t}},{}],17:[function(e,t,n){function r(e,t,n,r){return Array.isArray(t)||(t=[t]),"number"==typeof r&&isFinite(r)||(r=1/0),i(e,t,n!==!1,r)}function i(e,t,n,r){for(var a,o=[],s=0,l=t.length;s<l&&!(e(t[s])&&(o.push(t[s]),--r<=0))&&(a=t[s].children,!(n&&a&&a.length>0&&(a=i(e,a,n,r),o=o.concat(a),r-=a.length,r<=0)));s++);return o}function a(e,t){for(var n=0,r=t.length;n<r;n++)if(e(t[n]))return t[n];return null}function o(e,t){for(var n=null,r=0,i=t.length;r<i&&!n;r++)u(t[r])&&(e(t[r])?n=t[r]:t[r].children.length>0&&(n=o(e,t[r].children)));return n}function s(e,t){for(var n=0,r=t.length;n<r;n++)if(u(t[n])&&(e(t[n])||t[n].children.length>0&&s(e,t[n].children)))return!0;return!1}function l(e,t){for(var n=[],r=0,i=t.length;r<i;r++)u(t[r])&&(e(t[r])&&n.push(t[r]),t[r].children.length>0&&(n=n.concat(l(e,t[r].children))));return n}var u=e("domelementtype").isTag;t.exports={filter:r,find:i,findOneChild:a,findOne:o,existsOne:s,findAll:l}},{domelementtype:9}],18:[function(e,t,n){function r(e,t){return e.children?e.children.map(function(e){return o(e,t)}).join(""):""}function i(e){return Array.isArray(e)?e.map(i).join(""):s(e)||e.type===a.CDATA?i(e.children):e.type===a.Text?e.data:""}var a=e("domelementtype"),o=e("dom-serializer"),s=a.isTag;t.exports={getInnerHTML:r,getOuterHTML:o,getText:i}},{"dom-serializer":7,domelementtype:9}],19:[function(e,t,n){var r=n.getChildren=function(e){return e.children},i=n.getParent=function(e){return e.parent};n.getSiblings=function(e){var t=i(e);return t?r(t):[e]},n.getAttributeValue=function(e,t){return e.attribs&&e.attribs[t]},n.hasAttrib=function(e,t){return!!e.attribs&&hasOwnProperty.call(e.attribs,t)},n.getName=function(e){return e.name}},{}],20:[function(e,t,n){var r=e("./lib/encode.js"),i=e("./lib/decode.js");n.decode=function(e,t){return(!t||t<=0?i.XML:i.HTML)(e)},n.decodeStrict=function(e,t){return(!t||t<=0?i.XML:i.HTMLStrict)(e)},n.encode=function(e,t){return(!t||t<=0?r.XML:r.HTML)(e)},n.encodeXML=r.XML,n.encodeHTML4=n.encodeHTML5=n.encodeHTML=r.HTML,n.decodeXML=n.decodeXMLStrict=i.XML,n.decodeHTML4=n.decodeHTML5=n.decodeHTML=i.HTML,n.decodeHTML4Strict=n.decodeHTML5Strict=n.decodeHTMLStrict=i.HTMLStrict,n.escape=r.escape},{"./lib/decode.js":21,"./lib/encode.js":23}],21:[function(e,t,n){function r(e){var t=Object.keys(e).join("|"),n=a(e);t+="|#[xX][\\da-fA-F]+|#\\d+";var r=new RegExp("&(?:"+t+");","g");return function(e){return String(e).replace(r,n)}}function i(e,t){return e<t?1:-1}function a(e){return function(t){return"#"===t.charAt(1)?u("X"===t.charAt(2)||"x"===t.charAt(2)?parseInt(t.substr(3),16):parseInt(t.substr(2),10)):e[t.slice(1,-1)]}}var o=e("../maps/entities.json"),s=e("../maps/legacy.json"),l=e("../maps/xml.json"),u=e("./decode_codepoint.js"),c=r(l),p=r(o),h=function(){function e(e){return";"!==e.substr(-1)&&(e+=";"),c(e)}for(var t=Object.keys(s).sort(i),n=Object.keys(o).sort(i),r=0,l=0;r<n.length;r++)t[l]===n[r]?(n[r]+=";?",l++):n[r]+=";";var u=new RegExp("&(?:"+n.join("|")+"|#[xX][\\da-fA-F]+;?|#\\d+;?)","g"),c=a(o);return function(t){return String(t).replace(u,e)}}();t.exports={XML:c,HTML:h,HTMLStrict:p}},{"../maps/entities.json":25,"../maps/legacy.json":26,"../maps/xml.json":27,"./decode_codepoint.js":22}],22:[function(e,t,n){function r(e){if(e>=55296&&e<=57343||e>1114111)return"�";e in i&&(e=i[e]);var t="";return e>65535&&(e-=65536,t+=String.fromCharCode(e>>>10&1023|55296),e=56320|1023&e),t+=String.fromCharCode(e)}var i=e("../maps/decode.json");t.exports=r},{"../maps/decode.json":24}],23:[function(e,t,n){function r(e){return Object.keys(e).sort().reduce(function(t,n){return t[e[n]]="&"+n+";",t},{})}function i(e){var t=[],n=[];return Object.keys(e).forEach(function(e){1===e.length?t.push("\\"+e):n.push(e)}),n.unshift("["+t.join("")+"]"),new RegExp(n.join("|"),"g")}function a(e){return"&#x"+e.charCodeAt(0).toString(16).toUpperCase()+";"}function o(e){var t=e.charCodeAt(0),n=e.charCodeAt(1),r=1024*(t-55296)+n-56320+65536;return"&#x"+r.toString(16).toUpperCase()+";"}function s(e,t){function n(t){return e[t]}return function(e){return e.replace(t,n).replace(d,o).replace(f,a)}}function l(e){return e.replace(m,a).replace(d,o).replace(f,a)}var u=r(e("../maps/xml.json")),c=i(u);n.XML=s(u,c);var p=r(e("../maps/entities.json")),h=i(p);n.HTML=s(p,h);var f=/[^\0-\x7F]/g,d=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,m=i(u);n.escape=l},{"../maps/entities.json":25,"../maps/xml.json":27}],24:[function(e,t,n){t.exports={0:65533,128:8364,130:8218,131:402,132:8222,133:8230,134:8224,135:8225,136:710,137:8240,138:352,139:8249,140:338,142:381,145:8216,146:8217,147:8220,148:8221,149:8226,150:8211,151:8212,152:732,153:8482,154:353,155:8250,156:339,158:382,159:376}},{}],25:[function(e,t,n){t.exports={Aacute:"Á",aacute:"á",Abreve:"Ă",abreve:"ă",ac:"∾",acd:"∿",acE:"∾̳",Acirc:"Â",acirc:"â",acute:"´",Acy:"А",acy:"а",AElig:"Æ",aelig:"æ",af:"⁡",Afr:"𝔄",afr:"𝔞",Agrave:"À",agrave:"à",alefsym:"ℵ",aleph:"ℵ",Alpha:"Α",alpha:"α",Amacr:"Ā",amacr:"ā",amalg:"⨿",amp:"&",AMP:"&",andand:"⩕",And:"⩓",and:"∧",andd:"⩜",andslope:"⩘",andv:"⩚",ang:"∠",ange:"⦤",angle:"∠",angmsdaa:"⦨",angmsdab:"⦩",angmsdac:"⦪",angmsdad:"⦫",angmsdae:"⦬",angmsdaf:"⦭",angmsdag:"⦮",angmsdah:"⦯",angmsd:"∡",angrt:"∟",angrtvb:"⊾",angrtvbd:"⦝",angsph:"∢",angst:"Å",angzarr:"⍼",Aogon:"Ą",aogon:"ą",Aopf:"𝔸",aopf:"𝕒",apacir:"⩯",ap:"≈",apE:"⩰",ape:"≊",apid:"≋",apos:"'",ApplyFunction:"⁡",approx:"≈",approxeq:"≊",Aring:"Å",aring:"å",Ascr:"𝒜",ascr:"𝒶",Assign:"≔",ast:"*",asymp:"≈",asympeq:"≍",Atilde:"Ã",atilde:"ã",Auml:"Ä",auml:"ä",awconint:"∳",awint:"⨑",backcong:"≌",backepsilon:"϶",backprime:"‵",backsim:"∽",backsimeq:"⋍",Backslash:"∖",Barv:"⫧",barvee:"⊽",barwed:"⌅",Barwed:"⌆",barwedge:"⌅",bbrk:"⎵",bbrktbrk:"⎶",bcong:"≌",Bcy:"Б",bcy:"б",bdquo:"„",becaus:"∵",because:"∵",Because:"∵",bemptyv:"⦰",bepsi:"϶",bernou:"ℬ",Bernoullis:"ℬ",Beta:"Β",beta:"β",beth:"ℶ",between:"≬",Bfr:"𝔅",bfr:"𝔟",bigcap:"⋂",bigcirc:"◯",bigcup:"⋃",bigodot:"⨀",bigoplus:"⨁",bigotimes:"⨂",bigsqcup:"⨆",bigstar:"★",bigtriangledown:"▽",bigtriangleup:"△",biguplus:"⨄",bigvee:"⋁",bigwedge:"⋀",bkarow:"⤍",blacklozenge:"⧫",blacksquare:"▪",blacktriangle:"▴",blacktriangledown:"▾",blacktriangleleft:"◂",blacktriangleright:"▸",blank:"␣",blk12:"▒",blk14:"░",blk34:"▓",block:"█",bne:"=⃥",bnequiv:"≡⃥",bNot:"⫭",bnot:"⌐",Bopf:"𝔹",bopf:"𝕓",bot:"⊥",bottom:"⊥",bowtie:"⋈",boxbox:"⧉",boxdl:"┐",boxdL:"╕",boxDl:"╖",boxDL:"╗",boxdr:"┌",boxdR:"╒",boxDr:"╓",boxDR:"╔",boxh:"─",boxH:"═",boxhd:"┬",boxHd:"╤",boxhD:"╥",boxHD:"╦",boxhu:"┴",boxHu:"╧",boxhU:"╨",boxHU:"╩",boxminus:"⊟",boxplus:"⊞",boxtimes:"⊠",boxul:"┘",boxuL:"╛",boxUl:"╜",boxUL:"╝",boxur:"└",boxuR:"╘",boxUr:"╙",boxUR:"╚",boxv:"│",boxV:"║",boxvh:"┼",boxvH:"╪",boxVh:"╫",boxVH:"╬",boxvl:"┤",boxvL:"╡",boxVl:"╢",boxVL:"╣",boxvr:"├",boxvR:"╞",boxVr:"╟",boxVR:"╠",bprime:"‵",breve:"˘",Breve:"˘",brvbar:"¦",bscr:"𝒷",Bscr:"ℬ",bsemi:"⁏",bsim:"∽",bsime:"⋍",bsolb:"⧅",bsol:"\\",bsolhsub:"⟈",bull:"•",bullet:"•",bump:"≎",bumpE:"⪮",bumpe:"≏",Bumpeq:"≎",bumpeq:"≏",Cacute:"Ć",cacute:"ć",capand:"⩄",capbrcup:"⩉",capcap:"⩋",cap:"∩",Cap:"⋒",capcup:"⩇",capdot:"⩀",CapitalDifferentialD:"ⅅ",caps:"∩︀",caret:"⁁",caron:"ˇ",Cayleys:"ℭ",ccaps:"⩍",Ccaron:"Č",ccaron:"č",Ccedil:"Ç",ccedil:"ç",Ccirc:"Ĉ",ccirc:"ĉ",Cconint:"∰",ccups:"⩌",ccupssm:"⩐",Cdot:"Ċ",cdot:"ċ",cedil:"¸",Cedilla:"¸",cemptyv:"⦲",cent:"¢",centerdot:"·",CenterDot:"·",cfr:"𝔠",Cfr:"ℭ",CHcy:"Ч",chcy:"ч",check:"✓",checkmark:"✓",Chi:"Χ",chi:"χ",circ:"ˆ",circeq:"≗",circlearrowleft:"↺",circlearrowright:"↻",circledast:"⊛",circledcirc:"⊚",circleddash:"⊝",CircleDot:"⊙",circledR:"®",circledS:"Ⓢ",CircleMinus:"⊖",CirclePlus:"⊕",CircleTimes:"⊗",cir:"○",cirE:"⧃",cire:"≗",cirfnint:"⨐",cirmid:"⫯",cirscir:"⧂",ClockwiseContourIntegral:"∲",CloseCurlyDoubleQuote:"”",CloseCurlyQuote:"’",clubs:"♣",clubsuit:"♣",colon:":",Colon:"∷",Colone:"⩴",colone:"≔",coloneq:"≔",comma:",",commat:"@",comp:"∁",compfn:"∘",complement:"∁",complexes:"ℂ",cong:"≅",congdot:"⩭",Congruent:"≡",conint:"∮",Conint:"∯",ContourIntegral:"∮",copf:"𝕔",Copf:"ℂ",coprod:"∐",Coproduct:"∐",copy:"©",COPY:"©",copysr:"℗",CounterClockwiseContourIntegral:"∳",crarr:"↵",cross:"✗",Cross:"⨯",Cscr:"𝒞",cscr:"𝒸",csub:"⫏",csube:"⫑",csup:"⫐",csupe:"⫒",ctdot:"⋯",cudarrl:"⤸",cudarrr:"⤵",cuepr:"⋞",cuesc:"⋟",cularr:"↶",cularrp:"⤽",cupbrcap:"⩈",cupcap:"⩆",CupCap:"≍",cup:"∪",Cup:"⋓",cupcup:"⩊",cupdot:"⊍",cupor:"⩅",cups:"∪︀",curarr:"↷",curarrm:"⤼",curlyeqprec:"⋞",curlyeqsucc:"⋟",curlyvee:"⋎",curlywedge:"⋏",curren:"¤",curvearrowleft:"↶",curvearrowright:"↷",cuvee:"⋎",cuwed:"⋏",cwconint:"∲",cwint:"∱",cylcty:"⌭",dagger:"†",Dagger:"‡",daleth:"ℸ",darr:"↓",Darr:"↡",dArr:"⇓",dash:"‐",Dashv:"⫤",dashv:"⊣",dbkarow:"⤏",dblac:"˝",Dcaron:"Ď",dcaron:"ď",Dcy:"Д",dcy:"д",ddagger:"‡",ddarr:"⇊",DD:"ⅅ",dd:"ⅆ",DDotrahd:"⤑",ddotseq:"⩷",deg:"°",Del:"∇",Delta:"Δ",delta:"δ",demptyv:"⦱",dfisht:"⥿",Dfr:"𝔇",dfr:"𝔡",dHar:"⥥",dharl:"⇃",dharr:"⇂",DiacriticalAcute:"´",DiacriticalDot:"˙",DiacriticalDoubleAcute:"˝",DiacriticalGrave:"`",DiacriticalTilde:"˜",diam:"⋄",diamond:"⋄",Diamond:"⋄",diamondsuit:"♦",diams:"♦",die:"¨",DifferentialD:"ⅆ",digamma:"ϝ",disin:"⋲",div:"÷",divide:"÷",divideontimes:"⋇",divonx:"⋇",DJcy:"Ђ",djcy:"ђ",dlcorn:"⌞",dlcrop:"⌍",dollar:"$",Dopf:"𝔻",dopf:"𝕕",Dot:"¨",dot:"˙",DotDot:"⃜",doteq:"≐",doteqdot:"≑",DotEqual:"≐",dotminus:"∸",dotplus:"∔",dotsquare:"⊡",doublebarwedge:"⌆",DoubleContourIntegral:"∯",DoubleDot:"¨",DoubleDownArrow:"⇓",DoubleLeftArrow:"⇐",DoubleLeftRightArrow:"⇔",DoubleLeftTee:"⫤",DoubleLongLeftArrow:"⟸",DoubleLongLeftRightArrow:"⟺",DoubleLongRightArrow:"⟹",DoubleRightArrow:"⇒",DoubleRightTee:"⊨",DoubleUpArrow:"⇑",DoubleUpDownArrow:"⇕",DoubleVerticalBar:"∥",DownArrowBar:"⤓",downarrow:"↓",DownArrow:"↓",Downarrow:"⇓",DownArrowUpArrow:"⇵",DownBreve:"̑",downdownarrows:"⇊",downharpoonleft:"⇃",downharpoonright:"⇂",DownLeftRightVector:"⥐",DownLeftTeeVector:"⥞",DownLeftVectorBar:"⥖",DownLeftVector:"↽",DownRightTeeVector:"⥟",DownRightVectorBar:"⥗",DownRightVector:"⇁",DownTeeArrow:"↧",DownTee:"⊤",drbkarow:"⤐",drcorn:"⌟",drcrop:"⌌",Dscr:"𝒟",dscr:"𝒹",DScy:"Ѕ",dscy:"ѕ",dsol:"⧶",Dstrok:"Đ",dstrok:"đ",dtdot:"⋱",dtri:"▿",dtrif:"▾",duarr:"⇵",duhar:"⥯",dwangle:"⦦",DZcy:"Џ",dzcy:"џ",dzigrarr:"⟿",Eacute:"É",eacute:"é",easter:"⩮",Ecaron:"Ě",ecaron:"ě",Ecirc:"Ê",ecirc:"ê",ecir:"≖",ecolon:"≕",Ecy:"Э",ecy:"э",eDDot:"⩷",Edot:"Ė",edot:"ė",eDot:"≑",ee:"ⅇ",efDot:"≒",Efr:"𝔈",efr:"𝔢",eg:"⪚",Egrave:"È",egrave:"è",egs:"⪖",egsdot:"⪘",el:"⪙",Element:"∈",elinters:"⏧",ell:"ℓ",els:"⪕",elsdot:"⪗",Emacr:"Ē",emacr:"ē",empty:"∅",emptyset:"∅",EmptySmallSquare:"◻",emptyv:"∅",EmptyVerySmallSquare:"▫",emsp13:" ",emsp14:" ",emsp:" ",ENG:"Ŋ",eng:"ŋ",ensp:" ",Eogon:"Ę",eogon:"ę",Eopf:"𝔼",eopf:"𝕖",epar:"⋕",eparsl:"⧣",eplus:"⩱",epsi:"ε",Epsilon:"Ε",epsilon:"ε",epsiv:"ϵ",eqcirc:"≖",eqcolon:"≕",eqsim:"≂",eqslantgtr:"⪖",eqslantless:"⪕",Equal:"⩵",equals:"=",EqualTilde:"≂",equest:"≟",Equilibrium:"⇌",equiv:"≡",equivDD:"⩸",eqvparsl:"⧥",erarr:"⥱",erDot:"≓",escr:"ℯ",Escr:"ℰ",esdot:"≐",Esim:"⩳",esim:"≂",Eta:"Η",eta:"η",ETH:"Ð",eth:"ð",Euml:"Ë",euml:"ë",euro:"€",excl:"!",exist:"∃",Exists:"∃",expectation:"ℰ",exponentiale:"ⅇ",ExponentialE:"ⅇ",fallingdotseq:"≒",Fcy:"Ф",fcy:"ф",female:"♀",ffilig:"ffi",fflig:"ff",ffllig:"ffl",Ffr:"𝔉",ffr:"𝔣",filig:"fi",FilledSmallSquare:"◼",FilledVerySmallSquare:"▪",fjlig:"fj",flat:"♭",fllig:"fl",fltns:"▱",fnof:"ƒ",Fopf:"𝔽",fopf:"𝕗",forall:"∀",ForAll:"∀",fork:"⋔",forkv:"⫙",Fouriertrf:"ℱ",fpartint:"⨍",frac12:"½",frac13:"⅓",frac14:"¼",frac15:"⅕",frac16:"⅙",frac18:"⅛",frac23:"⅔",frac25:"⅖",frac34:"¾",frac35:"⅗",frac38:"⅜",frac45:"⅘",frac56:"⅚",frac58:"⅝",frac78:"⅞",frasl:"⁄",frown:"⌢",fscr:"𝒻",Fscr:"ℱ",gacute:"ǵ",Gamma:"Γ",gamma:"γ",Gammad:"Ϝ",gammad:"ϝ",gap:"⪆",Gbreve:"Ğ",gbreve:"ğ",Gcedil:"Ģ",Gcirc:"Ĝ",gcirc:"ĝ",Gcy:"Г",gcy:"г",Gdot:"Ġ",gdot:"ġ",ge:"≥",gE:"≧",gEl:"⪌",gel:"⋛",geq:"≥",geqq:"≧",geqslant:"⩾",gescc:"⪩",ges:"⩾",gesdot:"⪀",gesdoto:"⪂",gesdotol:"⪄",gesl:"⋛︀",gesles:"⪔",Gfr:"𝔊",gfr:"𝔤",gg:"≫",Gg:"⋙",ggg:"⋙",gimel:"ℷ",GJcy:"Ѓ",gjcy:"ѓ",gla:"⪥",gl:"≷",glE:"⪒",glj:"⪤",gnap:"⪊",gnapprox:"⪊",gne:"⪈",gnE:"≩",gneq:"⪈",gneqq:"≩",gnsim:"⋧",Gopf:"𝔾",gopf:"𝕘",grave:"`",GreaterEqual:"≥",GreaterEqualLess:"⋛",GreaterFullEqual:"≧",GreaterGreater:"⪢",GreaterLess:"≷",GreaterSlantEqual:"⩾",GreaterTilde:"≳",Gscr:"𝒢",gscr:"ℊ",gsim:"≳",gsime:"⪎",gsiml:"⪐",gtcc:"⪧",gtcir:"⩺",gt:">",GT:">",Gt:"≫",gtdot:"⋗",gtlPar:"⦕",gtquest:"⩼",gtrapprox:"⪆",gtrarr:"⥸",gtrdot:"⋗",gtreqless:"⋛",gtreqqless:"⪌",gtrless:"≷",gtrsim:"≳",gvertneqq:"≩︀",gvnE:"≩︀",Hacek:"ˇ",hairsp:" ",half:"½",hamilt:"ℋ",HARDcy:"Ъ",hardcy:"ъ",harrcir:"⥈",harr:"↔",hArr:"⇔",harrw:"↭",Hat:"^",hbar:"ℏ",Hcirc:"Ĥ",hcirc:"ĥ",hearts:"♥",heartsuit:"♥",hellip:"…",hercon:"⊹",hfr:"𝔥",Hfr:"ℌ",HilbertSpace:"ℋ",hksearow:"⤥",hkswarow:"⤦",hoarr:"⇿",homtht:"∻",hookleftarrow:"↩",hookrightarrow:"↪",hopf:"𝕙",Hopf:"ℍ",horbar:"―",HorizontalLine:"─",hscr:"𝒽",Hscr:"ℋ",hslash:"ℏ",Hstrok:"Ħ",hstrok:"ħ",HumpDownHump:"≎",HumpEqual:"≏",hybull:"⁃",hyphen:"‐",Iacute:"Í",iacute:"í",ic:"⁣",Icirc:"Î",icirc:"î",Icy:"И",icy:"и",Idot:"İ",IEcy:"Е",iecy:"е",iexcl:"¡",iff:"⇔",ifr:"𝔦",Ifr:"ℑ",Igrave:"Ì",igrave:"ì",ii:"ⅈ",iiiint:"⨌",iiint:"∭",iinfin:"⧜",iiota:"℩",IJlig:"IJ",ijlig:"ij",Imacr:"Ī",imacr:"ī",image:"ℑ",ImaginaryI:"ⅈ",imagline:"ℐ",imagpart:"ℑ",imath:"ı",Im:"ℑ",imof:"⊷",imped:"Ƶ",Implies:"⇒",incare:"℅","in":"∈",infin:"∞",infintie:"⧝",inodot:"ı",intcal:"⊺","int":"∫",Int:"∬",integers:"ℤ",Integral:"∫",intercal:"⊺",Intersection:"⋂",intlarhk:"⨗",intprod:"⨼",InvisibleComma:"⁣",InvisibleTimes:"⁢",IOcy:"Ё",iocy:"ё",Iogon:"Į",iogon:"į",Iopf:"𝕀",iopf:"𝕚",Iota:"Ι",iota:"ι",iprod:"⨼",iquest:"¿",iscr:"𝒾",Iscr:"ℐ",isin:"∈",isindot:"⋵",isinE:"⋹",isins:"⋴",isinsv:"⋳",isinv:"∈",it:"⁢",Itilde:"Ĩ",itilde:"ĩ",Iukcy:"І",iukcy:"і",Iuml:"Ï",iuml:"ï",Jcirc:"Ĵ",jcirc:"ĵ",Jcy:"Й",jcy:"й",Jfr:"𝔍",jfr:"𝔧",jmath:"ȷ",Jopf:"𝕁",jopf:"𝕛",Jscr:"𝒥",jscr:"𝒿",Jsercy:"Ј",jsercy:"ј",Jukcy:"Є",jukcy:"є",Kappa:"Κ",kappa:"κ",kappav:"ϰ",Kcedil:"Ķ",kcedil:"ķ",Kcy:"К",kcy:"к",Kfr:"𝔎",kfr:"𝔨",kgreen:"ĸ",KHcy:"Х",khcy:"х",KJcy:"Ќ",kjcy:"ќ",Kopf:"𝕂",kopf:"𝕜",Kscr:"𝒦",kscr:"𝓀",lAarr:"⇚",Lacute:"Ĺ",lacute:"ĺ",laemptyv:"⦴",lagran:"ℒ",Lambda:"Λ",lambda:"λ",lang:"⟨",Lang:"⟪",langd:"⦑",langle:"⟨",lap:"⪅",Laplacetrf:"ℒ",laquo:"«",larrb:"⇤",larrbfs:"⤟",larr:"←",Larr:"↞",lArr:"⇐",larrfs:"⤝",larrhk:"↩",larrlp:"↫",larrpl:"⤹",larrsim:"⥳",larrtl:"↢",latail:"⤙",lAtail:"⤛",lat:"⪫",late:"⪭",lates:"⪭︀",lbarr:"⤌",lBarr:"⤎",lbbrk:"❲",lbrace:"{",lbrack:"[",lbrke:"⦋",lbrksld:"⦏",lbrkslu:"⦍",Lcaron:"Ľ",lcaron:"ľ",Lcedil:"Ļ",lcedil:"ļ",lceil:"⌈",lcub:"{",Lcy:"Л",lcy:"л",ldca:"⤶",ldquo:"“",ldquor:"„",ldrdhar:"⥧",ldrushar:"⥋",ldsh:"↲",le:"≤",lE:"≦",LeftAngleBracket:"⟨",LeftArrowBar:"⇤",leftarrow:"←",LeftArrow:"←",Leftarrow:"⇐",LeftArrowRightArrow:"⇆",leftarrowtail:"↢",LeftCeiling:"⌈",LeftDoubleBracket:"⟦",LeftDownTeeVector:"⥡",LeftDownVectorBar:"⥙",LeftDownVector:"⇃",LeftFloor:"⌊",leftharpoondown:"↽",leftharpoonup:"↼",leftleftarrows:"⇇",leftrightarrow:"↔",LeftRightArrow:"↔",Leftrightarrow:"⇔",leftrightarrows:"⇆",leftrightharpoons:"⇋",leftrightsquigarrow:"↭",LeftRightVector:"⥎",LeftTeeArrow:"↤",LeftTee:"⊣",LeftTeeVector:"⥚",leftthreetimes:"⋋",LeftTriangleBar:"⧏",LeftTriangle:"⊲",LeftTriangleEqual:"⊴",LeftUpDownVector:"⥑",LeftUpTeeVector:"⥠",LeftUpVectorBar:"⥘",LeftUpVector:"↿",LeftVectorBar:"⥒",LeftVector:"↼",lEg:"⪋",leg:"⋚",leq:"≤",leqq:"≦",leqslant:"⩽",lescc:"⪨",les:"⩽",lesdot:"⩿",lesdoto:"⪁",lesdotor:"⪃",lesg:"⋚︀",lesges:"⪓",lessapprox:"⪅",lessdot:"⋖",lesseqgtr:"⋚",lesseqqgtr:"⪋",LessEqualGreater:"⋚",LessFullEqual:"≦",LessGreater:"≶",lessgtr:"≶",LessLess:"⪡",lesssim:"≲",LessSlantEqual:"⩽",LessTilde:"≲",lfisht:"⥼",lfloor:"⌊",Lfr:"𝔏",lfr:"𝔩",lg:"≶",lgE:"⪑",lHar:"⥢",lhard:"↽",lharu:"↼",lharul:"⥪",lhblk:"▄",LJcy:"Љ",ljcy:"љ",llarr:"⇇",ll:"≪",Ll:"⋘",llcorner:"⌞",Lleftarrow:"⇚",llhard:"⥫",
+lltri:"◺",Lmidot:"Ŀ",lmidot:"ŀ",lmoustache:"⎰",lmoust:"⎰",lnap:"⪉",lnapprox:"⪉",lne:"⪇",lnE:"≨",lneq:"⪇",lneqq:"≨",lnsim:"⋦",loang:"⟬",loarr:"⇽",lobrk:"⟦",longleftarrow:"⟵",LongLeftArrow:"⟵",Longleftarrow:"⟸",longleftrightarrow:"⟷",LongLeftRightArrow:"⟷",Longleftrightarrow:"⟺",longmapsto:"⟼",longrightarrow:"⟶",LongRightArrow:"⟶",Longrightarrow:"⟹",looparrowleft:"↫",looparrowright:"↬",lopar:"⦅",Lopf:"𝕃",lopf:"𝕝",loplus:"⨭",lotimes:"⨴",lowast:"∗",lowbar:"_",LowerLeftArrow:"↙",LowerRightArrow:"↘",loz:"◊",lozenge:"◊",lozf:"⧫",lpar:"(",lparlt:"⦓",lrarr:"⇆",lrcorner:"⌟",lrhar:"⇋",lrhard:"⥭",lrm:"‎",lrtri:"⊿",lsaquo:"‹",lscr:"𝓁",Lscr:"ℒ",lsh:"↰",Lsh:"↰",lsim:"≲",lsime:"⪍",lsimg:"⪏",lsqb:"[",lsquo:"‘",lsquor:"‚",Lstrok:"Ł",lstrok:"ł",ltcc:"⪦",ltcir:"⩹",lt:"<",LT:"<",Lt:"≪",ltdot:"⋖",lthree:"⋋",ltimes:"⋉",ltlarr:"⥶",ltquest:"⩻",ltri:"◃",ltrie:"⊴",ltrif:"◂",ltrPar:"⦖",lurdshar:"⥊",luruhar:"⥦",lvertneqq:"≨︀",lvnE:"≨︀",macr:"¯",male:"♂",malt:"✠",maltese:"✠",Map:"⤅",map:"↦",mapsto:"↦",mapstodown:"↧",mapstoleft:"↤",mapstoup:"↥",marker:"▮",mcomma:"⨩",Mcy:"М",mcy:"м",mdash:"—",mDDot:"∺",measuredangle:"∡",MediumSpace:" ",Mellintrf:"ℳ",Mfr:"𝔐",mfr:"𝔪",mho:"℧",micro:"µ",midast:"*",midcir:"⫰",mid:"∣",middot:"·",minusb:"⊟",minus:"−",minusd:"∸",minusdu:"⨪",MinusPlus:"∓",mlcp:"⫛",mldr:"…",mnplus:"∓",models:"⊧",Mopf:"𝕄",mopf:"𝕞",mp:"∓",mscr:"𝓂",Mscr:"ℳ",mstpos:"∾",Mu:"Μ",mu:"μ",multimap:"⊸",mumap:"⊸",nabla:"∇",Nacute:"Ń",nacute:"ń",nang:"∠⃒",nap:"≉",napE:"⩰̸",napid:"≋̸",napos:"ʼn",napprox:"≉",natural:"♮",naturals:"ℕ",natur:"♮",nbsp:" ",nbump:"≎̸",nbumpe:"≏̸",ncap:"⩃",Ncaron:"Ň",ncaron:"ň",Ncedil:"Ņ",ncedil:"ņ",ncong:"≇",ncongdot:"⩭̸",ncup:"⩂",Ncy:"Н",ncy:"н",ndash:"–",nearhk:"⤤",nearr:"↗",neArr:"⇗",nearrow:"↗",ne:"≠",nedot:"≐̸",NegativeMediumSpace:"​",NegativeThickSpace:"​",NegativeThinSpace:"​",NegativeVeryThinSpace:"​",nequiv:"≢",nesear:"⤨",nesim:"≂̸",NestedGreaterGreater:"≫",NestedLessLess:"≪",NewLine:"\n",nexist:"∄",nexists:"∄",Nfr:"𝔑",nfr:"𝔫",ngE:"≧̸",nge:"≱",ngeq:"≱",ngeqq:"≧̸",ngeqslant:"⩾̸",nges:"⩾̸",nGg:"⋙̸",ngsim:"≵",nGt:"≫⃒",ngt:"≯",ngtr:"≯",nGtv:"≫̸",nharr:"↮",nhArr:"⇎",nhpar:"⫲",ni:"∋",nis:"⋼",nisd:"⋺",niv:"∋",NJcy:"Њ",njcy:"њ",nlarr:"↚",nlArr:"⇍",nldr:"‥",nlE:"≦̸",nle:"≰",nleftarrow:"↚",nLeftarrow:"⇍",nleftrightarrow:"↮",nLeftrightarrow:"⇎",nleq:"≰",nleqq:"≦̸",nleqslant:"⩽̸",nles:"⩽̸",nless:"≮",nLl:"⋘̸",nlsim:"≴",nLt:"≪⃒",nlt:"≮",nltri:"⋪",nltrie:"⋬",nLtv:"≪̸",nmid:"∤",NoBreak:"⁠",NonBreakingSpace:" ",nopf:"𝕟",Nopf:"ℕ",Not:"⫬",not:"¬",NotCongruent:"≢",NotCupCap:"≭",NotDoubleVerticalBar:"∦",NotElement:"∉",NotEqual:"≠",NotEqualTilde:"≂̸",NotExists:"∄",NotGreater:"≯",NotGreaterEqual:"≱",NotGreaterFullEqual:"≧̸",NotGreaterGreater:"≫̸",NotGreaterLess:"≹",NotGreaterSlantEqual:"⩾̸",NotGreaterTilde:"≵",NotHumpDownHump:"≎̸",NotHumpEqual:"≏̸",notin:"∉",notindot:"⋵̸",notinE:"⋹̸",notinva:"∉",notinvb:"⋷",notinvc:"⋶",NotLeftTriangleBar:"⧏̸",NotLeftTriangle:"⋪",NotLeftTriangleEqual:"⋬",NotLess:"≮",NotLessEqual:"≰",NotLessGreater:"≸",NotLessLess:"≪̸",NotLessSlantEqual:"⩽̸",NotLessTilde:"≴",NotNestedGreaterGreater:"⪢̸",NotNestedLessLess:"⪡̸",notni:"∌",notniva:"∌",notnivb:"⋾",notnivc:"⋽",NotPrecedes:"⊀",NotPrecedesEqual:"⪯̸",NotPrecedesSlantEqual:"⋠",NotReverseElement:"∌",NotRightTriangleBar:"⧐̸",NotRightTriangle:"⋫",NotRightTriangleEqual:"⋭",NotSquareSubset:"⊏̸",NotSquareSubsetEqual:"⋢",NotSquareSuperset:"⊐̸",NotSquareSupersetEqual:"⋣",NotSubset:"⊂⃒",NotSubsetEqual:"⊈",NotSucceeds:"⊁",NotSucceedsEqual:"⪰̸",NotSucceedsSlantEqual:"⋡",NotSucceedsTilde:"≿̸",NotSuperset:"⊃⃒",NotSupersetEqual:"⊉",NotTilde:"≁",NotTildeEqual:"≄",NotTildeFullEqual:"≇",NotTildeTilde:"≉",NotVerticalBar:"∤",nparallel:"∦",npar:"∦",nparsl:"⫽⃥",npart:"∂̸",npolint:"⨔",npr:"⊀",nprcue:"⋠",nprec:"⊀",npreceq:"⪯̸",npre:"⪯̸",nrarrc:"⤳̸",nrarr:"↛",nrArr:"⇏",nrarrw:"↝̸",nrightarrow:"↛",nRightarrow:"⇏",nrtri:"⋫",nrtrie:"⋭",nsc:"⊁",nsccue:"⋡",nsce:"⪰̸",Nscr:"𝒩",nscr:"𝓃",nshortmid:"∤",nshortparallel:"∦",nsim:"≁",nsime:"≄",nsimeq:"≄",nsmid:"∤",nspar:"∦",nsqsube:"⋢",nsqsupe:"⋣",nsub:"⊄",nsubE:"⫅̸",nsube:"⊈",nsubset:"⊂⃒",nsubseteq:"⊈",nsubseteqq:"⫅̸",nsucc:"⊁",nsucceq:"⪰̸",nsup:"⊅",nsupE:"⫆̸",nsupe:"⊉",nsupset:"⊃⃒",nsupseteq:"⊉",nsupseteqq:"⫆̸",ntgl:"≹",Ntilde:"Ñ",ntilde:"ñ",ntlg:"≸",ntriangleleft:"⋪",ntrianglelefteq:"⋬",ntriangleright:"⋫",ntrianglerighteq:"⋭",Nu:"Ν",nu:"ν",num:"#",numero:"№",numsp:" ",nvap:"≍⃒",nvdash:"⊬",nvDash:"⊭",nVdash:"⊮",nVDash:"⊯",nvge:"≥⃒",nvgt:">⃒",nvHarr:"⤄",nvinfin:"⧞",nvlArr:"⤂",nvle:"≤⃒",nvlt:"<⃒",nvltrie:"⊴⃒",nvrArr:"⤃",nvrtrie:"⊵⃒",nvsim:"∼⃒",nwarhk:"⤣",nwarr:"↖",nwArr:"⇖",nwarrow:"↖",nwnear:"⤧",Oacute:"Ó",oacute:"ó",oast:"⊛",Ocirc:"Ô",ocirc:"ô",ocir:"⊚",Ocy:"О",ocy:"о",odash:"⊝",Odblac:"Ő",odblac:"ő",odiv:"⨸",odot:"⊙",odsold:"⦼",OElig:"Œ",oelig:"œ",ofcir:"⦿",Ofr:"𝔒",ofr:"𝔬",ogon:"˛",Ograve:"Ò",ograve:"ò",ogt:"⧁",ohbar:"⦵",ohm:"Ω",oint:"∮",olarr:"↺",olcir:"⦾",olcross:"⦻",oline:"‾",olt:"⧀",Omacr:"Ō",omacr:"ō",Omega:"Ω",omega:"ω",Omicron:"Ο",omicron:"ο",omid:"⦶",ominus:"⊖",Oopf:"𝕆",oopf:"𝕠",opar:"⦷",OpenCurlyDoubleQuote:"“",OpenCurlyQuote:"‘",operp:"⦹",oplus:"⊕",orarr:"↻",Or:"⩔",or:"∨",ord:"⩝",order:"ℴ",orderof:"ℴ",ordf:"ª",ordm:"º",origof:"⊶",oror:"⩖",orslope:"⩗",orv:"⩛",oS:"Ⓢ",Oscr:"𝒪",oscr:"ℴ",Oslash:"Ø",oslash:"ø",osol:"⊘",Otilde:"Õ",otilde:"õ",otimesas:"⨶",Otimes:"⨷",otimes:"⊗",Ouml:"Ö",ouml:"ö",ovbar:"⌽",OverBar:"‾",OverBrace:"⏞",OverBracket:"⎴",OverParenthesis:"⏜",para:"¶",parallel:"∥",par:"∥",parsim:"⫳",parsl:"⫽",part:"∂",PartialD:"∂",Pcy:"П",pcy:"п",percnt:"%",period:".",permil:"‰",perp:"⊥",pertenk:"‱",Pfr:"𝔓",pfr:"𝔭",Phi:"Φ",phi:"φ",phiv:"ϕ",phmmat:"ℳ",phone:"☎",Pi:"Π",pi:"π",pitchfork:"⋔",piv:"ϖ",planck:"ℏ",planckh:"ℎ",plankv:"ℏ",plusacir:"⨣",plusb:"⊞",pluscir:"⨢",plus:"+",plusdo:"∔",plusdu:"⨥",pluse:"⩲",PlusMinus:"±",plusmn:"±",plussim:"⨦",plustwo:"⨧",pm:"±",Poincareplane:"ℌ",pointint:"⨕",popf:"𝕡",Popf:"ℙ",pound:"£",prap:"⪷",Pr:"⪻",pr:"≺",prcue:"≼",precapprox:"⪷",prec:"≺",preccurlyeq:"≼",Precedes:"≺",PrecedesEqual:"⪯",PrecedesSlantEqual:"≼",PrecedesTilde:"≾",preceq:"⪯",precnapprox:"⪹",precneqq:"⪵",precnsim:"⋨",pre:"⪯",prE:"⪳",precsim:"≾",prime:"′",Prime:"″",primes:"ℙ",prnap:"⪹",prnE:"⪵",prnsim:"⋨",prod:"∏",Product:"∏",profalar:"⌮",profline:"⌒",profsurf:"⌓",prop:"∝",Proportional:"∝",Proportion:"∷",propto:"∝",prsim:"≾",prurel:"⊰",Pscr:"𝒫",pscr:"𝓅",Psi:"Ψ",psi:"ψ",puncsp:" ",Qfr:"𝔔",qfr:"𝔮",qint:"⨌",qopf:"𝕢",Qopf:"ℚ",qprime:"⁗",Qscr:"𝒬",qscr:"𝓆",quaternions:"ℍ",quatint:"⨖",quest:"?",questeq:"≟",quot:'"',QUOT:'"',rAarr:"⇛",race:"∽̱",Racute:"Ŕ",racute:"ŕ",radic:"√",raemptyv:"⦳",rang:"⟩",Rang:"⟫",rangd:"⦒",range:"⦥",rangle:"⟩",raquo:"»",rarrap:"⥵",rarrb:"⇥",rarrbfs:"⤠",rarrc:"⤳",rarr:"→",Rarr:"↠",rArr:"⇒",rarrfs:"⤞",rarrhk:"↪",rarrlp:"↬",rarrpl:"⥅",rarrsim:"⥴",Rarrtl:"⤖",rarrtl:"↣",rarrw:"↝",ratail:"⤚",rAtail:"⤜",ratio:"∶",rationals:"ℚ",rbarr:"⤍",rBarr:"⤏",RBarr:"⤐",rbbrk:"❳",rbrace:"}",rbrack:"]",rbrke:"⦌",rbrksld:"⦎",rbrkslu:"⦐",Rcaron:"Ř",rcaron:"ř",Rcedil:"Ŗ",rcedil:"ŗ",rceil:"⌉",rcub:"}",Rcy:"Р",rcy:"р",rdca:"⤷",rdldhar:"⥩",rdquo:"”",rdquor:"”",rdsh:"↳",real:"ℜ",realine:"ℛ",realpart:"ℜ",reals:"ℝ",Re:"ℜ",rect:"▭",reg:"®",REG:"®",ReverseElement:"∋",ReverseEquilibrium:"⇋",ReverseUpEquilibrium:"⥯",rfisht:"⥽",rfloor:"⌋",rfr:"𝔯",Rfr:"ℜ",rHar:"⥤",rhard:"⇁",rharu:"⇀",rharul:"⥬",Rho:"Ρ",rho:"ρ",rhov:"ϱ",RightAngleBracket:"⟩",RightArrowBar:"⇥",rightarrow:"→",RightArrow:"→",Rightarrow:"⇒",RightArrowLeftArrow:"⇄",rightarrowtail:"↣",RightCeiling:"⌉",RightDoubleBracket:"⟧",RightDownTeeVector:"⥝",RightDownVectorBar:"⥕",RightDownVector:"⇂",RightFloor:"⌋",rightharpoondown:"⇁",rightharpoonup:"⇀",rightleftarrows:"⇄",rightleftharpoons:"⇌",rightrightarrows:"⇉",rightsquigarrow:"↝",RightTeeArrow:"↦",RightTee:"⊢",RightTeeVector:"⥛",rightthreetimes:"⋌",RightTriangleBar:"⧐",RightTriangle:"⊳",RightTriangleEqual:"⊵",RightUpDownVector:"⥏",RightUpTeeVector:"⥜",RightUpVectorBar:"⥔",RightUpVector:"↾",RightVectorBar:"⥓",RightVector:"⇀",ring:"˚",risingdotseq:"≓",rlarr:"⇄",rlhar:"⇌",rlm:"‏",rmoustache:"⎱",rmoust:"⎱",rnmid:"⫮",roang:"⟭",roarr:"⇾",robrk:"⟧",ropar:"⦆",ropf:"𝕣",Ropf:"ℝ",roplus:"⨮",rotimes:"⨵",RoundImplies:"⥰",rpar:")",rpargt:"⦔",rppolint:"⨒",rrarr:"⇉",Rrightarrow:"⇛",rsaquo:"›",rscr:"𝓇",Rscr:"ℛ",rsh:"↱",Rsh:"↱",rsqb:"]",rsquo:"’",rsquor:"’",rthree:"⋌",rtimes:"⋊",rtri:"▹",rtrie:"⊵",rtrif:"▸",rtriltri:"⧎",RuleDelayed:"⧴",ruluhar:"⥨",rx:"℞",Sacute:"Ś",sacute:"ś",sbquo:"‚",scap:"⪸",Scaron:"Š",scaron:"š",Sc:"⪼",sc:"≻",sccue:"≽",sce:"⪰",scE:"⪴",Scedil:"Ş",scedil:"ş",Scirc:"Ŝ",scirc:"ŝ",scnap:"⪺",scnE:"⪶",scnsim:"⋩",scpolint:"⨓",scsim:"≿",Scy:"С",scy:"с",sdotb:"⊡",sdot:"⋅",sdote:"⩦",searhk:"⤥",searr:"↘",seArr:"⇘",searrow:"↘",sect:"§",semi:";",seswar:"⤩",setminus:"∖",setmn:"∖",sext:"✶",Sfr:"𝔖",sfr:"𝔰",sfrown:"⌢",sharp:"♯",SHCHcy:"Щ",shchcy:"щ",SHcy:"Ш",shcy:"ш",ShortDownArrow:"↓",ShortLeftArrow:"←",shortmid:"∣",shortparallel:"∥",ShortRightArrow:"→",ShortUpArrow:"↑",shy:"­",Sigma:"Σ",sigma:"σ",sigmaf:"ς",sigmav:"ς",sim:"∼",simdot:"⩪",sime:"≃",simeq:"≃",simg:"⪞",simgE:"⪠",siml:"⪝",simlE:"⪟",simne:"≆",simplus:"⨤",simrarr:"⥲",slarr:"←",SmallCircle:"∘",smallsetminus:"∖",smashp:"⨳",smeparsl:"⧤",smid:"∣",smile:"⌣",smt:"⪪",smte:"⪬",smtes:"⪬︀",SOFTcy:"Ь",softcy:"ь",solbar:"⌿",solb:"⧄",sol:"/",Sopf:"𝕊",sopf:"𝕤",spades:"♠",spadesuit:"♠",spar:"∥",sqcap:"⊓",sqcaps:"⊓︀",sqcup:"⊔",sqcups:"⊔︀",Sqrt:"√",sqsub:"⊏",sqsube:"⊑",sqsubset:"⊏",sqsubseteq:"⊑",sqsup:"⊐",sqsupe:"⊒",sqsupset:"⊐",sqsupseteq:"⊒",square:"□",Square:"□",SquareIntersection:"⊓",SquareSubset:"⊏",SquareSubsetEqual:"⊑",SquareSuperset:"⊐",SquareSupersetEqual:"⊒",SquareUnion:"⊔",squarf:"▪",squ:"□",squf:"▪",srarr:"→",Sscr:"𝒮",sscr:"𝓈",ssetmn:"∖",ssmile:"⌣",sstarf:"⋆",Star:"⋆",star:"☆",starf:"★",straightepsilon:"ϵ",straightphi:"ϕ",strns:"¯",sub:"⊂",Sub:"⋐",subdot:"⪽",subE:"⫅",sube:"⊆",subedot:"⫃",submult:"⫁",subnE:"⫋",subne:"⊊",subplus:"⪿",subrarr:"⥹",subset:"⊂",Subset:"⋐",subseteq:"⊆",subseteqq:"⫅",SubsetEqual:"⊆",subsetneq:"⊊",subsetneqq:"⫋",subsim:"⫇",subsub:"⫕",subsup:"⫓",succapprox:"⪸",succ:"≻",succcurlyeq:"≽",Succeeds:"≻",SucceedsEqual:"⪰",SucceedsSlantEqual:"≽",SucceedsTilde:"≿",succeq:"⪰",succnapprox:"⪺",succneqq:"⪶",succnsim:"⋩",succsim:"≿",SuchThat:"∋",sum:"∑",Sum:"∑",sung:"♪",sup1:"¹",sup2:"²",sup3:"³",sup:"⊃",Sup:"⋑",supdot:"⪾",supdsub:"⫘",supE:"⫆",supe:"⊇",supedot:"⫄",Superset:"⊃",SupersetEqual:"⊇",suphsol:"⟉",suphsub:"⫗",suplarr:"⥻",supmult:"⫂",supnE:"⫌",supne:"⊋",supplus:"⫀",supset:"⊃",Supset:"⋑",supseteq:"⊇",supseteqq:"⫆",supsetneq:"⊋",supsetneqq:"⫌",supsim:"⫈",supsub:"⫔",supsup:"⫖",swarhk:"⤦",swarr:"↙",swArr:"⇙",swarrow:"↙",swnwar:"⤪",szlig:"ß",Tab:"\t",target:"⌖",Tau:"Τ",tau:"τ",tbrk:"⎴",Tcaron:"Ť",tcaron:"ť",Tcedil:"Ţ",tcedil:"ţ",Tcy:"Т",tcy:"т",tdot:"⃛",telrec:"⌕",Tfr:"𝔗",tfr:"𝔱",there4:"∴",therefore:"∴",Therefore:"∴",Theta:"Θ",theta:"θ",thetasym:"ϑ",thetav:"ϑ",thickapprox:"≈",thicksim:"∼",ThickSpace:"  ",ThinSpace:" ",thinsp:" ",thkap:"≈",thksim:"∼",THORN:"Þ",thorn:"þ",tilde:"˜",Tilde:"∼",TildeEqual:"≃",TildeFullEqual:"≅",TildeTilde:"≈",timesbar:"⨱",timesb:"⊠",times:"×",timesd:"⨰",tint:"∭",toea:"⤨",topbot:"⌶",topcir:"⫱",top:"⊤",Topf:"𝕋",topf:"𝕥",topfork:"⫚",tosa:"⤩",tprime:"‴",trade:"™",TRADE:"™",triangle:"▵",triangledown:"▿",triangleleft:"◃",trianglelefteq:"⊴",triangleq:"≜",triangleright:"▹",trianglerighteq:"⊵",tridot:"◬",trie:"≜",triminus:"⨺",TripleDot:"⃛",triplus:"⨹",trisb:"⧍",tritime:"⨻",trpezium:"⏢",Tscr:"𝒯",tscr:"𝓉",TScy:"Ц",tscy:"ц",TSHcy:"Ћ",tshcy:"ћ",Tstrok:"Ŧ",tstrok:"ŧ",twixt:"≬",twoheadleftarrow:"↞",twoheadrightarrow:"↠",Uacute:"Ú",uacute:"ú",uarr:"↑",Uarr:"↟",uArr:"⇑",Uarrocir:"⥉",Ubrcy:"Ў",ubrcy:"ў",Ubreve:"Ŭ",ubreve:"ŭ",Ucirc:"Û",ucirc:"û",Ucy:"У",ucy:"у",udarr:"⇅",Udblac:"Ű",udblac:"ű",udhar:"⥮",ufisht:"⥾",Ufr:"𝔘",ufr:"𝔲",Ugrave:"Ù",ugrave:"ù",uHar:"⥣",uharl:"↿",uharr:"↾",uhblk:"▀",ulcorn:"⌜",ulcorner:"⌜",ulcrop:"⌏",ultri:"◸",Umacr:"Ū",umacr:"ū",uml:"¨",UnderBar:"_",UnderBrace:"⏟",UnderBracket:"⎵",UnderParenthesis:"⏝",Union:"⋃",UnionPlus:"⊎",Uogon:"Ų",uogon:"ų",Uopf:"𝕌",uopf:"𝕦",UpArrowBar:"⤒",uparrow:"↑",UpArrow:"↑",Uparrow:"⇑",UpArrowDownArrow:"⇅",updownarrow:"↕",UpDownArrow:"↕",Updownarrow:"⇕",UpEquilibrium:"⥮",upharpoonleft:"↿",upharpoonright:"↾",uplus:"⊎",UpperLeftArrow:"↖",UpperRightArrow:"↗",upsi:"υ",Upsi:"ϒ",upsih:"ϒ",Upsilon:"Υ",upsilon:"υ",UpTeeArrow:"↥",UpTee:"⊥",upuparrows:"⇈",urcorn:"⌝",urcorner:"⌝",urcrop:"⌎",Uring:"Ů",uring:"ů",urtri:"◹",Uscr:"𝒰",uscr:"𝓊",utdot:"⋰",Utilde:"Ũ",utilde:"ũ",utri:"▵",utrif:"▴",uuarr:"⇈",Uuml:"Ü",uuml:"ü",uwangle:"⦧",vangrt:"⦜",varepsilon:"ϵ",varkappa:"ϰ",varnothing:"∅",varphi:"ϕ",varpi:"ϖ",varpropto:"∝",varr:"↕",vArr:"⇕",varrho:"ϱ",varsigma:"ς",varsubsetneq:"⊊︀",varsubsetneqq:"⫋︀",varsupsetneq:"⊋︀",varsupsetneqq:"⫌︀",vartheta:"ϑ",vartriangleleft:"⊲",vartriangleright:"⊳",vBar:"⫨",Vbar:"⫫",vBarv:"⫩",Vcy:"В",vcy:"в",vdash:"⊢",vDash:"⊨",Vdash:"⊩",VDash:"⊫",Vdashl:"⫦",veebar:"⊻",vee:"∨",Vee:"⋁",veeeq:"≚",vellip:"⋮",verbar:"|",Verbar:"‖",vert:"|",Vert:"‖",VerticalBar:"∣",VerticalLine:"|",VerticalSeparator:"❘",VerticalTilde:"≀",VeryThinSpace:" ",Vfr:"𝔙",vfr:"𝔳",vltri:"⊲",vnsub:"⊂⃒",vnsup:"⊃⃒",Vopf:"𝕍",vopf:"𝕧",vprop:"∝",vrtri:"⊳",Vscr:"𝒱",vscr:"𝓋",vsubnE:"⫋︀",vsubne:"⊊︀",vsupnE:"⫌︀",vsupne:"⊋︀",Vvdash:"⊪",vzigzag:"⦚",Wcirc:"Ŵ",wcirc:"ŵ",wedbar:"⩟",wedge:"∧",Wedge:"⋀",wedgeq:"≙",weierp:"℘",Wfr:"𝔚",wfr:"𝔴",Wopf:"𝕎",wopf:"𝕨",wp:"℘",wr:"≀",wreath:"≀",Wscr:"𝒲",wscr:"𝓌",xcap:"⋂",xcirc:"◯",xcup:"⋃",xdtri:"▽",Xfr:"𝔛",xfr:"𝔵",xharr:"⟷",xhArr:"⟺",Xi:"Ξ",xi:"ξ",xlarr:"⟵",xlArr:"⟸",xmap:"⟼",xnis:"⋻",xodot:"⨀",Xopf:"𝕏",xopf:"𝕩",xoplus:"⨁",xotime:"⨂",xrarr:"⟶",xrArr:"⟹",Xscr:"𝒳",xscr:"𝓍",xsqcup:"⨆",xuplus:"⨄",xutri:"△",xvee:"⋁",xwedge:"⋀",Yacute:"Ý",yacute:"ý",YAcy:"Я",yacy:"я",Ycirc:"Ŷ",ycirc:"ŷ",Ycy:"Ы",ycy:"ы",yen:"¥",Yfr:"𝔜",yfr:"𝔶",YIcy:"Ї",yicy:"ї",Yopf:"𝕐",yopf:"𝕪",Yscr:"𝒴",yscr:"𝓎",YUcy:"Ю",yucy:"ю",yuml:"ÿ",Yuml:"Ÿ",Zacute:"Ź",zacute:"ź",Zcaron:"Ž",zcaron:"ž",Zcy:"З",zcy:"з",Zdot:"Ż",zdot:"ż",zeetrf:"ℨ",ZeroWidthSpace:"​",Zeta:"Ζ",zeta:"ζ",zfr:"𝔷",Zfr:"ℨ",ZHcy:"Ж",zhcy:"ж",zigrarr:"⇝",zopf:"𝕫",Zopf:"ℤ",Zscr:"𝒵",zscr:"𝓏",zwj:"‍",zwnj:"‌"}},{}],26:[function(e,t,n){t.exports={Aacute:"Á",aacute:"á",Acirc:"Â",acirc:"â",acute:"´",AElig:"Æ",aelig:"æ",Agrave:"À",agrave:"à",amp:"&",AMP:"&",Aring:"Å",aring:"å",Atilde:"Ã",atilde:"ã",Auml:"Ä",auml:"ä",brvbar:"¦",Ccedil:"Ç",ccedil:"ç",cedil:"¸",cent:"¢",copy:"©",COPY:"©",curren:"¤",deg:"°",divide:"÷",Eacute:"É",eacute:"é",Ecirc:"Ê",ecirc:"ê",Egrave:"È",egrave:"è",ETH:"Ð",eth:"ð",Euml:"Ë",euml:"ë",frac12:"½",frac14:"¼",frac34:"¾",gt:">",GT:">",Iacute:"Í",iacute:"í",Icirc:"Î",icirc:"î",iexcl:"¡",Igrave:"Ì",igrave:"ì",iquest:"¿",Iuml:"Ï",iuml:"ï",laquo:"«",lt:"<",LT:"<",macr:"¯",micro:"µ",middot:"·",nbsp:" ",not:"¬",Ntilde:"Ñ",ntilde:"ñ",Oacute:"Ó",oacute:"ó",Ocirc:"Ô",ocirc:"ô",Ograve:"Ò",ograve:"ò",ordf:"ª",ordm:"º",Oslash:"Ø",oslash:"ø",Otilde:"Õ",otilde:"õ",Ouml:"Ö",ouml:"ö",para:"¶",plusmn:"±",pound:"£",quot:'"',QUOT:'"',raquo:"»",reg:"®",REG:"®",sect:"§",shy:"­",sup1:"¹",sup2:"²",sup3:"³",szlig:"ß",THORN:"Þ",thorn:"þ",times:"×",Uacute:"Ú",uacute:"ú",Ucirc:"Û",ucirc:"û",Ugrave:"Ù",ugrave:"ù",uml:"¨",Uuml:"Ü",uuml:"ü",Yacute:"Ý",yacute:"ý",yen:"¥",yuml:"ÿ"}},{}],27:[function(e,t,n){t.exports={amp:"&",apos:"'",gt:">",lt:"<",quot:'"'}},{}],28:[function(e,t,n){function r(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function i(e){return"function"==typeof e}function a(e){return"number"==typeof e}function o(e){return"object"==typeof e&&null!==e}function s(e){return void 0===e}t.exports=r,r.EventEmitter=r,r.prototype._events=void 0,r.prototype._maxListeners=void 0,r.defaultMaxListeners=10,r.prototype.setMaxListeners=function(e){if(!a(e)||e<0||isNaN(e))throw TypeError("n must be a positive number");return this._maxListeners=e,this},r.prototype.emit=function(e){var t,n,r,a,l,u;if(this._events||(this._events={}),"error"===e&&(!this._events.error||o(this._events.error)&&!this._events.error.length)){if(t=arguments[1],t instanceof Error)throw t;var c=new Error('Uncaught, unspecified "error" event. ('+t+")");throw c.context=t,c}if(n=this._events[e],s(n))return!1;if(i(n))switch(arguments.length){case 1:n.call(this);break;case 2:n.call(this,arguments[1]);break;case 3:n.call(this,arguments[1],arguments[2]);break;default:a=Array.prototype.slice.call(arguments,1),n.apply(this,a)}else if(o(n))for(a=Array.prototype.slice.call(arguments,1),u=n.slice(),r=u.length,l=0;l<r;l++)u[l].apply(this,a);return!0},r.prototype.addListener=function(e,t){var n;if(!i(t))throw TypeError("listener must be a function");return this._events||(this._events={}),this._events.newListener&&this.emit("newListener",e,i(t.listener)?t.listener:t),this._events[e]?o(this._events[e])?this._events[e].push(t):this._events[e]=[this._events[e],t]:this._events[e]=t,o(this._events[e])&&!this._events[e].warned&&(n=s(this._maxListeners)?r.defaultMaxListeners:this._maxListeners,n&&n>0&&this._events[e].length>n&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace())),this},r.prototype.on=r.prototype.addListener,r.prototype.once=function(e,t){function n(){this.removeListener(e,n),r||(r=!0,t.apply(this,arguments))}if(!i(t))throw TypeError("listener must be a function");var r=!1;return n.listener=t,this.on(e,n),this},r.prototype.removeListener=function(e,t){var n,r,a,s;if(!i(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(n=this._events[e],a=n.length,r=-1,n===t||i(n.listener)&&n.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(o(n)){for(s=a;s-- >0;)if(n[s]===t||n[s].listener&&n[s].listener===t){r=s;break}if(r<0)return this;1===n.length?(n.length=0,delete this._events[e]):n.splice(r,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},r.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(n=this._events[e],i(n))this.removeListener(e,n);else if(n)for(;n.length;)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},r.prototype.listeners=function(e){var t;return t=this._events&&this._events[e]?i(this._events[e])?[this._events[e]]:this._events[e].slice():[]},r.prototype.listenerCount=function(e){if(this._events){var t=this._events[e];if(i(t))return 1;if(t)return t.length}return 0},r.listenerCount=function(e,t){return e.listenerCount(t)}},{}],29:[function(e,t,n){function r(e){this._cbs=e||{},this.events=[]}t.exports=r;var i=e("./").EVENTS;Object.keys(i).forEach(function(e){if(0===i[e])e="on"+e,r.prototype[e]=function(){this.events.push([e]),this._cbs[e]&&this._cbs[e]()};else if(1===i[e])e="on"+e,r.prototype[e]=function(t){this.events.push([e,t]),this._cbs[e]&&this._cbs[e](t)};else{if(2!==i[e])throw Error("wrong number of arguments");e="on"+e,r.prototype[e]=function(t,n){this.events.push([e,t,n]),this._cbs[e]&&this._cbs[e](t,n)}}}),r.prototype.onreset=function(){this.events=[],this._cbs.onreset&&this._cbs.onreset()},r.prototype.restart=function(){this._cbs.onreset&&this._cbs.onreset();for(var e=0,t=this.events.length;e<t;e++)if(this._cbs[this.events[e][0]]){var n=this.events[e].length;1===n?this._cbs[this.events[e][0]]():2===n?this._cbs[this.events[e][0]](this.events[e][1]):this._cbs[this.events[e][0]](this.events[e][1],this.events[e][2])}}},{"./":36}],30:[function(e,t,n){function r(e,t){this.init(e,t)}function i(e,t){return c.getElementsByTagName(e,t,!0)}function a(e,t){return c.getElementsByTagName(e,t,!0,1)[0]}function o(e,t,n){return c.getText(c.getElementsByTagName(e,t,n,1)).trim()}function s(e,t,n,r,i){var a=o(n,r,i);a&&(e[t]=a)}var l=e("./index.js"),u=l.DomHandler,c=l.DomUtils;e("inherits")(r,u),r.prototype.init=u;var p=function(e){return"rss"===e||"feed"===e||"rdf:RDF"===e};r.prototype.onend=function(){var e,t,n={},r=a(p,this.dom);r&&("feed"===r.name?(t=r.children,n.type="atom",s(n,"id","id",t),s(n,"title","title",t),(e=a("link",t))&&(e=e.attribs)&&(e=e.href)&&(n.link=e),s(n,"description","subtitle",t),(e=o("updated",t))&&(n.updated=new Date(e)),s(n,"author","email",t,!0),n.items=i("entry",t).map(function(e){var t,n={};return e=e.children,s(n,"id","id",e),s(n,"title","title",e),(t=a("link",e))&&(t=t.attribs)&&(t=t.href)&&(n.link=t),(t=o("summary",e)||o("content",e))&&(n.description=t),(t=o("updated",e))&&(n.pubDate=new Date(t)),n})):(t=a("channel",r.children).children,n.type=r.name.substr(0,3),n.id="",s(n,"title","title",t),s(n,"link","link",t),s(n,"description","description",t),(e=o("lastBuildDate",t))&&(n.updated=new Date(e)),s(n,"author","managingEditor",t,!0),n.items=i("item",r.children).map(function(e){var t,n={};return e=e.children,s(n,"id","guid",e),s(n,"title","title",e),s(n,"link","link",e),s(n,"description","description",e),(t=o("pubDate",e))&&(n.pubDate=new Date(t)),n}))),this.dom=n,u.prototype._handleCallback.call(this,r?null:Error("couldn't find root of feed"))},t.exports=r},{"./index.js":36,inherits:38}],31:[function(e,t,n){function r(e,t){this._options=t||{},this._cbs=e||{},this._tagname="",this._attribname="",this._attribvalue="",this._attribs=null,this._stack=[],this.startIndex=0,this.endIndex=null,this._lowerCaseTagNames="lowerCaseTags"in this._options?!!this._options.lowerCaseTags:!this._options.xmlMode,this._lowerCaseAttributeNames="lowerCaseAttributeNames"in this._options?!!this._options.lowerCaseAttributeNames:!this._options.xmlMode,this._options.Tokenizer&&(i=this._options.Tokenizer),this._tokenizer=new i(this._options,this),this._cbs.onparserinit&&this._cbs.onparserinit(this)}var i=e("./Tokenizer.js"),a={input:!0,option:!0,optgroup:!0,select:!0,button:!0,datalist:!0,textarea:!0},o={tr:{tr:!0,th:!0,td:!0},th:{th:!0},td:{thead:!0,th:!0,td:!0},body:{head:!0,link:!0,script:!0},li:{li:!0},p:{p:!0},h1:{p:!0},h2:{p:!0},h3:{p:!0},h4:{p:!0},h5:{p:!0},h6:{p:!0},select:a,input:a,output:a,button:a,datalist:a,textarea:a,option:{option:!0},optgroup:{optgroup:!0}},s={__proto__:null,area:!0,base:!0,basefont:!0,br:!0,col:!0,command:!0,embed:!0,frame:!0,hr:!0,img:!0,input:!0,isindex:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0,path:!0,circle:!0,ellipse:!0,line:!0,rect:!0,use:!0,stop:!0,polyline:!0,polygon:!0},l=/\s|\//;e("inherits")(r,e("events").EventEmitter),r.prototype._updatePosition=function(e){null===this.endIndex?this._tokenizer._sectionStart<=e?this.startIndex=0:this.startIndex=this._tokenizer._sectionStart-e:this.startIndex=this.endIndex+1,this.endIndex=this._tokenizer.getAbsoluteIndex()},r.prototype.ontext=function(e){this._updatePosition(1),this.endIndex--,this._cbs.ontext&&this._cbs.ontext(e)},r.prototype.onopentagname=function(e){if(this._lowerCaseTagNames&&(e=e.toLowerCase()),this._tagname=e,!this._options.xmlMode&&e in o)for(var t;(t=this._stack[this._stack.length-1])in o[e];this.onclosetag(t));!this._options.xmlMode&&e in s||this._stack.push(e),this._cbs.onopentagname&&this._cbs.onopentagname(e),this._cbs.onopentag&&(this._attribs={})},r.prototype.onopentagend=function(){this._updatePosition(1),this._attribs&&(this._cbs.onopentag&&this._cbs.onopentag(this._tagname,this._attribs),this._attribs=null),!this._options.xmlMode&&this._cbs.onclosetag&&this._tagname in s&&this._cbs.onclosetag(this._tagname),this._tagname=""},r.prototype.onclosetag=function(e){if(this._updatePosition(1),this._lowerCaseTagNames&&(e=e.toLowerCase()),!this._stack.length||e in s&&!this._options.xmlMode)this._options.xmlMode||"br"!==e&&"p"!==e||(this.onopentagname(e),this._closeCurrentTag());else{var t=this._stack.lastIndexOf(e);if(t!==-1)if(this._cbs.onclosetag)for(t=this._stack.length-t;t--;)this._cbs.onclosetag(this._stack.pop());else this._stack.length=t;else"p"!==e||this._options.xmlMode||(this.onopentagname(e),this._closeCurrentTag())}},r.prototype.onselfclosingtag=function(){this._options.xmlMode||this._options.recognizeSelfClosing?this._closeCurrentTag():this.onopentagend()},r.prototype._closeCurrentTag=function(){var e=this._tagname;this.onopentagend(),this._stack[this._stack.length-1]===e&&(this._cbs.onclosetag&&this._cbs.onclosetag(e),this._stack.pop())},r.prototype.onattribname=function(e){this._lowerCaseAttributeNames&&(e=e.toLowerCase()),this._attribname=e},r.prototype.onattribdata=function(e){this._attribvalue+=e},r.prototype.onattribend=function(){this._cbs.onattribute&&this._cbs.onattribute(this._attribname,this._attribvalue),this._attribs&&!Object.prototype.hasOwnProperty.call(this._attribs,this._attribname)&&(this._attribs[this._attribname]=this._attribvalue),this._attribname="",this._attribvalue=""},r.prototype._getInstructionName=function(e){var t=e.search(l),n=t<0?e:e.substr(0,t);return this._lowerCaseTagNames&&(n=n.toLowerCase()),n},r.prototype.ondeclaration=function(e){if(this._cbs.onprocessinginstruction){var t=this._getInstructionName(e);this._cbs.onprocessinginstruction("!"+t,"!"+e)}},r.prototype.onprocessinginstruction=function(e){if(this._cbs.onprocessinginstruction){var t=this._getInstructionName(e);this._cbs.onprocessinginstruction("?"+t,"?"+e)}},r.prototype.oncomment=function(e){this._updatePosition(4),this._cbs.oncomment&&this._cbs.oncomment(e),this._cbs.oncommentend&&this._cbs.oncommentend()},r.prototype.oncdata=function(e){this._updatePosition(1),this._options.xmlMode||this._options.recognizeCDATA?(this._cbs.oncdatastart&&this._cbs.oncdatastart(),this._cbs.ontext&&this._cbs.ontext(e),this._cbs.oncdataend&&this._cbs.oncdataend()):this.oncomment("[CDATA["+e+"]]")},r.prototype.onerror=function(e){this._cbs.onerror&&this._cbs.onerror(e)},r.prototype.onend=function(){if(this._cbs.onclosetag)for(var e=this._stack.length;e>0;this._cbs.onclosetag(this._stack[--e]));this._cbs.onend&&this._cbs.onend()},r.prototype.reset=function(){this._cbs.onreset&&this._cbs.onreset(),this._tokenizer.reset(),this._tagname="",this._attribname="",this._attribs=null,this._stack=[],this._cbs.onparserinit&&this._cbs.onparserinit(this)},r.prototype.parseComplete=function(e){this.reset(),this.end(e)},r.prototype.write=function(e){this._tokenizer.write(e)},r.prototype.end=function(e){this._tokenizer.end(e)},r.prototype.pause=function(){this._tokenizer.pause()},r.prototype.resume=function(){this._tokenizer.resume()},r.prototype.parseChunk=r.prototype.write,r.prototype.done=r.prototype.end,t.exports=r},{"./Tokenizer.js":34,events:28,inherits:38}],32:[function(e,t,n){function r(e){this._cbs=e||{}}t.exports=r;var i=e("./").EVENTS;Object.keys(i).forEach(function(e){if(0===i[e])e="on"+e,r.prototype[e]=function(){this._cbs[e]&&this._cbs[e]()};else if(1===i[e])e="on"+e,r.prototype[e]=function(t){this._cbs[e]&&this._cbs[e](t)};else{if(2!==i[e])throw Error("wrong number of arguments");e="on"+e,r.prototype[e]=function(t,n){this._cbs[e]&&this._cbs[e](t,n)}}})},{"./":36}],33:[function(e,t,n){function r(e){a.call(this,new i(this),e)}function i(e){this.scope=e}t.exports=r;var a=e("./WritableStream.js");e("inherits")(r,a),r.prototype.readable=!0;var o=e("../").EVENTS;Object.keys(o).forEach(function(e){if(0===o[e])i.prototype["on"+e]=function(){this.scope.emit(e)};else if(1===o[e])i.prototype["on"+e]=function(t){this.scope.emit(e,t)};else{if(2!==o[e])throw Error("wrong number of arguments!");i.prototype["on"+e]=function(t,n){this.scope.emit(e,t,n)}}})},{"../":36,"./WritableStream.js":35,inherits:38}],34:[function(e,t,n){function r(e){return" "===e||"\n"===e||"\t"===e||"\f"===e||"\r"===e}function i(e,t){return function(n){n===e&&(this._state=t)}}function a(e,t,n){var r=e.toLowerCase();return e===r?function(e){e===r?this._state=t:(this._state=n,this._index--)}:function(i){i===r||i===e?this._state=t:(this._state=n,this._index--)}}function o(e,t){var n=e.toLowerCase();return function(r){r===n||r===e?this._state=t:(this._state=m,this._index--)}}function s(e,t){this._state=f,this._buffer="",this._sectionStart=0,this._index=0,this._bufferOffset=0,this._baseState=f,this._special=me,this._cbs=t,this._running=!0,this._ended=!1,this._xmlMode=!(!e||!e.xmlMode),this._decodeEntities=!(!e||!e.decodeEntities)}t.exports=s;var l=e("entities/lib/decode_codepoint.js"),u=e("entities/maps/entities.json"),c=e("entities/maps/legacy.json"),p=e("entities/maps/xml.json"),h=0,f=h++,d=h++,m=h++,g=h++,y=h++,v=h++,b=h++,w=h++,_=h++,x=h++,A=h++,S=h++,j=h++,E=h++,O=h++,k=h++,T=h++,C=h++,I=h++,D=h++,L=h++,M=h++,R=h++,U=h++,P=h++,q=h++,B=h++,z=h++,N=h++,$=h++,F=h++,V=h++,H=h++,Y=h++,J=h++,W=h++,Q=h++,G=h++,K=h++,X=h++,Z=h++,ee=h++,te=h++,ne=h++,re=h++,ie=h++,ae=h++,oe=h++,se=h++,le=h++,ue=h++,ce=h++,pe=h++,he=h++,fe=h++,de=0,me=de++,ge=de++,ye=de++;s.prototype._stateText=function(e){"<"===e?(this._index>this._sectionStart&&this._cbs.ontext(this._getSection()),this._state=d,this._sectionStart=this._index):this._decodeEntities&&this._special===me&&"&"===e&&(this._index>this._sectionStart&&this._cbs.ontext(this._getSection()),this._baseState=f,this._state=ue,this._sectionStart=this._index)},s.prototype._stateBeforeTagName=function(e){"/"===e?this._state=y:"<"===e?(this._cbs.ontext(this._getSection()),this._sectionStart=this._index):">"===e||this._special!==me||r(e)?this._state=f:"!"===e?(this._state=O,this._sectionStart=this._index+1):"?"===e?(this._state=T,this._sectionStart=this._index+1):(this._state=this._xmlMode||"s"!==e&&"S"!==e?m:F,this._sectionStart=this._index)},s.prototype._stateInTagName=function(e){("/"===e||">"===e||r(e))&&(this._emitToken("onopentagname"),this._state=w,this._index--)},s.prototype._stateBeforeCloseingTagName=function(e){r(e)||(">"===e?this._state=f:this._special!==me?"s"===e||"S"===e?this._state=V:(this._state=f,this._index--):(this._state=v,this._sectionStart=this._index))},s.prototype._stateInCloseingTagName=function(e){(">"===e||r(e))&&(this._emitToken("onclosetag"),this._state=b,this._index--)},s.prototype._stateAfterCloseingTagName=function(e){">"===e&&(this._state=f,this._sectionStart=this._index+1)},s.prototype._stateBeforeAttributeName=function(e){">"===e?(this._cbs.onopentagend(),this._state=f,this._sectionStart=this._index+1):"/"===e?this._state=g:r(e)||(this._state=_,this._sectionStart=this._index)},s.prototype._stateInSelfClosingTag=function(e){">"===e?(this._cbs.onselfclosingtag(),this._state=f,this._sectionStart=this._index+1):r(e)||(this._state=w,this._index--)},s.prototype._stateInAttributeName=function(e){("="===e||"/"===e||">"===e||r(e))&&(this._cbs.onattribname(this._getSection()),this._sectionStart=-1,this._state=x,this._index--)},s.prototype._stateAfterAttributeName=function(e){"="===e?this._state=A:"/"===e||">"===e?(this._cbs.onattribend(),this._state=w,this._index--):r(e)||(this._cbs.onattribend(),this._state=_,this._sectionStart=this._index)},s.prototype._stateBeforeAttributeValue=function(e){'"'===e?(this._state=S,this._sectionStart=this._index+1):"'"===e?(this._state=j,this._sectionStart=this._index+1):r(e)||(this._state=E,this._sectionStart=this._index,this._index--)},s.prototype._stateInAttributeValueDoubleQuotes=function(e){'"'===e?(this._emitToken("onattribdata"),this._cbs.onattribend(),this._state=w):this._decodeEntities&&"&"===e&&(this._emitToken("onattribdata"),this._baseState=this._state,this._state=ue,this._sectionStart=this._index)},s.prototype._stateInAttributeValueSingleQuotes=function(e){"'"===e?(this._emitToken("onattribdata"),this._cbs.onattribend(),this._state=w):this._decodeEntities&&"&"===e&&(this._emitToken("onattribdata"),this._baseState=this._state,this._state=ue,this._sectionStart=this._index)},s.prototype._stateInAttributeValueNoQuotes=function(e){r(e)||">"===e?(this._emitToken("onattribdata"),this._cbs.onattribend(),this._state=w,this._index--):this._decodeEntities&&"&"===e&&(this._emitToken("onattribdata"),this._baseState=this._state,this._state=ue,this._sectionStart=this._index)},s.prototype._stateBeforeDeclaration=function(e){this._state="["===e?M:"-"===e?C:k},s.prototype._stateInDeclaration=function(e){
+">"===e&&(this._cbs.ondeclaration(this._getSection()),this._state=f,this._sectionStart=this._index+1)},s.prototype._stateInProcessingInstruction=function(e){">"===e&&(this._cbs.onprocessinginstruction(this._getSection()),this._state=f,this._sectionStart=this._index+1)},s.prototype._stateBeforeComment=function(e){"-"===e?(this._state=I,this._sectionStart=this._index+1):this._state=k},s.prototype._stateInComment=function(e){"-"===e&&(this._state=D)},s.prototype._stateAfterComment1=function(e){"-"===e?this._state=L:this._state=I},s.prototype._stateAfterComment2=function(e){">"===e?(this._cbs.oncomment(this._buffer.substring(this._sectionStart,this._index-2)),this._state=f,this._sectionStart=this._index+1):"-"!==e&&(this._state=I)},s.prototype._stateBeforeCdata1=a("C",R,k),s.prototype._stateBeforeCdata2=a("D",U,k),s.prototype._stateBeforeCdata3=a("A",P,k),s.prototype._stateBeforeCdata4=a("T",q,k),s.prototype._stateBeforeCdata5=a("A",B,k),s.prototype._stateBeforeCdata6=function(e){"["===e?(this._state=z,this._sectionStart=this._index+1):(this._state=k,this._index--)},s.prototype._stateInCdata=function(e){"]"===e&&(this._state=N)},s.prototype._stateAfterCdata1=i("]",$),s.prototype._stateAfterCdata2=function(e){">"===e?(this._cbs.oncdata(this._buffer.substring(this._sectionStart,this._index-2)),this._state=f,this._sectionStart=this._index+1):"]"!==e&&(this._state=z)},s.prototype._stateBeforeSpecial=function(e){"c"===e||"C"===e?this._state=H:"t"===e||"T"===e?this._state=te:(this._state=m,this._index--)},s.prototype._stateBeforeSpecialEnd=function(e){this._special!==ge||"c"!==e&&"C"!==e?this._special!==ye||"t"!==e&&"T"!==e?this._state=f:this._state=ae:this._state=G},s.prototype._stateBeforeScript1=o("R",Y),s.prototype._stateBeforeScript2=o("I",J),s.prototype._stateBeforeScript3=o("P",W),s.prototype._stateBeforeScript4=o("T",Q),s.prototype._stateBeforeScript5=function(e){("/"===e||">"===e||r(e))&&(this._special=ge),this._state=m,this._index--},s.prototype._stateAfterScript1=a("R",K,f),s.prototype._stateAfterScript2=a("I",X,f),s.prototype._stateAfterScript3=a("P",Z,f),s.prototype._stateAfterScript4=a("T",ee,f),s.prototype._stateAfterScript5=function(e){">"===e||r(e)?(this._special=me,this._state=v,this._sectionStart=this._index-6,this._index--):this._state=f},s.prototype._stateBeforeStyle1=o("Y",ne),s.prototype._stateBeforeStyle2=o("L",re),s.prototype._stateBeforeStyle3=o("E",ie),s.prototype._stateBeforeStyle4=function(e){("/"===e||">"===e||r(e))&&(this._special=ye),this._state=m,this._index--},s.prototype._stateAfterStyle1=a("Y",oe,f),s.prototype._stateAfterStyle2=a("L",se,f),s.prototype._stateAfterStyle3=a("E",le,f),s.prototype._stateAfterStyle4=function(e){">"===e||r(e)?(this._special=me,this._state=v,this._sectionStart=this._index-5,this._index--):this._state=f},s.prototype._stateBeforeEntity=a("#",ce,pe),s.prototype._stateBeforeNumericEntity=a("X",fe,he),s.prototype._parseNamedEntityStrict=function(){if(this._sectionStart+1<this._index){var e=this._buffer.substring(this._sectionStart+1,this._index),t=this._xmlMode?p:u;t.hasOwnProperty(e)&&(this._emitPartial(t[e]),this._sectionStart=this._index+1)}},s.prototype._parseLegacyEntity=function(){var e=this._sectionStart+1,t=this._index-e;for(t>6&&(t=6);t>=2;){var n=this._buffer.substr(e,t);if(c.hasOwnProperty(n))return this._emitPartial(c[n]),void(this._sectionStart+=t+1);t--}},s.prototype._stateInNamedEntity=function(e){";"===e?(this._parseNamedEntityStrict(),this._sectionStart+1<this._index&&!this._xmlMode&&this._parseLegacyEntity(),this._state=this._baseState):(e<"a"||e>"z")&&(e<"A"||e>"Z")&&(e<"0"||e>"9")&&(this._xmlMode||this._sectionStart+1===this._index||(this._baseState!==f?"="!==e&&this._parseNamedEntityStrict():this._parseLegacyEntity()),this._state=this._baseState,this._index--)},s.prototype._decodeNumericEntity=function(e,t){var n=this._sectionStart+e;if(n!==this._index){var r=this._buffer.substring(n,this._index),i=parseInt(r,t);this._emitPartial(l(i)),this._sectionStart=this._index}else this._sectionStart--;this._state=this._baseState},s.prototype._stateInNumericEntity=function(e){";"===e?(this._decodeNumericEntity(2,10),this._sectionStart++):(e<"0"||e>"9")&&(this._xmlMode?this._state=this._baseState:this._decodeNumericEntity(2,10),this._index--)},s.prototype._stateInHexEntity=function(e){";"===e?(this._decodeNumericEntity(3,16),this._sectionStart++):(e<"a"||e>"f")&&(e<"A"||e>"F")&&(e<"0"||e>"9")&&(this._xmlMode?this._state=this._baseState:this._decodeNumericEntity(3,16),this._index--)},s.prototype._cleanup=function(){this._sectionStart<0?(this._buffer="",this._index=0,this._bufferOffset+=this._index):this._running&&(this._state===f?(this._sectionStart!==this._index&&this._cbs.ontext(this._buffer.substr(this._sectionStart)),this._buffer="",this._bufferOffset+=this._index,this._index=0):this._sectionStart===this._index?(this._buffer="",this._bufferOffset+=this._index,this._index=0):(this._buffer=this._buffer.substr(this._sectionStart),this._index-=this._sectionStart,this._bufferOffset+=this._sectionStart),this._sectionStart=0)},s.prototype.write=function(e){this._ended&&this._cbs.onerror(Error(".write() after done!")),this._buffer+=e,this._parse()},s.prototype._parse=function(){for(;this._index<this._buffer.length&&this._running;){var e=this._buffer.charAt(this._index);this._state===f?this._stateText(e):this._state===d?this._stateBeforeTagName(e):this._state===m?this._stateInTagName(e):this._state===y?this._stateBeforeCloseingTagName(e):this._state===v?this._stateInCloseingTagName(e):this._state===b?this._stateAfterCloseingTagName(e):this._state===g?this._stateInSelfClosingTag(e):this._state===w?this._stateBeforeAttributeName(e):this._state===_?this._stateInAttributeName(e):this._state===x?this._stateAfterAttributeName(e):this._state===A?this._stateBeforeAttributeValue(e):this._state===S?this._stateInAttributeValueDoubleQuotes(e):this._state===j?this._stateInAttributeValueSingleQuotes(e):this._state===E?this._stateInAttributeValueNoQuotes(e):this._state===O?this._stateBeforeDeclaration(e):this._state===k?this._stateInDeclaration(e):this._state===T?this._stateInProcessingInstruction(e):this._state===C?this._stateBeforeComment(e):this._state===I?this._stateInComment(e):this._state===D?this._stateAfterComment1(e):this._state===L?this._stateAfterComment2(e):this._state===M?this._stateBeforeCdata1(e):this._state===R?this._stateBeforeCdata2(e):this._state===U?this._stateBeforeCdata3(e):this._state===P?this._stateBeforeCdata4(e):this._state===q?this._stateBeforeCdata5(e):this._state===B?this._stateBeforeCdata6(e):this._state===z?this._stateInCdata(e):this._state===N?this._stateAfterCdata1(e):this._state===$?this._stateAfterCdata2(e):this._state===F?this._stateBeforeSpecial(e):this._state===V?this._stateBeforeSpecialEnd(e):this._state===H?this._stateBeforeScript1(e):this._state===Y?this._stateBeforeScript2(e):this._state===J?this._stateBeforeScript3(e):this._state===W?this._stateBeforeScript4(e):this._state===Q?this._stateBeforeScript5(e):this._state===G?this._stateAfterScript1(e):this._state===K?this._stateAfterScript2(e):this._state===X?this._stateAfterScript3(e):this._state===Z?this._stateAfterScript4(e):this._state===ee?this._stateAfterScript5(e):this._state===te?this._stateBeforeStyle1(e):this._state===ne?this._stateBeforeStyle2(e):this._state===re?this._stateBeforeStyle3(e):this._state===ie?this._stateBeforeStyle4(e):this._state===ae?this._stateAfterStyle1(e):this._state===oe?this._stateAfterStyle2(e):this._state===se?this._stateAfterStyle3(e):this._state===le?this._stateAfterStyle4(e):this._state===ue?this._stateBeforeEntity(e):this._state===ce?this._stateBeforeNumericEntity(e):this._state===pe?this._stateInNamedEntity(e):this._state===he?this._stateInNumericEntity(e):this._state===fe?this._stateInHexEntity(e):this._cbs.onerror(Error("unknown _state"),this._state),this._index++}this._cleanup()},s.prototype.pause=function(){this._running=!1},s.prototype.resume=function(){this._running=!0,this._index<this._buffer.length&&this._parse(),this._ended&&this._finish()},s.prototype.end=function(e){this._ended&&this._cbs.onerror(Error(".end() after done!")),e&&this.write(e),this._ended=!0,this._running&&this._finish()},s.prototype._finish=function(){this._sectionStart<this._index&&this._handleTrailingData(),this._cbs.onend()},s.prototype._handleTrailingData=function(){var e=this._buffer.substr(this._sectionStart);this._state===z||this._state===N||this._state===$?this._cbs.oncdata(e):this._state===I||this._state===D||this._state===L?this._cbs.oncomment(e):this._state!==pe||this._xmlMode?this._state!==he||this._xmlMode?this._state!==fe||this._xmlMode?this._state!==m&&this._state!==w&&this._state!==A&&this._state!==x&&this._state!==_&&this._state!==j&&this._state!==S&&this._state!==E&&this._state!==v&&this._cbs.ontext(e):(this._decodeNumericEntity(3,16),this._sectionStart<this._index&&(this._state=this._baseState,this._handleTrailingData())):(this._decodeNumericEntity(2,10),this._sectionStart<this._index&&(this._state=this._baseState,this._handleTrailingData())):(this._parseLegacyEntity(),this._sectionStart<this._index&&(this._state=this._baseState,this._handleTrailingData()))},s.prototype.reset=function(){s.call(this,{xmlMode:this._xmlMode,decodeEntities:this._decodeEntities},this._cbs)},s.prototype.getAbsoluteIndex=function(){return this._bufferOffset+this._index},s.prototype._getSection=function(){return this._buffer.substring(this._sectionStart,this._index)},s.prototype._emitToken=function(e){this._cbs[e](this._getSection()),this._sectionStart=-1},s.prototype._emitPartial=function(e){this._baseState!==f?this._cbs.onattribdata(e):this._cbs.ontext(e)}},{"entities/lib/decode_codepoint.js":22,"entities/maps/entities.json":25,"entities/maps/legacy.json":26,"entities/maps/xml.json":27}],35:[function(e,t,n){function r(e,t){var n=this._parser=new i(e,t),r=this._decoder=new o;a.call(this,{decodeStrings:!1}),this.once("finish",function(){n.end(r.end())})}t.exports=r;var i=e("./Parser.js"),a=e("stream").Writable||e("readable-stream").Writable,o=e("string_decoder").StringDecoder,s=e("buffer").Buffer;e("inherits")(r,a),a.prototype._write=function(e,t,n){e instanceof s&&(e=this._decoder.write(e)),this._parser.write(e),n()}},{"./Parser.js":31,buffer:5,inherits:38,"readable-stream":3,stream:55,string_decoder:56}],36:[function(e,t,n){function r(e,n){return delete t.exports[e],t.exports[e]=n,n}var i=e("./Parser.js"),a=e("domhandler");t.exports={Parser:i,Tokenizer:e("./Tokenizer.js"),ElementType:e("domelementtype"),DomHandler:a,get FeedHandler(){return r("FeedHandler",e("./FeedHandler.js"))},get Stream(){return r("Stream",e("./Stream.js"))},get WritableStream(){return r("WritableStream",e("./WritableStream.js"))},get ProxyHandler(){return r("ProxyHandler",e("./ProxyHandler.js"))},get DomUtils(){return r("DomUtils",e("domutils"))},get CollectingHandler(){return r("CollectingHandler",e("./CollectingHandler.js"))},DefaultHandler:a,get RssHandler(){return r("RssHandler",this.FeedHandler)},parseDOM:function(e,t){var n=new a(t);return new i(n,t).end(e),n.dom},parseFeed:function(e,n){var r=new t.exports.FeedHandler(n);return new i(r,n).end(e),r.dom},createDomStream:function(e,t,n){var r=new a(e,t,n);return new i(r,t)},EVENTS:{attribute:2,cdatastart:0,cdataend:0,text:1,processinginstruction:2,comment:1,commentend:0,closetag:1,opentag:2,opentagname:1,error:1,end:0}}},{"./CollectingHandler.js":29,"./FeedHandler.js":30,"./Parser.js":31,"./ProxyHandler.js":32,"./Stream.js":33,"./Tokenizer.js":34,"./WritableStream.js":35,domelementtype:9,domhandler:10,domutils:13}],37:[function(e,t,n){n.read=function(e,t,n,r,i){var a,o,s=8*i-r-1,l=(1<<s)-1,u=l>>1,c=-7,p=n?i-1:0,h=n?-1:1,f=e[t+p];for(p+=h,a=f&(1<<-c)-1,f>>=-c,c+=s;c>0;a=256*a+e[t+p],p+=h,c-=8);for(o=a&(1<<-c)-1,a>>=-c,c+=r;c>0;o=256*o+e[t+p],p+=h,c-=8);if(0===a)a=1-u;else{if(a===l)return o?NaN:(f?-1:1)*(1/0);o+=Math.pow(2,r),a-=u}return(f?-1:1)*o*Math.pow(2,a-r)},n.write=function(e,t,n,r,i,a){var o,s,l,u=8*a-i-1,c=(1<<u)-1,p=c>>1,h=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,f=r?0:a-1,d=r?1:-1,m=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,o=c):(o=Math.floor(Math.log(t)/Math.LN2),t*(l=Math.pow(2,-o))<1&&(o--,l*=2),t+=o+p>=1?h/l:h*Math.pow(2,1-p),t*l>=2&&(o++,l/=2),o+p>=c?(s=0,o=c):o+p>=1?(s=(t*l-1)*Math.pow(2,i),o+=p):(s=t*Math.pow(2,p-1)*Math.pow(2,i),o=0));i>=8;e[n+f]=255&s,f+=d,s/=256,i-=8);for(o=o<<i|s,u+=i;u>0;e[n+f]=255&o,f+=d,o/=256,u-=8);e[n+f-d]|=128*m}},{}],38:[function(e,t,n){"function"==typeof Object.create?t.exports=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}:t.exports=function(e,t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}},{}],39:[function(e,t,n){function r(e){return!!e.constructor&&"function"==typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)}function i(e){return"function"==typeof e.readFloatLE&&"function"==typeof e.slice&&r(e.slice(0,0))}t.exports=function(e){return null!=e&&(r(e)||i(e)||!!e._isBuffer)}},{}],40:[function(e,t,n){var r={}.toString;t.exports=Array.isArray||function(e){return"[object Array]"==r.call(e)}},{}],41:[function(e,t,n){(function(e){"use strict";function n(t,n,r,i){if("function"!=typeof t)throw new TypeError('"callback" argument must be a function');var a,o,s=arguments.length;switch(s){case 0:case 1:return e.nextTick(t);case 2:return e.nextTick(function(){t.call(null,n)});case 3:return e.nextTick(function(){t.call(null,n,r)});case 4:return e.nextTick(function(){t.call(null,n,r,i)});default:for(a=new Array(s-1),o=0;o<a.length;)a[o++]=arguments[o];return e.nextTick(function(){t.apply(null,a)})}}!e.version||0===e.version.indexOf("v0.")||0===e.version.indexOf("v1.")&&0!==e.version.indexOf("v1.8.")?t.exports=n:t.exports=e.nextTick}).call(this,e("_process"))},{_process:42}],42:[function(e,t,n){function r(){throw new Error("setTimeout has not been defined")}function i(){throw new Error("clearTimeout has not been defined")}function a(e){if(p===setTimeout)return setTimeout(e,0);if((p===r||!p)&&setTimeout)return p=setTimeout,setTimeout(e,0);try{return p(e,0)}catch(t){try{return p.call(null,e,0)}catch(t){return p.call(this,e,0)}}}function o(e){if(h===clearTimeout)return clearTimeout(e);if((h===i||!h)&&clearTimeout)return h=clearTimeout,clearTimeout(e);try{return h(e)}catch(t){try{return h.call(null,e)}catch(t){return h.call(this,e)}}}function s(){g&&d&&(g=!1,d.length?m=d.concat(m):y=-1,m.length&&l())}function l(){if(!g){var e=a(s);g=!0;for(var t=m.length;t;){for(d=m,m=[];++y<t;)d&&d[y].run();y=-1,t=m.length}d=null,g=!1,o(e)}}function u(e,t){this.fun=e,this.array=t}function c(){}var p,h,f=t.exports={};!function(){try{p="function"==typeof setTimeout?setTimeout:r}catch(e){p=r}try{h="function"==typeof clearTimeout?clearTimeout:i}catch(e){h=i}}();var d,m=[],g=!1,y=-1;f.nextTick=function(e){var t=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];m.push(new u(e,t)),1!==m.length||g||a(l)},u.prototype.run=function(){this.fun.apply(null,this.array)},f.title="browser",f.browser=!0,f.env={},f.argv=[],f.version="",f.versions={},f.on=c,f.addListener=c,f.once=c,f.off=c,f.removeListener=c,f.removeAllListeners=c,f.emit=c,f.binding=function(e){throw new Error("process.binding is not supported")},f.cwd=function(){return"/"},f.chdir=function(e){throw new Error("process.chdir is not supported")},f.umask=function(){return 0}},{}],43:[function(e,t,n){t.exports=e("./lib/_stream_duplex.js")},{"./lib/_stream_duplex.js":44}],44:[function(e,t,n){"use strict";function r(e){return this instanceof r?(u.call(this,e),c.call(this,e),e&&e.readable===!1&&(this.readable=!1),e&&e.writable===!1&&(this.writable=!1),this.allowHalfOpen=!0,e&&e.allowHalfOpen===!1&&(this.allowHalfOpen=!1),void this.once("end",i)):new r(e)}function i(){this.allowHalfOpen||this._writableState.ended||s(a,this)}function a(e){e.end()}var o=Object.keys||function(e){var t=[];for(var n in e)t.push(n);return t};t.exports=r;var s=e("process-nextick-args"),l=e("core-util-is");l.inherits=e("inherits");var u=e("./_stream_readable"),c=e("./_stream_writable");l.inherits(r,u);for(var p=o(c.prototype),h=0;h<p.length;h++){var f=p[h];r.prototype[f]||(r.prototype[f]=c.prototype[f])}},{"./_stream_readable":46,"./_stream_writable":48,"core-util-is":6,inherits:38,"process-nextick-args":41}],45:[function(e,t,n){"use strict";function r(e){return this instanceof r?void i.call(this,e):new r(e)}t.exports=r;var i=e("./_stream_transform"),a=e("core-util-is");a.inherits=e("inherits"),a.inherits(r,i),r.prototype._transform=function(e,t,n){n(null,e)}},{"./_stream_transform":47,"core-util-is":6,inherits:38}],46:[function(e,t,n){(function(n){"use strict";function r(e,t,n){return"function"==typeof e.prependListener?e.prependListener(t,n):void(e._events&&e._events[t]?C(e._events[t])?e._events[t].unshift(n):e._events[t]=[n,e._events[t]]:e.on(t,n))}function i(t,n){z=z||e("./_stream_duplex"),t=t||{},this.objectMode=!!t.objectMode,n instanceof z&&(this.objectMode=this.objectMode||!!t.readableObjectMode);var r=t.highWaterMark,i=this.objectMode?16:16384;this.highWaterMark=r||0===r?r:i,this.highWaterMark=~~this.highWaterMark,this.buffer=new B,this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=null,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.resumeScheduled=!1,this.defaultEncoding=t.defaultEncoding||"utf8",this.ranOut=!1,this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,t.encoding&&(q||(q=e("string_decoder/").StringDecoder),this.decoder=new q(t.encoding),this.encoding=t.encoding)}function a(t){return z=z||e("./_stream_duplex"),this instanceof a?(this._readableState=new i(t,this),this.readable=!0,t&&"function"==typeof t.read&&(this._read=t.read),void I.call(this)):new a(t)}function o(e,t,n,r,i){var a=c(t,n);if(a)e.emit("error",a);else if(null===n)t.reading=!1,p(e,t);else if(t.objectMode||n&&n.length>0)if(t.ended&&!i){var o=new Error("stream.push() after EOF");e.emit("error",o)}else if(t.endEmitted&&i){var l=new Error("stream.unshift() after end event");e.emit("error",l)}else{var u;!t.decoder||i||r||(n=t.decoder.write(n),u=!t.objectMode&&0===n.length),i||(t.reading=!1),u||(t.flowing&&0===t.length&&!t.sync?(e.emit("data",n),e.read(0)):(t.length+=t.objectMode?1:n.length,i?t.buffer.unshift(n):t.buffer.push(n),t.needReadable&&h(e))),d(e,t)}else i||(t.reading=!1);return s(t)}function s(e){return!e.ended&&(e.needReadable||e.length<e.highWaterMark||0===e.length)}function l(e){return e>=N?e=N:(e--,e|=e>>>1,e|=e>>>2,e|=e>>>4,e|=e>>>8,e|=e>>>16,e++),e}function u(e,t){return e<=0||0===t.length&&t.ended?0:t.objectMode?1:e!==e?t.flowing&&t.length?t.buffer.head.data.length:t.length:(e>t.highWaterMark&&(t.highWaterMark=l(e)),e<=t.length?e:t.ended?t.length:(t.needReadable=!0,0))}function c(e,t){var n=null;return L.isBuffer(t)||"string"==typeof t||null===t||void 0===t||e.objectMode||(n=new TypeError("Invalid non-string/buffer chunk")),n}function p(e,t){if(!t.ended){if(t.decoder){var n=t.decoder.end();n&&n.length&&(t.buffer.push(n),t.length+=t.objectMode?1:n.length)}t.ended=!0,h(e)}}function h(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(P("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?T(f,e):f(e))}function f(e){P("emit readable"),e.emit("readable"),w(e)}function d(e,t){t.readingMore||(t.readingMore=!0,T(m,e,t))}function m(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length<t.highWaterMark&&(P("maybeReadMore read 0"),e.read(0),n!==t.length);)n=t.length;t.readingMore=!1}function g(e){return function(){var t=e._readableState;P("pipeOnDrain",t.awaitDrain),t.awaitDrain&&t.awaitDrain--,0===t.awaitDrain&&D(e,"data")&&(t.flowing=!0,w(e))}}function y(e){P("readable nexttick read 0"),e.read(0)}function v(e,t){t.resumeScheduled||(t.resumeScheduled=!0,T(b,e,t))}function b(e,t){t.reading||(P("resume read 0"),e.read(0)),t.resumeScheduled=!1,t.awaitDrain=0,e.emit("resume"),w(e),t.flowing&&!t.reading&&e.read(0)}function w(e){var t=e._readableState;for(P("flow",t.flowing);t.flowing&&null!==e.read(););}function _(e,t){if(0===t.length)return null;var n;return t.objectMode?n=t.buffer.shift():!e||e>=t.length?(n=t.decoder?t.buffer.join(""):1===t.buffer.length?t.buffer.head.data:t.buffer.concat(t.length),t.buffer.clear()):n=x(e,t.buffer,t.decoder),n}function x(e,t,n){var r;return e<t.head.data.length?(r=t.head.data.slice(0,e),t.head.data=t.head.data.slice(e)):r=e===t.head.data.length?t.shift():n?A(e,t):S(e,t),r}function A(e,t){var n=t.head,r=1,i=n.data;for(e-=i.length;n=n.next;){var a=n.data,o=e>a.length?a.length:e;if(i+=o===a.length?a:a.slice(0,e),e-=o,0===e){o===a.length?(++r,n.next?t.head=n.next:t.head=t.tail=null):(t.head=n,n.data=a.slice(o));break}++r}return t.length-=r,i}function S(e,t){var n=M.allocUnsafe(e),r=t.head,i=1;for(r.data.copy(n),e-=r.data.length;r=r.next;){var a=r.data,o=e>a.length?a.length:e;if(a.copy(n,n.length-e,0,o),e-=o,0===e){o===a.length?(++i,r.next?t.head=r.next:t.head=t.tail=null):(t.head=r,r.data=a.slice(o));break}++i}return t.length-=i,n}function j(e){var t=e._readableState;if(t.length>0)throw new Error('"endReadable()" called on non-empty stream');t.endEmitted||(t.ended=!0,T(E,t,e))}function E(e,t){e.endEmitted||0!==e.length||(e.endEmitted=!0,t.readable=!1,t.emit("end"))}function O(e,t){for(var n=0,r=e.length;n<r;n++)t(e[n],n)}function k(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1}t.exports=a;var T=e("process-nextick-args"),C=e("isarray");a.ReadableState=i;var I,D=(e("events").EventEmitter,function(e,t){return e.listeners(t).length});!function(){try{I=e("stream")}catch(t){}finally{I||(I=e("events").EventEmitter)}}();var L=e("buffer").Buffer,M=e("buffer-shims"),R=e("core-util-is");R.inherits=e("inherits");var U=e("util"),P=void 0;P=U&&U.debuglog?U.debuglog("stream"):function(){};var q,B=e("./internal/streams/BufferList");R.inherits(a,I);var z,z;a.prototype.push=function(e,t){var n=this._readableState;return n.objectMode||"string"!=typeof e||(t=t||n.defaultEncoding,t!==n.encoding&&(e=M.from(e,t),t="")),o(this,n,e,t,!1)},a.prototype.unshift=function(e){var t=this._readableState;return o(this,t,e,"",!0)},a.prototype.isPaused=function(){return this._readableState.flowing===!1},a.prototype.setEncoding=function(t){return q||(q=e("string_decoder/").StringDecoder),this._readableState.decoder=new q(t),this._readableState.encoding=t,this};var N=8388608;a.prototype.read=function(e){P("read",e),e=parseInt(e,10);var t=this._readableState,n=e;if(0!==e&&(t.emittedReadable=!1),0===e&&t.needReadable&&(t.length>=t.highWaterMark||t.ended))return P("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?j(this):h(this),null;if(e=u(e,t),0===e&&t.ended)return 0===t.length&&j(this),null;var r=t.needReadable;P("need readable",r),(0===t.length||t.length-e<t.highWaterMark)&&(r=!0,P("length less than watermark",r)),t.ended||t.reading?(r=!1,P("reading or ended",r)):r&&(P("do read"),t.reading=!0,t.sync=!0,0===t.length&&(t.needReadable=!0),this._read(t.highWaterMark),t.sync=!1,t.reading||(e=u(n,t)));var i;return i=e>0?_(e,t):null,null===i?(t.needReadable=!0,e=0):t.length-=e,0===t.length&&(t.ended||(t.needReadable=!0),n!==e&&t.ended&&j(this)),null!==i&&this.emit("data",i),i},a.prototype._read=function(e){this.emit("error",new Error("not implemented"))},a.prototype.pipe=function(e,t){function i(e){P("onunpipe"),e===h&&o()}function a(){P("onend"),e.end()}function o(){P("cleanup"),e.removeListener("close",u),e.removeListener("finish",c),e.removeListener("drain",y),e.removeListener("error",l),e.removeListener("unpipe",i),h.removeListener("end",a),h.removeListener("end",o),h.removeListener("data",s),v=!0,!f.awaitDrain||e._writableState&&!e._writableState.needDrain||y()}function s(t){P("ondata"),b=!1;var n=e.write(t);!1!==n||b||((1===f.pipesCount&&f.pipes===e||f.pipesCount>1&&k(f.pipes,e)!==-1)&&!v&&(P("false write response, pause",h._readableState.awaitDrain),h._readableState.awaitDrain++,b=!0),h.pause())}function l(t){P("onerror",t),p(),e.removeListener("error",l),0===D(e,"error")&&e.emit("error",t)}function u(){e.removeListener("finish",c),p()}function c(){P("onfinish"),e.removeListener("close",u),p()}function p(){P("unpipe"),h.unpipe(e)}var h=this,f=this._readableState;switch(f.pipesCount){case 0:f.pipes=e;break;case 1:f.pipes=[f.pipes,e];break;default:f.pipes.push(e)}f.pipesCount+=1,P("pipe count=%d opts=%j",f.pipesCount,t);var d=(!t||t.end!==!1)&&e!==n.stdout&&e!==n.stderr,m=d?a:o;f.endEmitted?T(m):h.once("end",m),e.on("unpipe",i);var y=g(h);e.on("drain",y);var v=!1,b=!1;return h.on("data",s),r(e,"error",l),e.once("close",u),e.once("finish",c),e.emit("pipe",h),f.flowing||(P("pipe resume"),h.resume()),e},a.prototype.unpipe=function(e){var t=this._readableState;if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes?this:(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this),this);if(!e){var n=t.pipes,r=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var i=0;i<r;i++)n[i].emit("unpipe",this);return this}var a=k(t.pipes,e);return a===-1?this:(t.pipes.splice(a,1),t.pipesCount-=1,1===t.pipesCount&&(t.pipes=t.pipes[0]),e.emit("unpipe",this),this)},a.prototype.on=function(e,t){var n=I.prototype.on.call(this,e,t);if("data"===e)this._readableState.flowing!==!1&&this.resume();else if("readable"===e){var r=this._readableState;r.endEmitted||r.readableListening||(r.readableListening=r.needReadable=!0,r.emittedReadable=!1,r.reading?r.length&&h(this,r):T(y,this))}return n},a.prototype.addListener=a.prototype.on,a.prototype.resume=function(){var e=this._readableState;return e.flowing||(P("resume"),e.flowing=!0,v(this,e)),this},a.prototype.pause=function(){return P("call pause flowing=%j",this._readableState.flowing),!1!==this._readableState.flowing&&(P("pause"),this._readableState.flowing=!1,this.emit("pause")),this},a.prototype.wrap=function(e){var t=this._readableState,n=!1,r=this;e.on("end",function(){if(P("wrapped end"),t.decoder&&!t.ended){var e=t.decoder.end();e&&e.length&&r.push(e)}r.push(null)}),e.on("data",function(i){if(P("wrapped data"),t.decoder&&(i=t.decoder.write(i)),(!t.objectMode||null!==i&&void 0!==i)&&(t.objectMode||i&&i.length)){var a=r.push(i);a||(n=!0,e.pause())}});for(var i in e)void 0===this[i]&&"function"==typeof e[i]&&(this[i]=function(t){return function(){return e[t].apply(e,arguments)}}(i));var a=["error","close","destroy","pause","resume"];return O(a,function(t){e.on(t,r.emit.bind(r,t))}),r._read=function(t){P("wrapped _read",t),n&&(n=!1,e.resume())},r},a._fromList=_}).call(this,e("_process"))},{"./_stream_duplex":44,"./internal/streams/BufferList":49,_process:42,buffer:5,"buffer-shims":4,"core-util-is":6,events:28,inherits:38,isarray:40,"process-nextick-args":41,"string_decoder/":56,util:3}],47:[function(e,t,n){"use strict";function r(e){this.afterTransform=function(t,n){return i(e,t,n)},this.needTransform=!1,this.transforming=!1,this.writecb=null,this.writechunk=null,this.writeencoding=null}function i(e,t,n){var r=e._transformState;r.transforming=!1;var i=r.writecb;if(!i)return e.emit("error",new Error("no writecb in Transform class"));r.writechunk=null,r.writecb=null,null!==n&&void 0!==n&&e.push(n),i(t);var a=e._readableState;a.reading=!1,(a.needReadable||a.length<a.highWaterMark)&&e._read(a.highWaterMark)}function a(e){if(!(this instanceof a))return new a(e);s.call(this,e),this._transformState=new r(this);var t=this;this._readableState.needReadable=!0,this._readableState.sync=!1,e&&("function"==typeof e.transform&&(this._transform=e.transform),"function"==typeof e.flush&&(this._flush=e.flush)),this.once("prefinish",function(){"function"==typeof this._flush?this._flush(function(e){o(t,e)}):o(t)})}function o(e,t){if(t)return e.emit("error",t);var n=e._writableState,r=e._transformState;if(n.length)throw new Error("Calling transform done when ws.length != 0");if(r.transforming)throw new Error("Calling transform done when still transforming");return e.push(null)}t.exports=a;var s=e("./_stream_duplex"),l=e("core-util-is");l.inherits=e("inherits"),l.inherits(a,s),a.prototype.push=function(e,t){return this._transformState.needTransform=!1,s.prototype.push.call(this,e,t)},a.prototype._transform=function(e,t,n){throw new Error("Not implemented")},a.prototype._write=function(e,t,n){var r=this._transformState;if(r.writecb=n,r.writechunk=e,r.writeencoding=t,!r.transforming){var i=this._readableState;(r.needTransform||i.needReadable||i.length<i.highWaterMark)&&this._read(i.highWaterMark)}},a.prototype._read=function(e){var t=this._transformState;null!==t.writechunk&&t.writecb&&!t.transforming?(t.transforming=!0,this._transform(t.writechunk,t.writeencoding,t.afterTransform)):t.needTransform=!0}},{"./_stream_duplex":44,"core-util-is":6,inherits:38}],48:[function(e,t,n){(function(n){"use strict";function r(){}function i(e,t,n){this.chunk=e,this.encoding=t,this.callback=n,this.next=null}function a(t,n){C=C||e("./_stream_duplex"),t=t||{},this.objectMode=!!t.objectMode,n instanceof C&&(this.objectMode=this.objectMode||!!t.writableObjectMode);var r=t.highWaterMark,i=this.objectMode?16:16384;this.highWaterMark=r||0===r?r:i,this.highWaterMark=~~this.highWaterMark,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1;var a=t.decodeStrings===!1;this.decodeStrings=!a,this.defaultEncoding=t.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=function(e){d(n,e)},this.writecb=null,this.writelen=0,this.bufferedRequest=null,this.lastBufferedRequest=null,this.pendingcb=0,this.prefinished=!1,this.errorEmitted=!1,this.bufferedRequestCount=0,this.corkedRequestsFree=new x(this)}function o(t){return C=C||e("./_stream_duplex"),this instanceof o||this instanceof C?(this._writableState=new a(t,this),this.writable=!0,t&&("function"==typeof t.write&&(this._write=t.write),"function"==typeof t.writev&&(this._writev=t.writev)),void E.call(this)):new o(t)}function s(e,t){var n=new Error("write after end");e.emit("error",n),A(t,n)}function l(e,t,n,r){var i=!0,a=!1;return null===n?a=new TypeError("May not write null values to stream"):k.isBuffer(n)||"string"==typeof n||void 0===n||t.objectMode||(a=new TypeError("Invalid non-string/buffer chunk")),a&&(e.emit("error",a),A(r,a),i=!1),i}function u(e,t,n){return e.objectMode||e.decodeStrings===!1||"string"!=typeof t||(t=T.from(t,n)),t}function c(e,t,n,r,a){n=u(t,n,r),k.isBuffer(n)&&(r="buffer");var o=t.objectMode?1:n.length;t.length+=o;var s=t.length<t.highWaterMark;if(s||(t.needDrain=!0),t.writing||t.corked){var l=t.lastBufferedRequest;t.lastBufferedRequest=new i(n,r,a),l?l.next=t.lastBufferedRequest:t.bufferedRequest=t.lastBufferedRequest,t.bufferedRequestCount+=1}else p(e,t,!1,o,n,r,a);return s}function p(e,t,n,r,i,a,o){t.writelen=r,t.writecb=o,t.writing=!0,t.sync=!0,n?e._writev(i,t.onwrite):e._write(i,a,t.onwrite),t.sync=!1}function h(e,t,n,r,i){--t.pendingcb,n?A(i,r):i(r),e._writableState.errorEmitted=!0,e.emit("error",r)}function f(e){e.writing=!1,e.writecb=null,e.length-=e.writelen,e.writelen=0}function d(e,t){var n=e._writableState,r=n.sync,i=n.writecb;if(f(n),t)h(e,n,r,t,i);else{var a=v(n);a||n.corked||n.bufferProcessing||!n.bufferedRequest||y(e,n),r?S(m,e,n,a,i):m(e,n,a,i)}}function m(e,t,n,r){n||g(e,t),t.pendingcb--,r(),w(e,t)}function g(e,t){0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"))}function y(e,t){t.bufferProcessing=!0;var n=t.bufferedRequest;if(e._writev&&n&&n.next){var r=t.bufferedRequestCount,i=new Array(r),a=t.corkedRequestsFree;a.entry=n;for(var o=0;n;)i[o]=n,n=n.next,o+=1;p(e,t,!0,t.length,i,"",a.finish),t.pendingcb++,t.lastBufferedRequest=null,a.next?(t.corkedRequestsFree=a.next,a.next=null):t.corkedRequestsFree=new x(t)}else{for(;n;){var s=n.chunk,l=n.encoding,u=n.callback,c=t.objectMode?1:s.length;if(p(e,t,!1,c,s,l,u),n=n.next,t.writing)break;
+}null===n&&(t.lastBufferedRequest=null)}t.bufferedRequestCount=0,t.bufferedRequest=n,t.bufferProcessing=!1}function v(e){return e.ending&&0===e.length&&null===e.bufferedRequest&&!e.finished&&!e.writing}function b(e,t){t.prefinished||(t.prefinished=!0,e.emit("prefinish"))}function w(e,t){var n=v(t);return n&&(0===t.pendingcb?(b(e,t),t.finished=!0,e.emit("finish")):b(e,t)),n}function _(e,t,n){t.ending=!0,w(e,t),n&&(t.finished?A(n):e.once("finish",n)),t.ended=!0,e.writable=!1}function x(e){var t=this;this.next=null,this.entry=null,this.finish=function(n){var r=t.entry;for(t.entry=null;r;){var i=r.callback;e.pendingcb--,i(n),r=r.next}e.corkedRequestsFree?e.corkedRequestsFree.next=t:e.corkedRequestsFree=t}}t.exports=o;var A=e("process-nextick-args"),S=!n.browser&&["v0.10","v0.9."].indexOf(n.version.slice(0,5))>-1?setImmediate:A;o.WritableState=a;var j=e("core-util-is");j.inherits=e("inherits");var E,O={deprecate:e("util-deprecate")};!function(){try{E=e("stream")}catch(t){}finally{E||(E=e("events").EventEmitter)}}();var k=e("buffer").Buffer,T=e("buffer-shims");j.inherits(o,E);var C;a.prototype.getBuffer=function(){for(var e=this.bufferedRequest,t=[];e;)t.push(e),e=e.next;return t},function(){try{Object.defineProperty(a.prototype,"buffer",{get:O.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.")})}catch(e){}}();var C;o.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe, not readable"))},o.prototype.write=function(e,t,n){var i=this._writableState,a=!1;return"function"==typeof t&&(n=t,t=null),k.isBuffer(e)?t="buffer":t||(t=i.defaultEncoding),"function"!=typeof n&&(n=r),i.ended?s(this,n):l(this,i,e,n)&&(i.pendingcb++,a=c(this,i,e,t,n)),a},o.prototype.cork=function(){var e=this._writableState;e.corked++},o.prototype.uncork=function(){var e=this._writableState;e.corked&&(e.corked--,e.writing||e.corked||e.finished||e.bufferProcessing||!e.bufferedRequest||y(this,e))},o.prototype.setDefaultEncoding=function(e){if("string"==typeof e&&(e=e.toLowerCase()),!(["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le","raw"].indexOf((e+"").toLowerCase())>-1))throw new TypeError("Unknown encoding: "+e);return this._writableState.defaultEncoding=e,this},o.prototype._write=function(e,t,n){n(new Error("not implemented"))},o.prototype._writev=null,o.prototype.end=function(e,t,n){var r=this._writableState;"function"==typeof e?(n=e,e=null,t=null):"function"==typeof t&&(n=t,t=null),null!==e&&void 0!==e&&this.write(e,t),r.corked&&(r.corked=1,this.uncork()),r.ending||r.finished||_(this,r,n)}}).call(this,e("_process"))},{"./_stream_duplex":44,_process:42,buffer:5,"buffer-shims":4,"core-util-is":6,events:28,inherits:38,"process-nextick-args":41,"util-deprecate":57}],49:[function(e,t,n){"use strict";function r(){this.head=null,this.tail=null,this.length=0}var i=(e("buffer").Buffer,e("buffer-shims"));t.exports=r,r.prototype.push=function(e){var t={data:e,next:null};this.length>0?this.tail.next=t:this.head=t,this.tail=t,++this.length},r.prototype.unshift=function(e){var t={data:e,next:this.head};0===this.length&&(this.tail=t),this.head=t,++this.length},r.prototype.shift=function(){if(0!==this.length){var e=this.head.data;return 1===this.length?this.head=this.tail=null:this.head=this.head.next,--this.length,e}},r.prototype.clear=function(){this.head=this.tail=null,this.length=0},r.prototype.join=function(e){if(0===this.length)return"";for(var t=this.head,n=""+t.data;t=t.next;)n+=e+t.data;return n},r.prototype.concat=function(e){if(0===this.length)return i.alloc(0);if(1===this.length)return this.head.data;for(var t=i.allocUnsafe(e>>>0),n=this.head,r=0;n;)n.data.copy(t,r),r+=n.data.length,n=n.next;return t}},{buffer:5,"buffer-shims":4}],50:[function(e,t,n){t.exports=e("./lib/_stream_passthrough.js")},{"./lib/_stream_passthrough.js":45}],51:[function(e,t,n){(function(r){var i=function(){try{return e("stream")}catch(t){}}();n=t.exports=e("./lib/_stream_readable.js"),n.Stream=i||n,n.Readable=n,n.Writable=e("./lib/_stream_writable.js"),n.Duplex=e("./lib/_stream_duplex.js"),n.Transform=e("./lib/_stream_transform.js"),n.PassThrough=e("./lib/_stream_passthrough.js"),!r.browser&&"disable"===r.env.READABLE_STREAM&&i&&(t.exports=i)}).call(this,e("_process"))},{"./lib/_stream_duplex.js":44,"./lib/_stream_passthrough.js":45,"./lib/_stream_readable.js":46,"./lib/_stream_transform.js":47,"./lib/_stream_writable.js":48,_process:42}],52:[function(e,t,n){t.exports=e("./lib/_stream_transform.js")},{"./lib/_stream_transform.js":47}],53:[function(e,t,n){t.exports=e("./lib/_stream_writable.js")},{"./lib/_stream_writable.js":48}],54:[function(e,t,n){t.exports=function(e){return e.replace(/[-\\^$*+?.()|[\]{}]/g,"\\$&")}},{}],55:[function(e,t,n){function r(){i.call(this)}t.exports=r;var i=e("events").EventEmitter,a=e("inherits");a(r,i),r.Readable=e("readable-stream/readable.js"),r.Writable=e("readable-stream/writable.js"),r.Duplex=e("readable-stream/duplex.js"),r.Transform=e("readable-stream/transform.js"),r.PassThrough=e("readable-stream/passthrough.js"),r.Stream=r,r.prototype.pipe=function(e,t){function n(t){e.writable&&!1===e.write(t)&&u.pause&&u.pause()}function r(){u.readable&&u.resume&&u.resume()}function a(){c||(c=!0,e.end())}function o(){c||(c=!0,"function"==typeof e.destroy&&e.destroy())}function s(e){if(l(),0===i.listenerCount(this,"error"))throw e}function l(){u.removeListener("data",n),e.removeListener("drain",r),u.removeListener("end",a),u.removeListener("close",o),u.removeListener("error",s),e.removeListener("error",s),u.removeListener("end",l),u.removeListener("close",l),e.removeListener("close",l)}var u=this;u.on("data",n),e.on("drain",r),e._isStdio||t&&t.end===!1||(u.on("end",a),u.on("close",o));var c=!1;return u.on("error",s),e.on("error",s),u.on("end",l),u.on("close",l),e.on("close",l),e.emit("pipe",u),e}},{events:28,inherits:38,"readable-stream/duplex.js":43,"readable-stream/passthrough.js":50,"readable-stream/readable.js":51,"readable-stream/transform.js":52,"readable-stream/writable.js":53}],56:[function(e,t,n){function r(e){if(e&&!l(e))throw new Error("Unknown encoding: "+e)}function i(e){return e.toString(this.encoding)}function a(e){this.charReceived=e.length%2,this.charLength=this.charReceived?2:0}function o(e){this.charReceived=e.length%3,this.charLength=this.charReceived?3:0}var s=e("buffer").Buffer,l=s.isEncoding||function(e){switch(e&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}},u=n.StringDecoder=function(e){switch(this.encoding=(e||"utf8").toLowerCase().replace(/[-_]/,""),r(e),this.encoding){case"utf8":this.surrogateSize=3;break;case"ucs2":case"utf16le":this.surrogateSize=2,this.detectIncompleteChar=a;break;case"base64":this.surrogateSize=3,this.detectIncompleteChar=o;break;default:return void(this.write=i)}this.charBuffer=new s(6),this.charReceived=0,this.charLength=0};u.prototype.write=function(e){for(var t="";this.charLength;){var n=e.length>=this.charLength-this.charReceived?this.charLength-this.charReceived:e.length;if(e.copy(this.charBuffer,this.charReceived,0,n),this.charReceived+=n,this.charReceived<this.charLength)return"";e=e.slice(n,e.length),t=this.charBuffer.slice(0,this.charLength).toString(this.encoding);var r=t.charCodeAt(t.length-1);if(!(r>=55296&&r<=56319)){if(this.charReceived=this.charLength=0,0===e.length)return t;break}this.charLength+=this.surrogateSize,t=""}this.detectIncompleteChar(e);var i=e.length;this.charLength&&(e.copy(this.charBuffer,0,e.length-this.charReceived,i),i-=this.charReceived),t+=e.toString(this.encoding,0,i);var i=t.length-1,r=t.charCodeAt(i);if(r>=55296&&r<=56319){var a=this.surrogateSize;return this.charLength+=a,this.charReceived+=a,this.charBuffer.copy(this.charBuffer,a,0,a),e.copy(this.charBuffer,0,0,a),t.substring(0,i)}return t},u.prototype.detectIncompleteChar=function(e){for(var t=e.length>=3?3:e.length;t>0;t--){var n=e[e.length-t];if(1==t&&n>>5==6){this.charLength=2;break}if(t<=2&&n>>4==14){this.charLength=3;break}if(t<=3&&n>>3==30){this.charLength=4;break}}this.charReceived=t},u.prototype.end=function(e){var t="";if(e&&e.length&&(t=this.write(e)),this.charReceived){var n=this.charReceived,r=this.charBuffer,i=this.encoding;t+=r.slice(0,n).toString(i)}return t}},{buffer:5}],57:[function(e,t,n){(function(e){function n(e,t){function n(){if(!i){if(r("throwDeprecation"))throw new Error(t);r("traceDeprecation")?console.trace(t):console.warn(t),i=!0}return e.apply(this,arguments)}if(r("noDeprecation"))return e;var i=!1;return n}function r(t){try{if(!e.localStorage)return!1}catch(n){return!1}var r=e.localStorage[t];return null!=r&&"true"===String(r).toLowerCase()}t.exports=n}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],58:[function(e,t,n){function r(){for(var e={},t=0;t<arguments.length;t++){var n=arguments[t];for(var r in n)i.call(n,r)&&(e[r]=n[r])}return e}t.exports=r;var i=Object.prototype.hasOwnProperty},{}]},{},[1])(1)}),function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.SwaggerClient=e()}}(function(){var t;return function n(e,t,r){function i(o,s){if(!t[o]){if(!e[o]){var l="function"==typeof require&&require;if(!s&&l)return l(o,!0);if(a)return a(o,!0);var u=new Error("Cannot find module '"+o+"'");throw u.code="MODULE_NOT_FOUND",u}var c=t[o]={exports:{}};e[o][0].call(c.exports,function(t){var n=e[o][1][t];return i(n?n:t)},c,c.exports,n,e,t,r)}return t[o].exports}for(var a="function"==typeof require&&require,o=0;o<r.length;o++)i(r[o]);return i}({1:[function(e,t,n){"use strict";var r=e("./lib/auth"),i=e("./lib/helpers"),a=e("./lib/client"),o=function(e,t){return i.log('This is deprecated, use "new SwaggerClient" instead.'),new a(e,t)};Array.prototype.indexOf||(Array.prototype.indexOf=function(e,t){for(var n=t||0,r=this.length;n<r;n++)if(this[n]===e)return n;return-1}),String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")}),String.prototype.endsWith||(String.prototype.endsWith=function(e){return this.indexOf(e,this.length-e.length)!==-1}),t.exports=a,a.ApiKeyAuthorization=r.ApiKeyAuthorization,a.PasswordAuthorization=r.PasswordAuthorization,a.CookieAuthorization=r.CookieAuthorization,a.SwaggerApi=o,a.SwaggerClient=o,a.SchemaMarkup=e("./lib/schema-markup")},{"./lib/auth":2,"./lib/client":3,"./lib/helpers":4,"./lib/schema-markup":7}],2:[function(e,t,n){"use strict";var r=e("./helpers"),i=e("btoa"),a=e("cookiejar").CookieJar,o={each:e("lodash-compat/collection/each"),includes:e("lodash-compat/collection/includes"),isObject:e("lodash-compat/lang/isObject"),isArray:e("lodash-compat/lang/isArray")},s=t.exports.SwaggerAuthorizations=function(e){this.authz=e||{}};s.prototype.add=function(e,t){if(o.isObject(e))for(var n in e)this.authz[n]=e[n];else"string"==typeof e&&(this.authz[e]=t);return t},s.prototype.remove=function(e){return delete this.authz[e]},s.prototype.apply=function(e,t){var n=!0,r=!t,i=[],a=e.clientAuthorizations||this.authz;return o.each(t,function(e,t){"string"==typeof t&&i.push(t),o.each(e,function(e,t){i.push(t)})}),o.each(a,function(t,a){if(r||o.includes(i,a)){var s=t.apply(e);n=n&&!!s}}),n};var l=t.exports.ApiKeyAuthorization=function(e,t,n){this.name=e,this.value=t,this.type=n};l.prototype.apply=function(e){if("query"===this.type){var t;if(e.url.indexOf("?")>0){t=e.url.substring(e.url.indexOf("?")+1);var n=t.split("&");if(n&&n.length>0)for(var r=0;r<n.length;r++){var i=n[r].split("=");if(i&&i.length>0&&i[0]===this.name)return!1}}return e.url.indexOf("?")>0?e.url=e.url+"&"+this.name+"="+this.value:e.url=e.url+"?"+this.name+"="+this.value,!0}if("header"===this.type)return"undefined"==typeof e.headers[this.name]&&(e.headers[this.name]=this.value),!0};var u=t.exports.CookieAuthorization=function(e){this.cookie=e};u.prototype.apply=function(e){return e.cookieJar=e.cookieJar||new a,e.cookieJar.setCookie(this.cookie),!0};var c=t.exports.PasswordAuthorization=function(e,t){3===arguments.length&&(r.log("PasswordAuthorization: the 'name' argument has been removed, pass only username and password"),e=arguments[1],t=arguments[2]),this.username=e,this.password=t};c.prototype.apply=function(e){return"undefined"==typeof e.headers.Authorization&&(e.headers.Authorization="Basic "+i(this.username+":"+this.password)),!0}},{"./helpers":4,btoa:13,cookiejar:18,"lodash-compat/collection/each":52,"lodash-compat/collection/includes":55,"lodash-compat/lang/isArray":140,"lodash-compat/lang/isObject":144}],3:[function(e,t,n){"use strict";var r={bind:e("lodash-compat/function/bind"),cloneDeep:e("lodash-compat/lang/cloneDeep"),find:e("lodash-compat/collection/find"),forEach:e("lodash-compat/collection/forEach"),indexOf:e("lodash-compat/array/indexOf"),isArray:e("lodash-compat/lang/isArray"),isObject:e("lodash-compat/lang/isObject"),isFunction:e("lodash-compat/lang/isFunction"),isPlainObject:e("lodash-compat/lang/isPlainObject"),isUndefined:e("lodash-compat/lang/isUndefined")},i=e("./auth"),a=e("./helpers"),o=e("./types/model"),s=e("./types/operation"),l=e("./types/operationGroup"),u=e("./resolver"),c=e("./http"),p=e("./spec-converter"),h=e("q"),f=["apis","authorizationScheme","authorizations","basePath","build","buildFrom1_1Spec","buildFrom1_2Spec","buildFromSpec","clientAuthorizations","convertInfo","debug","defaultErrorCallback","defaultSuccessCallback","enableCookies","fail","failure","finish","help","host","idFromOp","info","initialize","isBuilt","isValid","modelPropertyMacro","models","modelsArray","options","parameterMacro","parseUri","progress","resourceCount","sampleModels","selfReflect","setConsolidatedModels","spec","supportedSubmitMethods","swaggerRequestHeaders","tagFromLabel","title","url","useJQuery","jqueryAjaxCache"],d=["apis","asCurl","description","externalDocs","help","label","name","operation","operations","operationsArray","path","tag"],m=["delete","get","head","options","patch","post","put"],g=t.exports=function(e,t){return this.authorizations=null,this.authorizationScheme=null,this.basePath=null,this.debug=!1,this.enableCookies=!1,this.info=null,this.isBuilt=!1,this.isValid=!1,this.modelsArray=[],this.resourceCount=0,this.url=null,this.useJQuery=!1,this.jqueryAjaxCache=!1,this.swaggerObject={},this.deferredClient=void 0,this.clientAuthorizations=new i.SwaggerAuthorizations,"undefined"!=typeof e?this.initialize(e,t):this};g.prototype.initialize=function(e,t){if(this.models={},this.sampleModels={},"string"==typeof e?this.url=e:r.isObject(e)&&(t=e,this.url=t.url),this.url&&this.url.indexOf("http:")===-1&&this.url.indexOf("https:")===-1&&"undefined"!=typeof window&&"undefined"!=typeof window.location&&(this.url=window.location.origin+this.url),t=t||{},this.clientAuthorizations.add(t.authorizations),this.swaggerRequestHeaders=t.swaggerRequestHeaders||"application/json;charset=utf-8,*/*",this.defaultSuccessCallback=t.defaultSuccessCallback||null,this.defaultErrorCallback=t.defaultErrorCallback||null,this.modelPropertyMacro=t.modelPropertyMacro||null,this.connectionAgent=t.connectionAgent||null,this.parameterMacro=t.parameterMacro||null,this.usePromise=t.usePromise||null,this.timeout=t.timeout||null,this.fetchSpecTimeout="undefined"!=typeof t.fetchSpecTimeout?t.fetchSpecTimeout:t.timeout||null,this.usePromise&&(this.deferredClient=h.defer()),"function"==typeof t.success&&(this.success=t.success),t.useJQuery&&(this.useJQuery=t.useJQuery),t.jqueryAjaxCache&&(this.jqueryAjaxCache=t.jqueryAjaxCache),t.enableCookies&&(this.enableCookies=t.enableCookies),this.options=t||{},this.options.timeout=this.timeout,this.options.fetchSpecTimeout=this.fetchSpecTimeout,this.supportedSubmitMethods=t.supportedSubmitMethods||[],this.failure=t.failure||function(e){throw e},this.progress=t.progress||function(){},this.spec=r.cloneDeep(t.spec),t.scheme&&(this.scheme=t.scheme),this.usePromise||"function"==typeof t.success)return this.ready=!0,this.build()},g.prototype.build=function(e){if(this.isBuilt)return this;var t=this;this.spec?this.progress("fetching resource list; Please wait."):this.progress("fetching resource list: "+this.url+"; Please wait.");var n={useJQuery:this.useJQuery,jqueryAjaxCache:this.jqueryAjaxCache,connectionAgent:this.connectionAgent,enableCookies:this.enableCookies,url:this.url,method:"get",headers:{accept:this.swaggerRequestHeaders},on:{error:function(e){return t&&t.url&&"http"!==t.url.substring(0,4)?t.fail("Please specify the protocol for "+t.url):!e.errObj||"ECONNABORTED"!==e.errObj.code&&e.errObj.message.indexOf("timeout")===-1?0===e.status?t.fail("Can't read from server.  It may not have the appropriate access-control-origin settings."):404===e.status?t.fail("Can't read swagger JSON from "+t.url):t.fail(e.status+" : "+e.statusText+" "+t.url):t.fail("Request timed out after "+t.fetchSpecTimeout+"ms")},response:function(e){var n=e.obj;if(!n)return t.fail("failed to parse JSON/YAML response");if(t.swaggerVersion=n.swaggerVersion,t.swaggerObject=n,n.swagger&&2===parseInt(n.swagger))t.swaggerVersion=n.swagger,(new u).resolve(n,t.url,t.buildFromSpec,t),t.isValid=!0;else{var r=new p;t.oldSwaggerObject=t.swaggerObject,r.setDocumentationLocation(t.url),r.convert(n,t.clientAuthorizations,t.options,function(e){t.swaggerObject=e,(new u).resolve(e,t.url,t.buildFromSpec,t),t.isValid=!0})}}}};if(this.fetchSpecTimeout&&(n.timeout=this.fetchSpecTimeout),this.spec&&"object"==typeof this.spec)t.swaggerObject=this.spec,setTimeout(function(){(new u).resolve(t.spec,t.url,t.buildFromSpec,t)},10);else{if(this.clientAuthorizations.apply(n),e)return n;(new c).execute(n,this.options)}return this.usePromise?this.deferredClient.promise:this},g.prototype.buildFromSpec=function(e){if(this.isBuilt)return this;this.apis={},this.apisArray=[],this.basePath=e.basePath||"",this.consumes=e.consumes,this.host=e.host||"",this.info=e.info||{},this.produces=e.produces,this.schemes=e.schemes||[],this.securityDefinitions=r.cloneDeep(e.securityDefinitions),this.security=e.security,this.title=e.title||"";var t,n,i,u,c={},p=this;if(e.externalDocs&&(this.externalDocs=e.externalDocs),this.authSchemes=this.securityDefinitions,this.securityDefinitions)for(t in this.securityDefinitions){var h=this.securityDefinitions[t];h.vendorExtensions={};for(var g in h)if(a.extractExtensions(g,h),"scopes"===g){var y=h[g];if("object"==typeof y){y.vendorExtensions={};for(var v in y)a.extractExtensions(v,y),0===v.indexOf("x-")&&delete y[v]}}}if(Array.isArray(e.tags))for(c={},n=0;n<e.tags.length;n++){var b=r.cloneDeep(e.tags[n]);c[b.name]=b;for(u in b){if("externalDocs"===u&&"object"==typeof b[u])for(var w in b[u])a.extractExtensions(w,b[u]);a.extractExtensions(u,b)}}if("string"==typeof this.url){if(i=this.parseUri(this.url),"undefined"==typeof this.scheme&&"undefined"==typeof this.schemes||0===this.schemes.length)"undefined"!=typeof i&&"undefined"!=typeof i.scheme&&(this.scheme=i.scheme),"undefined"!=typeof window&&"undefined"!=typeof window.location?this.scheme=window.location.protocol.replace(":",""):this.scheme=i.scheme||"http";else if("undefined"!=typeof window&&"undefined"!=typeof window.location&&0===window.location.protocol.indexOf("chrome-extension"))this.scheme=i.scheme;else if("undefined"==typeof this.scheme)if("undefined"!=typeof window&&"undefined"!=typeof window.location){var _=window.location.protocol.replace(":","");"https"===_&&this.schemes.indexOf(_)===-1?(a.log("Cannot call a http server from https inside a browser!"),this.scheme="http"):this.schemes.indexOf(_)!==-1?this.scheme=_:this.schemes.indexOf("https")!==-1?this.scheme="https":this.scheme="http"}else this.scheme=this.schemes[0]||i.scheme;"undefined"!=typeof this.host&&""!==this.host||(this.host=i.host,i.port&&(this.host=this.host+":"+i.port))}else"undefined"==typeof this.schemes||0===this.schemes.length?this.scheme="http":"undefined"==typeof this.scheme&&(this.scheme=this.schemes[0]);this.definitions=e.definitions;for(t in this.definitions){var x=new o(t,this.definitions[t],this.models,this.modelPropertyMacro);x&&(this.models[t]=x)}p.apis.help=r.bind(p.help,p),r.forEach(e.paths,function(e,t){r.isPlainObject(e)&&r.forEach(m,function(n){var i=e[n];if(!r.isUndefined(i)){if(!r.isPlainObject(i))return void a.log("The '"+n+"' operation for '"+t+"' path is not an Operation Object");var o=i.tags;!r.isUndefined(o)&&r.isArray(o)&&0!==o.length||(o=i.tags=["default"]);var h=p.idFromOp(t,n,i),m=new s(p,i.scheme,h,n,t,i,p.definitions,p.models,p.clientAuthorizations);m.connectionAgent=p.connectionAgent,m.vendorExtensions={};for(u in i)a.extractExtensions(u,m,i[u]);if(m.externalDocs=i.externalDocs,m.externalDocs){m.externalDocs=r.cloneDeep(m.externalDocs),m.externalDocs.vendorExtensions={};for(u in m.externalDocs)a.extractExtensions(u,m.externalDocs)}r.forEach(o,function(e){var t=r.indexOf(f,e)>-1?"_"+e:e,n=r.indexOf(d,e)>-1?"_"+e:e,i=p[t];if(t!==e&&a.log("The '"+e+"' tag conflicts with a SwaggerClient function/property name.  Use 'client."+t+"' or 'client.apis."+e+"' instead of 'client."+e+"'."),n!==e&&a.log("The '"+e+"' tag conflicts with a SwaggerClient operation function/property name.  Use 'client.apis."+n+"' instead of 'client.apis."+e+"'."),r.indexOf(d,h)>-1&&(a.log("The '"+h+"' operationId conflicts with a SwaggerClient operation function/property name.  Use 'client.apis."+n+"._"+h+"' instead of 'client.apis."+n+"."+h+"'."),h="_"+h,m.nickname=h),r.isUndefined(i)){i=p[t]=p.apis[n]={},i.operations={},i.label=n,i.apis={};var o=c[e];r.isUndefined(o)||(i.description=o.description,i.externalDocs=o.externalDocs,i.vendorExtensions=o.vendorExtensions),p[t].help=r.bind(p.help,i),p.apisArray.push(new l(e,i.description,i.externalDocs,m))}h=p.makeUniqueOperationId(h,p.apis[n]),r.isFunction(i.help)||(i.help=r.bind(p.help,i)),p.apis[n][h]=i[h]=r.bind(m.execute,m),p.apis[n][h].help=i[h].help=r.bind(m.help,m),p.apis[n][h].asCurl=i[h].asCurl=r.bind(m.asCurl,m),i.apis[h]=i.operations[h]=m;var s=r.find(p.apisArray,function(t){return t.tag===e});s&&s.operationsArray.push(m)})}})});var A=[];return r.forEach(Object.keys(c),function(e){var t;for(t in p.apisArray){var n=p.apisArray[t];n&&e===n.name&&(A.push(n),p.apisArray[t]=null)}}),r.forEach(p.apisArray,function(e){e&&A.push(e)}),p.apisArray=A,r.forEach(e.definitions,function(e,t){e.id=t.toLowerCase(),e.name=t,p.modelsArray.push(e)}),this.isBuilt=!0,this.usePromise?(this.isValid=!0,this.isBuilt=!0,this.deferredClient.resolve(this),this.deferredClient.promise):(this.success&&this.success(),this)},g.prototype.makeUniqueOperationId=function(e,t){for(var n=0,i=e;;){var a=!1;if(r.forEach(t.operations,function(e){e.nickname===i&&(a=!0)}),!a)return i;i=e+"_"+n,n++}return e},g.prototype.parseUri=function(e){var t=/^(((([^:\/#\?]+:)?(?:(\/\/)((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/,n=t.exec(e);return{scheme:n[4]?n[4].replace(":",""):void 0,host:n[11],port:n[12],path:n[15]}},g.prototype.help=function(e){var t="";return this instanceof g?r.forEach(this.apis,function(e,n){r.isPlainObject(e)&&(t+="operations for the '"+n+"' tag\n",r.forEach(e.operations,function(e,n){t+="  * "+n+": "+e.summary+"\n"}))}):(this instanceof l||r.isPlainObject(this))&&(t+="operations for the '"+this.label+"' tag\n",r.forEach(this.apis,function(e,n){t+="  * "+n+": "+e.summary+"\n"})),e?t:(a.log(t),t)},g.prototype.tagFromLabel=function(e){return e},g.prototype.idFromOp=function(e,t,n){n&&n.operationId||(n=n||{},n.operationId=t+"_"+e);var r=n.operationId.replace(/[\s!@#$%^&*()_+=\[{\]};:<>|.\/?,\\'""-]/g,"_")||e.substring(1)+"_"+t;return r=r.replace(/((_){2,})/g,"_"),r=r.replace(/^(_)*/g,""),r=r.replace(/([_])*$/g,"")},g.prototype.setHost=function(e){this.host=e,this.apis&&r.forEach(this.apis,function(t){t.operations&&r.forEach(t.operations,function(t){t.host=e})})},g.prototype.setBasePath=function(e){this.basePath=e,this.apis&&r.forEach(this.apis,function(t){t.operations&&r.forEach(t.operations,function(t){t.basePath=e})})},g.prototype.setSchemes=function(e){this.schemes=e,e&&e.length>0&&this.apis&&r.forEach(this.apis,function(t){t.operations&&r.forEach(t.operations,function(t){t.scheme=e[0]})})},g.prototype.fail=function(e){return this.usePromise?(this.deferredClient.reject(e),this.deferredClient.promise):void(this.failure?this.failure(e):this.failure(e))}},{"./auth":2,"./helpers":4,"./http":5,"./resolver":6,"./spec-converter":8,"./types/model":9,"./types/operation":10,"./types/operationGroup":11,"lodash-compat/array/indexOf":49,"lodash-compat/collection/find":53,"lodash-compat/collection/forEach":54,"lodash-compat/function/bind":58,"lodash-compat/lang/cloneDeep":138,"lodash-compat/lang/isArray":140,"lodash-compat/lang/isFunction":142,"lodash-compat/lang/isObject":144,"lodash-compat/lang/isPlainObject":145,"lodash-compat/lang/isUndefined":148,q:157}],4:[function(e,t,n){(function(n){"use strict";var r={isPlainObject:e("lodash-compat/lang/isPlainObject"),indexOf:e("lodash-compat/array/indexOf")};t.exports.__bind=function(e,t){return function(){return e.apply(t,arguments)}};var i=t.exports.log=function(){console&&"test"!==n.env.NODE_ENV&&console.log(Array.prototype.slice.call(arguments)[0])};t.exports.fail=function(e){i(e)},t.exports.optionHtml=function(e,t){return'<tr><td class="optionName">'+e+":</td><td>"+t+"</td></tr>"};var a=t.exports.resolveSchema=function(e){return r.isPlainObject(e.schema)&&(e=a(e.schema)),e};t.exports.simpleRef=function(e){return"undefined"==typeof e?null:0===e.indexOf("#/definitions/")?e.substring("#/definitions/".length):e},t.exports.extractExtensions=function(e,t,n){e&&t&&"string"==typeof e&&0===e.indexOf("x-")&&(t.vendorExtensions=t.vendorExtensions||{},n?t.vendorExtensions[e]=n:t.vendorExtensions[e]=t[e])}}).call(this,e("_process"))},{_process:12,"lodash-compat/array/indexOf":49,"lodash-compat/lang/isPlainObject":145}],5:[function(t,n,r){(function(r){"use strict";var i=t("./helpers"),a=t("superagent"),o=t("js-yaml"),s={isObject:t("lodash-compat/lang/isObject"),keys:t("lodash-compat/object/keys")},l=function(){this.type="JQueryHttpClient"},u=function(){this.type="SuperagentHttpClient"},c=n.exports=function(){};c.prototype.execute=function(t,n){var r;r=n&&n.client?n.client:new u(n),r.opts=n||{},n&&n.requestAgent&&(a=n.requestAgent);var i=!1;if("undefined"!=typeof window&&"undefined"!=typeof window.jQuery&&(i=!0),"options"===t.method.toLowerCase()&&"SuperagentHttpClient"===r.type&&(e("forcing jQuery as OPTIONS are not supported by SuperAgent"),t.useJQuery=!0),this.isInternetExplorer()&&(t.useJQuery===!1||!i))throw new Error("Unsupported configuration! JQuery is required but not available");(t&&t.useJQuery===!0||this.isInternetExplorer()&&i)&&(r=new l(n));var o=t.on.response,c=t.on.error,p=function(e){return n&&n.requestInterceptor&&(e=n.requestInterceptor.apply(e)),e},h=function(e){return n&&n.responseInterceptor&&(e=n.responseInterceptor.apply(e,[t])),o(e)},f=function(e){n&&n.responseInterceptor&&(e=n.responseInterceptor.apply(e,[t])),c(e)};return t.on.error=function(e){f(e)},t.on.response=function(e){e&&e.status>=400?f(e):h(e)},s.isObject(t)&&s.isObject(t.body)&&t.body.type&&"formData"===t.body.type&&n.useJQuery&&(t.contentType=!1,t.processData=!1,delete t.headers["Content-Type"]),t=p(t)||t,t.beforeSend?t.beforeSend(function(e){r.execute(e||t)}):r.execute(t),t.deferred?t.deferred.promise:t},c.prototype.isInternetExplorer=function(){var e=!1;if("undefined"!=typeof navigator&&navigator.userAgent){var t=navigator.userAgent.toLowerCase();if(t.indexOf("msie")!==-1){var n=parseInt(t.split("msie")[1]);n<=8&&(e=!0)}}return e},l.prototype.execute=function(e){var t=this.jQuery||"undefined"!=typeof window&&window.jQuery,n=e.on,r=e;if("undefined"==typeof t||t===!1)throw new Error("Unsupported configuration! JQuery is required but not available");return e.type=e.method,e.cache=e.jqueryAjaxCache,e.data=e.body,delete e.jqueryAjaxCache,delete e.useJQuery,delete e.body,e.complete=function(e){for(var t={},a=e.getAllResponseHeaders().split("\n"),s=0;s<a.length;s++){var l=a[s].trim();if(0!==l.length){var u=l.indexOf(":");if(u!==-1){var c=l.substring(0,u).trim(),p=l.substring(u+1).trim();t[c]=p}else t[l]=null}}var h={url:r.url,method:r.method,status:e.status,statusText:e.statusText,data:e.responseText,headers:t};try{var f=e.responseJSON||o.safeLoad(e.responseText);h.obj="string"==typeof f?{}:f}catch(d){i.log("unable to parse JSON/YAML content")}if(h.obj=h.obj||null,e.status>=200&&e.status<300)n.response(h);else{if(!(0===e.status||e.status>=400&&e.status<599))return n.response(h);n.error(h)}},t.support.cors=!0,t.ajax(e)},u.prototype.execute=function(e){var t=e.method.toLowerCase(),n=e.timeout;"delete"===t&&(t="del");var l=e.headers||{},u=a[t](e.url);e.connectionAgent&&u.agent(e.connectionAgent),n&&u.timeout(n),e.enableCookies&&u.withCredentials();var c=e.headers.Accept;if(this.binaryRequest(c)&&u.on("request",function(){this.xhr&&(this.xhr.responseType="blob")}),e.body)if(s.isObject(e.body)){var p=e.headers["Content-Type"]||"";if(0===p.indexOf("multipart/form-data"))if(delete l["Content-Type"],"[object FormData]"==={}.toString.apply(e.body))u.send(e.body);else{var h,f,d;for(h in e.body)if(f=e.body[h],Array.isArray(f))for(d in f)u.field(h,d);else u.field(h,f)}else s.isObject(e.body)&&(e.body=JSON.stringify(e.body),u.send(e.body))}else u.send(e.body);var m;for(m in l)u.set(m,l[m]);"function"==typeof u.buffer&&u.buffer(),u.end(function(t,n){n=n||{status:0,headers:{error:"no response from server"}};var a,l={url:e.url,method:e.method,headers:n.headers};if(!t&&n.error&&(t=n.error),t&&e.on&&e.on.error){if(l.errObj=t,l.status=n?n.status:500,l.statusText=n?n.text:t.message,n.headers&&n.headers["content-type"]&&n.headers["content-type"].indexOf("application/json")>=0)try{l.obj=JSON.parse(l.statusText)}catch(u){l.obj=null}a=e.on.error}else if(n&&e.on&&e.on.response){var c;if(n.body&&s.keys(n.body).length>0)c=n.body;else try{c=o.safeLoad(n.text),c="string"==typeof c?null:c}catch(u){i.log("cannot parse JSON/YAML content")}"function"==typeof r&&r.isBuffer(c)?l.data=c:l.obj="object"==typeof c?c:null,l.status=n.status,l.statusText=n.text,a=e.on.response}n.xhr&&n.xhr.response?l.data=n.xhr.response:l.data||(l.data=l.statusText),a&&a(l)})},u.prototype.binaryRequest=function(e){return!!e&&(/^image/i.test(e)||/^application\/pdf/.test(e)||/^application\/octet-stream/.test(e))}}).call(this,t("buffer").Buffer)},{"./helpers":4,buffer:14,"js-yaml":19,"lodash-compat/lang/isObject":144,"lodash-compat/object/keys":149,superagent:158}],6:[function(e,t,n){"use strict";function r(e){var t={},n=/[a-z]+:\/\//i.exec(e);n&&(t.proto=n[0].slice(0,-3),e=e.slice(t.proto.length+1)),"//"===e.slice(0,2)&&(t.domain=e.slice(2).split("/")[0],e=e.slice(2+t.domain.length));var r=e.split("#");return r[0].length&&(t.path=r[0]),r.length>1&&(t.fragment=r.slice(1).join("#")),t}function i(e){var t=e.path;return void 0===t&&(t=""),void 0!==e.fragment&&(t+="#"+e.fragment),void 0!==e.domain&&("/"===t.slice(0,1)&&(t=t.slice(1)),t="//"+e.domain+"/"+t,void 0!==e.proto&&(t=e.proto+":"+t)),t}function a(e,t){var n=r(t);if(void 0!==n.domain)return t;var a=r(e);if(void 0===n.path)a.fragment=n.fragment;else if("/"===n.path.slice(0,1))a.path=n.path,a.fragment=n.fragment;else{var o=void 0===a.path?[]:a.path.split("/"),s=n.path.split("/");for(o.length&&o.pop();".."===s[0]||"."===s[0];)".."===s[0]&&o.pop(),s.shift();a.path=o.concat(s).join("/"),a.fragment=n.fragment}return i(a)}var o=e("./http"),s={isObject:e("lodash-compat/lang/isObject"),cloneDeep:e("lodash-compat/lang/cloneDeep"),isArray:e("lodash-compat/lang/isArray"),isString:e("lodash-compat/lang/isString")},l=t.exports=function(){this.failedUrls=[],this.resolverCache={},this.pendingUrls={}};l.prototype.processAllOf=function(e,t,n,r,i,a){
+var o,s,l;n["x-resolved-from"]=["#/definitions/"+t];var u=n.allOf;for(u.sort(function(e,t){return e.$ref&&t.$ref?0:e.$ref?-1:1}),o=0;o<u.length;o++)l=u[o],s="/definitions/"+t+"/allOf",this.resolveInline(e,a,l,r,i,s)},l.prototype.resolve=function(e,t,n,r){this.spec=e;var i,a,l=t,u=n,c=r,p={};"function"==typeof t&&(l=null,u=t,c=n);var h,f=l;this.scope=c||this,this.iteration=this.iteration||0,this.scope.options&&this.scope.options.requestInterceptor&&(p.requestInterceptor=this.scope.options.requestInterceptor),this.scope.options&&this.scope.options.responseInterceptor&&(p.responseInterceptor=this.scope.options.responseInterceptor);var d,m,g,y,v,b,w,_=0,x={},A={},S=[];e.definitions=e.definitions||{};for(d in e.definitions){var j=e.definitions[d];if(j.$ref)this.resolveInline(l,e,j,S,A,j);else{for(y in j.properties)g=j.properties[y],s.isArray(g.allOf)?this.processAllOf(l,d,g,S,A,e):this.resolveTo(l,g,S,"/definitions");j.allOf&&this.processAllOf(l,d,j,S,A,e)}}e.parameters=e.parameters||{};for(d in e.parameters){if(v=e.parameters[d],"body"===v["in"]&&v.schema)if(s.isArray(v.schema.allOf)){h="inline_model";var E=h;for(b=!1,w=0;!b;){if("undefined"==typeof e.definitions[E]){b=!0;break}E=h+"_"+w,w++}e.definitions[E]={allOf:v.schema.allOf},delete v.schema.allOf,v.schema.$ref="#/definitions/"+E,this.processAllOf(l,E,e.definitions[E],S,A,e)}else this.resolveTo(l,v.schema,S,i);v.$ref&&this.resolveInline(l,e,v,S,A,v.$ref)}for(d in e.paths){var O,k,T;if(m=e.paths[d],"object"==typeof m){for(O in m)if("$ref"===O)i="/paths"+d,this.resolveInline(l,e,m,S,A,i);else{k=m[O];var C=m.parameters||[],I=k.parameters||[];C.forEach(function(e){I.unshift(e)}),"parameters"!==O&&s.isObject(k)&&(k.parameters=k.parameters||I);for(a in I){if(v=I[a],i="/paths"+d+"/"+O+"/parameters","body"===v["in"]&&v.schema)if(s.isArray(v.schema.allOf)){for(h="inline_model",d=h,b=!1,w=0;!b;){if("undefined"==typeof e.definitions[d]){b=!0;break}d=h+"_"+w,w++}e.definitions[d]={allOf:v.schema.allOf},delete v.schema.allOf,v.schema.$ref="#/definitions/"+d,this.processAllOf(l,d,e.definitions[d],S,A,e)}else this.resolveTo(l,v.schema,S,i);v.$ref&&this.resolveInline(l,e,v,S,A,v.$ref)}for(T in k.responses){var D=k.responses[T];if(i="/paths"+d+"/"+O+"/responses/"+T,s.isObject(D)&&(D.$ref&&this.resolveInline(l,e,D,S,A,i),D.schema)){var L=D;if(s.isArray(L.schema.allOf)){for(h="inline_model",d=h,b=!1,w=0;!b;){if("undefined"==typeof e.definitions[d]){b=!0;break}d=h+"_"+w,w++}e.definitions[d]={allOf:L.schema.allOf},delete L.schema.allOf,delete L.schema.type,L.schema.$ref="#/definitions/"+d,this.processAllOf(l,d,e.definitions[d],S,A,e)}else"array"===L.schema.type?L.schema.items&&L.schema.items.$ref&&this.resolveInline(l,e,L.schema.items,S,A,i):this.resolveTo(l,D.schema,S,i)}}}m.parameters=[]}}var M,R=0,U=[],P=S;for(a=0;a<P.length;a++){var q=P[a];if(l===q.root){if("ref"===q.resolveAs){var B,z=((q.root||"")+"/"+q.key).split("/"),N=[],$="";if(q.key.indexOf("../")>=0){for(var F=0;F<z.length;F++)".."===z[F]?N=N.slice(0,N.length-1):N.push(z[F]);for(B=0;B<N.length;B++)B>0&&($+="/"),$+=N[B];q.root=$,U.push(q)}else if(M=q.key.split("#"),2===M.length){0!==M[0].indexOf("http:")&&0!==M[0].indexOf("https:")||(q.root=M[0]),i=M[1].split("/");var V,H=e;for(B=0;B<i.length;B++){var Y=i[B];if(""!==Y){if(H=H[Y],"undefined"==typeof H){V=null;break}V=H}}null===V&&U.push(q)}}else if("inline"===q.resolveAs){if(q.key&&q.key.indexOf("#")===-1&&"/"!==q.key.charAt(0)){for(M=q.root.split("/"),i="",a=0;a<M.length-1;a++)i+=M[a]+"/";i+=q.key,q.root=i,q.location=""}U.push(q)}}else U.push(q)}R=U.length;for(var J={},W=0;W<U.length;W++)!function(e,t,n,r,i){if(e.root&&e.root!==l)if(n.failedUrls.indexOf(e.root)===-1){var a={useJQuery:!1,url:e.root,method:"get",headers:{accept:n.scope.swaggerRequestHeaders||"application/json"},on:{error:function(i){_+=1,console.log("failed url: "+a.url),n.failedUrls.push(a.url),r&&delete r[e.root],A[e.key]={root:e.root,location:e.location},_===R&&n.finish(t,f,S,x,A,u)},response:function(i){var a=i.obj;r&&delete r[e.root],n.resolverCache&&(n.resolverCache[e.root]=a),n.resolveItem(a,e.root,S,x,A,e),_+=1,_===R&&n.finish(t,f,S,x,A,u)}}};c&&c.fetchSpecTimeout&&(a.timeout=c.fetchSpecTimeout),c&&c.clientAuthorizations&&c.clientAuthorizations.apply(a),function h(){setTimeout(function(){if(r[a.url])h();else{var e=n.resolverCache[a.url];s.isObject(e)?a.on.response({obj:e}):(r[a.url]=!0,(new o).execute(a,p))}},0)}()}else _+=1,A[e.key]={root:e.root,location:e.location},_===R&&n.finish(t,f,S,x,A,u);else n.resolveItem(t,f,S,x,A,e),_+=1,_===R&&n.finish(t,l,S,x,A,u,!0)}(U[W],e,this,J,W);0===Object.keys(U).length&&this.finish(e,f,S,x,A,u)},l.prototype.resolveItem=function(e,t,n,r,i,a){var o=a.location,s=e,l=o.split("/");if(""!==o)for(var u=0;u<l.length;u++){var c=l[u];if(c.indexOf("~1")!==-1&&(c=l[u].replace(/~0/g,"~").replace(/~1/g,"/"),"/"!==c.charAt(0)&&(c="/"+c)),"undefined"==typeof s||null===s)break;if(""===c&&u===l.length-1&&l.length>1){s=null;break}c.length>0&&(s=s[c])}var p=a.key;l=a.key.split("/");var h=l[l.length-1];h.indexOf("#")>=0&&(h=h.split("#")[1]),null!==s&&"undefined"!=typeof s?r[p]={name:h,obj:s,key:a.key,root:a.root}:i[p]={root:a.root,location:a.location}},l.prototype.finish=function(e,t,n,r,i,a,o){var s,l;for(s in n){var u=n[s],c=u.key,p=r[c];if(p)if(e.definitions=e.definitions||{},"ref"===u.resolveAs){if(o!==!0)for(c in p.obj)l=this.retainRoot(c,p.obj[c],u.root),p.obj[c]=l;e.definitions[p.name]=p.obj,u.obj.$ref="#/definitions/"+p.name}else if("inline"===u.resolveAs){var h=u.obj;h["x-resolved-from"]=[u.key],delete h.$ref;for(c in p.obj)l=p.obj[c],o!==!0&&(l=this.retainRoot(c,p.obj[c],u.root)),h[c]=l}}var f=this.countUnresolvedRefs(e);0===f||this.iteration>5?(this.resolveAllOf(e.definitions),this.resolverCache=null,a.call(this.scope,e,i)):(this.iteration+=1,this.resolve(e,t,a,this.scope))},l.prototype.countUnresolvedRefs=function(e){var t,n=this.getRefs(e),r=[],i=[];for(t in n)0===t.indexOf("#")?r.push(t.substring(1)):i.push(t);for(t=0;t<r.length;t++)for(var a=r[t],o=a.split("/"),s=e,l=0;l<o.length;l++){var u=o[l];if(""!==u&&(s=s[u],"undefined"==typeof s)){i.push(a);break}}return i.length},l.prototype.getRefs=function(e,t){t=t||e;var n={};for(var r in t)if(t.hasOwnProperty(r)){var i=t[r];if("$ref"===r&&"string"==typeof i)n[i]=null;else if(s.isObject(i)){var a=this.getRefs(i);for(var o in a)n[o]=null}}return n},l.prototype.retainRoot=function(e,t,n){if(s.isObject(t))for(var r in t){var i=t[r];"$ref"===r&&"string"==typeof i?t[r]=a(n,i):s.isObject(i)&&this.retainRoot(r,i,n)}else s.isString(t)&&"$ref"===e&&(t=a(n,t));return t},l.prototype.resolveInline=function(e,t,n,r,i,a){var o,s,l,u,c=n.$ref,p=n.$ref,h=!1;if(e=e||"",p){if(0===p.indexOf("../")){for(s=p.split("../"),l=e.split("/"),p="",o=0;o<s.length;o++)""===s[o]?l=l.slice(0,l.length-1):p+=s[o];for(e="",o=0;o<l.length-1;o++)o>0&&(e+="/"),e+=l[o];h=!0}if(p.indexOf("#")>=0)if(0===p.indexOf("/"))u=p.split("#"),s=e.split("//"),l=s[1].split("/"),e=s[0]+"//"+l[0]+u[0],a=u[1];else{if(u=p.split("#"),""!==u[0]){if(l=e.split("/"),l=l.slice(0,l.length-1),!h){e="";for(var f=0;f<l.length;f++)f>0&&(e+="/"),e+=l[f]}e+="/"+p.split("#")[0]}a=u[1]}if(0===p.indexOf("http:")||0===p.indexOf("https:"))p.indexOf("#")>=0?(e=p.split("#")[0],a=p.split("#")[1]):(e=p,a=""),r.push({obj:n,resolveAs:"inline",root:e,key:c,location:a});else if(0===p.indexOf("#"))a=p.split("#")[1],r.push({obj:n,resolveAs:"inline",root:e,key:c,location:a});else if(0===p.indexOf("/")&&p.indexOf("#")===-1){a=p;var d=e.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i);d&&(e=d[0]+p.substring(1),a=""),r.push({obj:n,resolveAs:"inline",root:e,key:c,location:a})}else r.push({obj:n,resolveAs:"inline",root:e,key:c,location:a})}else"array"===n.type&&this.resolveTo(e,n.items,r,a)},l.prototype.resolveTo=function(e,t,n,r){var i,a,o=t.$ref,l=e;if("undefined"!=typeof o&&null!==o){if(o.indexOf("#")>=0){var u=o.split("#");if(u[0]&&0===o.indexOf("/"));else if(!u[0]||0!==u[0].indexOf("http:")&&0!==u[0].indexOf("https:")){if(u[0]&&u[0].length>0){for(i=e.split("/"),l="",a=0;a<i.length-1;a++)l+=i[a]+"/";l+=u[0]}}else l=u[0],o=u[1];r=u[1]}else if(0===o.indexOf("http:")||0===o.indexOf("https:"))l=o,r="";else{for(i=e.split("/"),l="",a=0;a<i.length-1;a++)l+=i[a]+"/";l+=o,r=""}n.push({obj:t,resolveAs:"ref",root:l,key:o,location:r})}else if("array"===t.type){var c=t.items;this.resolveTo(e,c,n,r)}else if(t&&(t.properties||t.additionalProperties)){var p=this.uniqueName("inline_model");t.title&&(p=this.uniqueName(t.title)),delete t.title,this.spec.definitions[p]=s.cloneDeep(t),t.$ref="#/definitions/"+p,delete t.type,delete t.properties}},l.prototype.uniqueName=function(e){for(var t=e,n=0;;){if(!s.isObject(this.spec.definitions[t]))return t;t=e+"_"+n,n++}},l.prototype.resolveAllOf=function(e,t,n){n=n||0,t=t||e;var r;for(var i in t)if(t.hasOwnProperty(i)){var a=t[i];if(null===a)throw new TypeError("Swagger 2.0 does not support null types ("+t+").  See https://github.com/swagger-api/swagger-spec/issues/229.");if("object"==typeof a&&this.resolveAllOf(e,a,n+1),a&&"undefined"!=typeof a.allOf){var o=a.allOf;if(s.isArray(o)){var l=s.cloneDeep(a);delete l.allOf,l["x-composed"]=!0,"undefined"!=typeof a["x-resolved-from"]&&(l["x-resolved-from"]=a["x-resolved-from"]);for(var u=0;u<o.length;u++){var c=o[u],p="self";"undefined"!=typeof c["x-resolved-from"]&&(p=c["x-resolved-from"][0]);for(var h in c)if(l.hasOwnProperty(h))if("properties"===h){var f=c[h];for(r in f){l.properties[r]=s.cloneDeep(f[r]);var d=f[r]["x-resolved-from"];"undefined"!=typeof d&&"self"!==d||(d=p),l.properties[r]["x-resolved-from"]=d}}else if("required"===h){for(var m=l.required.concat(c[h]),g=0;g<m.length;++g)for(var y=g+1;y<m.length;++y)m[g]===m[y]&&m.splice(y--,1);l.required=m}else"x-resolved-from"===h&&l["x-resolved-from"].push(p);else if(l[h]=s.cloneDeep(c[h]),"properties"===h)for(r in l[h])l[h][r]["x-resolved-from"]=p}t[i]=l}}}}},{"./http":5,"lodash-compat/lang/cloneDeep":138,"lodash-compat/lang/isArray":140,"lodash-compat/lang/isObject":144,"lodash-compat/lang/isString":146}],7:[function(e,t,n){"use strict";var r=e("./helpers"),i={isPlainObject:e("lodash-compat/lang/isPlainObject"),isUndefined:e("lodash-compat/lang/isUndefined"),isArray:e("lodash-compat/lang/isArray"),isObject:e("lodash-compat/lang/isObject"),isEmpty:e("lodash-compat/lang/isEmpty"),map:e("lodash-compat/collection/map"),indexOf:e("lodash-compat/array/indexOf"),cloneDeep:e("lodash-compat/lang/cloneDeep"),keys:e("lodash-compat/object/keys"),forEach:e("lodash-compat/collection/forEach")},a=t.exports.optionHtml=function(e,t){return'<tr><td class="optionName">'+e+":</td><td>"+t+"</td></tr>"};t.exports.typeFromJsonSchema=function(e,t){var n;return"integer"===e&&"int32"===t?n="integer":"integer"===e&&"int64"===t?n="long":"integer"===e&&"undefined"==typeof t?n="long":"string"===e&&"date-time"===t?n="date-time":"string"===e&&"date"===t?n="date":"number"===e&&"float"===t?n="float":"number"===e&&"double"===t?n="double":"number"===e&&"undefined"==typeof t?n="double":"boolean"===e?n="boolean":"string"===e&&(n="string"),n};var o=t.exports.getStringSignature=function(e,t){var n="";return"undefined"!=typeof e.$ref?n+=r.simpleRef(e.$ref):"undefined"==typeof e.type?n+="object":"array"===e.type?t?n+=o(e.items||e.$ref||{}):(n+="Array[",n+=o(e.items||e.$ref||{}),n+="]"):n+="integer"===e.type&&"int32"===e.format?"integer":"integer"===e.type&&"int64"===e.format?"long":"integer"===e.type&&"undefined"==typeof e.format?"long":"string"===e.type&&"date-time"===e.format?"date-time":"string"===e.type&&"date"===e.format?"date":"string"===e.type&&"undefined"==typeof e.format?"string":"number"===e.type&&"float"===e.format?"float":"number"===e.type&&"double"===e.format?"double":"number"===e.type&&"undefined"==typeof e.format?"double":"boolean"===e.type?"boolean":e.$ref?r.simpleRef(e.$ref):e.type,n},s=t.exports.schemaToJSON=function(e,t,n,a){e=r.resolveSchema(e),"function"!=typeof a&&(a=function(e){return(e||{})["default"]}),n=n||{};var o,l,u=e.type||"object",c=e.format;return i.isUndefined(e.example)?i.isUndefined(e.items)&&i.isArray(e["enum"])&&(l=e["enum"][0]):l=e.example,i.isUndefined(l)&&(e.$ref?(o=t[r.simpleRef(e.$ref)],i.isUndefined(o)||(i.isUndefined(n[o.name])?(n[o.name]=o,l=s(o.definition,t,n,a),delete n[o.name]):l="array"===o.type?[]:{})):i.isUndefined(e["default"])?"string"===u?l="date-time"===c?(new Date).toISOString():"date"===c?(new Date).toISOString().split("T")[0]:"string":"integer"===u?l=0:"number"===u?l=0:"boolean"===u?l=!0:"object"===u?(l={},i.forEach(e.properties,function(e,r){var o=i.cloneDeep(e);o["default"]=a(e),l[r]=s(o,t,n,a)})):"array"===u&&(l=[],i.isArray(e.items)?i.forEach(e.items,function(e){l.push(s(e,t,n,a))}):i.isPlainObject(e.items)?l.push(s(e.items,t,n,a)):i.isUndefined(e.items)?l.push({}):r.log("Array type's 'items' property is not an array or an object, cannot process")):l=e["default"]),l};t.exports.schemaToHTML=function(e,t,n,o){function s(e,t,a){var o,s=t;return e.$ref?(s=e.title||r.simpleRef(e.$ref),o=n[s]):i.isUndefined(t)&&(s=e.title||"Inline Model "+ ++m,o={definition:e}),a!==!0&&(f[s]=i.isUndefined(o)?{}:o.definition),s}function l(e){var t='<span class="propType">',n=e.type||"object";return e.$ref?t+=s(e,r.simpleRef(e.$ref)):"object"===n?t+=i.isUndefined(e.properties)?"object":s(e):"array"===n?(t+="Array[",i.isArray(e.items)?t+=i.map(e.items,s).join(","):i.isPlainObject(e.items)?t+=i.isUndefined(e.items.$ref)?i.isUndefined(e.items.type)||i.indexOf(["array","object"],e.items.type)!==-1?s(e.items):e.items.type:s(e.items,r.simpleRef(e.items.$ref)):(r.log("Array type's 'items' schema is not an array or an object, cannot process"),t+="object"),t+="]"):t+=e.type,t+="</span>"}function u(e,t){var n="",r=e.type||"object",o="array"===r;switch(o&&(r=i.isPlainObject(e.items)&&!i.isUndefined(e.items.type)?e.items.type:"object"),i.isUndefined(e["default"])||(n+=a("Default",e["default"])),r){case"string":e.minLength&&(n+=a("Min. Length",e.minLength)),e.maxLength&&(n+=a("Max. Length",e.maxLength)),e.pattern&&(n+=a("Reg. Exp.",e.pattern));break;case"integer":case"number":e.minimum&&(n+=a("Min. Value",e.minimum)),e.exclusiveMinimum&&(n+=a("Exclusive Min.","true")),e.maximum&&(n+=a("Max. Value",e.maximum)),e.exclusiveMaximum&&(n+=a("Exclusive Max.","true")),e.multipleOf&&(n+=a("Multiple Of",e.multipleOf))}if(o&&(e.minItems&&(n+=a("Min. Items",e.minItems)),e.maxItems&&(n+=a("Max. Items",e.maxItems)),e.uniqueItems&&(n+=a("Unique Items","true")),e.collectionFormat&&(n+=a("Coll. Format",e.collectionFormat))),i.isUndefined(e.items)&&i.isArray(e["enum"])){var s;s="number"===r||"integer"===r?e["enum"].join(", "):'"'+e["enum"].join('", "')+'"',n+=a("Enum",s)}return n.length>0&&(t='<span class="propWrap">'+t+'<table class="optionsWrapper"><tr><th colspan="2">'+r+"</th></tr>"+n+"</table></span>"),t}function c(e,t){var a=e.type||"object",c="array"===e.type,f=p+t+" "+(c?"[":"{")+h;if(t&&d.push(t),c)i.isArray(e.items)?f+="<div>"+i.map(e.items,function(e){var t=e.type||"object";return i.isUndefined(e.$ref)?i.indexOf(["array","object"],t)>-1?"object"===t&&i.isUndefined(e.properties)?"object":s(e):u(e,t):s(e,r.simpleRef(e.$ref))}).join(",</div><div>"):i.isPlainObject(e.items)?f+=i.isUndefined(e.items.$ref)?i.indexOf(["array","object"],e.items.type||"object")>-1?(i.isUndefined(e.items.type)||"object"===e.items.type)&&i.isUndefined(e.items.properties)?"<div>object</div>":"<div>"+s(e.items)+"</div>":"<div>"+u(e.items,e.items.type)+"</div>":"<div>"+s(e.items,r.simpleRef(e.items.$ref))+"</div>":(r.log("Array type's 'items' property is not an array or an object, cannot process"),f+="<div>object</div>");else if(e.$ref)f+="<div>"+s(e,t)+"</div>";else if("object"===a){if(i.isPlainObject(e.properties)){var m=i.map(e.properties,function(t,a){var s,c,p=i.indexOf(e.required,a)>=0,h=i.cloneDeep(t),f=p?"required":"",d='<span class="propName '+f+'">'+a+"</span> (";return h["default"]=o(h),h=r.resolveSchema(h),c=t.description||h.description,i.isUndefined(h.$ref)||(s=n[r.simpleRef(h.$ref)],i.isUndefined(s)||i.indexOf([void 0,"array","object"],s.definition.type)!==-1||(h=r.resolveSchema(s.definition))),d+=l(h),p||(d+=', <span class="propOptKey">optional</span>'),t.readOnly&&(d+=', <span class="propReadOnly">read only</span>'),d+=")",i.isUndefined(c)||(d+=': <span class="propDesc">'+c+"</span>"),h["enum"]&&(d+=' = <span class="propVals">[\''+h["enum"].join("', '")+"']</span>"),"<div"+(t.readOnly?' class="readOnly"':"")+">"+u(h,d)}).join(",</div>");m&&(f+=m+"</div>")}}else f+="<div>"+u(e,a)+"</div>";return f+p+(c?"]":"}")+h}var p='<span class="strong">',h="</span>";if(i.isObject(arguments[0])&&(e=void 0,t=arguments[0],n=arguments[1],o=arguments[2]),n=n||{},t=r.resolveSchema(t),i.isEmpty(t))return p+"Empty"+h;if("string"==typeof t.$ref&&(e=r.simpleRef(t.$ref),t=n[e],"undefined"==typeof t))return p+e+" is not defined!"+h;"string"!=typeof e&&(e=t.title||"Inline Model"),t.definition&&(t=t.definition),"function"!=typeof o&&(o=function(e){return(e||{})["default"]});for(var f={},d=[],m=0,g=c(t,e);i.keys(f).length>0;)i.forEach(f,function(e,t){var n=i.indexOf(d,t)>-1;delete f[t],n||(d.push(t),g+="<br />"+c(e,t))});return g}},{"./helpers":4,"lodash-compat/array/indexOf":49,"lodash-compat/collection/forEach":54,"lodash-compat/collection/map":56,"lodash-compat/lang/cloneDeep":138,"lodash-compat/lang/isArray":140,"lodash-compat/lang/isEmpty":141,"lodash-compat/lang/isObject":144,"lodash-compat/lang/isPlainObject":145,"lodash-compat/lang/isUndefined":148,"lodash-compat/object/keys":149}],8:[function(e,t,n){"use strict";var r=e("./http"),i={isObject:e("lodash-compat/lang/isObject")},a=t.exports=function(){this.errors=[],this.warnings=[],this.modelMap={}};a.prototype.setDocumentationLocation=function(e){this.docLocation=e},a.prototype.convert=function(e,t,n,r){if(!e||!Array.isArray(e.apis))return this.finish(r,null);this.clientAuthorizations=t;var i={swagger:"2.0"};i.originalVersion=e.swaggerVersion,this.apiInfo(e,i),this.securityDefinitions(e,i),e.basePath&&this.setDocumentationLocation(e.basePath);var a,o=!1;for(a=0;a<e.apis.length;a++){var s=e.apis[a];Array.isArray(s.operations)&&(o=!0)}o?(this.declaration(e,i),this.finish(r,i)):this.resourceListing(e,i,n,r)},a.prototype.declaration=function(e,t){var n,r,a,o;if(e.apis){0===e.basePath.indexOf("http://")?(a=e.basePath.substring("http://".length),o=a.indexOf("/"),o>0?(t.host=a.substring(0,o),t.basePath=a.substring(o)):(t.host=a,t.basePath="/")):0===e.basePath.indexOf("https://")?(a=e.basePath.substring("https://".length),o=a.indexOf("/"),o>0?(t.host=a.substring(0,o),t.basePath=a.substring(o)):(t.host=a,t.basePath="/")):t.basePath=e.basePath;var s;if(e.authorizations&&(s=e.authorizations),e.consumes&&(t.consumes=e.consumes),e.produces&&(t.produces=e.produces),i.isObject(e))for(n in e.models){var l=e.models[n],u=l.id||n;this.modelMap[u]=n}for(r=0;r<e.apis.length;r++){var c=e.apis[r],p=c.path,h=c.operations;this.operations(p,e.resourcePath,h,s,t)}var f=e.models||{};this.models(f,t)}},a.prototype.models=function(e,t){if(i.isObject(e)){var n;t.definitions=t.definitions||{};for(n in e){var r,a=e[n],o=[],s={properties:{}};for(r in a.properties){var l=a.properties[r],u={};this.dataType(l,u),l.description&&(u.description=l.description),l["enum"]&&(u["enum"]=l["enum"]),"boolean"==typeof l.required&&l.required===!0&&o.push(r),"string"==typeof l.required&&"true"===l.required&&o.push(r),s.properties[r]=u}o.length>0?s.required=o:s.required=a.required,t.definitions[n]=s}}},a.prototype.extractTag=function(e){var t=e||"default";return 0!==t.indexOf("http:")&&0!==t.indexOf("https:")||(t=t.split(["/"]),t=t[t.length-1].substring()),t.endsWith(".json")&&(t=t.substring(0,t.length-".json".length)),t.replace("/","")},a.prototype.operations=function(e,t,n,r,i){if(Array.isArray(n)){var a;i.paths||(i.paths={});var o=i.paths[e]||{},s=this.extractTag(t);i.tags=i.tags||[];var l=!1;for(a=0;a<i.tags.length;a++){var u=i.tags[a];u.name===s&&(l=!0)}for(l||i.tags.push({name:s}),a=0;a<n.length;a++){var c=n[a],p=(c.method||c.httpMethod).toLowerCase(),h={tags:[s]},f=c.authorizations;if(f&&0===Object.keys(f).length&&(f=r),"undefined"!=typeof f){var d;for(var m in f){h.security=h.security||[];var g=f[m];if(g){var y=[];for(var v in g)y.push(g[v].scope);d={},d[m]=y,h.security.push(d)}else d={},d[m]=[],h.security.push(d)}}c.consumes?h.consumes=c.consumes:i.consumes&&(h.consumes=i.consumes),c.produces?h.produces=c.produces:i.produces&&(h.produces=i.produces),c.summary&&(h.summary=c.summary),c.notes&&(h.description=c.notes),c.nickname&&(h.operationId=c.nickname),c.deprecated&&(h.deprecated=c.deprecated),this.authorizations(f,i),this.parameters(h,c.parameters,i),this.responseMessages(h,c,i),o[p]=h}i.paths[e]=o}},a.prototype.responseMessages=function(e,t){if(i.isObject(t)){var n={};this.dataType(t,n),!n.schema&&n.type&&(n={schema:n}),e.responses=e.responses||{};var r=!1;if(Array.isArray(t.responseMessages)){var a,o=t.responseMessages;for(a=0;a<o.length;a++){var s=o[a],l={description:s.message};200===s.code&&(r=!0),s.responseModel&&(l.schema={$ref:"#/definitions/"+s.responseModel}),e.responses[""+s.code]=l}}r?e.responses["default"]=n:e.responses[200]=n}},a.prototype.authorizations=function(e){!i.isObject(e)},a.prototype.parameters=function(e,t){if(Array.isArray(t)){var n;for(n=0;n<t.length;n++){var r=t[n],i={};if(i.name=r.name,i.description=r.description,i.required=r.required,i["in"]=r.paramType,"body"===i["in"]&&(i.name="body"),"form"===i["in"]&&(i["in"]="formData"),r["enum"]&&(i["enum"]=r["enum"]),r.allowMultiple===!0||"true"===r.allowMultiple){var a={};if(this.dataType(r,a),i.type="array",i.items=a,r.allowableValues){var o=r.allowableValues;"LIST"===o.valueType&&(i["enum"]=o.values)}}else this.dataType(r,i);"undefined"!=typeof r.defaultValue&&(i["default"]=r.defaultValue),e.parameters=e.parameters||[],e.parameters.push(i)}}},a.prototype.dataType=function(e,t){if(i.isObject(e)){e.minimum&&(t.minimum=e.minimum),e.maximum&&(t.maximum=e.maximum),e.format&&(t.format=e.format),"undefined"!=typeof e.defaultValue&&(t["default"]=e.defaultValue);var n=this.toJsonSchema(e);n&&(t=t||{},n.type&&(t.type=n.type),n.format&&(t.format=n.format),n.$ref&&(t.schema={$ref:n.$ref}),n.items&&(t.items=n.items))}},a.prototype.toJsonSchema=function(e){if(!e)return"object";var t=e.type||e.dataType||e.responseClass||"",n=t.toLowerCase(),r=(e.format||"").toLowerCase();if(0===n.indexOf("list[")){var i=t.substring(5,t.length-1),a=this.toJsonSchema({type:i});return{type:"array",items:a}}if("int"===n||"integer"===n&&"int32"===r)return{type:"integer",format:"int32"};if("long"===n||"integer"===n&&"int64"===r)return{type:"integer",format:"int64"};if("integer"===n)return{type:"integer",format:"int64"};if("float"===n||"number"===n&&"float"===r)return{type:"number",format:"float"};if("double"===n||"number"===n&&"double"===r)return{type:"number",format:"double"};if("string"===n&&"date-time"===r||"date"===n)return{type:"string",format:"date-time"};if("string"===n)return{type:"string"};if("file"===n)return{type:"file"};if("boolean"===n)return{type:"boolean"};if("boolean"===n)return{type:"boolean"};if("array"===n||"list"===n){if(e.items){var o=this.toJsonSchema(e.items);return{type:"array",items:o}}return{type:"array",items:{type:"object"}}}return e.$ref?{$ref:this.modelMap[e.$ref]?"#/definitions/"+this.modelMap[e.$ref]:e.$ref}:"void"===n||""===n?{}:this.modelMap[e.type]?{$ref:"#/definitions/"+this.modelMap[e.type]}:{type:e.type}},a.prototype.resourceListing=function(e,t,n,i){var a,o=0,s=this,l=e.apis.length,u=t,c={};n&&n.requestInterceptor&&(c.requestInterceptor=n.requestInterceptor),n&&n.responseInterceptor&&(c.responseInterceptor=n.responseInterceptor);var p="application/json";for(n&&n.swaggerRequestHeaders&&(p=n.swaggerRequestHeaders),0===l&&this.finish(i,t),a=0;a<l;a++){var h=e.apis[a],f=h.path,d=this.getAbsolutePath(e.swaggerVersion,this.docLocation,f);h.description&&(t.tags=t.tags||[],t.tags.push({name:this.extractTag(h.path),description:h.description||""}));var m={url:d,headers:{accept:p},on:{},method:"get",timeout:n.timeout};m.on.response=function(e){o+=1;var t=e.obj;t&&s.declaration(t,u),o===l&&s.finish(i,u)},m.on.error=function(e){console.error(e),o+=1,o===l&&s.finish(i,u)},this.clientAuthorizations&&"function"==typeof this.clientAuthorizations.apply&&this.clientAuthorizations.apply(m),(new r).execute(m,c)}},a.prototype.getAbsolutePath=function(e,t,n){if("1.0"===e&&t.endsWith(".json")){var r=t.lastIndexOf("/");r>0&&(t=t.substring(0,r))}var i=t;return 0===n.indexOf("http:")||0===n.indexOf("https:")?i=n:(t.endsWith("/")&&(i=t.substring(0,t.length-1)),i+=n),i=i.replace("{format}","json")},a.prototype.securityDefinitions=function(e,t){if(e.authorizations){var n;for(n in e.authorizations){var r=!1,i={vendorExtensions:{}},a=e.authorizations[n];if("apiKey"===a.type)i.type="apiKey",i["in"]=a.passAs,i.name=a.keyname||n,r=!0;else if("basicAuth"===a.type)i.type="basicAuth",r=!0;else if("oauth2"===a.type){var o,s=a.scopes||[],l={};for(o in s){var u=s[o];l[u.scope]=u.description}if(i.type="oauth2",o>0&&(i.scopes=l),a.grantTypes){if(a.grantTypes.implicit){var c=a.grantTypes.implicit;i.flow="implicit",i.authorizationUrl=c.loginEndpoint,r=!0}if(a.grantTypes.authorization_code&&!i.flow){var p=a.grantTypes.authorization_code;i.flow="accessCode",i.authorizationUrl=p.tokenRequestEndpoint.url,i.tokenUrl=p.tokenEndpoint.url,r=!0}}}r&&(t.securityDefinitions=t.securityDefinitions||{},t.securityDefinitions[n]=i)}}},a.prototype.apiInfo=function(e,t){if(e.info){var n=e.info;t.info={},n.contact&&(t.info.contact={},t.info.contact.email=n.contact),n.description&&(t.info.description=n.description),n.title&&(t.info.title=n.title),n.termsOfServiceUrl&&(t.info.termsOfService=n.termsOfServiceUrl),(n.license||n.licenseUrl)&&(t.license={},n.license&&(t.license.name=n.license),n.licenseUrl&&(t.license.url=n.licenseUrl))}else this.warnings.push("missing info section")},a.prototype.finish=function(e,t){e(t)}},{"./http":5,"lodash-compat/lang/isObject":144}],9:[function(e,t,n){"use strict";var r=(e("../helpers").log,{isPlainObject:e("lodash-compat/lang/isPlainObject"),isString:e("lodash-compat/lang/isString")}),i=e("../schema-markup.js"),a=e("js-yaml"),o=t.exports=function(e,t,n,r){return this.definition=t||{},this.isArray="array"===t.type,this.models=n||{},this.name=e||t.title||"Inline Model",this.modelPropertyMacro=r||function(e){return e["default"]},this};o.prototype.createJSONSample=o.prototype.getSampleValue=function(e){return e=e||{},e[this.name]=this,this.examples&&r.isPlainObject(this.examples)&&this.examples["application/json"]?(this.definition.example=this.examples["application/json"],r.isString(this.definition.example)&&(this.definition.example=a.safeLoad(this.definition.example))):this.definition.example||(this.definition.example=this.examples),i.schemaToJSON(this.definition,this.models,e,this.modelPropertyMacro)},o.prototype.getMockSignature=function(){return i.schemaToHTML(this.name,this.definition,this.models,this.modelPropertyMacro)}},{"../helpers":4,"../schema-markup.js":7,"js-yaml":19,"lodash-compat/lang/isPlainObject":145,"lodash-compat/lang/isString":146}],10:[function(e,t,n){"use strict";function r(e,t){if(i.isEmpty(t))return e[0];for(var n=0,r=t.length;n<r;n++)if(e.indexOf(t[n])>-1)return t[n];return e[0]}var i={cloneDeep:e("lodash-compat/lang/cloneDeep"),isUndefined:e("lodash-compat/lang/isUndefined"),isEmpty:e("lodash-compat/lang/isEmpty"),isObject:e("lodash-compat/lang/isObject")},a=e("../helpers"),o=e("./model"),s=e("../http"),l=e("q"),u=t.exports=function(e,t,n,r,i,s,l,u,c){var p=[];e=e||{},s=s||{},e&&e.options&&(this.client=e.options.client||null,this.requestInterceptor=e.options.requestInterceptor||null,this.responseInterceptor=e.options.responseInterceptor||null,this.requestAgent=e.options.requestAgent),this.authorizations=s.security,this.basePath=e.basePath||"/",this.clientAuthorizations=c,this.consumes=s.consumes||e.consumes||["application/json"],this.produces=s.produces||e.produces||["application/json"],this.deprecated=s.deprecated,this.description=s.description,this.host=e.host,this.method=r||p.push("Operation "+n+" is missing method."),this.models=u||{},this.nickname=n||p.push("Operations must have a nickname."),this.operation=s,this.operations={},this.parameters=null!==s?s.parameters||[]:{},this.parent=e,this.path=i||p.push("Operation "+this.nickname+" is missing path."),this.responses=s.responses||{},this.scheme=t||e.scheme||"http",this.schemes=s.schemes||e.schemes,this.security=s.security||e.security,this.summary=s.summary||"",this.timeout=e.timeout,this.type=null,this.useJQuery=e.useJQuery,this.jqueryAjaxCache=e.jqueryAjaxCache,this.enableCookies=e.enableCookies;var h;if(this.host||("undefined"!=typeof window?this.host=window.location.host:this.host="localhost"),this.parameterMacro=e.parameterMacro||function(e,t){return t["default"]},this.inlineModels=[],"/"!==this.basePath&&"/"===this.basePath.slice(-1)&&(this.basePath=this.basePath.slice(0,-1)),"string"==typeof this.deprecated)switch(this.deprecated.toLowerCase()){case"true":case"yes":case"1":this.deprecated=!0;break;case"false":case"no":case"0":case null:this.deprecated=!1;break;default:this.deprecated=Boolean(this.deprecated)}var f,d;if(l)for(h in l)d=new o(h,l[h],this.models,e.modelPropertyMacro),d&&(this.models[h]=d);else l={};for(f=0;f<this.parameters.length;f++){var m,g=this.parameters[f];g["default"]=this.parameterMacro(this,g),"array"===g.type&&(g.isList=!0,g.allowMultiple=!0);var y=this.getType(g);y&&"boolean"===y.toString().toLowerCase()&&(g.allowableValues={},g.isList=!0,g["enum"]=[!0,!1]);for(h in g)a.extractExtensions(h,g);"undefined"!=typeof g["x-example"]&&(m=g["x-example"],g["default"]=m),g["x-examples"]&&(m=g["x-examples"]["default"],"undefined"!=typeof m&&(g["default"]=m));var v=g["enum"]||g.items&&g.items["enum"];if("undefined"!=typeof v){var b;for(g.allowableValues={},g.allowableValues.values=[],g.allowableValues.descriptiveValues=[],b=0;b<v.length;b++){var w=v[b],_=w===g["default"]||w+""===g["default"];g.allowableValues.values.push(w),g.allowableValues.descriptiveValues.push({value:w+"",isDefault:_})}}"array"===g.type&&(y=[y],"undefined"==typeof g.allowableValues&&(delete g.isList,delete g.allowMultiple)),g.modelSignature={type:y,definitions:this.models},g.signature=this.getModelSignature(y,this.models).toString(),g.sampleJSON=this.getModelSampleJSON(y,this.models),g.responseClassSignature=g.signature}var x,A,S,j=this.responses;j[200]?(S=j[200],A="200"):j[201]?(S=j[201],A="201"):j[202]?(S=j[202],A="202"):j[203]?(S=j[203],A="203"):j[204]?(S=j[204],A="204"):j[205]?(S=j[205],A="205"):j[206]?(S=j[206],A="206"):j["default"]&&(S=j["default"],A="default");for(x in j)if(a.extractExtensions(x,j),"string"==typeof x&&x.indexOf("x-")===-1){var E=j[x];if("object"==typeof E&&"object"==typeof E.headers){var O=E.headers;for(var k in O){var T=O[k];if("object"==typeof T)for(var C in T)a.extractExtensions(C,T)}}}if(S)for(x in S)a.extractExtensions(x,S);if(S&&S.schema){var I,D=this.resolveModel(S.schema,l);delete j[A],D?(this.successResponse={},I=this.successResponse[A]=D):S.schema.type&&"object"!==S.schema.type&&"array"!==S.schema.type?(this.successResponse={},I=this.successResponse[A]=S.schema):(this.successResponse={},I=this.successResponse[A]=new o((void 0),S.schema||{},this.models,e.modelPropertyMacro)),I&&(I.vendorExtensions=S.vendorExtensions,S.description&&(I.description=S.description),S.examples&&(I.examples=S.examples),S.headers&&(I.headers=S.headers)),this.type=S}return p.length>0&&this.resource&&this.resource.api&&this.resource.api.fail&&this.resource.api.fail(p),this};u.prototype.isDefaultArrayItemValue=function(e,t){return t["default"]&&Array.isArray(t["default"])?t["default"].indexOf(e)!==-1:e===t["default"]},u.prototype.getType=function(e){var t,n=e.type,r=e.format,i=!1;"integer"===n&&"int32"===r?t="integer":"integer"===n&&"int64"===r?t="long":"integer"===n?t="integer":"string"===n?t="date-time"===r?"date-time":"date"===r?"date":"string":"number"===n&&"float"===r?t="float":"number"===n&&"double"===r?t="double":"number"===n?t="double":"boolean"===n?t="boolean":"array"===n?(i=!0,
+e.items&&(t=this.getType(e.items))):"file"===n&&(t="file"),e.$ref&&(t=a.simpleRef(e.$ref));var o=e.schema;if(o){var s=o.$ref;return s?(s=a.simpleRef(s),i?[s]:s):"object"===o.type?this.addInlineModel(o):this.getType(o)}return i?[t]:t},u.prototype.addInlineModel=function(e){var t=this.inlineModels.length,n=this.resolveModel(e,{});return n?(this.inlineModels.push(n),"Inline Model "+t):null},u.prototype.getInlineModel=function(e){if(/^Inline Model \d+$/.test(e)){var t=parseInt(e.substr("Inline Model".length).trim(),10),n=this.inlineModels[t];return n}return null},u.prototype.resolveModel=function(e,t){if("undefined"!=typeof e.$ref){var n=e.$ref;if(0===n.indexOf("#/definitions/")&&(n=n.substring("#/definitions/".length)),t[n])return new o(n,t[n],this.models,this.parent.modelPropertyMacro)}else if(e&&"object"==typeof e&&("object"===e.type||i.isUndefined(e.type)))return new o((void 0),e,this.models,this.parent.modelPropertyMacro);return null},u.prototype.help=function(e){for(var t=this.nickname+": "+this.summary+"\n",n=0;n<this.parameters.length;n++){var r=this.parameters[n],i=r.signature;t+="\n  * "+r.name+" ("+i+"): "+r.description}return"undefined"==typeof e&&a.log(t),t},u.prototype.getModelSignature=function(e,t){var n,r;return e instanceof Array&&(r=!0,e=e[0]),"undefined"==typeof e?(e="undefined",n=!0):t[e]?(e=t[e],n=!1):this.getInlineModel(e)?(e=this.getInlineModel(e),n=!1):n=!0,n?r?"Array["+e+"]":e.toString():r?"Array["+e.getMockSignature()+"]":e.getMockSignature()},u.prototype.supportHeaderParams=function(){return!0},u.prototype.supportedSubmitMethods=function(){return this.parent.supportedSubmitMethods},u.prototype.getHeaderParams=function(e){for(var t=this.setContentTypes(e,{}),n={},r=0;r<this.parameters.length;r++){var i=this.parameters[r];"header"===i["in"]&&(n[i.name.toLowerCase()]=i)}for(var a in e){var o=n[a.toLowerCase()];if("undefined"!=typeof o){var s=e[a];Array.isArray(s)&&(s=s.toString()),t[o.name]=s}}return t},u.prototype.urlify=function(e,t){for(var n={},r=this.path.replace(/#.*/,""),i="",a=0;a<this.parameters.length;a++){var o=this.parameters[a];if("undefined"!=typeof e[o.name]){var s;if("string"===o.type&&"password"===o.format&&t&&(s=!0),"path"===o["in"]){var l=new RegExp("{"+o.name+"}","gi"),u=e[o.name];Array.isArray(u)?u=this.encodePathCollection(o.collectionFormat,o.name,u,s):"undefined"!=typeof o["x-escape"]&&o["x-escape"]!==!0||(u=this.encodePathParam(u,s)),r=r.replace(l,u)}else if("query"===o["in"]&&"undefined"!=typeof e[o.name])if(i+=""===i&&r.indexOf("?")<0?"?":"&","undefined"!=typeof o.collectionFormat){var c=e[o.name];i+=Array.isArray(c)?this.encodeQueryCollection(o.collectionFormat,o.name,c,s):this.encodeQueryKey(o.name)+"="+this.encodeQueryParam(e[o.name],s)}else i+=this.encodeQueryKey(o.name)+"="+this.encodeQueryParam(e[o.name],s);else"formData"===o["in"]&&(n[o.name]=e[o.name])}else if("query"===o["in"]&&"undefined"==typeof e[o.name]&&o.allowEmptyValue===!0)if(i+=""===i&&r.indexOf("?")<0?"?":"&","undefined"!=typeof o.collectionFormat||"array"===o.type){var c,p=o.collectionFormat||"multi";i+=Array.isArray(c)?this.encodeQueryCollection(p,o.name,c,s):this.encodeQueryCollection(p,o.name,[c],s)}else i+=this.encodeQueryKey(o.name)+"="+this.encodeQueryParam("",s)}var h=this.scheme+"://"+this.host;return"/"!==this.basePath&&(h+=this.basePath),h+r+i},u.prototype.getMissingParams=function(e){var t,n=[];for(t=0;t<this.parameters.length;t++){var r=this.parameters[t];r.required===!0&&"undefined"==typeof e[r.name]&&(n=r.name)}return n},u.prototype.getBody=function(e,t,n){for(var r,i,a,o,s,l={},u=!1,p=0;p<this.parameters.length;p++)if(i=this.parameters[p],"undefined"!=typeof t[i.name]){var h;"string"===i.type&&"password"===i.format&&(h="password"),"body"===i["in"]?a=t[i.name]:"formData"===i["in"]&&(l[i.name]={param:i,value:t[i.name],password:h},r=!0)}else"body"===i["in"]&&(u=!0);if(u&&"undefined"==typeof a){var f=e["Content-Type"];f&&0===f.indexOf("application/json")&&(a="{}")}var d=!1;if(e["Content-Type"]&&e["Content-Type"].indexOf("multipart/form-data")>=0&&(d=!0),r&&!d){var m="";for(o in l){i=l[o].param,s=l[o].value;var g;n&&n.maskPasswords&&(g=l[o].password),"undefined"!=typeof s&&(Array.isArray(s)?(""!==m&&(m+="&"),m+=this.encodeQueryCollection(i.collectionFormat,o,s,g)):(""!==m&&(m+="&"),m+=encodeURIComponent(o)+"="+c(encodeURIComponent(s),g)))}a=m}else if(d){var y;if("function"==typeof FormData){y=new FormData,y.type="formData";for(o in l)if(i=l[o].param,s=t[o],"undefined"!=typeof s)if("[object File]"==={}.toString.apply(s))y.append(o,s);else if("file"===s.type&&s.value)y.append(o,s.value);else if(Array.isArray(s))if("multi"===i.collectionFormat){y["delete"](o);for(var v in s)y.append(o,s[v])}else y.append(o,this.encodeQueryCollection(i.collectionFormat,o,s).split("=").slice(1).join("="));else y.append(o,s);a=y}else{y={};for(o in l)if(s=t[o],Array.isArray(s)){var b,w=i.collectionFormat||"multi";if("ssv"===w)b=" ";else if("pipes"===w)b="|";else if("tsv"===w)b="\t";else{if("multi"===w){y[o]=s;break}b=","}var _;s.forEach(function(e){_?_+=b:_="",_+=e}),y[o]=_}else y[o]=s;a=y}e["Content-Type"]="multipart/form-data"}return a},u.prototype.getModelSampleJSON=function(e,t){var n,r,a;if(t=t||{},n=e instanceof Array,a=n?e[0]:e,t[a]?r=t[a].createJSONSample():this.getInlineModel(a)&&(r=this.getInlineModel(a).createJSONSample()),r){if(r=n?[r]:r,"string"==typeof r)return r;if(i.isObject(r)){var o=r;if(r instanceof Array&&r.length>0&&(o=r[0]),o.nodeName&&"Node"==typeof o){var s=(new XMLSerializer).serializeToString(o);return this.formatXml(s)}return JSON.stringify(r,null,2)}return r}},u.prototype["do"]=function(e,t,n,r,i){return this.execute(e,t,n,r,i)},u.prototype.execute=function(e,t,n,r,o){var u,c,p,h,f=e||{},d={};i.isObject(t)&&(d=t,u=n,c=r),h="undefined"!=typeof d.timeout?d.timeout:this.timeout,this.client&&(d.client=this.client),this.requestAgent&&(d.requestAgent=this.requestAgent),!d.requestInterceptor&&this.requestInterceptor&&(d.requestInterceptor=this.requestInterceptor),!d.responseInterceptor&&this.responseInterceptor&&(d.responseInterceptor=this.responseInterceptor),"function"==typeof t&&(u=t,c=n),this.parent.usePromise?p=l.defer():(u=u||this.parent.defaultSuccessCallback||a.log,c=c||this.parent.defaultErrorCallback||a.log),"undefined"==typeof d.useJQuery&&(d.useJQuery=this.useJQuery),"undefined"==typeof d.jqueryAjaxCache&&(d.jqueryAjaxCache=this.jqueryAjaxCache),"undefined"==typeof d.enableCookies&&(d.enableCookies=this.enableCookies);var m=this.getMissingParams(f);if(m.length>0){var g="missing required params: "+m;return a.fail(g),this.parent.usePromise?(p.reject(g),p.promise):(c(g,o),{})}var y,v=this.getHeaderParams(f),b=this.setContentTypes(f,d),w={};for(y in v)w[y]=v[y];for(y in b)w[y]=b[y];var _=this.getBody(b,f,d),x=this.urlify(f,d.maskPasswords);if(x.indexOf(".{format}")>0&&w){var A=w.Accept||w.accept;A&&A.indexOf("json")>0?x=x.replace(".{format}",".json"):A&&A.indexOf("xml")>0&&(x=x.replace(".{format}",".xml"))}var S={url:x,method:this.method.toUpperCase(),body:_,enableCookies:d.enableCookies,useJQuery:d.useJQuery,jqueryAjaxCache:d.jqueryAjaxCache,deferred:p,headers:w,clientAuthorizations:d.clientAuthorizations,operation:this,connectionAgent:this.connectionAgent,on:{response:function(e){return p?(p.resolve(e),p.promise):u(e,o)},error:function(e){return p?(p.reject(e),p.promise):c(e,o)}}};return h&&(S.timeout=h),this.clientAuthorizations.apply(S,this.operation.security),d.mock===!0?(d.requestInterceptor&&d.requestInterceptor.apply(S),S):(new s).execute(S,d)},u.prototype.setContentTypes=function(e,t){var n,i,o=this.parameters,s=e.parameterContentType||r(this.consumes,["application/json","application/yaml"]),l=t.responseContentType||r(this.produces,["application/json","application/yaml"]),u=[],c=[],p={};for(i=0;i<o.length;i++){var h=o[i];if("formData"===h["in"])"file"===h.type?u.push(h):c.push(h);else if("header"===h["in"]&&t){var f=h.name,d=t[h.name];"undefined"!=typeof t[h.name]&&(p[f]=d)}else"body"===h["in"]&&"undefined"!=typeof e[h.name]&&(n=e[h.name])}var m=n||u.length||c.length;if("post"===this.method||"put"===this.method||"patch"===this.method||("delete"===this.method||"get"===this.method)&&m){if(t.requestContentType&&(s=t.requestContentType),c.length>0){if(s=void 0,t.requestContentType)s=t.requestContentType;else if(u.length>0)s="multipart/form-data";else if(this.consumes&&this.consumes.length>0)for(var g in this.consumes){var y=this.consumes[g];0!==y.indexOf("application/x-www-form-urlencoded")&&0!==y.indexOf("multipart/form-data")||(s=y)}"undefined"==typeof s&&(s="application/x-www-form-urlencoded")}}else s=null;return s&&this.consumes&&this.consumes.indexOf(s)===-1&&a.log("server doesn't consume "+s+", try "+JSON.stringify(this.consumes)),this.matchesAccept(l)||a.log("server can't produce "+l),s&&""!==n||"application/x-www-form-urlencoded"===s?p["Content-Type"]=s:this.consumes&&this.consumes.length>0&&"application/x-www-form-urlencoded"===this.consumes[0]&&(p["Content-Type"]=this.consumes[0]),l&&(p.Accept=l),p},u.prototype.matchesAccept=function(e){return!e||!this.produces||(this.produces.indexOf(e)!==-1||this.produces.indexOf("*/*")!==-1)},u.prototype.asCurl=function(e,t){var n={mock:!0,maskPasswords:!0};if("object"==typeof t)for(var r in t)n[r]=t[r];var a=this.execute(e,n);this.clientAuthorizations.apply(a,this.operation.security);var o=[];if(o.push("-X "+this.method.toUpperCase()),"undefined"!=typeof a.headers){var s;for(s in a.headers){var l=a.headers[s];"string"==typeof l&&(l=l.replace(/\'/g,"\\u0027")),o.push("--header '"+s+": "+l+"'")}}var u=!1,p=!1,h=a.headers["Content-Type"];if(h&&0===h.indexOf("application/x-www-form-urlencoded")?u=!0:h&&0===h.indexOf("multipart/form-data")&&(u=!0,p=!0),a.body){var f;if(i.isObject(a.body)){if(p){p=!0;for(var d=0;d<this.parameters.length;d++){var m=this.parameters[d];if("formData"===m["in"]){f||(f="");var g;if(g="function"==typeof FormData&&a.body instanceof FormData?a.body.getAll(m.name):a.body[m.name])if("file"===m.type)g.name&&(f+="-F "+m.name+'=@"'+g.name+'" ');else if(Array.isArray(g))if("multi"===m.collectionFormat)for(var y in g)f+="-F "+this.encodeQueryKey(m.name)+"="+c(g[y],m.format)+" ";else f+="-F "+this.encodeQueryCollection(m.collectionFormat,m.name,c(g,m.format))+" ";else f+="-F "+this.encodeQueryKey(m.name)+"="+c(g,m.format)+" "}}}f||(f=JSON.stringify(a.body))}else f=a.body;f=f.replace(/\'/g,"%27").replace(/\n/g," \\ \n "),u||(f=f.replace(/&/g,"%26")),p?o.push(f):o.push("-d '"+f.replace(/@/g,"%40")+"'")}return"curl "+o.join(" ")+" '"+a.url+"'"},u.prototype.encodePathCollection=function(e,t,n,r){var i,a="",o="";for(o="ssv"===e?"%20":"tsv"===e?"%09":"pipes"===e?"|":",",i=0;i<n.length;i++)0===i?a=this.encodeQueryParam(n[i],r):a+=o+this.encodeQueryParam(n[i],r);return a},u.prototype.encodeQueryCollection=function(e,t,n,r){var i,a="";if(e=e||"default","default"===e||"multi"===e)for(i=0;i<n.length;i++)i>0&&(a+="&"),a+=this.encodeQueryKey(t)+"="+c(this.encodeQueryParam(n[i]),r);else{var o="";if("csv"===e)o=",";else if("ssv"===e)o="%20";else if("tsv"===e)o="%09";else if("pipes"===e)o="|";else if("brackets"===e)for(i=0;i<n.length;i++)0!==i&&(a+="&"),a+=this.encodeQueryKey(t)+"[]="+c(this.encodeQueryParam(n[i]),r);if(""!==o)for(i=0;i<n.length;i++)0===i?a=this.encodeQueryKey(t)+"="+this.encodeQueryParam(n[i]):a+=o+this.encodeQueryParam(n[i])}return a},u.prototype.encodeQueryKey=function(e){return encodeURIComponent(e).replace("%5B","[").replace("%5D","]").replace("%24","$")},u.prototype.encodeQueryParam=function(e,t){return t?"******":void 0!==e&&null!==e?encodeURIComponent(e):""},u.prototype.encodePathParam=function(e,t){return encodeURIComponent(e,t)};var c=function(e,t){return"string"==typeof t&&"password"===t?"******":e}},{"../helpers":4,"../http":5,"./model":9,"lodash-compat/lang/cloneDeep":138,"lodash-compat/lang/isEmpty":141,"lodash-compat/lang/isObject":144,"lodash-compat/lang/isUndefined":148,q:157}],11:[function(e,t,n){"use strict";var r=t.exports=function(e,t,n,r){this.description=t,this.externalDocs=n,this.name=e,this.operation=r,this.operationsArray=[],this.path=e,this.tag=e};r.prototype.sort=function(){}},{}],12:[function(e,t,n){function r(){if(!s){s=!0;for(var e,t=o.length;t;){e=o,o=[];for(var n=-1;++n<t;)e[n]();t=o.length}s=!1}}function i(){}var a=t.exports={},o=[],s=!1;a.nextTick=function(e){o.push(e),s||setTimeout(r,0)},a.title="browser",a.browser=!0,a.env={},a.argv=[],a.version="",a.versions={},a.on=i,a.addListener=i,a.once=i,a.off=i,a.removeListener=i,a.removeAllListeners=i,a.emit=i,a.binding=function(e){throw new Error("process.binding is not supported")},a.cwd=function(){return"/"},a.chdir=function(e){throw new Error("process.chdir is not supported")},a.umask=function(){return 0}},{}],13:[function(e,t,n){(function(e){!function(){"use strict";function n(t){var n;return n=t instanceof e?t:new e(t.toString(),"binary"),n.toString("base64")}t.exports=n}()}).call(this,e("buffer").Buffer)},{buffer:14}],14:[function(e,t,n){function r(){return i.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function i(e){return this instanceof i?(this.length=0,this.parent=void 0,"number"==typeof e?a(this,e):"string"==typeof e?o(this,e,arguments.length>1?arguments[1]:"utf8"):s(this,e)):arguments.length>1?new i(e,arguments[1]):new i(e)}function a(e,t){if(e=d(e,t<0?0:0|m(t)),!i.TYPED_ARRAY_SUPPORT)for(var n=0;n<t;n++)e[n]=0;return e}function o(e,t,n){"string"==typeof n&&""!==n||(n="utf8");var r=0|y(t,n);return e=d(e,r),e.write(t,n),e}function s(e,t){if(i.isBuffer(t))return l(e,t);if(Q(t))return u(e,t);if(null==t)throw new TypeError("must start with number, buffer, array or string");if("undefined"!=typeof ArrayBuffer){if(t.buffer instanceof ArrayBuffer)return c(e,t);if(t instanceof ArrayBuffer)return p(e,t)}return t.length?h(e,t):f(e,t)}function l(e,t){var n=0|m(t.length);return e=d(e,n),t.copy(e,0,0,n),e}function u(e,t){var n=0|m(t.length);e=d(e,n);for(var r=0;r<n;r+=1)e[r]=255&t[r];return e}function c(e,t){var n=0|m(t.length);e=d(e,n);for(var r=0;r<n;r+=1)e[r]=255&t[r];return e}function p(e,t){return i.TYPED_ARRAY_SUPPORT?(t.byteLength,e=i._augment(new Uint8Array(t))):e=c(e,new Uint8Array(t)),e}function h(e,t){var n=0|m(t.length);e=d(e,n);for(var r=0;r<n;r+=1)e[r]=255&t[r];return e}function f(e,t){var n,r=0;"Buffer"===t.type&&Q(t.data)&&(n=t.data,r=0|m(n.length)),e=d(e,r);for(var i=0;i<r;i+=1)e[i]=255&n[i];return e}function d(e,t){i.TYPED_ARRAY_SUPPORT?e=i._augment(new Uint8Array(t)):(e.length=t,e._isBuffer=!0);var n=0!==t&&t<=i.poolSize>>>1;return n&&(e.parent=G),e}function m(e){if(e>=r())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+r().toString(16)+" bytes");return 0|e}function g(e,t){if(!(this instanceof g))return new g(e,t);var n=new i(e,t);return delete n.parent,n}function y(e,t){"string"!=typeof e&&(e=""+e);var n=e.length;if(0===n)return 0;for(var r=!1;;)switch(t){case"ascii":case"binary":case"raw":case"raws":return n;case"utf8":case"utf-8":return $(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return H(e).length;default:if(r)return $(e).length;t=(""+t).toLowerCase(),r=!0}}function v(e,t,n){var r=!1;if(t=0|t,n=void 0===n||n===1/0?this.length:0|n,e||(e="utf8"),t<0&&(t=0),n>this.length&&(n=this.length),n<=t)return"";for(;;)switch(e){case"hex":return C(this,t,n);case"utf8":case"utf-8":return E(this,t,n);case"ascii":return k(this,t,n);case"binary":return T(this,t,n);case"base64":return j(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return I(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}function b(e,t,n,r){n=Number(n)||0;var i=e.length-n;r?(r=Number(r),r>i&&(r=i)):r=i;var a=t.length;if(a%2!==0)throw new Error("Invalid hex string");r>a/2&&(r=a/2);for(var o=0;o<r;o++){var s=parseInt(t.substr(2*o,2),16);if(isNaN(s))throw new Error("Invalid hex string");e[n+o]=s}return o}function w(e,t,n,r){return Y($(t,e.length-n),e,n,r)}function _(e,t,n,r){return Y(F(t),e,n,r)}function x(e,t,n,r){return _(e,t,n,r)}function A(e,t,n,r){return Y(H(t),e,n,r)}function S(e,t,n,r){return Y(V(t,e.length-n),e,n,r)}function j(e,t,n){return 0===t&&n===e.length?J.fromByteArray(e):J.fromByteArray(e.slice(t,n))}function E(e,t,n){n=Math.min(e.length,n);for(var r=[],i=t;i<n;){var a=e[i],o=null,s=a>239?4:a>223?3:a>191?2:1;if(i+s<=n){var l,u,c,p;switch(s){case 1:a<128&&(o=a);break;case 2:l=e[i+1],128===(192&l)&&(p=(31&a)<<6|63&l,p>127&&(o=p));break;case 3:l=e[i+1],u=e[i+2],128===(192&l)&&128===(192&u)&&(p=(15&a)<<12|(63&l)<<6|63&u,p>2047&&(p<55296||p>57343)&&(o=p));break;case 4:l=e[i+1],u=e[i+2],c=e[i+3],128===(192&l)&&128===(192&u)&&128===(192&c)&&(p=(15&a)<<18|(63&l)<<12|(63&u)<<6|63&c,p>65535&&p<1114112&&(o=p))}}null===o?(o=65533,s=1):o>65535&&(o-=65536,r.push(o>>>10&1023|55296),o=56320|1023&o),r.push(o),i+=s}return O(r)}function O(e){var t=e.length;if(t<=K)return String.fromCharCode.apply(String,e);for(var n="",r=0;r<t;)n+=String.fromCharCode.apply(String,e.slice(r,r+=K));return n}function k(e,t,n){var r="";n=Math.min(e.length,n);for(var i=t;i<n;i++)r+=String.fromCharCode(127&e[i]);return r}function T(e,t,n){var r="";n=Math.min(e.length,n);for(var i=t;i<n;i++)r+=String.fromCharCode(e[i]);return r}function C(e,t,n){var r=e.length;(!t||t<0)&&(t=0),(!n||n<0||n>r)&&(n=r);for(var i="",a=t;a<n;a++)i+=N(e[a]);return i}function I(e,t,n){for(var r=e.slice(t,n),i="",a=0;a<r.length;a+=2)i+=String.fromCharCode(r[a]+256*r[a+1]);return i}function D(e,t,n){if(e%1!==0||e<0)throw new RangeError("offset is not uint");if(e+t>n)throw new RangeError("Trying to access beyond buffer length")}function L(e,t,n,r,a,o){if(!i.isBuffer(e))throw new TypeError("buffer must be a Buffer instance");if(t>a||t<o)throw new RangeError("value is out of bounds");if(n+r>e.length)throw new RangeError("index out of range")}function M(e,t,n,r){t<0&&(t=65535+t+1);for(var i=0,a=Math.min(e.length-n,2);i<a;i++)e[n+i]=(t&255<<8*(r?i:1-i))>>>8*(r?i:1-i)}function R(e,t,n,r){t<0&&(t=4294967295+t+1);for(var i=0,a=Math.min(e.length-n,4);i<a;i++)e[n+i]=t>>>8*(r?i:3-i)&255}function U(e,t,n,r,i,a){if(t>i||t<a)throw new RangeError("value is out of bounds");if(n+r>e.length)throw new RangeError("index out of range");if(n<0)throw new RangeError("index out of range")}function P(e,t,n,r,i){return i||U(e,t,n,4,3.4028234663852886e38,-3.4028234663852886e38),W.write(e,t,n,r,23,4),n+4}function q(e,t,n,r,i){return i||U(e,t,n,8,1.7976931348623157e308,-1.7976931348623157e308),W.write(e,t,n,r,52,8),n+8}function B(e){if(e=z(e).replace(Z,""),e.length<2)return"";for(;e.length%4!==0;)e+="=";return e}function z(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}function N(e){return e<16?"0"+e.toString(16):e.toString(16)}function $(e,t){t=t||1/0;for(var n,r=e.length,i=null,a=[],o=0;o<r;o++){if(n=e.charCodeAt(o),n>55295&&n<57344){if(!i){if(n>56319){(t-=3)>-1&&a.push(239,191,189);continue}if(o+1===r){(t-=3)>-1&&a.push(239,191,189);continue}i=n;continue}if(n<56320){(t-=3)>-1&&a.push(239,191,189),i=n;continue}n=i-55296<<10|n-56320|65536}else i&&(t-=3)>-1&&a.push(239,191,189);if(i=null,n<128){if((t-=1)<0)break;a.push(n)}else if(n<2048){if((t-=2)<0)break;a.push(n>>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;a.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;a.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return a}function F(e){for(var t=[],n=0;n<e.length;n++)t.push(255&e.charCodeAt(n));return t}function V(e,t){for(var n,r,i,a=[],o=0;o<e.length&&!((t-=2)<0);o++)n=e.charCodeAt(o),r=n>>8,i=n%256,a.push(i),a.push(r);return a}function H(e){return J.toByteArray(B(e))}function Y(e,t,n,r){for(var i=0;i<r&&!(i+n>=t.length||i>=e.length);i++)t[i+n]=e[i];return i}var J=e("base64-js"),W=e("ieee754"),Q=e("is-array");n.Buffer=i,n.SlowBuffer=g,n.INSPECT_MAX_BYTES=50,i.poolSize=8192;var G={};i.TYPED_ARRAY_SUPPORT=function(){function e(){}try{var t=new Uint8Array(1);return t.foo=function(){return 42},t.constructor=e,42===t.foo()&&t.constructor===e&&"function"==typeof t.subarray&&0===t.subarray(1,1).byteLength}catch(n){return!1}}(),i.isBuffer=function(e){return!(null==e||!e._isBuffer)},i.compare=function(e,t){if(!i.isBuffer(e)||!i.isBuffer(t))throw new TypeError("Arguments must be Buffers");if(e===t)return 0;for(var n=e.length,r=t.length,a=0,o=Math.min(n,r);a<o&&e[a]===t[a];)++a;return a!==o&&(n=e[a],r=t[a]),n<r?-1:r<n?1:0},i.isEncoding=function(e){switch(String(e).toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"raw":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return!0;default:return!1}},i.concat=function(e,t){if(!Q(e))throw new TypeError("list argument must be an Array of Buffers.");if(0===e.length)return new i(0);var n;if(void 0===t)for(t=0,n=0;n<e.length;n++)t+=e[n].length;var r=new i(t),a=0;for(n=0;n<e.length;n++){var o=e[n];o.copy(r,a),a+=o.length}return r},i.byteLength=y,i.prototype.length=void 0,i.prototype.parent=void 0,i.prototype.toString=function(){var e=0|this.length;return 0===e?"":0===arguments.length?E(this,0,e):v.apply(this,arguments)},i.prototype.equals=function(e){if(!i.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e||0===i.compare(this,e)},i.prototype.inspect=function(){var e="",t=n.INSPECT_MAX_BYTES;return this.length>0&&(e=this.toString("hex",0,t).match(/.{2}/g).join(" "),this.length>t&&(e+=" ... ")),"<Buffer "+e+">"},i.prototype.compare=function(e){if(!i.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e?0:i.compare(this,e)},i.prototype.indexOf=function(e,t){function n(e,t,n){for(var r=-1,i=0;n+i<e.length;i++)if(e[n+i]===t[r===-1?0:i-r]){if(r===-1&&(r=i),i-r+1===t.length)return n+r}else r=-1;return-1}if(t>2147483647?t=2147483647:t<-2147483648&&(t=-2147483648),t>>=0,0===this.length)return-1;if(t>=this.length)return-1;if(t<0&&(t=Math.max(this.length+t,0)),"string"==typeof e)return 0===e.length?-1:String.prototype.indexOf.call(this,e,t);if(i.isBuffer(e))return n(this,e,t);if("number"==typeof e)return i.TYPED_ARRAY_SUPPORT&&"function"===Uint8Array.prototype.indexOf?Uint8Array.prototype.indexOf.call(this,e,t):n(this,[e],t);throw new TypeError("val must be string, number or Buffer")},i.prototype.get=function(e){return console.log(".get() is deprecated. Access using array indexes instead."),this.readUInt8(e)},i.prototype.set=function(e,t){return console.log(".set() is deprecated. Access using array indexes instead."),this.writeUInt8(e,t)},i.prototype.write=function(e,t,n,r){if(void 0===t)r="utf8",n=this.length,t=0;else if(void 0===n&&"string"==typeof t)r=t,n=this.length,t=0;else if(isFinite(t))t=0|t,isFinite(n)?(n=0|n,void 0===r&&(r="utf8")):(r=n,n=void 0);else{var i=r;r=t,t=0|n,n=i}var a=this.length-t;if((void 0===n||n>a)&&(n=a),e.length>0&&(n<0||t<0)||t>this.length)throw new RangeError("attempt to write outside buffer bounds");r||(r="utf8");for(var o=!1;;)switch(r){case"hex":return b(this,e,t,n);case"utf8":case"utf-8":return w(this,e,t,n);case"ascii":return _(this,e,t,n);case"binary":return x(this,e,t,n);case"base64":return A(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return S(this,e,t,n);default:if(o)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),o=!0}},i.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var K=4096;i.prototype.slice=function(e,t){var n=this.length;e=~~e,t=void 0===t?n:~~t,e<0?(e+=n,e<0&&(e=0)):e>n&&(e=n),t<0?(t+=n,t<0&&(t=0)):t>n&&(t=n),t<e&&(t=e);var r;if(i.TYPED_ARRAY_SUPPORT)r=i._augment(this.subarray(e,t));else{var a=t-e;r=new i(a,(void 0));for(var o=0;o<a;o++)r[o]=this[o+e]}return r.length&&(r.parent=this.parent||this),r},i.prototype.readUIntLE=function(e,t,n){e=0|e,t=0|t,n||D(e,t,this.length);for(var r=this[e],i=1,a=0;++a<t&&(i*=256);)r+=this[e+a]*i;return r},i.prototype.readUIntBE=function(e,t,n){e=0|e,t=0|t,n||D(e,t,this.length);for(var r=this[e+--t],i=1;t>0&&(i*=256);)r+=this[e+--t]*i;return r},i.prototype.readUInt8=function(e,t){return t||D(e,1,this.length),this[e]},i.prototype.readUInt16LE=function(e,t){return t||D(e,2,this.length),this[e]|this[e+1]<<8},i.prototype.readUInt16BE=function(e,t){return t||D(e,2,this.length),this[e]<<8|this[e+1]},i.prototype.readUInt32LE=function(e,t){return t||D(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},i.prototype.readUInt32BE=function(e,t){return t||D(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},i.prototype.readIntLE=function(e,t,n){e=0|e,t=0|t,n||D(e,t,this.length);for(var r=this[e],i=1,a=0;++a<t&&(i*=256);)r+=this[e+a]*i;return i*=128,r>=i&&(r-=Math.pow(2,8*t)),r},i.prototype.readIntBE=function(e,t,n){e=0|e,t=0|t,n||D(e,t,this.length);for(var r=t,i=1,a=this[e+--r];r>0&&(i*=256);)a+=this[e+--r]*i;return i*=128,a>=i&&(a-=Math.pow(2,8*t)),a},i.prototype.readInt8=function(e,t){return t||D(e,1,this.length),128&this[e]?(255-this[e]+1)*-1:this[e]},i.prototype.readInt16LE=function(e,t){t||D(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},i.prototype.readInt16BE=function(e,t){t||D(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},i.prototype.readInt32LE=function(e,t){return t||D(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},i.prototype.readInt32BE=function(e,t){return t||D(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},i.prototype.readFloatLE=function(e,t){return t||D(e,4,this.length),W.read(this,e,!0,23,4)},i.prototype.readFloatBE=function(e,t){return t||D(e,4,this.length),W.read(this,e,!1,23,4)},i.prototype.readDoubleLE=function(e,t){return t||D(e,8,this.length),W.read(this,e,!0,52,8)},i.prototype.readDoubleBE=function(e,t){return t||D(e,8,this.length),W.read(this,e,!1,52,8)},i.prototype.writeUIntLE=function(e,t,n,r){e=+e,t=0|t,n=0|n,r||L(this,e,t,n,Math.pow(2,8*n),0);var i=1,a=0;for(this[t]=255&e;++a<n&&(i*=256);)this[t+a]=e/i&255;return t+n},i.prototype.writeUIntBE=function(e,t,n,r){e=+e,t=0|t,n=0|n,r||L(this,e,t,n,Math.pow(2,8*n),0);var i=n-1,a=1;for(this[t+i]=255&e;--i>=0&&(a*=256);)this[t+i]=e/a&255;return t+n},i.prototype.writeUInt8=function(e,t,n){return e=+e,t=0|t,n||L(this,e,t,1,255,0),i.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=e,t+1},i.prototype.writeUInt16LE=function(e,t,n){return e=+e,t=0|t,n||L(this,e,t,2,65535,0),i.TYPED_ARRAY_SUPPORT?(this[t]=e,this[t+1]=e>>>8):M(this,e,t,!0),t+2},i.prototype.writeUInt16BE=function(e,t,n){return e=+e,t=0|t,n||L(this,e,t,2,65535,0),i.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=e):M(this,e,t,!1),t+2},i.prototype.writeUInt32LE=function(e,t,n){return e=+e,t=0|t,n||L(this,e,t,4,4294967295,0),i.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=e):R(this,e,t,!0),t+4},i.prototype.writeUInt32BE=function(e,t,n){return e=+e,t=0|t,n||L(this,e,t,4,4294967295,0),i.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=e):R(this,e,t,!1),t+4},i.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t=0|t,!r){var i=Math.pow(2,8*n-1);L(this,e,t,n,i-1,-i)}var a=0,o=1,s=e<0?1:0;for(this[t]=255&e;++a<n&&(o*=256);)this[t+a]=(e/o>>0)-s&255;return t+n},i.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t=0|t,!r){var i=Math.pow(2,8*n-1);L(this,e,t,n,i-1,-i)}var a=n-1,o=1,s=e<0?1:0;for(this[t+a]=255&e;--a>=0&&(o*=256);)this[t+a]=(e/o>>0)-s&255;return t+n},i.prototype.writeInt8=function(e,t,n){return e=+e,t=0|t,n||L(this,e,t,1,127,-128),i.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),e<0&&(e=255+e+1),this[t]=e,t+1},i.prototype.writeInt16LE=function(e,t,n){return e=+e,t=0|t,n||L(this,e,t,2,32767,-32768),i.TYPED_ARRAY_SUPPORT?(this[t]=e,this[t+1]=e>>>8):M(this,e,t,!0),t+2},i.prototype.writeInt16BE=function(e,t,n){return e=+e,t=0|t,n||L(this,e,t,2,32767,-32768),i.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=e):M(this,e,t,!1),t+2},i.prototype.writeInt32LE=function(e,t,n){return e=+e,t=0|t,n||L(this,e,t,4,2147483647,-2147483648),i.TYPED_ARRAY_SUPPORT?(this[t]=e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):R(this,e,t,!0),t+4},i.prototype.writeInt32BE=function(e,t,n){return e=+e,t=0|t,n||L(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),i.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=e):R(this,e,t,!1),t+4},i.prototype.writeFloatLE=function(e,t,n){return P(this,e,t,!0,n)},i.prototype.writeFloatBE=function(e,t,n){return P(this,e,t,!1,n)},i.prototype.writeDoubleLE=function(e,t,n){return q(this,e,t,!0,n)},i.prototype.writeDoubleBE=function(e,t,n){return q(this,e,t,!1,n)},i.prototype.copy=function(e,t,n,r){if(n||(n=0),r||0===r||(r=this.length),t>=e.length&&(t=e.length),t||(t=0),r>0&&r<n&&(r=n),r===n)return 0;if(0===e.length||0===this.length)return 0;if(t<0)throw new RangeError("targetStart out of bounds");if(n<0||n>=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t<r-n&&(r=e.length-t+n);var a,o=r-n;if(this===e&&n<t&&t<r)for(a=o-1;a>=0;a--)e[a+t]=this[a+n];else if(o<1e3||!i.TYPED_ARRAY_SUPPORT)for(a=0;a<o;a++)e[a+t]=this[a+n];else e._set(this.subarray(n,n+o),t);return o},i.prototype.fill=function(e,t,n){if(e||(e=0),t||(t=0),n||(n=this.length),n<t)throw new RangeError("end < start");if(n!==t&&0!==this.length){if(t<0||t>=this.length)throw new RangeError("start out of bounds");if(n<0||n>this.length)throw new RangeError("end out of bounds");var r;if("number"==typeof e)for(r=t;r<n;r++)this[r]=e;else{var i=$(e.toString()),a=i.length;for(r=t;r<n;r++)this[r]=i[r%a]}return this}},i.prototype.toArrayBuffer=function(){if("undefined"!=typeof Uint8Array){if(i.TYPED_ARRAY_SUPPORT)return new i(this).buffer;for(var e=new Uint8Array(this.length),t=0,n=e.length;t<n;t+=1)e[t]=this[t];return e.buffer}throw new TypeError("Buffer.toArrayBuffer not supported in this browser")};var X=i.prototype;i._augment=function(e){return e.constructor=i,e._isBuffer=!0,e._set=e.set,e.get=X.get,e.set=X.set,e.write=X.write,e.toString=X.toString,e.toLocaleString=X.toString,e.toJSON=X.toJSON,e.equals=X.equals,e.compare=X.compare,e.indexOf=X.indexOf,e.copy=X.copy,e.slice=X.slice,e.readUIntLE=X.readUIntLE,e.readUIntBE=X.readUIntBE,e.readUInt8=X.readUInt8,e.readUInt16LE=X.readUInt16LE,e.readUInt16BE=X.readUInt16BE,e.readUInt32LE=X.readUInt32LE,e.readUInt32BE=X.readUInt32BE,e.readIntLE=X.readIntLE,e.readIntBE=X.readIntBE,e.readInt8=X.readInt8,e.readInt16LE=X.readInt16LE,e.readInt16BE=X.readInt16BE,e.readInt32LE=X.readInt32LE,e.readInt32BE=X.readInt32BE,e.readFloatLE=X.readFloatLE,e.readFloatBE=X.readFloatBE,e.readDoubleLE=X.readDoubleLE,e.readDoubleBE=X.readDoubleBE,e.writeUInt8=X.writeUInt8,e.writeUIntLE=X.writeUIntLE,e.writeUIntBE=X.writeUIntBE,e.writeUInt16LE=X.writeUInt16LE,e.writeUInt16BE=X.writeUInt16BE,e.writeUInt32LE=X.writeUInt32LE,e.writeUInt32BE=X.writeUInt32BE,e.writeIntLE=X.writeIntLE,e.writeIntBE=X.writeIntBE,e.writeInt8=X.writeInt8,e.writeInt16LE=X.writeInt16LE,e.writeInt16BE=X.writeInt16BE,e.writeInt32LE=X.writeInt32LE,e.writeInt32BE=X.writeInt32BE,e.writeFloatLE=X.writeFloatLE,e.writeFloatBE=X.writeFloatBE,e.writeDoubleLE=X.writeDoubleLE,e.writeDoubleBE=X.writeDoubleBE,e.fill=X.fill,e.inspect=X.inspect,e.toArrayBuffer=X.toArrayBuffer,e};var Z=/[^+\/0-9A-Za-z-_]/g},{"base64-js":15,ieee754:16,"is-array":17}],15:[function(e,t,n){var r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";!function(e){"use strict";function t(e){var t=e.charCodeAt(0);return t===o||t===p?62:t===s||t===h?63:t<l?-1:t<l+10?t-l+26+26:t<c+26?t-c:t<u+26?t-u+26:void 0}function n(e){function n(e){u[p++]=e}var r,i,o,s,l,u;if(e.length%4>0)throw new Error("Invalid string. Length must be a multiple of 4");var c=e.length;l="="===e.charAt(c-2)?2:"="===e.charAt(c-1)?1:0,u=new a(3*e.length/4-l),o=l>0?e.length-4:e.length;var p=0;for(r=0,i=0;r<o;r+=4,i+=3)s=t(e.charAt(r))<<18|t(e.charAt(r+1))<<12|t(e.charAt(r+2))<<6|t(e.charAt(r+3)),n((16711680&s)>>16),n((65280&s)>>8),n(255&s);return 2===l?(s=t(e.charAt(r))<<2|t(e.charAt(r+1))>>4,n(255&s)):1===l&&(s=t(e.charAt(r))<<10|t(e.charAt(r+1))<<4|t(e.charAt(r+2))>>2,
+n(s>>8&255),n(255&s)),u}function i(e){function t(e){return r.charAt(e)}function n(e){return t(e>>18&63)+t(e>>12&63)+t(e>>6&63)+t(63&e)}var i,a,o,s=e.length%3,l="";for(i=0,o=e.length-s;i<o;i+=3)a=(e[i]<<16)+(e[i+1]<<8)+e[i+2],l+=n(a);switch(s){case 1:a=e[e.length-1],l+=t(a>>2),l+=t(a<<4&63),l+="==";break;case 2:a=(e[e.length-2]<<8)+e[e.length-1],l+=t(a>>10),l+=t(a>>4&63),l+=t(a<<2&63),l+="="}return l}var a="undefined"!=typeof Uint8Array?Uint8Array:Array,o="+".charCodeAt(0),s="/".charCodeAt(0),l="0".charCodeAt(0),u="a".charCodeAt(0),c="A".charCodeAt(0),p="-".charCodeAt(0),h="_".charCodeAt(0);e.toByteArray=n,e.fromByteArray=i}("undefined"==typeof n?this.base64js={}:n)},{}],16:[function(e,t,n){n.read=function(e,t,n,r,i){var a,o,s=8*i-r-1,l=(1<<s)-1,u=l>>1,c=-7,p=n?i-1:0,h=n?-1:1,f=e[t+p];for(p+=h,a=f&(1<<-c)-1,f>>=-c,c+=s;c>0;a=256*a+e[t+p],p+=h,c-=8);for(o=a&(1<<-c)-1,a>>=-c,c+=r;c>0;o=256*o+e[t+p],p+=h,c-=8);if(0===a)a=1-u;else{if(a===l)return o?NaN:(f?-1:1)*(1/0);o+=Math.pow(2,r),a-=u}return(f?-1:1)*o*Math.pow(2,a-r)},n.write=function(e,t,n,r,i,a){var o,s,l,u=8*a-i-1,c=(1<<u)-1,p=c>>1,h=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,f=r?0:a-1,d=r?1:-1,m=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,o=c):(o=Math.floor(Math.log(t)/Math.LN2),t*(l=Math.pow(2,-o))<1&&(o--,l*=2),t+=o+p>=1?h/l:h*Math.pow(2,1-p),t*l>=2&&(o++,l/=2),o+p>=c?(s=0,o=c):o+p>=1?(s=(t*l-1)*Math.pow(2,i),o+=p):(s=t*Math.pow(2,p-1)*Math.pow(2,i),o=0));i>=8;e[n+f]=255&s,f+=d,s/=256,i-=8);for(o=o<<i|s,u+=i;u>0;e[n+f]=255&o,f+=d,o/=256,u-=8);e[n+f-d]|=128*m}},{}],17:[function(e,t,n){var r=Array.isArray,i=Object.prototype.toString;t.exports=r||function(e){return!!e&&"[object Array]"==i.call(e)}},{}],18:[function(e,t,n){!function(){"use strict";function e(t,n,r,i){return this instanceof e?(this.domain=t||void 0,this.path=n||"/",this.secure=!!r,this.script=!!i,this):new e(t,n,r,i)}function t(e,n,r){return e instanceof t?e:this instanceof t?(this.name=null,this.value=null,this.expiration_date=1/0,this.path=String(r||"/"),this.explicit_path=!1,this.domain=n||null,this.explicit_domain=!1,this.secure=!1,this.noscript=!1,e&&this.parse(e,n,r),this):new t(e,n,r)}function r(){var e,n,i;return this instanceof r?(e=Object.create(null),this.setCookie=function(r,a,o){var s,l;if(r=new t(r,a,o),s=r.expiration_date<=Date.now(),void 0!==e[r.name]){for(n=e[r.name],l=0;l<n.length;l+=1)if(i=n[l],i.collidesWith(r))return s?(n.splice(l,1),0===n.length&&delete e[r.name],!1):(n[l]=r,r);return!s&&(n.push(r),r)}return!s&&(e[r.name]=[r],e[r.name])},this.getCookie=function(t,r){var i,a;if(n=e[t])for(a=0;a<n.length;a+=1)if(i=n[a],i.expiration_date<=Date.now())0===n.length&&delete e[i.name];else if(i.matches(r))return i},this.getCookies=function(t){var n,r,i=[];for(n in e)r=this.getCookie(n,t),r&&i.push(r);return i.toString=function(){return i.join(":")},i.toValueString=function(){return i.map(function(e){return e.toValueString()}).join(";")},i},this):new r}n.CookieAccessInfo=e,n.Cookie=t,t.prototype.toString=function(){var e=[this.name+"="+this.value];return this.expiration_date!==1/0&&e.push("expires="+new Date(this.expiration_date).toGMTString()),this.domain&&e.push("domain="+this.domain),this.path&&e.push("path="+this.path),this.secure&&e.push("secure"),this.noscript&&e.push("httponly"),e.join("; ")},t.prototype.toValueString=function(){return this.name+"="+this.value};var i=/[:](?=\s*[a-zA-Z0-9_\-]+\s*[=])/g;t.prototype.parse=function(e,n,r){if(this instanceof t){var i,a=e.split(";").filter(function(e){return!!e}),o=a[0].match(/([^=]+)=([\s\S]*)/),s=o[1],l=o[2];for(this.name=s,this.value=l,i=1;i<a.length;i+=1)switch(o=a[i].match(/([^=]+)(?:=([\s\S]*))?/),s=o[1].trim().toLowerCase(),l=o[2],s){case"httponly":this.noscript=!0;break;case"expires":this.expiration_date=l?Number(Date.parse(l)):1/0;break;case"path":this.path=l?l.trim():"",this.explicit_path=!0;break;case"domain":this.domain=l?l.trim():"",this.explicit_domain=!!this.domain;break;case"secure":this.secure=!0}return this.explicit_path||(this.path=r||"/"),this.explicit_domain||(this.domain=n),this}return(new t).parse(e,n,r)},t.prototype.matches=function(e){return!(this.noscript&&e.script||this.secure&&!e.secure||!this.collidesWith(e))},t.prototype.collidesWith=function(e){if(this.path&&!e.path||this.domain&&!e.domain)return!1;if(this.path&&0!==e.path.indexOf(this.path))return!1;if(this.explicit_path&&0!==e.path.indexOf(this.path))return!1;var t=e.domain&&e.domain.replace(/^[\.]/,""),n=this.domain&&this.domain.replace(/^[\.]/,"");if(n===t)return!0;if(n){if(!this.explicit_domain)return!1;var r=t.indexOf(n);return r!==-1&&r===t.length-n.length}return!0},n.CookieJar=r,r.prototype.setCookies=function(e,n,r){e=Array.isArray(e)?e:e.split(i);var a,o,s=[];for(e=e.map(function(e){return new t(e,n,r)}),a=0;a<e.length;a+=1)o=e[a],this.setCookie(o,n,r)&&s.push(o);return s}}()},{}],19:[function(e,t,n){"use strict";var r=e("./lib/js-yaml.js");t.exports=r},{"./lib/js-yaml.js":20}],20:[function(e,t,n){"use strict";function r(e){return function(){throw new Error("Function "+e+" is deprecated and cannot be used.")}}var i=e("./js-yaml/loader"),a=e("./js-yaml/dumper");t.exports.Type=e("./js-yaml/type"),t.exports.Schema=e("./js-yaml/schema"),t.exports.FAILSAFE_SCHEMA=e("./js-yaml/schema/failsafe"),t.exports.JSON_SCHEMA=e("./js-yaml/schema/json"),t.exports.CORE_SCHEMA=e("./js-yaml/schema/core"),t.exports.DEFAULT_SAFE_SCHEMA=e("./js-yaml/schema/default_safe"),t.exports.DEFAULT_FULL_SCHEMA=e("./js-yaml/schema/default_full"),t.exports.load=i.load,t.exports.loadAll=i.loadAll,t.exports.safeLoad=i.safeLoad,t.exports.safeLoadAll=i.safeLoadAll,t.exports.dump=a.dump,t.exports.safeDump=a.safeDump,t.exports.YAMLException=e("./js-yaml/exception"),t.exports.MINIMAL_SCHEMA=e("./js-yaml/schema/failsafe"),t.exports.SAFE_SCHEMA=e("./js-yaml/schema/default_safe"),t.exports.DEFAULT_SCHEMA=e("./js-yaml/schema/default_full"),t.exports.scan=r("scan"),t.exports.parse=r("parse"),t.exports.compose=r("compose"),t.exports.addConstructor=r("addConstructor")},{"./js-yaml/dumper":22,"./js-yaml/exception":23,"./js-yaml/loader":24,"./js-yaml/schema":26,"./js-yaml/schema/core":27,"./js-yaml/schema/default_full":28,"./js-yaml/schema/default_safe":29,"./js-yaml/schema/failsafe":30,"./js-yaml/schema/json":31,"./js-yaml/type":32}],21:[function(e,t,n){"use strict";function r(e){return"undefined"==typeof e||null===e}function i(e){return"object"==typeof e&&null!==e}function a(e){return Array.isArray(e)?e:r(e)?[]:[e]}function o(e,t){var n,r,i,a;if(t)for(a=Object.keys(t),n=0,r=a.length;n<r;n+=1)i=a[n],e[i]=t[i];return e}function s(e,t){var n,r="";for(n=0;n<t;n+=1)r+=e;return r}function l(e){return 0===e&&Number.NEGATIVE_INFINITY===1/e}t.exports.isNothing=r,t.exports.isObject=i,t.exports.toArray=a,t.exports.repeat=s,t.exports.isNegativeZero=l,t.exports.extend=o},{}],22:[function(e,t,n){"use strict";function r(e,t){var n,r,i,a,o,s,l;if(null===t)return{};for(n={},r=Object.keys(t),i=0,a=r.length;i<a;i+=1)o=r[i],s=String(t[o]),"!!"===o.slice(0,2)&&(o="tag:yaml.org,2002:"+o.slice(2)),l=e.compiledTypeMap[o],l&&R.call(l.styleAliases,s)&&(s=l.styleAliases[s]),n[o]=s;return n}function i(e){var t,n,r;if(t=e.toString(16).toUpperCase(),e<=255)n="x",r=2;else if(e<=65535)n="u",r=4;else{if(!(e<=4294967295))throw new I("code point within a string may not be greater than 0xFFFFFFFF");n="U",r=8}return"\\"+n+C.repeat("0",r-t.length)+t}function a(e){this.schema=e.schema||D,this.indent=Math.max(1,e.indent||2),this.skipInvalid=e.skipInvalid||!1,this.flowLevel=C.isNothing(e.flowLevel)?-1:e.flowLevel,this.styleMap=r(this.schema,e.styles||null),this.sortKeys=e.sortKeys||!1,this.lineWidth=e.lineWidth||80,this.noRefs=e.noRefs||!1,this.noCompatMode=e.noCompatMode||!1,this.implicitTypes=this.schema.compiledImplicit,this.explicitTypes=this.schema.compiledExplicit,this.tag=null,this.result="",this.duplicates=[],this.usedDuplicates=null}function o(e,t){for(var n,r=C.repeat(" ",t),i=0,a=-1,o="",s=e.length;i<s;)a=e.indexOf("\n",i),a===-1?(n=e.slice(i),i=s):(n=e.slice(i,a+1),i=a+1),n.length&&"\n"!==n&&(o+=r),o+=n;return o}function s(e,t){return"\n"+C.repeat(" ",e.indent*t)}function l(e,t){var n,r,i;for(n=0,r=e.implicitTypes.length;n<r;n+=1)if(i=e.implicitTypes[n],i.resolve(t))return!0;return!1}function u(e){return e===q||e===U}function c(e){return 32<=e&&e<=126||161<=e&&e<=55295&&8232!==e&&8233!==e||57344<=e&&e<=65533&&65279!==e||65536<=e&&e<=1114111}function p(e){return c(e)&&65279!==e&&e!==Y&&e!==X&&e!==Z&&e!==te&&e!==re&&e!==W&&e!==N}function h(e){return c(e)&&65279!==e&&!u(e)&&e!==J&&e!==G&&e!==W&&e!==Y&&e!==X&&e!==Z&&e!==te&&e!==re&&e!==N&&e!==F&&e!==H&&e!==B&&e!==ne&&e!==Q&&e!==V&&e!==z&&e!==$&&e!==K&&e!==ee}function f(e,t,n,r,i){var a,o,s=!1,l=!1,f=r!==-1,d=-1,m=h(e.charCodeAt(0))&&!u(e.charCodeAt(e.length-1));if(t)for(a=0;a<e.length;a++){if(o=e.charCodeAt(a),!c(o))return ce;m=m&&p(o)}else{for(a=0;a<e.length;a++){if(o=e.charCodeAt(a),o===P)s=!0,f&&(l=l||a-d-1>r&&" "!==e[d+1],d=a);else if(!c(o))return ce;m=m&&p(o)}l=l||f&&a-d-1>r&&" "!==e[d+1]}return s||l?" "===e[0]&&n>9?ce:l?ue:le:m&&!i(e)?oe:se}function d(e,t,n,r){e.dump=function(){function i(t){return l(e,t)}if(0===t.length)return"''";if(!e.noCompatMode&&ae.indexOf(t)!==-1)return"'"+t+"'";var a=e.indent*Math.max(1,n),s=e.lineWidth===-1?-1:Math.max(Math.min(e.lineWidth,40),e.lineWidth-a),u=r||e.flowLevel>-1&&n>=e.flowLevel;switch(f(t,u,e.indent,s,i)){case oe:return t;case se:return"'"+t.replace(/'/g,"''")+"'";case le:return"|"+m(t,e.indent)+g(o(t,a));case ue:return">"+m(t,e.indent)+g(o(y(t,s),a));case ce:return'"'+b(t,s)+'"';default:throw new I("impossible error: invalid scalar style")}}()}function m(e,t){var n=" "===e[0]?String(t):"",r="\n"===e[e.length-1],i=r&&("\n"===e[e.length-2]||"\n"===e),a=i?"+":r?"":"-";return n+a+"\n"}function g(e){return"\n"===e[e.length-1]?e.slice(0,-1):e}function y(e,t){for(var n,r,i=/(\n+)([^\n]*)/g,a=function(){var n=e.indexOf("\n");return n=n!==-1?n:e.length,i.lastIndex=n,v(e.slice(0,n),t)}(),o="\n"===e[0]||" "===e[0];r=i.exec(e);){var s=r[1],l=r[2];n=" "===l[0],a+=s+(o||n||""===l?"":"\n")+v(l,t),o=n}return a}function v(e,t){if(""===e||" "===e[0])return e;for(var n,r,i=/ [^ ]/g,a=0,o=0,s=0,l="";n=i.exec(e);)s=n.index,s-a>t&&(r=o>a?o:s,l+="\n"+e.slice(a,r),a=r+1),o=s;return l+="\n",l+=e.length-a>t&&o>a?e.slice(a,o)+"\n"+e.slice(o+1):e.slice(a),l.slice(1)}function b(e){for(var t,n,r="",a=0;a<e.length;a++)t=e.charCodeAt(a),n=ie[t],r+=!n&&c(t)?e[a]:n||i(t);return r}function w(e,t,n){var r,i,a="",o=e.tag;for(r=0,i=n.length;r<i;r+=1)j(e,t,n[r],!1,!1)&&(0!==r&&(a+=", "),a+=e.dump);e.tag=o,e.dump="["+a+"]"}function _(e,t,n,r){var i,a,o="",l=e.tag;for(i=0,a=n.length;i<a;i+=1)j(e,t+1,n[i],!0,!0)&&(r&&0===i||(o+=s(e,t)),o+="- "+e.dump);e.tag=l,e.dump=o||"[]"}function x(e,t,n){var r,i,a,o,s,l="",u=e.tag,c=Object.keys(n);for(r=0,i=c.length;r<i;r+=1)s="",0!==r&&(s+=", "),a=c[r],o=n[a],j(e,t,a,!1,!1)&&(e.dump.length>1024&&(s+="? "),s+=e.dump+": ",j(e,t,o,!1,!1)&&(s+=e.dump,l+=s));e.tag=u,e.dump="{"+l+"}"}function A(e,t,n,r){var i,a,o,l,u,c,p="",h=e.tag,f=Object.keys(n);if(e.sortKeys===!0)f.sort();else if("function"==typeof e.sortKeys)f.sort(e.sortKeys);else if(e.sortKeys)throw new I("sortKeys must be a boolean or a function");for(i=0,a=f.length;i<a;i+=1)c="",r&&0===i||(c+=s(e,t)),o=f[i],l=n[o],j(e,t+1,o,!0,!0,!0)&&(u=null!==e.tag&&"?"!==e.tag||e.dump&&e.dump.length>1024,u&&(c+=e.dump&&P===e.dump.charCodeAt(0)?"?":"? "),c+=e.dump,u&&(c+=s(e,t)),j(e,t+1,l,!0,u)&&(c+=e.dump&&P===e.dump.charCodeAt(0)?":":": ",c+=e.dump,p+=c));e.tag=h,e.dump=p||"{}"}function S(e,t,n){var r,i,a,o,s,l;for(i=n?e.explicitTypes:e.implicitTypes,a=0,o=i.length;a<o;a+=1)if(s=i[a],(s.instanceOf||s.predicate)&&(!s.instanceOf||"object"==typeof t&&t instanceof s.instanceOf)&&(!s.predicate||s.predicate(t))){if(e.tag=n?s.tag:"?",s.represent){if(l=e.styleMap[s.tag]||s.defaultStyle,"[object Function]"===M.call(s.represent))r=s.represent(t,l);else{if(!R.call(s.represent,l))throw new I("!<"+s.tag+'> tag resolver accepts not "'+l+'" style');r=s.represent[l](t,l)}e.dump=r}return!0}return!1}function j(e,t,n,r,i,a){e.tag=null,e.dump=n,S(e,n,!1)||S(e,n,!0);var o=M.call(e.dump);r&&(r=e.flowLevel<0||e.flowLevel>t);var s,l,u="[object Object]"===o||"[object Array]"===o;if(u&&(s=e.duplicates.indexOf(n),l=s!==-1),(null!==e.tag&&"?"!==e.tag||l||2!==e.indent&&t>0)&&(i=!1),l&&e.usedDuplicates[s])e.dump="*ref_"+s;else{if(u&&l&&!e.usedDuplicates[s]&&(e.usedDuplicates[s]=!0),"[object Object]"===o)r&&0!==Object.keys(e.dump).length?(A(e,t,e.dump,i),l&&(e.dump="&ref_"+s+e.dump)):(x(e,t,e.dump),l&&(e.dump="&ref_"+s+" "+e.dump));else if("[object Array]"===o)r&&0!==e.dump.length?(_(e,t,e.dump,i),l&&(e.dump="&ref_"+s+e.dump)):(w(e,t,e.dump),l&&(e.dump="&ref_"+s+" "+e.dump));else{if("[object String]"!==o){if(e.skipInvalid)return!1;throw new I("unacceptable kind of an object to dump "+o)}"?"!==e.tag&&d(e,e.dump,t,a)}null!==e.tag&&"?"!==e.tag&&(e.dump="!<"+e.tag+"> "+e.dump)}return!0}function E(e,t){var n,r,i=[],a=[];for(O(e,i,a),n=0,r=a.length;n<r;n+=1)t.duplicates.push(i[a[n]]);t.usedDuplicates=new Array(r)}function O(e,t,n){var r,i,a;if(null!==e&&"object"==typeof e)if(i=t.indexOf(e),i!==-1)n.indexOf(i)===-1&&n.push(i);else if(t.push(e),Array.isArray(e))for(i=0,a=e.length;i<a;i+=1)O(e[i],t,n);else for(r=Object.keys(e),i=0,a=r.length;i<a;i+=1)O(e[r[i]],t,n)}function k(e,t){t=t||{};var n=new a(t);return n.noRefs||E(e,n),j(n,0,e,!0,!0)?n.dump+"\n":""}function T(e,t){return k(e,C.extend({schema:L},t))}var C=e("./common"),I=e("./exception"),D=e("./schema/default_full"),L=e("./schema/default_safe"),M=Object.prototype.toString,R=Object.prototype.hasOwnProperty,U=9,P=10,q=32,B=33,z=34,N=35,$=37,F=38,V=39,H=42,Y=44,J=45,W=58,Q=62,G=63,K=64,X=91,Z=93,ee=96,te=123,ne=124,re=125,ie={};ie[0]="\\0",ie[7]="\\a",ie[8]="\\b",ie[9]="\\t",ie[10]="\\n",ie[11]="\\v",ie[12]="\\f",ie[13]="\\r",ie[27]="\\e",ie[34]='\\"',ie[92]="\\\\",ie[133]="\\N",ie[160]="\\_",ie[8232]="\\L",ie[8233]="\\P";var ae=["y","Y","yes","Yes","YES","on","On","ON","n","N","no","No","NO","off","Off","OFF"],oe=1,se=2,le=3,ue=4,ce=5;t.exports.dump=k,t.exports.safeDump=T},{"./common":21,"./exception":23,"./schema/default_full":28,"./schema/default_safe":29}],23:[function(e,t,n){"use strict";function r(e,t){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack||"",this.name="YAMLException",this.reason=e,this.mark=t,this.message=(this.reason||"(unknown reason)")+(this.mark?" "+this.mark.toString():"")}r.prototype=Object.create(Error.prototype),r.prototype.constructor=r,r.prototype.toString=function(e){var t=this.name+": ";return t+=this.reason||"(unknown reason)",!e&&this.mark&&(t+=" "+this.mark.toString()),t},t.exports=r},{}],24:[function(e,t,n){"use strict";function r(e){return 10===e||13===e}function i(e){return 9===e||32===e}function a(e){return 9===e||32===e||10===e||13===e}function o(e){return 44===e||91===e||93===e||123===e||125===e}function s(e){var t;return 48<=e&&e<=57?e-48:(t=32|e,97<=t&&t<=102?t-97+10:-1)}function l(e){return 120===e?2:117===e?4:85===e?8:0}function u(e){return 48<=e&&e<=57?e-48:-1}function c(e){return 48===e?"\0":97===e?"\a":98===e?"\b":116===e?"\t":9===e?"\t":110===e?"\n":118===e?"\x0B":102===e?"\f":114===e?"\r":101===e?"\e":32===e?" ":34===e?'"':47===e?"/":92===e?"\\":78===e?"\85":95===e?" ":76===e?"\u2028":80===e?"\u2029":""}function p(e){return e<=65535?String.fromCharCode(e):String.fromCharCode((e-65536>>10)+55296,(e-65536&1023)+56320)}function h(e,t){this.input=e,this.filename=t.filename||null,this.schema=t.schema||V,this.onWarning=t.onWarning||null,this.legacy=t.legacy||!1,this.json=t.json||!1,this.listener=t.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=e.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.documents=[]}function f(e,t){return new N(t,new $(e.filename,e.input,e.position,e.line,e.position-e.lineStart))}function d(e,t){throw f(e,t)}function m(e,t){e.onWarning&&e.onWarning.call(null,f(e,t))}function g(e,t,n,r){var i,a,o,s;if(t<n){if(s=e.input.slice(t,n),r)for(i=0,a=s.length;i<a;i+=1)o=s.charCodeAt(i),9===o||32<=o&&o<=1114111||d(e,"expected valid JSON character");else Z.test(s)&&d(e,"the stream contains non-printable characters");e.result+=s}}function y(e,t,n,r){var i,a,o,s;for(z.isObject(n)||d(e,"cannot merge mappings; the provided source object is unacceptable"),i=Object.keys(n),o=0,s=i.length;o<s;o+=1)a=i[o],H.call(t,a)||(t[a]=n[a],r[a]=!0)}function v(e,t,n,r,i,a){var o,s;if(i=String(i),null===t&&(t={}),"tag:yaml.org,2002:merge"===r)if(Array.isArray(a))for(o=0,s=a.length;o<s;o+=1)y(e,t,a[o],n);else y(e,t,a,n);else e.json||H.call(n,i)||!H.call(t,i)||d(e,"duplicated mapping key"),t[i]=a,delete n[i];return t}function b(e){var t;t=e.input.charCodeAt(e.position),10===t?e.position++:13===t?(e.position++,10===e.input.charCodeAt(e.position)&&e.position++):d(e,"a line break is expected"),e.line+=1,e.lineStart=e.position}function w(e,t,n){for(var a=0,o=e.input.charCodeAt(e.position);0!==o;){for(;i(o);)o=e.input.charCodeAt(++e.position);if(t&&35===o)do o=e.input.charCodeAt(++e.position);while(10!==o&&13!==o&&0!==o);if(!r(o))break;for(b(e),o=e.input.charCodeAt(e.position),a++,e.lineIndent=0;32===o;)e.lineIndent++,o=e.input.charCodeAt(++e.position)}return n!==-1&&0!==a&&e.lineIndent<n&&m(e,"deficient indentation"),a}function _(e){var t,n=e.position;return t=e.input.charCodeAt(n),!(45!==t&&46!==t||t!==e.input.charCodeAt(n+1)||t!==e.input.charCodeAt(n+2)||(n+=3,t=e.input.charCodeAt(n),0!==t&&!a(t)))}function x(e,t){1===t?e.result+=" ":t>1&&(e.result+=z.repeat("\n",t-1))}function A(e,t,n){var s,l,u,c,p,h,f,d,m,y=e.kind,v=e.result;if(m=e.input.charCodeAt(e.position),a(m)||o(m)||35===m||38===m||42===m||33===m||124===m||62===m||39===m||34===m||37===m||64===m||96===m)return!1;if((63===m||45===m)&&(l=e.input.charCodeAt(e.position+1),a(l)||n&&o(l)))return!1;for(e.kind="scalar",e.result="",u=c=e.position,p=!1;0!==m;){if(58===m){if(l=e.input.charCodeAt(e.position+1),a(l)||n&&o(l))break}else if(35===m){if(s=e.input.charCodeAt(e.position-1),a(s))break}else{if(e.position===e.lineStart&&_(e)||n&&o(m))break;if(r(m)){if(h=e.line,f=e.lineStart,d=e.lineIndent,w(e,!1,-1),e.lineIndent>=t){p=!0,m=e.input.charCodeAt(e.position);continue}e.position=c,e.line=h,e.lineStart=f,e.lineIndent=d;break}}p&&(g(e,u,c,!1),x(e,e.line-h),u=c=e.position,p=!1),i(m)||(c=e.position+1),m=e.input.charCodeAt(++e.position)}return g(e,u,c,!1),!!e.result||(e.kind=y,e.result=v,!1)}function S(e,t){var n,i,a;if(n=e.input.charCodeAt(e.position),39!==n)return!1;for(e.kind="scalar",e.result="",e.position++,i=a=e.position;0!==(n=e.input.charCodeAt(e.position));)if(39===n){if(g(e,i,e.position,!0),n=e.input.charCodeAt(++e.position),39!==n)return!0;i=a=e.position,e.position++}else r(n)?(g(e,i,a,!0),x(e,w(e,!1,t)),i=a=e.position):e.position===e.lineStart&&_(e)?d(e,"unexpected end of the document within a single quoted scalar"):(e.position++,a=e.position);d(e,"unexpected end of the stream within a single quoted scalar")}function j(e,t){var n,i,a,o,u,c;if(c=e.input.charCodeAt(e.position),34!==c)return!1;for(e.kind="scalar",e.result="",e.position++,n=i=e.position;0!==(c=e.input.charCodeAt(e.position));){if(34===c)return g(e,n,e.position,!0),e.position++,!0;if(92===c){if(g(e,n,e.position,!0),c=e.input.charCodeAt(++e.position),r(c))w(e,!1,t);else if(c<256&&ie[c])e.result+=ae[c],e.position++;else if((u=l(c))>0){for(a=u,o=0;a>0;a--)c=e.input.charCodeAt(++e.position),(u=s(c))>=0?o=(o<<4)+u:d(e,"expected hexadecimal character");e.result+=p(o),e.position++}else d(e,"unknown escape sequence");n=i=e.position}else r(c)?(g(e,n,i,!0),x(e,w(e,!1,t)),n=i=e.position):e.position===e.lineStart&&_(e)?d(e,"unexpected end of the document within a double quoted scalar"):(e.position++,i=e.position)}d(e,"unexpected end of the stream within a double quoted scalar")}function E(e,t){var n,r,i,o,s,l,u,c,p,h,f,m=!0,g=e.tag,y=e.anchor,b={};if(f=e.input.charCodeAt(e.position),91===f)o=93,u=!1,r=[];else{if(123!==f)return!1;o=125,u=!0,r={}}for(null!==e.anchor&&(e.anchorMap[e.anchor]=r),f=e.input.charCodeAt(++e.position);0!==f;){if(w(e,!0,t),f=e.input.charCodeAt(e.position),f===o)return e.position++,e.tag=g,e.anchor=y,e.kind=u?"mapping":"sequence",e.result=r,!0;m||d(e,"missed comma between flow collection entries"),p=c=h=null,s=l=!1,63===f&&(i=e.input.charCodeAt(e.position+1),a(i)&&(s=l=!0,e.position++,w(e,!0,t))),n=e.line,L(e,t,Y,!1,!0),p=e.tag,c=e.result,w(e,!0,t),f=e.input.charCodeAt(e.position),!l&&e.line!==n||58!==f||(s=!0,f=e.input.charCodeAt(++e.position),w(e,!0,t),L(e,t,Y,!1,!0),h=e.result),u?v(e,r,b,p,c,h):s?r.push(v(e,null,b,p,c,h)):r.push(c),w(e,!0,t),f=e.input.charCodeAt(e.position),44===f?(m=!0,f=e.input.charCodeAt(++e.position)):m=!1}d(e,"unexpected end of the stream within a flow collection")}function O(e,t){var n,a,o,s,l=G,c=!1,p=!1,h=t,f=0,m=!1;if(s=e.input.charCodeAt(e.position),124===s)a=!1;else{if(62!==s)return!1;a=!0}for(e.kind="scalar",e.result="";0!==s;)if(s=e.input.charCodeAt(++e.position),43===s||45===s)G===l?l=43===s?X:K:d(e,"repeat of a chomping mode identifier");else{if(!((o=u(s))>=0))break;0===o?d(e,"bad explicit indentation width of a block scalar; it cannot be less than one"):p?d(e,"repeat of an indentation width identifier"):(h=t+o-1,p=!0)}if(i(s)){do s=e.input.charCodeAt(++e.position);while(i(s));if(35===s)do s=e.input.charCodeAt(++e.position);while(!r(s)&&0!==s)}for(;0!==s;){for(b(e),e.lineIndent=0,s=e.input.charCodeAt(e.position);(!p||e.lineIndent<h)&&32===s;)e.lineIndent++,s=e.input.charCodeAt(++e.position);if(!p&&e.lineIndent>h&&(h=e.lineIndent),r(s))f++;else{if(e.lineIndent<h){l===X?e.result+=z.repeat("\n",c?1+f:f):l===G&&c&&(e.result+="\n");break}for(a?i(s)?(m=!0,e.result+=z.repeat("\n",c?1+f:f)):m?(m=!1,e.result+=z.repeat("\n",f+1)):0===f?c&&(e.result+=" "):e.result+=z.repeat("\n",f):e.result+=z.repeat("\n",c?1+f:f),c=!0,p=!0,f=0,n=e.position;!r(s)&&0!==s;)s=e.input.charCodeAt(++e.position);g(e,n,e.position,!1)}}return!0}function k(e,t){var n,r,i,o=e.tag,s=e.anchor,l=[],u=!1;for(null!==e.anchor&&(e.anchorMap[e.anchor]=l),i=e.input.charCodeAt(e.position);0!==i&&45===i&&(r=e.input.charCodeAt(e.position+1),a(r));)if(u=!0,e.position++,w(e,!0,-1)&&e.lineIndent<=t)l.push(null),i=e.input.charCodeAt(e.position);else if(n=e.line,L(e,t,W,!1,!0),l.push(e.result),w(e,!0,-1),i=e.input.charCodeAt(e.position),(e.line===n||e.lineIndent>t)&&0!==i)d(e,"bad indentation of a sequence entry");else if(e.lineIndent<t)break;return!!u&&(e.tag=o,e.anchor=s,e.kind="sequence",e.result=l,!0)}function T(e,t,n){var r,o,s,l,u=e.tag,c=e.anchor,p={},h={},f=null,m=null,g=null,y=!1,b=!1;for(null!==e.anchor&&(e.anchorMap[e.anchor]=p),l=e.input.charCodeAt(e.position);0!==l;){if(r=e.input.charCodeAt(e.position+1),s=e.line,63!==l&&58!==l||!a(r)){if(!L(e,n,J,!1,!0))break;if(e.line===s){for(l=e.input.charCodeAt(e.position);i(l);)l=e.input.charCodeAt(++e.position);if(58===l)l=e.input.charCodeAt(++e.position),a(l)||d(e,"a whitespace character is expected after the key-value separator within a block mapping"),y&&(v(e,p,h,f,m,null),f=m=g=null),b=!0,y=!1,o=!1,f=e.tag,m=e.result;else{if(!b)return e.tag=u,e.anchor=c,!0;d(e,"can not read an implicit mapping pair; a colon is missed")}}else{if(!b)return e.tag=u,e.anchor=c,!0;d(e,"can not read a block mapping entry; a multiline key may not be an implicit key")}}else 63===l?(y&&(v(e,p,h,f,m,null),f=m=g=null),b=!0,y=!0,o=!0):y?(y=!1,o=!0):d(e,"incomplete explicit mapping pair; a key node is missed"),e.position+=1,l=r;if((e.line===s||e.lineIndent>t)&&(L(e,t,Q,!0,o)&&(y?m=e.result:g=e.result),y||(v(e,p,h,f,m,g),f=m=g=null),w(e,!0,-1),l=e.input.charCodeAt(e.position)),e.lineIndent>t&&0!==l)d(e,"bad indentation of a mapping entry");else if(e.lineIndent<t)break}return y&&v(e,p,h,f,m,null),b&&(e.tag=u,e.anchor=c,e.kind="mapping",e.result=p),b}function C(e){var t,n,r,i,o=!1,s=!1;if(i=e.input.charCodeAt(e.position),33!==i)return!1;if(null!==e.tag&&d(e,"duplication of a tag property"),i=e.input.charCodeAt(++e.position),60===i?(o=!0,i=e.input.charCodeAt(++e.position)):33===i?(s=!0,n="!!",i=e.input.charCodeAt(++e.position)):n="!",t=e.position,o){do i=e.input.charCodeAt(++e.position);while(0!==i&&62!==i);e.position<e.length?(r=e.input.slice(t,e.position),i=e.input.charCodeAt(++e.position)):d(e,"unexpected end of the stream within a verbatim tag")}else{for(;0!==i&&!a(i);)33===i&&(s?d(e,"tag suffix cannot contain exclamation marks"):(n=e.input.slice(t-1,e.position+1),ne.test(n)||d(e,"named tag handle cannot contain such characters"),s=!0,t=e.position+1)),i=e.input.charCodeAt(++e.position);r=e.input.slice(t,e.position),te.test(r)&&d(e,"tag suffix cannot contain flow indicator characters")}return r&&!re.test(r)&&d(e,"tag name cannot contain such characters: "+r),o?e.tag=r:H.call(e.tagMap,n)?e.tag=e.tagMap[n]+r:"!"===n?e.tag="!"+r:"!!"===n?e.tag="tag:yaml.org,2002:"+r:d(e,'undeclared tag handle "'+n+'"'),!0}function I(e){var t,n;if(n=e.input.charCodeAt(e.position),38!==n)return!1;for(null!==e.anchor&&d(e,"duplication of an anchor property"),n=e.input.charCodeAt(++e.position),t=e.position;0!==n&&!a(n)&&!o(n);)n=e.input.charCodeAt(++e.position);return e.position===t&&d(e,"name of an anchor node must contain at least one character"),e.anchor=e.input.slice(t,e.position),!0}function D(e){var t,n,r;if(r=e.input.charCodeAt(e.position),42!==r)return!1;for(r=e.input.charCodeAt(++e.position),t=e.position;0!==r&&!a(r)&&!o(r);)r=e.input.charCodeAt(++e.position);return e.position===t&&d(e,"name of an alias node must contain at least one character"),n=e.input.slice(t,e.position),e.anchorMap.hasOwnProperty(n)||d(e,'unidentified alias "'+n+'"'),e.result=e.anchorMap[n],w(e,!0,-1),!0}function L(e,t,n,r,i){var a,o,s,l,u,c,p,h,f=1,m=!1,g=!1;if(null!==e.listener&&e.listener("open",e),e.tag=null,e.anchor=null,e.kind=null,e.result=null,a=o=s=Q===n||W===n,r&&w(e,!0,-1)&&(m=!0,e.lineIndent>t?f=1:e.lineIndent===t?f=0:e.lineIndent<t&&(f=-1)),1===f)for(;C(e)||I(e);)w(e,!0,-1)?(m=!0,s=a,e.lineIndent>t?f=1:e.lineIndent===t?f=0:e.lineIndent<t&&(f=-1)):s=!1;if(s&&(s=m||i),1!==f&&Q!==n||(p=Y===n||J===n?t:t+1,h=e.position-e.lineStart,1===f?s&&(k(e,h)||T(e,h,p))||E(e,p)?g=!0:(o&&O(e,p)||S(e,p)||j(e,p)?g=!0:D(e)?(g=!0,null===e.tag&&null===e.anchor||d(e,"alias node should not have any properties")):A(e,p,Y===n)&&(g=!0,null===e.tag&&(e.tag="?")),null!==e.anchor&&(e.anchorMap[e.anchor]=e.result)):0===f&&(g=s&&k(e,h))),null!==e.tag&&"!"!==e.tag)if("?"===e.tag){for(l=0,u=e.implicitTypes.length;l<u;l+=1)if(c=e.implicitTypes[l],c.resolve(e.result)){e.result=c.construct(e.result),e.tag=c.tag,null!==e.anchor&&(e.anchorMap[e.anchor]=e.result);break}}else H.call(e.typeMap,e.tag)?(c=e.typeMap[e.tag],null!==e.result&&c.kind!==e.kind&&d(e,"unacceptable node kind for !<"+e.tag+'> tag; it should be "'+c.kind+'", not "'+e.kind+'"'),c.resolve(e.result)?(e.result=c.construct(e.result),null!==e.anchor&&(e.anchorMap[e.anchor]=e.result)):d(e,"cannot resolve a node with !<"+e.tag+"> explicit tag")):d(e,"unknown tag !<"+e.tag+">");return null!==e.listener&&e.listener("close",e),null!==e.tag||null!==e.anchor||g}function M(e){var t,n,o,s,l=e.position,u=!1;for(e.version=null,e.checkLineBreaks=e.legacy,e.tagMap={},e.anchorMap={};0!==(s=e.input.charCodeAt(e.position))&&(w(e,!0,-1),s=e.input.charCodeAt(e.position),!(e.lineIndent>0||37!==s));){for(u=!0,s=e.input.charCodeAt(++e.position),t=e.position;0!==s&&!a(s);)s=e.input.charCodeAt(++e.position);for(n=e.input.slice(t,e.position),o=[],n.length<1&&d(e,"directive name must not be less than one character in length");0!==s;){for(;i(s);)s=e.input.charCodeAt(++e.position);if(35===s){do s=e.input.charCodeAt(++e.position);while(0!==s&&!r(s));break}if(r(s))break;for(t=e.position;0!==s&&!a(s);)s=e.input.charCodeAt(++e.position);o.push(e.input.slice(t,e.position))}0!==s&&b(e),H.call(se,n)?se[n](e,n,o):m(e,'unknown document directive "'+n+'"')}return w(e,!0,-1),0===e.lineIndent&&45===e.input.charCodeAt(e.position)&&45===e.input.charCodeAt(e.position+1)&&45===e.input.charCodeAt(e.position+2)?(e.position+=3,w(e,!0,-1)):u&&d(e,"directives end mark is expected"),L(e,e.lineIndent-1,Q,!1,!0),w(e,!0,-1),e.checkLineBreaks&&ee.test(e.input.slice(l,e.position))&&m(e,"non-ASCII line breaks are interpreted as content"),e.documents.push(e.result),e.position===e.lineStart&&_(e)?void(46===e.input.charCodeAt(e.position)&&(e.position+=3,w(e,!0,-1))):void(e.position<e.length-1&&d(e,"end of the stream or a document separator is expected"))}function R(e,t){e=String(e),t=t||{},0!==e.length&&(10!==e.charCodeAt(e.length-1)&&13!==e.charCodeAt(e.length-1)&&(e+="\n"),65279===e.charCodeAt(0)&&(e=e.slice(1)));var n=new h(e,t);for(n.input+="\0";32===n.input.charCodeAt(n.position);)n.lineIndent+=1,n.position+=1;for(;n.position<n.length-1;)M(n);return n.documents}function U(e,t,n){var r,i,a=R(e,n);for(r=0,i=a.length;r<i;r+=1)t(a[r])}function P(e,t){var n=R(e,t);if(0!==n.length){if(1===n.length)return n[0];throw new N("expected a single document in the stream, but found more")}}function q(e,t,n){U(e,t,z.extend({schema:F},n))}function B(e,t){return P(e,z.extend({schema:F},t))}for(var z=e("./common"),N=e("./exception"),$=e("./mark"),F=e("./schema/default_safe"),V=e("./schema/default_full"),H=Object.prototype.hasOwnProperty,Y=1,J=2,W=3,Q=4,G=1,K=2,X=3,Z=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,ee=/[\x85\u2028\u2029]/,te=/[,\[\]\{\}]/,ne=/^(?:!|!!|![a-z\-]+!)$/i,re=/^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i,ie=new Array(256),ae=new Array(256),oe=0;oe<256;oe++)ie[oe]=c(oe)?1:0,ae[oe]=c(oe);var se={YAML:function(e,t,n){var r,i,a;null!==e.version&&d(e,"duplication of %YAML directive"),1!==n.length&&d(e,"YAML directive accepts exactly one argument"),r=/^([0-9]+)\.([0-9]+)$/.exec(n[0]),null===r&&d(e,"ill-formed argument of the YAML directive"),i=parseInt(r[1],10),a=parseInt(r[2],10),1!==i&&d(e,"unacceptable YAML version of the document"),e.version=n[0],e.checkLineBreaks=a<2,1!==a&&2!==a&&m(e,"unsupported YAML version of the document")},TAG:function(e,t,n){var r,i;2!==n.length&&d(e,"TAG directive accepts exactly two arguments"),r=n[0],i=n[1],ne.test(r)||d(e,"ill-formed tag handle (first argument) of the TAG directive"),H.call(e.tagMap,r)&&d(e,'there is a previously declared suffix for "'+r+'" tag handle'),re.test(i)||d(e,"ill-formed tag prefix (second argument) of the TAG directive"),e.tagMap[r]=i}};t.exports.loadAll=U,t.exports.load=P,t.exports.safeLoadAll=q,t.exports.safeLoad=B},{"./common":21,"./exception":23,"./mark":25,"./schema/default_full":28,"./schema/default_safe":29}],25:[function(e,t,n){"use strict";function r(e,t,n,r,i){this.name=e,this.buffer=t,this.position=n,this.line=r,this.column=i}var i=e("./common");r.prototype.getSnippet=function(e,t){var n,r,a,o,s;if(!this.buffer)return null;for(e=e||4,t=t||75,n="",r=this.position;r>0&&"\0\r\n\85\u2028\u2029".indexOf(this.buffer.charAt(r-1))===-1;)if(r-=1,this.position-r>t/2-1){n=" ... ",r+=5;break}for(a="",o=this.position;o<this.buffer.length&&"\0\r\n\85\u2028\u2029".indexOf(this.buffer.charAt(o))===-1;)if(o+=1,o-this.position>t/2-1){a=" ... ",o-=5;break}return s=this.buffer.slice(r,o),i.repeat(" ",e)+n+s+a+"\n"+i.repeat(" ",e+this.position-r+n.length)+"^"},r.prototype.toString=function(e){var t,n="";return this.name&&(n+='in "'+this.name+'" '),n+="at line "+(this.line+1)+", column "+(this.column+1),e||(t=this.getSnippet(),t&&(n+=":\n"+t)),n},t.exports=r},{"./common":21}],26:[function(e,t,n){"use strict";function r(e,t,n){var i=[];return e.include.forEach(function(e){n=r(e,t,n)}),e[t].forEach(function(e){n.forEach(function(t,n){t.tag===e.tag&&i.push(n)}),n.push(e)}),n.filter(function(e,t){return i.indexOf(t)===-1})}function i(){function e(e){r[e.tag]=e}var t,n,r={};for(t=0,n=arguments.length;t<n;t+=1)arguments[t].forEach(e);return r}function a(e){this.include=e.include||[],this.implicit=e.implicit||[],
+this.explicit=e.explicit||[],this.implicit.forEach(function(e){if(e.loadKind&&"scalar"!==e.loadKind)throw new s("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.")}),this.compiledImplicit=r(this,"implicit",[]),this.compiledExplicit=r(this,"explicit",[]),this.compiledTypeMap=i(this.compiledImplicit,this.compiledExplicit)}var o=e("./common"),s=e("./exception"),l=e("./type");a.DEFAULT=null,a.create=function(){var e,t;switch(arguments.length){case 1:e=a.DEFAULT,t=arguments[0];break;case 2:e=arguments[0],t=arguments[1];break;default:throw new s("Wrong number of arguments for Schema.create function")}if(e=o.toArray(e),t=o.toArray(t),!e.every(function(e){return e instanceof a}))throw new s("Specified list of super schemas (or a single Schema object) contains a non-Schema object.");if(!t.every(function(e){return e instanceof l}))throw new s("Specified list of YAML types (or a single Type object) contains a non-Type object.");return new a({include:e,explicit:t})},t.exports=a},{"./common":21,"./exception":23,"./type":32}],27:[function(e,t,n){"use strict";var r=e("../schema");t.exports=new r({include:[e("./json")]})},{"../schema":26,"./json":31}],28:[function(e,t,n){"use strict";var r=e("../schema");t.exports=r.DEFAULT=new r({include:[e("./default_safe")],explicit:[e("../type/js/undefined"),e("../type/js/regexp"),e("../type/js/function")]})},{"../schema":26,"../type/js/function":37,"../type/js/regexp":38,"../type/js/undefined":39,"./default_safe":29}],29:[function(e,t,n){"use strict";var r=e("../schema");t.exports=new r({include:[e("./core")],implicit:[e("../type/timestamp"),e("../type/merge")],explicit:[e("../type/binary"),e("../type/omap"),e("../type/pairs"),e("../type/set")]})},{"../schema":26,"../type/binary":33,"../type/merge":41,"../type/omap":43,"../type/pairs":44,"../type/set":46,"../type/timestamp":48,"./core":27}],30:[function(e,t,n){"use strict";var r=e("../schema");t.exports=new r({explicit:[e("../type/str"),e("../type/seq"),e("../type/map")]})},{"../schema":26,"../type/map":40,"../type/seq":45,"../type/str":47}],31:[function(e,t,n){"use strict";var r=e("../schema");t.exports=new r({include:[e("./failsafe")],implicit:[e("../type/null"),e("../type/bool"),e("../type/int"),e("../type/float")]})},{"../schema":26,"../type/bool":34,"../type/float":35,"../type/int":36,"../type/null":42,"./failsafe":30}],32:[function(e,t,n){"use strict";function r(e){var t={};return null!==e&&Object.keys(e).forEach(function(n){e[n].forEach(function(e){t[String(e)]=n})}),t}function i(e,t){if(t=t||{},Object.keys(t).forEach(function(t){if(o.indexOf(t)===-1)throw new a('Unknown option "'+t+'" is met in definition of "'+e+'" YAML type.')}),this.tag=e,this.kind=t.kind||null,this.resolve=t.resolve||function(){return!0},this.construct=t.construct||function(e){return e},this.instanceOf=t.instanceOf||null,this.predicate=t.predicate||null,this.represent=t.represent||null,this.defaultStyle=t.defaultStyle||null,this.styleAliases=r(t.styleAliases||null),s.indexOf(this.kind)===-1)throw new a('Unknown kind "'+this.kind+'" is specified for "'+e+'" YAML type.')}var a=e("./exception"),o=["kind","resolve","construct","instanceOf","predicate","represent","defaultStyle","styleAliases"],s=["scalar","sequence","mapping"];t.exports=i},{"./exception":23}],33:[function(e,t,n){"use strict";function r(e){if(null===e)return!1;var t,n,r=0,i=e.length,a=p;for(n=0;n<i;n++)if(t=a.indexOf(e.charAt(n)),!(t>64)){if(t<0)return!1;r+=6}return r%8===0}function i(e){var t,n,r=e.replace(/[\r\n=]/g,""),i=r.length,a=p,o=0,l=[];for(t=0;t<i;t++)t%4===0&&t&&(l.push(o>>16&255),l.push(o>>8&255),l.push(255&o)),o=o<<6|a.indexOf(r.charAt(t));return n=i%4*6,0===n?(l.push(o>>16&255),l.push(o>>8&255),l.push(255&o)):18===n?(l.push(o>>10&255),l.push(o>>2&255)):12===n&&l.push(o>>4&255),s?new s(l):l}function a(e){var t,n,r="",i=0,a=e.length,o=p;for(t=0;t<a;t++)t%3===0&&t&&(r+=o[i>>18&63],r+=o[i>>12&63],r+=o[i>>6&63],r+=o[63&i]),i=(i<<8)+e[t];return n=a%3,0===n?(r+=o[i>>18&63],r+=o[i>>12&63],r+=o[i>>6&63],r+=o[63&i]):2===n?(r+=o[i>>10&63],r+=o[i>>4&63],r+=o[i<<2&63],r+=o[64]):1===n&&(r+=o[i>>2&63],r+=o[i<<4&63],r+=o[64],r+=o[64]),r}function o(e){return s&&s.isBuffer(e)}var s;try{var l=e;s=l("buffer").Buffer}catch(u){}var c=e("../type"),p="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r";t.exports=new c("tag:yaml.org,2002:binary",{kind:"scalar",resolve:r,construct:i,predicate:o,represent:a})},{"../type":32}],34:[function(e,t,n){"use strict";function r(e){if(null===e)return!1;var t=e.length;return 4===t&&("true"===e||"True"===e||"TRUE"===e)||5===t&&("false"===e||"False"===e||"FALSE"===e)}function i(e){return"true"===e||"True"===e||"TRUE"===e}function a(e){return"[object Boolean]"===Object.prototype.toString.call(e)}var o=e("../type");t.exports=new o("tag:yaml.org,2002:bool",{kind:"scalar",resolve:r,construct:i,predicate:a,represent:{lowercase:function(e){return e?"true":"false"},uppercase:function(e){return e?"TRUE":"FALSE"},camelcase:function(e){return e?"True":"False"}},defaultStyle:"lowercase"})},{"../type":32}],35:[function(e,t,n){"use strict";function r(e){return null!==e&&!!u.test(e)}function i(e){var t,n,r,i;return t=e.replace(/_/g,"").toLowerCase(),n="-"===t[0]?-1:1,i=[],"+-".indexOf(t[0])>=0&&(t=t.slice(1)),".inf"===t?1===n?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:".nan"===t?NaN:t.indexOf(":")>=0?(t.split(":").forEach(function(e){i.unshift(parseFloat(e,10))}),t=0,r=1,i.forEach(function(e){t+=e*r,r*=60}),n*t):n*parseFloat(t,10)}function a(e,t){var n;if(isNaN(e))switch(t){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===e)switch(t){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===e)switch(t){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(s.isNegativeZero(e))return"-0.0";return n=e.toString(10),c.test(n)?n.replace("e",".e"):n}function o(e){return"[object Number]"===Object.prototype.toString.call(e)&&(e%1!==0||s.isNegativeZero(e))}var s=e("../common"),l=e("../type"),u=new RegExp("^(?:[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+][0-9]+)?|\\.[0-9_]+(?:[eE][-+][0-9]+)?|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$"),c=/^[-+]?[0-9]+e/;t.exports=new l("tag:yaml.org,2002:float",{kind:"scalar",resolve:r,construct:i,predicate:o,represent:a,defaultStyle:"lowercase"})},{"../common":21,"../type":32}],36:[function(e,t,n){"use strict";function r(e){return 48<=e&&e<=57||65<=e&&e<=70||97<=e&&e<=102}function i(e){return 48<=e&&e<=55}function a(e){return 48<=e&&e<=57}function o(e){if(null===e)return!1;var t,n=e.length,o=0,s=!1;if(!n)return!1;if(t=e[o],"-"!==t&&"+"!==t||(t=e[++o]),"0"===t){if(o+1===n)return!0;if(t=e[++o],"b"===t){for(o++;o<n;o++)if(t=e[o],"_"!==t){if("0"!==t&&"1"!==t)return!1;s=!0}return s}if("x"===t){for(o++;o<n;o++)if(t=e[o],"_"!==t){if(!r(e.charCodeAt(o)))return!1;s=!0}return s}for(;o<n;o++)if(t=e[o],"_"!==t){if(!i(e.charCodeAt(o)))return!1;s=!0}return s}for(;o<n;o++)if(t=e[o],"_"!==t){if(":"===t)break;if(!a(e.charCodeAt(o)))return!1;s=!0}return!!s&&(":"!==t||/^(:[0-5]?[0-9])+$/.test(e.slice(o)))}function s(e){var t,n,r=e,i=1,a=[];return r.indexOf("_")!==-1&&(r=r.replace(/_/g,"")),t=r[0],"-"!==t&&"+"!==t||("-"===t&&(i=-1),r=r.slice(1),t=r[0]),"0"===r?0:"0"===t?"b"===r[1]?i*parseInt(r.slice(2),2):"x"===r[1]?i*parseInt(r,16):i*parseInt(r,8):r.indexOf(":")!==-1?(r.split(":").forEach(function(e){a.unshift(parseInt(e,10))}),r=0,n=1,a.forEach(function(e){r+=e*n,n*=60}),i*r):i*parseInt(r,10)}function l(e){return"[object Number]"===Object.prototype.toString.call(e)&&e%1===0&&!u.isNegativeZero(e)}var u=e("../common"),c=e("../type");t.exports=new c("tag:yaml.org,2002:int",{kind:"scalar",resolve:o,construct:s,predicate:l,represent:{binary:function(e){return"0b"+e.toString(2)},octal:function(e){return"0"+e.toString(8)},decimal:function(e){return e.toString(10)},hexadecimal:function(e){return"0x"+e.toString(16).toUpperCase()}},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}})},{"../common":21,"../type":32}],37:[function(e,t,n){"use strict";function r(e){if(null===e)return!1;try{var t="("+e+")",n=s.parse(t,{range:!0});return"Program"===n.type&&1===n.body.length&&"ExpressionStatement"===n.body[0].type&&"FunctionExpression"===n.body[0].expression.type}catch(r){return!1}}function i(e){var t,n="("+e+")",r=s.parse(n,{range:!0}),i=[];if("Program"!==r.type||1!==r.body.length||"ExpressionStatement"!==r.body[0].type||"FunctionExpression"!==r.body[0].expression.type)throw new Error("Failed to resolve function");return r.body[0].expression.params.forEach(function(e){i.push(e.name)}),t=r.body[0].expression.body.range,new Function(i,n.slice(t[0]+1,t[1]-1))}function a(e){return e.toString()}function o(e){return"[object Function]"===Object.prototype.toString.call(e)}var s;try{var l=e;s=l("esprima")}catch(u){"undefined"!=typeof window&&(s=window.esprima)}var c=e("../../type");t.exports=new c("tag:yaml.org,2002:js/function",{kind:"scalar",resolve:r,construct:i,predicate:o,represent:a})},{"../../type":32}],38:[function(e,t,n){"use strict";function r(e){if(null===e)return!1;if(0===e.length)return!1;var t=e,n=/\/([gim]*)$/.exec(e),r="";if("/"===t[0]){if(n&&(r=n[1]),r.length>3)return!1;if("/"!==t[t.length-r.length-1])return!1}return!0}function i(e){var t=e,n=/\/([gim]*)$/.exec(e),r="";return"/"===t[0]&&(n&&(r=n[1]),t=t.slice(1,t.length-r.length-1)),new RegExp(t,r)}function a(e){var t="/"+e.source+"/";return e.global&&(t+="g"),e.multiline&&(t+="m"),e.ignoreCase&&(t+="i"),t}function o(e){return"[object RegExp]"===Object.prototype.toString.call(e)}var s=e("../../type");t.exports=new s("tag:yaml.org,2002:js/regexp",{kind:"scalar",resolve:r,construct:i,predicate:o,represent:a})},{"../../type":32}],39:[function(e,t,n){"use strict";function r(){return!0}function i(){}function a(){return""}function o(e){return"undefined"==typeof e}var s=e("../../type");t.exports=new s("tag:yaml.org,2002:js/undefined",{kind:"scalar",resolve:r,construct:i,predicate:o,represent:a})},{"../../type":32}],40:[function(e,t,n){"use strict";var r=e("../type");t.exports=new r("tag:yaml.org,2002:map",{kind:"mapping",construct:function(e){return null!==e?e:{}}})},{"../type":32}],41:[function(e,t,n){"use strict";function r(e){return"<<"===e||null===e}var i=e("../type");t.exports=new i("tag:yaml.org,2002:merge",{kind:"scalar",resolve:r})},{"../type":32}],42:[function(e,t,n){"use strict";function r(e){if(null===e)return!0;var t=e.length;return 1===t&&"~"===e||4===t&&("null"===e||"Null"===e||"NULL"===e)}function i(){return null}function a(e){return null===e}var o=e("../type");t.exports=new o("tag:yaml.org,2002:null",{kind:"scalar",resolve:r,construct:i,predicate:a,represent:{canonical:function(){return"~"},lowercase:function(){return"null"},uppercase:function(){return"NULL"},camelcase:function(){return"Null"}},defaultStyle:"lowercase"})},{"../type":32}],43:[function(e,t,n){"use strict";function r(e){if(null===e)return!0;var t,n,r,i,a,l=[],u=e;for(t=0,n=u.length;t<n;t+=1){if(r=u[t],a=!1,"[object Object]"!==s.call(r))return!1;for(i in r)if(o.call(r,i)){if(a)return!1;a=!0}if(!a)return!1;if(l.indexOf(i)!==-1)return!1;l.push(i)}return!0}function i(e){return null!==e?e:[]}var a=e("../type"),o=Object.prototype.hasOwnProperty,s=Object.prototype.toString;t.exports=new a("tag:yaml.org,2002:omap",{kind:"sequence",resolve:r,construct:i})},{"../type":32}],44:[function(e,t,n){"use strict";function r(e){if(null===e)return!0;var t,n,r,i,a,s=e;for(a=new Array(s.length),t=0,n=s.length;t<n;t+=1){if(r=s[t],"[object Object]"!==o.call(r))return!1;if(i=Object.keys(r),1!==i.length)return!1;a[t]=[i[0],r[i[0]]]}return!0}function i(e){if(null===e)return[];var t,n,r,i,a,o=e;for(a=new Array(o.length),t=0,n=o.length;t<n;t+=1)r=o[t],i=Object.keys(r),a[t]=[i[0],r[i[0]]];return a}var a=e("../type"),o=Object.prototype.toString;t.exports=new a("tag:yaml.org,2002:pairs",{kind:"sequence",resolve:r,construct:i})},{"../type":32}],45:[function(e,t,n){"use strict";var r=e("../type");t.exports=new r("tag:yaml.org,2002:seq",{kind:"sequence",construct:function(e){return null!==e?e:[]}})},{"../type":32}],46:[function(e,t,n){"use strict";function r(e){if(null===e)return!0;var t,n=e;for(t in n)if(o.call(n,t)&&null!==n[t])return!1;return!0}function i(e){return null!==e?e:{}}var a=e("../type"),o=Object.prototype.hasOwnProperty;t.exports=new a("tag:yaml.org,2002:set",{kind:"mapping",resolve:r,construct:i})},{"../type":32}],47:[function(e,t,n){"use strict";var r=e("../type");t.exports=new r("tag:yaml.org,2002:str",{kind:"scalar",construct:function(e){return null!==e?e:""}})},{"../type":32}],48:[function(e,t,n){"use strict";function r(e){return null!==e&&(null!==s.exec(e)||null!==l.exec(e))}function i(e){var t,n,r,i,a,o,u,c,p,h,f=0,d=null;if(t=s.exec(e),null===t&&(t=l.exec(e)),null===t)throw new Error("Date resolve error");if(n=+t[1],r=+t[2]-1,i=+t[3],!t[4])return new Date(Date.UTC(n,r,i));if(a=+t[4],o=+t[5],u=+t[6],t[7]){for(f=t[7].slice(0,3);f.length<3;)f+="0";f=+f}return t[9]&&(c=+t[10],p=+(t[11]||0),d=6e4*(60*c+p),"-"===t[9]&&(d=-d)),h=new Date(Date.UTC(n,r,i,a,o,u,f)),d&&h.setTime(h.getTime()-d),h}function a(e){return e.toISOString()}var o=e("../type"),s=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"),l=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$");t.exports=new o("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:r,construct:i,instanceOf:Date,represent:a})},{"../type":32}],49:[function(e,t,n){function r(e,t,n){var r=e?e.length:0;if(!r)return-1;if("number"==typeof n)n=n<0?o(r+n,0):n;else if(n){var s=a(e,t);return s<r&&(t===t?t===e[s]:e[s]!==e[s])?s:-1}return i(e,t,n||0)}var i=e("../internal/baseIndexOf"),a=e("../internal/binaryIndex"),o=Math.max;t.exports=r},{"../internal/baseIndexOf":78,"../internal/binaryIndex":92}],50:[function(e,t,n){function r(e){var t=e?e.length:0;return t?e[t-1]:void 0}t.exports=r},{}],51:[function(e,t,n){function r(e){if(l(e)&&!s(e)&&!(e instanceof i)){if(e instanceof a)return e;if(p.call(e,"__chain__")&&p.call(e,"__wrapped__"))return u(e)}return new a(e)}var i=e("../internal/LazyWrapper"),a=e("../internal/LodashWrapper"),o=e("../internal/baseLodash"),s=e("../lang/isArray"),l=e("../internal/isObjectLike"),u=e("../internal/wrapperClone"),c=Object.prototype,p=c.hasOwnProperty;r.prototype=o.prototype,t.exports=r},{"../internal/LazyWrapper":60,"../internal/LodashWrapper":61,"../internal/baseLodash":82,"../internal/isObjectLike":126,"../internal/wrapperClone":137,"../lang/isArray":140}],52:[function(e,t,n){t.exports=e("./forEach")},{"./forEach":54}],53:[function(e,t,n){var r=e("../internal/baseEach"),i=e("../internal/createFind"),a=i(r);t.exports=a},{"../internal/baseEach":71,"../internal/createFind":102}],54:[function(e,t,n){var r=e("../internal/arrayEach"),i=e("../internal/baseEach"),a=e("../internal/createForEach"),o=a(r,i);t.exports=o},{"../internal/arrayEach":63,"../internal/baseEach":71,"../internal/createForEach":103}],55:[function(e,t,n){function r(e,t,n,r){var h=e?a(e):0;return l(h)||(e=c(e),h=e.length),n="number"!=typeof n||r&&s(t,n,r)?0:n<0?p(h+n,0):n||0,"string"==typeof e||!o(e)&&u(e)?n<=h&&e.indexOf(t,n)>-1:!!h&&i(e,t,n)>-1}var i=e("../internal/baseIndexOf"),a=e("../internal/getLength"),o=e("../lang/isArray"),s=e("../internal/isIterateeCall"),l=e("../internal/isLength"),u=e("../lang/isString"),c=e("../object/values"),p=Math.max;t.exports=r},{"../internal/baseIndexOf":78,"../internal/getLength":112,"../internal/isIterateeCall":122,"../internal/isLength":125,"../lang/isArray":140,"../lang/isString":146,"../object/values":152}],56:[function(e,t,n){function r(e,t,n){var r=s(e)?i:o;return t=a(t,n,3),r(e,t)}var i=e("../internal/arrayMap"),a=e("../internal/baseCallback"),o=e("../internal/baseMap"),s=e("../lang/isArray");t.exports=r},{"../internal/arrayMap":64,"../internal/baseCallback":67,"../internal/baseMap":83,"../lang/isArray":140}],57:[function(e,t,n){var r=e("../internal/getNative"),i=r(Date,"now"),a=i||function(){return(new Date).getTime()};t.exports=a},{"../internal/getNative":114}],58:[function(e,t,n){var r=e("../internal/createWrapper"),i=e("../internal/replaceHolders"),a=e("./restParam"),o=1,s=32,l=a(function(e,t,n){var a=o;if(n.length){var u=i(n,l.placeholder);a|=s}return r(e,a,t,n,u)});l.placeholder={},t.exports=l},{"../internal/createWrapper":106,"../internal/replaceHolders":132,"./restParam":59}],59:[function(e,t,n){function r(e,t){if("function"!=typeof e)throw new TypeError(i);return t=a(void 0===t?e.length-1:+t||0,0),function(){for(var n=arguments,r=-1,i=a(n.length-t,0),o=Array(i);++r<i;)o[r]=n[t+r];switch(t){case 0:return e.call(this,o);case 1:return e.call(this,n[0],o);case 2:return e.call(this,n[0],n[1],o)}var s=Array(t+1);for(r=-1;++r<t;)s[r]=n[r];return s[t]=o,e.apply(this,s)}}var i="Expected a function",a=Math.max;t.exports=r},{}],60:[function(e,t,n){function r(e){this.__wrapped__=e,this.__actions__=[],this.__dir__=1,this.__filtered__=!1,this.__iteratees__=[],this.__takeCount__=o,this.__views__=[]}var i=e("./baseCreate"),a=e("./baseLodash"),o=Number.POSITIVE_INFINITY;r.prototype=i(a.prototype),r.prototype.constructor=r,t.exports=r},{"./baseCreate":70,"./baseLodash":82}],61:[function(e,t,n){function r(e,t,n){this.__wrapped__=e,this.__actions__=n||[],this.__chain__=!!t}var i=e("./baseCreate"),a=e("./baseLodash");r.prototype=i(a.prototype),r.prototype.constructor=r,t.exports=r},{"./baseCreate":70,"./baseLodash":82}],62:[function(e,t,n){function r(e,t){var n=-1,r=e.length;for(t||(t=Array(r));++n<r;)t[n]=e[n];return t}t.exports=r},{}],63:[function(e,t,n){function r(e,t){for(var n=-1,r=e.length;++n<r&&t(e[n],n,e)!==!1;);return e}t.exports=r},{}],64:[function(e,t,n){function r(e,t){for(var n=-1,r=e.length,i=Array(r);++n<r;)i[n]=t(e[n],n,e);return i}t.exports=r},{}],65:[function(e,t,n){function r(e,t){for(var n=-1,r=e.length;++n<r;)if(t(e[n],n,e))return!0;return!1}t.exports=r},{}],66:[function(e,t,n){function r(e,t){return null==t?e:i(t,a(t),e)}var i=e("./baseCopy"),a=e("../object/keys");t.exports=r},{"../object/keys":149,"./baseCopy":69}],67:[function(e,t,n){function r(e,t,n){var r=typeof e;return"function"==r?void 0===t?e:o(e,t,n):null==e?s:"object"==r?i(e):void 0===t?l(e):a(e,t)}var i=e("./baseMatches"),a=e("./baseMatchesProperty"),o=e("./bindCallback"),s=e("../utility/identity"),l=e("../utility/property");t.exports=r},{"../utility/identity":154,"../utility/property":156,"./baseMatches":84,"./baseMatchesProperty":85,"./bindCallback":94}],68:[function(e,t,n){function r(e,t,n,m,g,y,v){var w;if(n&&(w=g?n(e,m,g):n(e)),void 0!==w)return w;if(!f(e))return e;var _=p(e);if(_){if(w=l(e),!t)return i(e,w)}else{var A=B.call(e),S=A==b;if(A!=x&&A!=d&&(!S||g))return P[A]?u(e,A,t):g?e:{};if(h(e))return g?e:{};if(w=c(S?{}:e),!t)return o(w,e)}y||(y=[]),v||(v=[]);for(var j=y.length;j--;)if(y[j]==e)return v[j];return y.push(e),v.push(w),(_?a:s)(e,function(i,a){w[a]=r(i,t,n,a,e,y,v)}),w}var i=e("./arrayCopy"),a=e("./arrayEach"),o=e("./baseAssign"),s=e("./baseForOwn"),l=e("./initCloneArray"),u=e("./initCloneByTag"),c=e("./initCloneObject"),p=e("../lang/isArray"),h=e("./isHostObject"),f=e("../lang/isObject"),d="[object Arguments]",m="[object Array]",g="[object Boolean]",y="[object Date]",v="[object Error]",b="[object Function]",w="[object Map]",_="[object Number]",x="[object Object]",A="[object RegExp]",S="[object Set]",j="[object String]",E="[object WeakMap]",O="[object ArrayBuffer]",k="[object Float32Array]",T="[object Float64Array]",C="[object Int8Array]",I="[object Int16Array]",D="[object Int32Array]",L="[object Uint8Array]",M="[object Uint8ClampedArray]",R="[object Uint16Array]",U="[object Uint32Array]",P={};P[d]=P[m]=P[O]=P[g]=P[y]=P[k]=P[T]=P[C]=P[I]=P[D]=P[_]=P[x]=P[A]=P[j]=P[L]=P[M]=P[R]=P[U]=!0,P[v]=P[b]=P[w]=P[S]=P[E]=!1;var q=Object.prototype,B=q.toString;t.exports=r},{"../lang/isArray":140,"../lang/isObject":144,"./arrayCopy":62,"./arrayEach":63,"./baseAssign":66,"./baseForOwn":76,"./initCloneArray":116,"./initCloneByTag":117,"./initCloneObject":118,"./isHostObject":120}],69:[function(e,t,n){function r(e,t,n){n||(n={});for(var r=-1,i=t.length;++r<i;){var a=t[r];n[a]=e[a]}return n}t.exports=r},{}],70:[function(e,t,n){var r=e("../lang/isObject"),i=function(){function e(){}return function(t){if(r(t)){e.prototype=t;var n=new e;e.prototype=void 0}return n||{}}}();t.exports=i},{"../lang/isObject":144}],71:[function(e,t,n){var r=e("./baseForOwn"),i=e("./createBaseEach"),a=i(r);t.exports=a},{"./baseForOwn":76,"./createBaseEach":98}],72:[function(e,t,n){function r(e,t,n,r){var i;return n(e,function(e,n,a){if(t(e,n,a))return i=r?n:e,!1}),i}t.exports=r},{}],73:[function(e,t,n){function r(e,t,n){for(var r=e.length,i=n?r:-1;n?i--:++i<r;)if(t(e[i],i,e))return i;return-1}t.exports=r},{}],74:[function(e,t,n){var r=e("./createBaseFor"),i=r();t.exports=i},{"./createBaseFor":99}],75:[function(e,t,n){function r(e,t){return i(e,t,a)}var i=e("./baseFor"),a=e("../object/keysIn");t.exports=r},{"../object/keysIn":150,"./baseFor":74}],76:[function(e,t,n){function r(e,t){return i(e,t,a)}var i=e("./baseFor"),a=e("../object/keys");t.exports=r},{"../object/keys":149,"./baseFor":74}],77:[function(e,t,n){function r(e,t,n){if(null!=e){e=i(e),void 0!==n&&n in e&&(t=[n]);for(var r=0,a=t.length;null!=e&&r<a;)e=i(e)[t[r++]];return r&&r==a?e:void 0}}var i=e("./toObject");t.exports=r},{"./toObject":135}],78:[function(e,t,n){function r(e,t,n){if(t!==t)return i(e,n);for(var r=n-1,a=e.length;++r<a;)if(e[r]===t)return r;return-1}var i=e("./indexOfNaN");t.exports=r},{"./indexOfNaN":115}],79:[function(e,t,n){function r(e,t,n,s,l,u){return e===t||(null==e||null==t||!a(e)&&!o(t)?e!==e&&t!==t:i(e,t,r,n,s,l,u))}var i=e("./baseIsEqualDeep"),a=e("../lang/isObject"),o=e("./isObjectLike");t.exports=r},{"../lang/isObject":144,"./baseIsEqualDeep":80,"./isObjectLike":126}],80:[function(e,t,n){function r(e,t,n,r,f,g,y){var v=s(e),b=s(t),w=p,_=p;v||(w=m.call(e),w==c?w=h:w!=h&&(v=u(e))),b||(_=m.call(t),_==c?_=h:_!=h&&(b=u(t)));var x=w==h&&!l(e),A=_==h&&!l(t),S=w==_;if(S&&!v&&!x)return a(e,t,w);if(!f){var j=x&&d.call(e,"__wrapped__"),E=A&&d.call(t,"__wrapped__");if(j||E)return n(j?e.value():e,E?t.value():t,r,f,g,y)}if(!S)return!1;g||(g=[]),y||(y=[]);for(var O=g.length;O--;)if(g[O]==e)return y[O]==t;g.push(e),y.push(t);var k=(v?i:o)(e,t,n,r,f,g,y);return g.pop(),y.pop(),k}var i=e("./equalArrays"),a=e("./equalByTag"),o=e("./equalObjects"),s=e("../lang/isArray"),l=e("./isHostObject"),u=e("../lang/isTypedArray"),c="[object Arguments]",p="[object Array]",h="[object Object]",f=Object.prototype,d=f.hasOwnProperty,m=f.toString;t.exports=r},{"../lang/isArray":140,"../lang/isTypedArray":147,"./equalArrays":107,"./equalByTag":108,"./equalObjects":109,"./isHostObject":120}],81:[function(e,t,n){function r(e,t,n){var r=t.length,o=r,s=!n;if(null==e)return!o;for(e=a(e);r--;){var l=t[r];if(s&&l[2]?l[1]!==e[l[0]]:!(l[0]in e))return!1}for(;++r<o;){l=t[r];var u=l[0],c=e[u],p=l[1];if(s&&l[2]){if(void 0===c&&!(u in e))return!1}else{var h=n?n(c,p,u):void 0;if(!(void 0===h?i(p,c,n,!0):h))return!1}}return!0}var i=e("./baseIsEqual"),a=e("./toObject");t.exports=r},{"./baseIsEqual":79,"./toObject":135}],82:[function(e,t,n){function r(){}t.exports=r},{}],83:[function(e,t,n){function r(e,t){var n=-1,r=a(e)?Array(e.length):[];return i(e,function(e,i,a){r[++n]=t(e,i,a)}),r}var i=e("./baseEach"),a=e("./isArrayLike");t.exports=r},{"./baseEach":71,"./isArrayLike":119}],84:[function(e,t,n){function r(e){var t=a(e);if(1==t.length&&t[0][2]){var n=t[0][0],r=t[0][1];return function(e){return null!=e&&(e=o(e),e[n]===r&&(void 0!==r||n in e))}}return function(e){return i(e,t)}}var i=e("./baseIsMatch"),a=e("./getMatchData"),o=e("./toObject");t.exports=r},{"./baseIsMatch":81,"./getMatchData":113,"./toObject":135}],85:[function(e,t,n){function r(e,t){var n=s(e),r=l(e)&&u(t),f=e+"";return e=h(e),function(s){if(null==s)return!1;var l=f;if(s=p(s),(n||!r)&&!(l in s)){if(s=1==e.length?s:i(s,o(e,0,-1)),null==s)return!1;l=c(e),s=p(s)}return s[l]===t?void 0!==t||l in s:a(t,s[l],void 0,!0)}}var i=e("./baseGet"),a=e("./baseIsEqual"),o=e("./baseSlice"),s=e("../lang/isArray"),l=e("./isKey"),u=e("./isStrictComparable"),c=e("../array/last"),p=e("./toObject"),h=e("./toPath");t.exports=r},{"../array/last":50,"../lang/isArray":140,"./baseGet":77,"./baseIsEqual":79,"./baseSlice":89,"./isKey":123,"./isStrictComparable":127,"./toObject":135,"./toPath":136}],86:[function(e,t,n){function r(e){return function(t){return null==t?void 0:i(t)[e]}}var i=e("./toObject");t.exports=r},{"./toObject":135}],87:[function(e,t,n){function r(e){var t=e+"";return e=a(e),function(n){return i(n,e,t)}}var i=e("./baseGet"),a=e("./toPath");t.exports=r},{"./baseGet":77,"./toPath":136}],88:[function(e,t,n){var r=e("../utility/identity"),i=e("./metaMap"),a=i?function(e,t){return i.set(e,t),e}:r;t.exports=a},{"../utility/identity":154,"./metaMap":129}],89:[function(e,t,n){function r(e,t,n){var r=-1,i=e.length;t=null==t?0:+t||0,t<0&&(t=-t>i?0:i+t),n=void 0===n||n>i?i:+n||0,n<0&&(n+=i),i=t>n?0:n-t>>>0,t>>>=0;for(var a=Array(i);++r<i;)a[r]=e[r+t];return a}t.exports=r},{}],90:[function(e,t,n){function r(e){return null==e?"":e+""}t.exports=r},{}],91:[function(e,t,n){function r(e,t){for(var n=-1,r=t.length,i=Array(r);++n<r;)i[n]=e[t[n]];return i}t.exports=r},{}],92:[function(e,t,n){function r(e,t,n){var r=0,o=e?e.length:r;if("number"==typeof t&&t===t&&o<=s){for(;r<o;){var l=r+o>>>1,u=e[l];(n?u<=t:u<t)&&null!==u?r=l+1:o=l}return o}return i(e,t,a,n)}var i=e("./binaryIndexBy"),a=e("../utility/identity"),o=4294967295,s=o>>>1;t.exports=r},{"../utility/identity":154,"./binaryIndexBy":93}],93:[function(e,t,n){function r(e,t,n,r){t=n(t);for(var o=0,l=e?e.length:0,u=t!==t,c=null===t,p=void 0===t;o<l;){var h=i((o+l)/2),f=n(e[h]),d=void 0!==f,m=f===f;if(u)var g=m||r;else g=c?m&&d&&(r||null!=f):p?m&&(r||d):null!=f&&(r?f<=t:f<t);g?o=h+1:l=h}return a(l,s)}var i=Math.floor,a=Math.min,o=4294967295,s=o-1;t.exports=r},{}],94:[function(e,t,n){function r(e,t,n){if("function"!=typeof e)return i;if(void 0===t)return e;switch(n){case 1:return function(n){return e.call(t,n)};case 3:return function(n,r,i){return e.call(t,n,r,i)};case 4:return function(n,r,i,a){return e.call(t,n,r,i,a)};case 5:return function(n,r,i,a,o){return e.call(t,n,r,i,a,o)}}return function(){return e.apply(t,arguments)}}var i=e("../utility/identity");t.exports=r},{"../utility/identity":154}],95:[function(e,t,n){(function(e){function n(e){var t=new r(e.byteLength),n=new i(t);return n.set(new i(e)),t}var r=e.ArrayBuffer,i=e.Uint8Array;t.exports=n}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],96:[function(e,t,n){function r(e,t,n){for(var r=n.length,a=-1,o=i(e.length-r,0),s=-1,l=t.length,u=Array(l+o);++s<l;)u[s]=t[s];for(;++a<r;)u[n[a]]=e[a];for(;o--;)u[s++]=e[a++];return u}var i=Math.max;t.exports=r},{}],97:[function(e,t,n){function r(e,t,n){for(var r=-1,a=n.length,o=-1,s=i(e.length-a,0),l=-1,u=t.length,c=Array(s+u);++o<s;)c[o]=e[o];for(var p=o;++l<u;)c[p+l]=t[l];for(;++r<a;)c[p+n[r]]=e[o++];return c}var i=Math.max;t.exports=r},{}],98:[function(e,t,n){function r(e,t){return function(n,r){var s=n?i(n):0;if(!a(s))return e(n,r);for(var l=t?s:-1,u=o(n);(t?l--:++l<s)&&r(u[l],l,u)!==!1;);return n}}var i=e("./getLength"),a=e("./isLength"),o=e("./toObject");t.exports=r},{"./getLength":112,"./isLength":125,"./toObject":135}],99:[function(e,t,n){function r(e){return function(t,n,r){for(var a=i(t),o=r(t),s=o.length,l=e?s:-1;e?l--:++l<s;){var u=o[l];if(n(a[u],u,a)===!1)break}return t}}var i=e("./toObject");t.exports=r},{"./toObject":135}],100:[function(e,t,n){(function(n){function r(e,t){function r(){var i=this&&this!==n&&this instanceof r?a:e;return i.apply(t,arguments)}var a=i(e);return r}var i=e("./createCtorWrapper");t.exports=r}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./createCtorWrapper":101}],101:[function(e,t,n){function r(e){return function(){var t=arguments;switch(t.length){case 0:return new e;case 1:return new e(t[0]);case 2:return new e(t[0],t[1]);case 3:return new e(t[0],t[1],t[2]);case 4:return new e(t[0],t[1],t[2],t[3]);case 5:return new e(t[0],t[1],t[2],t[3],t[4]);case 6:return new e(t[0],t[1],t[2],t[3],t[4],t[5]);case 7:return new e(t[0],t[1],t[2],t[3],t[4],t[5],t[6])}var n=i(e.prototype),r=e.apply(n,t);return a(r)?r:n}}var i=e("./baseCreate"),a=e("../lang/isObject");t.exports=r},{"../lang/isObject":144,"./baseCreate":70}],102:[function(e,t,n){function r(e,t){return function(n,r,l){if(r=i(r,l,3),s(n)){var u=o(n,r,t);return u>-1?n[u]:void 0}return a(n,r,e)}}var i=e("./baseCallback"),a=e("./baseFind"),o=e("./baseFindIndex"),s=e("../lang/isArray");t.exports=r},{"../lang/isArray":140,"./baseCallback":67,"./baseFind":72,"./baseFindIndex":73}],103:[function(e,t,n){function r(e,t){return function(n,r,o){return"function"==typeof r&&void 0===o&&a(n)?e(n,r):t(n,i(r,o,3))}}var i=e("./bindCallback"),a=e("../lang/isArray");t.exports=r},{"../lang/isArray":140,"./bindCallback":94}],104:[function(e,t,n){(function(n){function r(e,t,_,x,A,S,j,E,O,k){function T(){for(var d=arguments.length,m=d,g=Array(d);m--;)g[m]=arguments[m];if(x&&(g=a(g,x,A)),S&&(g=o(g,S,j)),L||R){var b=T.placeholder,P=c(g,b);if(d-=P.length,d<k){var q=E?i(E):void 0,B=w(k-d,0),z=L?P:void 0,N=L?void 0:P,$=L?g:void 0,F=L?void 0:g;t|=L?y:v,t&=~(L?v:y),M||(t&=~(h|f));var V=[e,t,_,$,z,F,N,q,O,B],H=r.apply(void 0,V);return l(e)&&p(H,V),H.placeholder=b,H}}var Y=I?_:this,J=D?Y[e]:e;return E&&(g=u(g,E)),C&&O<g.length&&(g.length=O),this&&this!==n&&this instanceof T&&(J=U||s(e)),J.apply(Y,g)}var C=t&b,I=t&h,D=t&f,L=t&m,M=t&d,R=t&g,U=D?void 0:s(e);return T}var i=e("./arrayCopy"),a=e("./composeArgs"),o=e("./composeArgsRight"),s=e("./createCtorWrapper"),l=e("./isLaziable"),u=e("./reorder"),c=e("./replaceHolders"),p=e("./setData"),h=1,f=2,d=4,m=8,g=16,y=32,v=64,b=128,w=Math.max;t.exports=r}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./arrayCopy":62,"./composeArgs":96,"./composeArgsRight":97,"./createCtorWrapper":101,"./isLaziable":124,"./reorder":131,"./replaceHolders":132,"./setData":133}],105:[function(e,t,n){(function(n){function r(e,t,r,o){function s(){for(var t=-1,i=arguments.length,a=-1,c=o.length,p=Array(c+i);++a<c;)p[a]=o[a];for(;i--;)p[a++]=arguments[++t];var h=this&&this!==n&&this instanceof s?u:e;return h.apply(l?r:this,p)}var l=t&a,u=i(e);return s}var i=e("./createCtorWrapper"),a=1;t.exports=r}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./createCtorWrapper":101}],106:[function(e,t,n){function r(e,t,n,r,y,v,b,w){var _=t&h;if(!_&&"function"!=typeof e)throw new TypeError(m);var x=r?r.length:0;if(x||(t&=~(f|d),r=y=void 0),x-=y?y.length:0,t&d){var A=r,S=y;r=y=void 0}var j=_?void 0:l(e),E=[e,t,n,r,y,A,S,v,b,w];if(j&&(u(E,j),t=E[1],w=E[9]),E[9]=null==w?_?0:e.length:g(w-x,0)||0,t==p)var O=a(E[0],E[2]);else O=t!=f&&t!=(p|f)||E[4].length?o.apply(void 0,E):s.apply(void 0,E);var k=j?i:c;return k(O,E)}var i=e("./baseSetData"),a=e("./createBindWrapper"),o=e("./createHybridWrapper"),s=e("./createPartialWrapper"),l=e("./getData"),u=e("./mergeData"),c=e("./setData"),p=1,h=2,f=32,d=64,m="Expected a function",g=Math.max;t.exports=r},{"./baseSetData":88,"./createBindWrapper":100,"./createHybridWrapper":104,"./createPartialWrapper":105,"./getData":110,"./mergeData":128,"./setData":133}],107:[function(e,t,n){function r(e,t,n,r,a,o,s){var l=-1,u=e.length,c=t.length;if(u!=c&&!(a&&c>u))return!1;for(;++l<u;){var p=e[l],h=t[l],f=r?r(a?h:p,a?p:h,l):void 0;if(void 0!==f){if(f)continue;return!1}if(a){
+if(!i(t,function(e){return p===e||n(p,e,r,a,o,s)}))return!1}else if(p!==h&&!n(p,h,r,a,o,s))return!1}return!0}var i=e("./arraySome");t.exports=r},{"./arraySome":65}],108:[function(e,t,n){function r(e,t,n){switch(n){case i:case a:return+e==+t;case o:return e.name==t.name&&e.message==t.message;case s:return e!=+e?t!=+t:e==+t;case l:case u:return e==t+""}return!1}var i="[object Boolean]",a="[object Date]",o="[object Error]",s="[object Number]",l="[object RegExp]",u="[object String]";t.exports=r},{}],109:[function(e,t,n){function r(e,t,n,r,a,s,l){var u=i(e),c=u.length,p=i(t),h=p.length;if(c!=h&&!a)return!1;for(var f=c;f--;){var d=u[f];if(!(a?d in t:o.call(t,d)))return!1}for(var m=a;++f<c;){d=u[f];var g=e[d],y=t[d],v=r?r(a?y:g,a?g:y,d):void 0;if(!(void 0===v?n(g,y,r,a,s,l):v))return!1;m||(m="constructor"==d)}if(!m){var b=e.constructor,w=t.constructor;if(b!=w&&"constructor"in e&&"constructor"in t&&!("function"==typeof b&&b instanceof b&&"function"==typeof w&&w instanceof w))return!1}return!0}var i=e("../object/keys"),a=Object.prototype,o=a.hasOwnProperty;t.exports=r},{"../object/keys":149}],110:[function(e,t,n){var r=e("./metaMap"),i=e("../utility/noop"),a=r?function(e){return r.get(e)}:i;t.exports=a},{"../utility/noop":155,"./metaMap":129}],111:[function(e,t,n){function r(e){for(var t=e.name+"",n=i[t],r=n?n.length:0;r--;){var a=n[r],o=a.func;if(null==o||o==e)return a.name}return t}var i=e("./realNames");t.exports=r},{"./realNames":130}],112:[function(e,t,n){var r=e("./baseProperty"),i=r("length");t.exports=i},{"./baseProperty":86}],113:[function(e,t,n){function r(e){for(var t=a(e),n=t.length;n--;)t[n][2]=i(t[n][1]);return t}var i=e("./isStrictComparable"),a=e("../object/pairs");t.exports=r},{"../object/pairs":151,"./isStrictComparable":127}],114:[function(e,t,n){function r(e,t){var n=null==e?void 0:e[t];return i(n)?n:void 0}var i=e("../lang/isNative");t.exports=r},{"../lang/isNative":143}],115:[function(e,t,n){function r(e,t,n){for(var r=e.length,i=t+(n?0:-1);n?i--:++i<r;){var a=e[i];if(a!==a)return i}return-1}t.exports=r},{}],116:[function(e,t,n){function r(e){var t=e.length,n=new e.constructor(t);return t&&"string"==typeof e[0]&&a.call(e,"index")&&(n.index=e.index,n.input=e.input),n}var i=Object.prototype,a=i.hasOwnProperty;t.exports=r},{}],117:[function(e,t,n){(function(n){function r(e,t,n){var r=e.constructor;switch(t){case c:return i(e);case a:case o:return new r((+e));case p:case h:case f:case d:case m:case g:case y:case v:case b:r instanceof r&&(r=x[t]);var _=e.buffer;return new r(n?i(_):_,e.byteOffset,e.length);case s:case u:return new r(e);case l:var A=new r(e.source,w.exec(e));A.lastIndex=e.lastIndex}return A}var i=e("./bufferClone"),a="[object Boolean]",o="[object Date]",s="[object Number]",l="[object RegExp]",u="[object String]",c="[object ArrayBuffer]",p="[object Float32Array]",h="[object Float64Array]",f="[object Int8Array]",d="[object Int16Array]",m="[object Int32Array]",g="[object Uint8Array]",y="[object Uint8ClampedArray]",v="[object Uint16Array]",b="[object Uint32Array]",w=/\w*$/,_=n.Uint8Array,x={};x[p]=n.Float32Array,x[h]=n.Float64Array,x[f]=n.Int8Array,x[d]=n.Int16Array,x[m]=n.Int32Array,x[g]=_,x[y]=n.Uint8ClampedArray,x[v]=n.Uint16Array,x[b]=n.Uint32Array,t.exports=r}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./bufferClone":95}],118:[function(e,t,n){function r(e){var t=e.constructor;return"function"==typeof t&&t instanceof t||(t=Object),new t}t.exports=r},{}],119:[function(e,t,n){function r(e){return null!=e&&a(i(e))}var i=e("./getLength"),a=e("./isLength");t.exports=r},{"./getLength":112,"./isLength":125}],120:[function(e,t,n){var r=function(){try{Object({toString:0}+"")}catch(e){return function(){return!1}}return function(e){return"function"!=typeof e.toString&&"string"==typeof(e+"")}}();t.exports=r},{}],121:[function(e,t,n){function r(e,t){return e="number"==typeof e||i.test(e)?+e:-1,t=null==t?a:t,e>-1&&e%1==0&&e<t}var i=/^\d+$/,a=9007199254740991;t.exports=r},{}],122:[function(e,t,n){function r(e,t,n){if(!o(n))return!1;var r=typeof t;if("number"==r?i(n)&&a(t,n.length):"string"==r&&t in n){var s=n[t];return e===e?e===s:s!==s}return!1}var i=e("./isArrayLike"),a=e("./isIndex"),o=e("../lang/isObject");t.exports=r},{"../lang/isObject":144,"./isArrayLike":119,"./isIndex":121}],123:[function(e,t,n){function r(e,t){var n=typeof e;if("string"==n&&s.test(e)||"number"==n)return!0;if(i(e))return!1;var r=!o.test(e);return r||null!=t&&e in a(t)}var i=e("../lang/isArray"),a=e("./toObject"),o=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/,s=/^\w*$/;t.exports=r},{"../lang/isArray":140,"./toObject":135}],124:[function(e,t,n){function r(e){var t=o(e),n=s[t];if("function"!=typeof n||!(t in i.prototype))return!1;if(e===n)return!0;var r=a(n);return!!r&&e===r[0]}var i=e("./LazyWrapper"),a=e("./getData"),o=e("./getFuncName"),s=e("../chain/lodash");t.exports=r},{"../chain/lodash":51,"./LazyWrapper":60,"./getData":110,"./getFuncName":111}],125:[function(e,t,n){function r(e){return"number"==typeof e&&e>-1&&e%1==0&&e<=i}var i=9007199254740991;t.exports=r},{}],126:[function(e,t,n){function r(e){return!!e&&"object"==typeof e}t.exports=r},{}],127:[function(e,t,n){function r(e){return e===e&&!i(e)}var i=e("../lang/isObject");t.exports=r},{"../lang/isObject":144}],128:[function(e,t,n){function r(e,t){var n=e[1],r=t[1],m=n|r,g=m<p,y=r==p&&n==c||r==p&&n==h&&e[7].length<=t[8]||r==(p|h)&&n==c;if(!g&&!y)return e;r&l&&(e[2]=t[2],m|=n&l?0:u);var v=t[3];if(v){var b=e[3];e[3]=b?a(b,v,t[4]):i(v),e[4]=b?s(e[3],f):i(t[4])}return v=t[5],v&&(b=e[5],e[5]=b?o(b,v,t[6]):i(v),e[6]=b?s(e[5],f):i(t[6])),v=t[7],v&&(e[7]=i(v)),r&p&&(e[8]=null==e[8]?t[8]:d(e[8],t[8])),null==e[9]&&(e[9]=t[9]),e[0]=t[0],e[1]=m,e}var i=e("./arrayCopy"),a=e("./composeArgs"),o=e("./composeArgsRight"),s=e("./replaceHolders"),l=1,u=4,c=8,p=128,h=256,f="__lodash_placeholder__",d=Math.min;t.exports=r},{"./arrayCopy":62,"./composeArgs":96,"./composeArgsRight":97,"./replaceHolders":132}],129:[function(e,t,n){(function(n){var r=e("./getNative"),i=r(n,"WeakMap"),a=i&&new i;t.exports=a}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./getNative":114}],130:[function(e,t,n){var r={};t.exports=r},{}],131:[function(e,t,n){function r(e,t){for(var n=e.length,r=o(t.length,n),s=i(e);r--;){var l=t[r];e[r]=a(l,n)?s[l]:void 0}return e}var i=e("./arrayCopy"),a=e("./isIndex"),o=Math.min;t.exports=r},{"./arrayCopy":62,"./isIndex":121}],132:[function(e,t,n){function r(e,t){for(var n=-1,r=e.length,a=-1,o=[];++n<r;)e[n]===t&&(e[n]=i,o[++a]=n);return o}var i="__lodash_placeholder__";t.exports=r},{}],133:[function(e,t,n){var r=e("./baseSetData"),i=e("../date/now"),a=150,o=16,s=function(){var e=0,t=0;return function(n,s){var l=i(),u=o-(l-t);if(t=l,u>0){if(++e>=a)return n}else e=0;return r(n,s)}}();t.exports=s},{"../date/now":57,"./baseSetData":88}],134:[function(e,t,n){function r(e){for(var t=u(e),n=t.length,r=n&&e.length,c=!!r&&s(r)&&(a(e)||i(e)||l(e)),h=-1,f=[];++h<n;){var d=t[h];(c&&o(d,r)||p.call(e,d))&&f.push(d)}return f}var i=e("../lang/isArguments"),a=e("../lang/isArray"),o=e("./isIndex"),s=e("./isLength"),l=e("../lang/isString"),u=e("../object/keysIn"),c=Object.prototype,p=c.hasOwnProperty;t.exports=r},{"../lang/isArguments":139,"../lang/isArray":140,"../lang/isString":146,"../object/keysIn":150,"./isIndex":121,"./isLength":125}],135:[function(e,t,n){function r(e){if(o.unindexedChars&&a(e)){for(var t=-1,n=e.length,r=Object(e);++t<n;)r[t]=e.charAt(t);return r}return i(e)?e:Object(e)}var i=e("../lang/isObject"),a=e("../lang/isString"),o=e("../support");t.exports=r},{"../lang/isObject":144,"../lang/isString":146,"../support":153}],136:[function(e,t,n){function r(e){if(a(e))return e;var t=[];return i(e).replace(o,function(e,n,r,i){t.push(r?i.replace(s,"$1"):n||e)}),t}var i=e("./baseToString"),a=e("../lang/isArray"),o=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g,s=/\\(\\)?/g;t.exports=r},{"../lang/isArray":140,"./baseToString":90}],137:[function(e,t,n){function r(e){return e instanceof i?e.clone():new a(e.__wrapped__,e.__chain__,o(e.__actions__))}var i=e("./LazyWrapper"),a=e("./LodashWrapper"),o=e("./arrayCopy");t.exports=r},{"./LazyWrapper":60,"./LodashWrapper":61,"./arrayCopy":62}],138:[function(e,t,n){function r(e,t,n){return"function"==typeof t?i(e,!0,a(t,n,3)):i(e,!0)}var i=e("../internal/baseClone"),a=e("../internal/bindCallback");t.exports=r},{"../internal/baseClone":68,"../internal/bindCallback":94}],139:[function(e,t,n){function r(e){return a(e)&&i(e)&&s.call(e,"callee")&&!l.call(e,"callee")}var i=e("../internal/isArrayLike"),a=e("../internal/isObjectLike"),o=Object.prototype,s=o.hasOwnProperty,l=o.propertyIsEnumerable;t.exports=r},{"../internal/isArrayLike":119,"../internal/isObjectLike":126}],140:[function(e,t,n){var r=e("../internal/getNative"),i=e("../internal/isLength"),a=e("../internal/isObjectLike"),o="[object Array]",s=Object.prototype,l=s.toString,u=r(Array,"isArray"),c=u||function(e){return a(e)&&i(e.length)&&l.call(e)==o};t.exports=c},{"../internal/getNative":114,"../internal/isLength":125,"../internal/isObjectLike":126}],141:[function(e,t,n){function r(e){return null==e||(o(e)&&(a(e)||u(e)||i(e)||l(e)&&s(e.splice))?!e.length:!c(e).length)}var i=e("./isArguments"),a=e("./isArray"),o=e("../internal/isArrayLike"),s=e("./isFunction"),l=e("../internal/isObjectLike"),u=e("./isString"),c=e("../object/keys");t.exports=r},{"../internal/isArrayLike":119,"../internal/isObjectLike":126,"../object/keys":149,"./isArguments":139,"./isArray":140,"./isFunction":142,"./isString":146}],142:[function(e,t,n){function r(e){return i(e)&&s.call(e)==a}var i=e("./isObject"),a="[object Function]",o=Object.prototype,s=o.toString;t.exports=r},{"./isObject":144}],143:[function(e,t,n){function r(e){return null!=e&&(i(e)?p.test(u.call(e)):o(e)&&(a(e)?p:s).test(e))}var i=e("./isFunction"),a=e("../internal/isHostObject"),o=e("../internal/isObjectLike"),s=/^\[object .+?Constructor\]$/,l=Object.prototype,u=Function.prototype.toString,c=l.hasOwnProperty,p=RegExp("^"+u.call(c).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");t.exports=r},{"../internal/isHostObject":120,"../internal/isObjectLike":126,"./isFunction":142}],144:[function(e,t,n){function r(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}t.exports=r},{}],145:[function(e,t,n){function r(e){var t;if(!s(e)||h.call(e)!=u||o(e)||a(e)||!p.call(e,"constructor")&&(t=e.constructor,"function"==typeof t&&!(t instanceof t)))return!1;var n;return l.ownLast?(i(e,function(e,t,r){return n=p.call(r,t),!1}),n!==!1):(i(e,function(e,t){n=t}),void 0===n||p.call(e,n))}var i=e("../internal/baseForIn"),a=e("./isArguments"),o=e("../internal/isHostObject"),s=e("../internal/isObjectLike"),l=e("../support"),u="[object Object]",c=Object.prototype,p=c.hasOwnProperty,h=c.toString;t.exports=r},{"../internal/baseForIn":75,"../internal/isHostObject":120,"../internal/isObjectLike":126,"../support":153,"./isArguments":139}],146:[function(e,t,n){function r(e){return"string"==typeof e||i(e)&&s.call(e)==a}var i=e("../internal/isObjectLike"),a="[object String]",o=Object.prototype,s=o.toString;t.exports=r},{"../internal/isObjectLike":126}],147:[function(e,t,n){function r(e){return a(e)&&i(e.length)&&!!T[I.call(e)]}var i=e("../internal/isLength"),a=e("../internal/isObjectLike"),o="[object Arguments]",s="[object Array]",l="[object Boolean]",u="[object Date]",c="[object Error]",p="[object Function]",h="[object Map]",f="[object Number]",d="[object Object]",m="[object RegExp]",g="[object Set]",y="[object String]",v="[object WeakMap]",b="[object ArrayBuffer]",w="[object Float32Array]",_="[object Float64Array]",x="[object Int8Array]",A="[object Int16Array]",S="[object Int32Array]",j="[object Uint8Array]",E="[object Uint8ClampedArray]",O="[object Uint16Array]",k="[object Uint32Array]",T={};T[w]=T[_]=T[x]=T[A]=T[S]=T[j]=T[E]=T[O]=T[k]=!0,T[o]=T[s]=T[b]=T[l]=T[u]=T[c]=T[p]=T[h]=T[f]=T[d]=T[m]=T[g]=T[y]=T[v]=!1;var C=Object.prototype,I=C.toString;t.exports=r},{"../internal/isLength":125,"../internal/isObjectLike":126}],148:[function(e,t,n){function r(e){return void 0===e}t.exports=r},{}],149:[function(e,t,n){var r=e("../internal/getNative"),i=e("../internal/isArrayLike"),a=e("../lang/isObject"),o=e("../internal/shimKeys"),s=e("../support"),l=r(Object,"keys"),u=l?function(e){var t=null==e?void 0:e.constructor;return"function"==typeof t&&t.prototype===e||("function"==typeof e?s.enumPrototypes:i(e))?o(e):a(e)?l(e):[]}:o;t.exports=u},{"../internal/getNative":114,"../internal/isArrayLike":119,"../internal/shimKeys":134,"../lang/isObject":144,"../support":153}],150:[function(e,t,n){function r(e){if(null==e)return[];c(e)||(e=Object(e));var t=e.length;t=t&&u(t)&&(o(e)||a(e)||p(e))&&t||0;for(var n=e.constructor,r=-1,i=s(n)&&n.prototype||S,f=i===e,d=Array(t),m=t>0,y=h.enumErrorProps&&(e===A||e instanceof Error),v=h.enumPrototypes&&s(e);++r<t;)d[r]=r+"";for(var w in e)v&&"prototype"==w||y&&("message"==w||"name"==w)||m&&l(w,t)||"constructor"==w&&(f||!E.call(e,w))||d.push(w);if(h.nonEnumShadows&&e!==S){var T=e===j?_:e===A?g:O.call(e),C=k[T]||k[b];for(T==b&&(i=S),t=x.length;t--;){w=x[t];var I=C[w];f&&I||(I?!E.call(e,w):e[w]===i[w])||d.push(w)}}return d}var i=e("../internal/arrayEach"),a=e("../lang/isArguments"),o=e("../lang/isArray"),s=e("../lang/isFunction"),l=e("../internal/isIndex"),u=e("../internal/isLength"),c=e("../lang/isObject"),p=e("../lang/isString"),h=e("../support"),f="[object Array]",d="[object Boolean]",m="[object Date]",g="[object Error]",y="[object Function]",v="[object Number]",b="[object Object]",w="[object RegExp]",_="[object String]",x=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"],A=Error.prototype,S=Object.prototype,j=String.prototype,E=S.hasOwnProperty,O=S.toString,k={};k[f]=k[m]=k[v]={constructor:!0,toLocaleString:!0,toString:!0,valueOf:!0},k[d]=k[_]={constructor:!0,toString:!0,valueOf:!0},k[g]=k[y]=k[w]={constructor:!0,toString:!0},k[b]={constructor:!0},i(x,function(e){for(var t in k)if(E.call(k,t)){var n=k[t];n[e]=E.call(n,e)}}),t.exports=r},{"../internal/arrayEach":63,"../internal/isIndex":121,"../internal/isLength":125,"../lang/isArguments":139,"../lang/isArray":140,"../lang/isFunction":142,"../lang/isObject":144,"../lang/isString":146,"../support":153}],151:[function(e,t,n){function r(e){e=a(e);for(var t=-1,n=i(e),r=n.length,o=Array(r);++t<r;){var s=n[t];o[t]=[s,e[s]]}return o}var i=e("./keys"),a=e("../internal/toObject");t.exports=r},{"../internal/toObject":135,"./keys":149}],152:[function(e,t,n){function r(e){return i(e,a(e))}var i=e("../internal/baseValues"),a=e("./keys");t.exports=r},{"../internal/baseValues":91,"./keys":149}],153:[function(e,t,n){var r=Array.prototype,i=Error.prototype,a=Object.prototype,o=a.propertyIsEnumerable,s=r.splice,l={};!function(e){var t=function(){this.x=e},n={0:e,length:e},r=[];t.prototype={valueOf:e,y:e};for(var a in new t)r.push(a);l.enumErrorProps=o.call(i,"message")||o.call(i,"name"),l.enumPrototypes=o.call(t,"prototype"),l.nonEnumShadows=!/valueOf/.test(r),l.ownLast="x"!=r[0],l.spliceObjects=(s.call(n,0,1),!n[0]),l.unindexedChars="x"[0]+Object("x")[0]!="xx"}(1,0),t.exports=l},{}],154:[function(e,t,n){function r(e){return e}t.exports=r},{}],155:[function(e,t,n){function r(){}t.exports=r},{}],156:[function(e,t,n){function r(e){return o(e)?i(e):a(e)}var i=e("../internal/baseProperty"),a=e("../internal/basePropertyDeep"),o=e("../internal/isKey");t.exports=r},{"../internal/baseProperty":86,"../internal/basePropertyDeep":87,"../internal/isKey":123}],157:[function(e,n,r){(function(e){!function(e){"use strict";if("function"==typeof bootstrap)bootstrap("promise",e);else if("object"==typeof r&&"object"==typeof n)n.exports=e();else if("function"==typeof t&&t.amd)t(e);else if("undefined"!=typeof ses){if(!ses.ok())return;ses.makeQ=e}else{if("undefined"==typeof window&&"undefined"==typeof self)throw new Error("This environment was not anticipated by Q. Please file a bug.");var i="undefined"!=typeof window?window:self,a=i.Q;i.Q=e(),i.Q.noConflict=function(){return i.Q=a,this}}}(function(){"use strict";function t(e){return function(){return Q.apply(e,arguments)}}function n(e){return e===Object(e)}function r(e){return"[object StopIteration]"===re(e)||e instanceof H}function i(e,t){if($&&t.stack&&"object"==typeof e&&null!==e&&e.stack&&e.stack.indexOf(ie)===-1){for(var n=[],r=t;r;r=r.source)r.stack&&n.unshift(r.stack);n.unshift(e.stack);var i=n.join("\n"+ie+"\n");e.stack=a(i)}}function a(e){for(var t=e.split("\n"),n=[],r=0;r<t.length;++r){var i=t[r];l(i)||o(i)||!i||n.push(i)}return n.join("\n")}function o(e){return e.indexOf("(module.js:")!==-1||e.indexOf("(node.js:")!==-1}function s(e){var t=/at .+ \((.+):(\d+):(?:\d+)\)$/.exec(e);if(t)return[t[1],Number(t[2])];var n=/at ([^ ]+):(\d+):(?:\d+)$/.exec(e);if(n)return[n[1],Number(n[2])];var r=/.*@(.+):(\d+)$/.exec(e);return r?[r[1],Number(r[2])]:void 0}function l(e){var t=s(e);if(!t)return!1;var n=t[0],r=t[1];return n===V&&r>=Y&&r<=ue}function u(){if($)try{throw new Error}catch(e){var t=e.stack.split("\n"),n=t[0].indexOf("@")>0?t[1]:t[2],r=s(n);if(!r)return;return V=r[0],r[1]}}function c(e,t,n){return function(){return"undefined"!=typeof console&&"function"==typeof console.warn&&console.warn(t+" is deprecated, use "+n+" instead.",new Error("").stack),e.apply(e,arguments)}}function p(e){return e instanceof m?e:b(e)?k(e):O(e)}function h(){function e(e){t=e,a.source=e,K(n,function(t,n){p.nextTick(function(){e.promiseDispatch.apply(e,n)})},void 0),n=void 0,r=void 0}var t,n=[],r=[],i=ee(h.prototype),a=ee(m.prototype);if(a.promiseDispatch=function(e,i,a){var o=G(arguments);n?(n.push(o),"when"===i&&a[1]&&r.push(a[1])):p.nextTick(function(){t.promiseDispatch.apply(t,o)})},a.valueOf=function(){if(n)return a;var e=y(t);return v(e)&&(t=e),e},a.inspect=function(){return t?t.inspect():{state:"pending"}},p.longStackSupport&&$)try{throw new Error}catch(o){a.stack=o.stack.substring(o.stack.indexOf("\n")+1)}return i.promise=a,i.resolve=function(n){t||e(p(n))},i.fulfill=function(n){t||e(O(n))},i.reject=function(n){t||e(E(n))},i.notify=function(e){t||K(r,function(t,n){p.nextTick(function(){n(e)})},void 0)},i}function f(e){if("function"!=typeof e)throw new TypeError("resolver must be a function.");var t=h();try{e(t.resolve,t.reject,t.notify)}catch(n){t.reject(n)}return t.promise}function d(e){return f(function(t,n){for(var r=0,i=e.length;r<i;r++)p(e[r]).then(t,n)})}function m(e,t,n){void 0===t&&(t=function(e){return E(new Error("Promise does not support operation: "+e))}),void 0===n&&(n=function(){return{state:"unknown"}});var r=ee(m.prototype);if(r.promiseDispatch=function(n,i,a){var o;try{o=e[i]?e[i].apply(r,a):t.call(r,i,a)}catch(s){o=E(s)}n&&n(o)},r.inspect=n,n){var i=n();"rejected"===i.state&&(r.exception=i.reason),r.valueOf=function(){var e=n();return"pending"===e.state||"rejected"===e.state?r:e.value}}return r}function g(e,t,n,r){return p(e).then(t,n,r)}function y(e){if(v(e)){var t=e.inspect();if("fulfilled"===t.state)return t.value}return e}function v(e){return e instanceof m}function b(e){return n(e)&&"function"==typeof e.then}function w(e){return v(e)&&"pending"===e.inspect().state}function _(e){return!v(e)||"fulfilled"===e.inspect().state}function x(e){return v(e)&&"rejected"===e.inspect().state}function A(){ae.length=0,oe.length=0,le||(le=!0)}function S(t,n){le&&("object"==typeof e&&"function"==typeof e.emit&&p.nextTick.runAfter(function(){X(oe,t)!==-1&&(e.emit("unhandledRejection",n,t),se.push(t))}),oe.push(t),n&&"undefined"!=typeof n.stack?ae.push(n.stack):ae.push("(no stack) "+n))}function j(t){if(le){var n=X(oe,t);n!==-1&&("object"==typeof e&&"function"==typeof e.emit&&p.nextTick.runAfter(function(){var r=X(se,t);r!==-1&&(e.emit("rejectionHandled",ae[n],t),se.splice(r,1))}),oe.splice(n,1),ae.splice(n,1))}}function E(e){var t=m({when:function(t){return t&&j(this),t?t(e):this}},function(){return this},function(){return{state:"rejected",reason:e}});return S(t,e),t}function O(e){return m({when:function(){return e},get:function(t){return e[t]},set:function(t,n){e[t]=n},"delete":function(t){delete e[t]},post:function(t,n){return null===t||void 0===t?e.apply(void 0,n):e[t].apply(e,n)},apply:function(t,n){return e.apply(t,n)},keys:function(){return ne(e)}},void 0,function(){return{state:"fulfilled",value:e}})}function k(e){var t=h();return p.nextTick(function(){try{e.then(t.resolve,t.reject,t.notify)}catch(n){t.reject(n)}}),t.promise}function T(e){return m({isDef:function(){}},function(t,n){return R(e,t,n)},function(){return p(e).inspect()})}function C(e,t,n){return p(e).spread(t,n)}function I(e){return function(){function t(e,t){var o;if("undefined"==typeof StopIteration){try{o=n[e](t)}catch(s){return E(s)}return o.done?p(o.value):g(o.value,i,a)}try{o=n[e](t)}catch(s){return r(s)?p(s.value):E(s)}return g(o,i,a)}var n=e.apply(this,arguments),i=t.bind(t,"next"),a=t.bind(t,"throw");return i()}}function D(e){p.done(p.async(e)())}function L(e){throw new H(e)}function M(e){return function(){return C([this,U(arguments)],function(t,n){return e.apply(t,n)})}}function R(e,t,n){return p(e).dispatch(t,n)}function U(e){return g(e,function(e){var t=0,n=h();return K(e,function(r,i,a){var o;v(i)&&"fulfilled"===(o=i.inspect()).state?e[a]=o.value:(++t,g(i,function(r){e[a]=r,0===--t&&n.resolve(e)},n.reject,function(e){n.notify({index:a,value:e})}))},void 0),0===t&&n.resolve(e),n.promise})}function P(e){if(0===e.length)return p.resolve();var t=p.defer(),n=0;return K(e,function(r,i,a){function o(e){t.resolve(e)}function s(){n--,0===n&&t.reject(new Error("Can't get fulfillment value from any promise, all promises were rejected."))}function l(e){t.notify({index:a,value:e})}var u=e[a];n++,g(u,o,s,l)},void 0),t.promise}function q(e){return g(e,function(e){return e=Z(e,p),g(U(Z(e,function(e){return g(e,J,J)})),function(){return e})})}function B(e){return p(e).allSettled()}function z(e,t){return p(e).then(void 0,void 0,t)}function N(e,t){return p(e).nodeify(t)}var $=!1;try{throw new Error}catch(F){$=!!F.stack}var V,H,Y=u(),J=function(){},W=function(){function t(){for(var e,t;r.next;)r=r.next,e=r.task,r.task=void 0,t=r.domain,t&&(r.domain=void 0,t.enter()),n(e,t);for(;l.length;)e=l.pop(),n(e);a=!1}function n(e,n){try{e()}catch(r){if(s)throw n&&n.exit(),setTimeout(t,0),n&&n.enter(),r;setTimeout(function(){throw r},0)}n&&n.exit()}var r={task:void 0,next:null},i=r,a=!1,o=void 0,s=!1,l=[];if(W=function(t){i=i.next={task:t,domain:s&&e.domain,next:null},a||(a=!0,o())},"object"==typeof e&&"[object process]"===e.toString()&&e.nextTick)s=!0,o=function(){e.nextTick(t)};else if("function"==typeof setImmediate)o="undefined"!=typeof window?setImmediate.bind(window,t):function(){setImmediate(t)};else if("undefined"!=typeof MessageChannel){var u=new MessageChannel;u.port1.onmessage=function(){o=c,u.port1.onmessage=t,t()};var c=function(){u.port2.postMessage(0)};o=function(){setTimeout(t,0),c()}}else o=function(){setTimeout(t,0)};return W.runAfter=function(e){l.push(e),a||(a=!0,o())},W}(),Q=Function.call,G=t(Array.prototype.slice),K=t(Array.prototype.reduce||function(e,t){var n=0,r=this.length;if(1===arguments.length)for(;;){if(n in this){t=this[n++];break}if(++n>=r)throw new TypeError}for(;n<r;n++)n in this&&(t=e(t,this[n],n));return t}),X=t(Array.prototype.indexOf||function(e){for(var t=0;t<this.length;t++)if(this[t]===e)return t;return-1}),Z=t(Array.prototype.map||function(e,t){var n=this,r=[];return K(n,function(i,a,o){r.push(e.call(t,a,o,n))},void 0),r}),ee=Object.create||function(e){function t(){}return t.prototype=e,new t},te=t(Object.prototype.hasOwnProperty),ne=Object.keys||function(e){var t=[];for(var n in e)te(e,n)&&t.push(n);return t},re=t(Object.prototype.toString);H="undefined"!=typeof ReturnValue?ReturnValue:function(e){this.value=e};var ie="From previous event:";p.resolve=p,p.nextTick=W,p.longStackSupport=!1,"object"==typeof e&&e&&e.env&&e.env.Q_DEBUG&&(p.longStackSupport=!0),p.defer=h,h.prototype.makeNodeResolver=function(){var e=this;return function(t,n){t?e.reject(t):arguments.length>2?e.resolve(G(arguments,1)):e.resolve(n)}},p.Promise=f,p.promise=f,f.race=d,f.all=U,f.reject=E,f.resolve=p,p.passByCopy=function(e){return e},m.prototype.passByCopy=function(){return this},p.join=function(e,t){return p(e).join(t)},m.prototype.join=function(e){return p([this,e]).spread(function(e,t){if(e===t)return e;throw new Error("Can't join: not the same: "+e+" "+t)})},p.race=d,m.prototype.race=function(){return this.then(p.race)},p.makePromise=m,m.prototype.toString=function(){return"[object Promise]"},m.prototype.then=function(e,t,n){function r(t){try{return"function"==typeof e?e(t):t}catch(n){return E(n)}}function a(e){if("function"==typeof t){i(e,s);try{return t(e)}catch(n){return E(n)}}return E(e)}function o(e){return"function"==typeof n?n(e):e}var s=this,l=h(),u=!1;return p.nextTick(function(){s.promiseDispatch(function(e){u||(u=!0,l.resolve(r(e)))},"when",[function(e){u||(u=!0,l.resolve(a(e)))}])}),s.promiseDispatch(void 0,"when",[void 0,function(e){var t,n=!1;try{t=o(e)}catch(r){if(n=!0,!p.onerror)throw r;p.onerror(r)}n||l.notify(t)}]),l.promise},p.tap=function(e,t){return p(e).tap(t)},m.prototype.tap=function(e){return e=p(e),this.then(function(t){return e.fcall(t).thenResolve(t)})},p.when=g,m.prototype.thenResolve=function(e){return this.then(function(){return e})},p.thenResolve=function(e,t){return p(e).thenResolve(t)},m.prototype.thenReject=function(e){return this.then(function(){throw e})},p.thenReject=function(e,t){return p(e).thenReject(t)},p.nearer=y,p.isPromise=v,p.isPromiseAlike=b,p.isPending=w,m.prototype.isPending=function(){return"pending"===this.inspect().state},p.isFulfilled=_,m.prototype.isFulfilled=function(){return"fulfilled"===this.inspect().state},p.isRejected=x,m.prototype.isRejected=function(){return"rejected"===this.inspect().state};var ae=[],oe=[],se=[],le=!0;p.resetUnhandledRejections=A,p.getUnhandledReasons=function(){return ae.slice()},p.stopUnhandledRejectionTracking=function(){A(),le=!1},A(),p.reject=E,p.fulfill=O,p.master=T,p.spread=C,m.prototype.spread=function(e,t){return this.all().then(function(t){return e.apply(void 0,t)},t)},p.async=I,p.spawn=D,p["return"]=L,p.promised=M,p.dispatch=R,m.prototype.dispatch=function(e,t){var n=this,r=h();return p.nextTick(function(){n.promiseDispatch(r.resolve,e,t)}),r.promise},p.get=function(e,t){return p(e).dispatch("get",[t])},m.prototype.get=function(e){return this.dispatch("get",[e])},p.set=function(e,t,n){return p(e).dispatch("set",[t,n])},m.prototype.set=function(e,t){return this.dispatch("set",[e,t])},p.del=p["delete"]=function(e,t){return p(e).dispatch("delete",[t])},m.prototype.del=m.prototype["delete"]=function(e){return this.dispatch("delete",[e])},p.mapply=p.post=function(e,t,n){return p(e).dispatch("post",[t,n])},m.prototype.mapply=m.prototype.post=function(e,t){return this.dispatch("post",[e,t])},p.send=p.mcall=p.invoke=function(e,t){return p(e).dispatch("post",[t,G(arguments,2)])},m.prototype.send=m.prototype.mcall=m.prototype.invoke=function(e){return this.dispatch("post",[e,G(arguments,1)])},p.fapply=function(e,t){return p(e).dispatch("apply",[void 0,t])},m.prototype.fapply=function(e){return this.dispatch("apply",[void 0,e])},p["try"]=p.fcall=function(e){return p(e).dispatch("apply",[void 0,G(arguments,1)])},m.prototype.fcall=function(){return this.dispatch("apply",[void 0,G(arguments)])},p.fbind=function(e){var t=p(e),n=G(arguments,1);return function(){return t.dispatch("apply",[this,n.concat(G(arguments))])}},m.prototype.fbind=function(){var e=this,t=G(arguments);return function(){return e.dispatch("apply",[this,t.concat(G(arguments))])}},p.keys=function(e){return p(e).dispatch("keys",[])},m.prototype.keys=function(){return this.dispatch("keys",[])},p.all=U,m.prototype.all=function(){return U(this)},p.any=P,m.prototype.any=function(){return P(this)},p.allResolved=c(q,"allResolved","allSettled"),m.prototype.allResolved=function(){return q(this)},p.allSettled=B,m.prototype.allSettled=function(){return this.then(function(e){return U(Z(e,function(e){function t(){return e.inspect()}return e=p(e),e.then(t,t)}))})},p.fail=p["catch"]=function(e,t){return p(e).then(void 0,t)},m.prototype.fail=m.prototype["catch"]=function(e){return this.then(void 0,e)},p.progress=z,m.prototype.progress=function(e){return this.then(void 0,void 0,e)},p.fin=p["finally"]=function(e,t){return p(e)["finally"](t)},m.prototype.fin=m.prototype["finally"]=function(e){return e=p(e),this.then(function(t){return e.fcall().then(function(){return t})},function(t){return e.fcall().then(function(){throw t})})},p.done=function(e,t,n,r){return p(e).done(t,n,r)},m.prototype.done=function(t,n,r){var a=function(e){p.nextTick(function(){if(i(e,o),!p.onerror)throw e;p.onerror(e)})},o=t||n||r?this.then(t,n,r):this;"object"==typeof e&&e&&e.domain&&(a=e.domain.bind(a)),o.then(void 0,a)},p.timeout=function(e,t,n){return p(e).timeout(t,n)},m.prototype.timeout=function(e,t){var n=h(),r=setTimeout(function(){t&&"string"!=typeof t||(t=new Error(t||"Timed out after "+e+" ms"),t.code="ETIMEDOUT"),n.reject(t)},e);return this.then(function(e){clearTimeout(r),n.resolve(e)},function(e){clearTimeout(r),n.reject(e)},n.notify),n.promise},p.delay=function(e,t){return void 0===t&&(t=e,e=void 0),p(e).delay(t)},m.prototype.delay=function(e){return this.then(function(t){var n=h();return setTimeout(function(){n.resolve(t)},e),n.promise})},p.nfapply=function(e,t){return p(e).nfapply(t)},m.prototype.nfapply=function(e){var t=h(),n=G(e);return n.push(t.makeNodeResolver()),this.fapply(n).fail(t.reject),t.promise},p.nfcall=function(e){var t=G(arguments,1);return p(e).nfapply(t)},m.prototype.nfcall=function(){var e=G(arguments),t=h();return e.push(t.makeNodeResolver()),this.fapply(e).fail(t.reject),t.promise},p.nfbind=p.denodeify=function(e){var t=G(arguments,1);return function(){var n=t.concat(G(arguments)),r=h();return n.push(r.makeNodeResolver()),p(e).fapply(n).fail(r.reject),r.promise}},m.prototype.nfbind=m.prototype.denodeify=function(){var e=G(arguments);return e.unshift(this),p.denodeify.apply(void 0,e)},p.nbind=function(e,t){var n=G(arguments,2);return function(){function r(){return e.apply(t,arguments)}var i=n.concat(G(arguments)),a=h();return i.push(a.makeNodeResolver()),p(r).fapply(i).fail(a.reject),a.promise}},m.prototype.nbind=function(){var e=G(arguments,0);return e.unshift(this),p.nbind.apply(void 0,e)},p.nmapply=p.npost=function(e,t,n){return p(e).npost(t,n)},m.prototype.nmapply=m.prototype.npost=function(e,t){var n=G(t||[]),r=h();return n.push(r.makeNodeResolver()),this.dispatch("post",[e,n]).fail(r.reject),r.promise},p.nsend=p.nmcall=p.ninvoke=function(e,t){var n=G(arguments,2),r=h();return n.push(r.makeNodeResolver()),p(e).dispatch("post",[t,n]).fail(r.reject),r.promise},m.prototype.nsend=m.prototype.nmcall=m.prototype.ninvoke=function(e){var t=G(arguments,1),n=h();return t.push(n.makeNodeResolver()),this.dispatch("post",[e,t]).fail(n.reject),n.promise},p.nodeify=N,m.prototype.nodeify=function(e){return e?void this.then(function(t){p.nextTick(function(){e(null,t)})},function(t){p.nextTick(function(){e(t)})}):this},p.noConflict=function(){throw new Error("Q.noConflict only works when Q is used as a global")};var ue=u();return p})}).call(this,e("_process"))},{_process:12}],158:[function(e,t,n){function r(){}function i(e){if(!y(e))return e;var t=[];for(var n in e)a(t,n,e[n]);return t.join("&")}function a(e,t,n){if(null!=n)if(Array.isArray(n))n.forEach(function(n){a(e,t,n)});else if(y(n))for(var r in n)a(e,t+"["+r+"]",n[r]);else e.push(encodeURIComponent(t)+"="+encodeURIComponent(n));else null===n&&e.push(encodeURIComponent(t))}function o(e){for(var t,n,r={},i=e.split("&"),a=0,o=i.length;a<o;++a)t=i[a],n=t.indexOf("="),n==-1?r[decodeURIComponent(t)]="":r[decodeURIComponent(t.slice(0,n))]=decodeURIComponent(t.slice(n+1));
+return r}function s(e){var t,n,r,i,a=e.split(/\r?\n/),o={};a.pop();for(var s=0,l=a.length;s<l;++s)n=a[s],t=n.indexOf(":"),r=n.slice(0,t).toLowerCase(),i=b(n.slice(t+1)),o[r]=i;return o}function l(e){return/[\/+]json\b/.test(e)}function u(e){return e.split(/ *; */).shift()}function c(e){return e.split(/ *; */).reduce(function(e,t){var n=t.split(/ *= */),r=n.shift(),i=n.shift();return r&&i&&(e[r]=i),e},{})}function p(e,t){t=t||{},this.req=e,this.xhr=this.req.xhr,this.text="HEAD"!=this.req.method&&(""===this.xhr.responseType||"text"===this.xhr.responseType)||"undefined"==typeof this.xhr.responseType?this.xhr.responseText:null,this.statusText=this.req.xhr.statusText,this._setStatusProperties(this.xhr.status),this.header=this.headers=s(this.xhr.getAllResponseHeaders()),this.header["content-type"]=this.xhr.getResponseHeader("content-type"),this._setHeaderProperties(this.header),this.body="HEAD"!=this.req.method?this._parseBody(this.text?this.text:this.xhr.response):null}function h(e,t){var n=this;this._query=this._query||[],this.method=e,this.url=t,this.header={},this._header={},this.on("end",function(){var e=null,t=null;try{t=new p(n)}catch(r){return e=new Error("Parser is unable to parse the response"),e.parse=!0,e.original=r,e.rawResponse=n.xhr&&n.xhr.responseText?n.xhr.responseText:null,e.statusCode=n.xhr&&n.xhr.status?n.xhr.status:null,n.callback(e)}n.emit("response",t);var i;try{(t.status<200||t.status>=300)&&(i=new Error(t.statusText||"Unsuccessful HTTP response"),i.original=e,i.response=t,i.status=t.status)}catch(r){i=r}i?n.callback(i,t):n.callback(null,t)})}function f(e,t){var n=v("DELETE",e);return t&&n.end(t),n}var d;"undefined"!=typeof window?d=window:"undefined"!=typeof self?d=self:(console.warn("Using browser-only version of superagent in non-browser environment"),d=this);var m=e("emitter"),g=e("./request-base"),y=e("./is-object"),v=t.exports=e("./request").bind(null,h);v.getXHR=function(){if(!(!d.XMLHttpRequest||d.location&&"file:"==d.location.protocol&&d.ActiveXObject))return new XMLHttpRequest;try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(e){}try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(e){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(e){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(e){}throw Error("Browser-only verison of superagent could not find XHR")};var b="".trim?function(e){return e.trim()}:function(e){return e.replace(/(^\s*|\s*$)/g,"")};v.serializeObject=i,v.parseString=o,v.types={html:"text/html",json:"application/json",xml:"application/xml",urlencoded:"application/x-www-form-urlencoded",form:"application/x-www-form-urlencoded","form-data":"application/x-www-form-urlencoded"},v.serialize={"application/x-www-form-urlencoded":i,"application/json":JSON.stringify},v.parse={"application/x-www-form-urlencoded":o,"application/json":JSON.parse},p.prototype.get=function(e){return this.header[e.toLowerCase()]},p.prototype._setHeaderProperties=function(e){var t=this.header["content-type"]||"";this.type=u(t);var n=c(t);for(var r in n)this[r]=n[r]},p.prototype._parseBody=function(e){var t=v.parse[this.type];return!t&&l(this.type)&&(t=v.parse["application/json"]),t&&e&&(e.length||e instanceof Object)?t(e):null},p.prototype._setStatusProperties=function(e){1223===e&&(e=204);var t=e/100|0;this.status=this.statusCode=e,this.statusType=t,this.info=1==t,this.ok=2==t,this.clientError=4==t,this.serverError=5==t,this.error=(4==t||5==t)&&this.toError(),this.accepted=202==e,this.noContent=204==e,this.badRequest=400==e,this.unauthorized=401==e,this.notAcceptable=406==e,this.notFound=404==e,this.forbidden=403==e},p.prototype.toError=function(){var e=this.req,t=e.method,n=e.url,r="cannot "+t+" "+n+" ("+this.status+")",i=new Error(r);return i.status=this.status,i.method=t,i.url=n,i},v.Response=p,m(h.prototype);for(var w in g)h.prototype[w]=g[w];h.prototype.type=function(e){return this.set("Content-Type",v.types[e]||e),this},h.prototype.responseType=function(e){return this._responseType=e,this},h.prototype.accept=function(e){return this.set("Accept",v.types[e]||e),this},h.prototype.auth=function(e,t,n){switch(n||(n={type:"basic"}),n.type){case"basic":var r=btoa(e+":"+t);this.set("Authorization","Basic "+r);break;case"auto":this.username=e,this.password=t}return this},h.prototype.query=function(e){return"string"!=typeof e&&(e=i(e)),e&&this._query.push(e),this},h.prototype.attach=function(e,t,n){return this._getFormData().append(e,t,n||t.name),this},h.prototype._getFormData=function(){return this._formData||(this._formData=new d.FormData),this._formData},h.prototype.callback=function(e,t){var n=this._callback;this.clearTimeout(),n(e,t)},h.prototype.crossDomainError=function(){var e=new Error("Request has been terminated\nPossible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.");e.crossDomain=!0,e.status=this.status,e.method=this.method,e.url=this.url,this.callback(e)},h.prototype._timeoutError=function(){var e=this._timeout,t=new Error("timeout of "+e+"ms exceeded");t.timeout=e,this.callback(t)},h.prototype._appendQueryString=function(){var e=this._query.join("&");e&&(this.url+=~this.url.indexOf("?")?"&"+e:"?"+e)},h.prototype.end=function(e){var t=this,n=this.xhr=v.getXHR(),i=this._timeout,a=this._formData||this._data;this._callback=e||r,n.onreadystatechange=function(){if(4==n.readyState){var e;try{e=n.status}catch(r){e=0}if(0==e){if(t.timedout)return t._timeoutError();if(t._aborted)return;return t.crossDomainError()}t.emit("end")}};var o=function(e){e.total>0&&(e.percent=e.loaded/e.total*100),e.direction="download",t.emit("progress",e)};this.hasListeners("progress")&&(n.onprogress=o);try{n.upload&&this.hasListeners("progress")&&(n.upload.onprogress=o)}catch(s){}if(i&&!this._timer&&(this._timer=setTimeout(function(){t.timedout=!0,t.abort()},i)),this._appendQueryString(),this.username&&this.password?n.open(this.method,this.url,!0,this.username,this.password):n.open(this.method,this.url,!0),this._withCredentials&&(n.withCredentials=!0),"GET"!=this.method&&"HEAD"!=this.method&&"string"!=typeof a&&!this._isHost(a)){var u=this._header["content-type"],c=this._serializer||v.serialize[u?u.split(";")[0]:""];!c&&l(u)&&(c=v.serialize["application/json"]),c&&(a=c(a))}for(var p in this.header)null!=this.header[p]&&n.setRequestHeader(p,this.header[p]);return this._responseType&&(n.responseType=this._responseType),this.emit("request",this),n.send("undefined"!=typeof a?a:null),this},v.Request=h,v.get=function(e,t,n){var r=v("GET",e);return"function"==typeof t&&(n=t,t=null),t&&r.query(t),n&&r.end(n),r},v.head=function(e,t,n){var r=v("HEAD",e);return"function"==typeof t&&(n=t,t=null),t&&r.send(t),n&&r.end(n),r},v.options=function(e,t,n){var r=v("OPTIONS",e);return"function"==typeof t&&(n=t,t=null),t&&r.send(t),n&&r.end(n),r},v.del=f,v["delete"]=f,v.patch=function(e,t,n){var r=v("PATCH",e);return"function"==typeof t&&(n=t,t=null),t&&r.send(t),n&&r.end(n),r},v.post=function(e,t,n){var r=v("POST",e);return"function"==typeof t&&(n=t,t=null),t&&r.send(t),n&&r.end(n),r},v.put=function(e,t,n){var r=v("PUT",e);return"function"==typeof t&&(n=t,t=null),t&&r.send(t),n&&r.end(n),r}},{"./is-object":159,"./request":161,"./request-base":160,emitter:162}],159:[function(e,t,n){function r(e){return null!==e&&"object"==typeof e}t.exports=r},{}],160:[function(e,t,n){var r=e("./is-object");n.clearTimeout=function(){return this._timeout=0,clearTimeout(this._timer),this},n.parse=function(e){return this._parser=e,this},n.serialize=function(e){return this._serializer=e,this},n.timeout=function(e){return this._timeout=e,this},n.then=function(e,t){if(!this._fullfilledPromise){var n=this;this._fullfilledPromise=new Promise(function(e,t){n.end(function(n,r){n?t(n):e(r)})})}return this._fullfilledPromise.then(e,t)},n.use=function(e){return e(this),this},n.get=function(e){return this._header[e.toLowerCase()]},n.getHeader=n.get,n.set=function(e,t){if(r(e)){for(var n in e)this.set(n,e[n]);return this}return this._header[e.toLowerCase()]=t,this.header[e]=t,this},n.unset=function(e){return delete this._header[e.toLowerCase()],delete this.header[e],this},n.field=function(e,t){return this._getFormData().append(e,t),this},n.abort=function(){return this._aborted?this:(this._aborted=!0,this.xhr&&this.xhr.abort(),this.req&&this.req.abort(),this.clearTimeout(),this.emit("abort"),this)},n.withCredentials=function(){return this._withCredentials=!0,this},n.redirects=function(e){return this._maxRedirects=e,this},n.toJSON=function(){return{method:this.method,url:this.url,data:this._data,headers:this._header}},n._isHost=function(e){var t={}.toString.call(e);switch(t){case"[object File]":case"[object Blob]":case"[object FormData]":return!0;default:return!1}},n.send=function(e){var t=r(e),n=this._header["content-type"];if(t&&r(this._data))for(var i in e)this._data[i]=e[i];else"string"==typeof e?(n||this.type("form"),n=this._header["content-type"],"application/x-www-form-urlencoded"==n?this._data=this._data?this._data+"&"+e:e:this._data=(this._data||"")+e):this._data=e;return!t||this._isHost(e)?this:(n||this.type("json"),this)}},{"./is-object":159}],161:[function(e,t,n){function r(e,t,n){return"function"==typeof n?new e("GET",t).end(n):2==arguments.length?new e("GET",t):new e(t,n)}t.exports=r},{}],162:[function(e,t,n){function r(e){if(e)return i(e)}function i(e){for(var t in r.prototype)e[t]=r.prototype[t];return e}"undefined"!=typeof t&&(t.exports=r),r.prototype.on=r.prototype.addEventListener=function(e,t){return this._callbacks=this._callbacks||{},(this._callbacks["$"+e]=this._callbacks["$"+e]||[]).push(t),this},r.prototype.once=function(e,t){function n(){this.off(e,n),t.apply(this,arguments)}return n.fn=t,this.on(e,n),this},r.prototype.off=r.prototype.removeListener=r.prototype.removeAllListeners=r.prototype.removeEventListener=function(e,t){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var n=this._callbacks["$"+e];if(!n)return this;if(1==arguments.length)return delete this._callbacks["$"+e],this;for(var r,i=0;i<n.length;i++)if(r=n[i],r===t||r.fn===t){n.splice(i,1);break}return this},r.prototype.emit=function(e){this._callbacks=this._callbacks||{};var t=[].slice.call(arguments,1),n=this._callbacks["$"+e];if(n){n=n.slice(0);for(var r=0,i=n.length;r<i;++r)n[r].apply(this,t)}return this},r.prototype.listeners=function(e){return this._callbacks=this._callbacks||{},this._callbacks["$"+e]||[]},r.prototype.hasListeners=function(e){return!!this.listeners(e).length}},{}]},{},[1])(1)}),window.SwaggerUi=Backbone.Router.extend({dom_id:"swagger_ui",options:null,api:null,headerView:null,mainView:null,initialize:function(e){e=e||{},"model"!==e.defaultModelRendering&&(e.defaultModelRendering="schema"),e.highlightSizeThreshold||(e.highlightSizeThreshold=1e5),e.dom_id&&(this.dom_id=e.dom_id,delete e.dom_id),e.supportedSubmitMethods||(e.supportedSubmitMethods=["get","put","post","delete","head","options","patch"]),"string"==typeof e.oauth2RedirectUrl&&(window.oAuthRedirectUrl=e.oauth2RedirectUrl),$("#"+this.dom_id).length||$("body").append('<div id="'+this.dom_id+'"></div>'),this.options=e,marked.setOptions({gfm:!0});var t=this;this.options.success=function(){return t.render()},this.options.progress=function(e){return t.showMessage(e)},this.options.failure=function(e){return t.onLoadFailure(e)},this.headerView=new SwaggerUi.Views.HeaderView({el:$("#header")}),this.headerView.on("update-swagger-ui",function(e){return t.updateSwaggerUi(e)}),JSONEditor.defaults.iconlibs.swagger=JSONEditor.AbstractIconLib.extend({mapping:{collapse:"collapse",expand:"expand"},icon_prefix:"swagger-"})},setOption:function(e,t){this.options[e]=t},getOption:function(e){return this.options[e]},updateSwaggerUi:function(e){this.options.url=e.url,this.load()},load:function(){this.mainView&&this.mainView.clear(),this.authView&&this.authView.remove();var e=this.options.url;e&&0!==e.indexOf("http")&&(e=this.buildUrl(window.location.href.toString(),e)),this.api&&(this.options.authorizations=this.api.clientAuthorizations.authz),this.options.url=e,this.headerView.update(e),this.api=new SwaggerClient(this.options)},collapseAll:function(){Docs.collapseEndpointListForResource("")},listAll:function(){Docs.collapseOperationsForResource("")},expandAll:function(){Docs.expandOperationsForResource("")},render:function(){var e;switch(this.showMessage("Finished Loading Resource Information. Rendering Swagger UI..."),this.mainView=new SwaggerUi.Views.MainView({model:this.api,el:$("#"+this.dom_id),swaggerOptions:this.options,router:this}).render(),_.isEmpty(this.api.securityDefinitions)||(e=_.map(this.api.securityDefinitions,function(e,t){var n={};return n[t]=e,n}),this.authView=new SwaggerUi.Views.AuthButtonView({data:SwaggerUi.utils.parseSecurityDefinitions(e),router:this}),$("#auth_container").append(this.authView.render().el)),this.showMessage(),this.options.docExpansion){case"full":this.expandAll();break;case"list":this.listAll()}this.renderGFM(),this.options.onComplete&&this.options.onComplete(this.api,this),setTimeout(Docs.shebang.bind(this),100)},buildUrl:function(e,t){if(0===t.indexOf("/")){var n=e.split("/");return e=n[0]+"//"+n[2],e+t}var r=e.length;return e.indexOf("?")>-1&&(r=Math.min(r,e.indexOf("?"))),e.indexOf("#")>-1&&(r=Math.min(r,e.indexOf("#"))),e=e.substring(0,r),e.indexOf("/",e.length-1)!==-1?e+t:e+"/"+t},showMessage:function(e){void 0===e&&(e="");var t=$("#message-bar");t.removeClass("message-fail"),t.addClass("message-success"),t.text(e),window.SwaggerTranslator&&window.SwaggerTranslator.translate(t)},onLoadFailure:function(e){void 0===e&&(e=""),$("#message-bar").removeClass("message-success"),$("#message-bar").addClass("message-fail");var t=$("#message-bar").text(e);return this.options.onFailure&&this.options.onFailure(e),t},renderGFM:function(){$(".markdown").each(function(){$(this).html(marked($(this).html()))}),$(".propDesc",".model-signature .description").each(function(){$(this).html(marked($(this).html())).addClass("markdown")})}}),window.SwaggerUi.Views={},window.SwaggerUi.Models={},window.SwaggerUi.Collections={},window.SwaggerUi.partials={},window.SwaggerUi.utils={},function(){function e(e){"console"in window&&"function"==typeof window.console.warn&&console.warn(e)}window.authorizations={add:function(){if(e("Using window.authorizations is deprecated. Please use SwaggerUi.api.clientAuthorizations.add()."),"undefined"==typeof window.swaggerUi)throw new TypeError("window.swaggerUi is not defined");window.swaggerUi instanceof SwaggerUi&&window.swaggerUi.api.clientAuthorizations.add.apply(window.swaggerUi.api.clientAuthorizations,arguments)}},window.ApiKeyAuthorization=function(){e("window.ApiKeyAuthorization is deprecated. Please use SwaggerClient.ApiKeyAuthorization."),SwaggerClient.ApiKeyAuthorization.apply(window,arguments)},window.PasswordAuthorization=function(){e("window.PasswordAuthorization is deprecated. Please use SwaggerClient.PasswordAuthorization."),SwaggerClient.PasswordAuthorization.apply(window,arguments)}}(),function(e,t){"function"==typeof define&&define.amd?define(["b"],function(n){return e.SwaggerUi=t(n)}):"object"==typeof exports?module.exports=t(require("b")):e.SwaggerUi=t(e.b)}(this,function(){return SwaggerUi}),window.SwaggerUi.utils={parseSecurityDefinitions:function(e,t){var n=Object.assign({},t),r=[],i=[],a=[],o=window.SwaggerUi.utils;return Array.isArray(e)?(e.forEach(function(e){var t={},s={};for(var l in e)if(Array.isArray(e[l])){if(!n[l])continue;if(n[l]=n[l]||{},"oauth2"===n[l].type){s[l]=Object.assign({},n[l]),s[l].scopes=Object.assign({},n[l].scopes);for(var u in s[l].scopes)e[l].indexOf(u)<0&&delete s[l].scopes[u];s[l].scopes=o.parseOauth2Scopes(s[l].scopes),a=_.merge(a,s[l].scopes)}else t[l]=Object.assign({},n[l])}else"oauth2"===e[l].type?(s[l]=Object.assign({},e[l]),s[l].scopes=o.parseOauth2Scopes(s[l].scopes),a=_.merge(a,s[l].scopes)):t[l]=e[l];_.isEmpty(t)||i.push(t),_.isEmpty(s)||r.push(s)}),{auths:i,oauth2:r,scopes:a}):null},parseOauth2Scopes:function(e){var t,n=Object.assign({},e),r=[];for(t in n)r.push({scope:t,description:n[t]});return r},sanitize:function(e){return e=e.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,""),e=e.replace(/(on\w+="[^"]*")*(on\w+='[^']*')*(on\w+=\w*\(\w*\))*/gi,"")}},SwaggerUi.Models.ApiKeyAuthModel=Backbone.Model.extend({defaults:{"in":"",name:"",title:"",value:""},initialize:function(){this.on("change",this.validate)},validate:function(){var e=!!this.get("value");return this.set("valid",e),e}}),SwaggerUi.Views.ApiKeyAuthView=Backbone.View.extend({events:{"change .input_apiKey_entry":"apiKeyChange"},selectors:{apikeyInput:".input_apiKey_entry"},template:Handlebars.templates.apikey_auth,initialize:function(e){this.options=e||{},this.router=this.options.router},render:function(){return this.$el.html(this.template(this.model.toJSON())),this},apiKeyChange:function(e){var t=$(e.target).val();t&&this.$(this.selectors.apikeyInput).removeClass("error"),this.model.set("value",t)},isValid:function(){return this.model.validate()},highlightInvalid:function(){this.isValid()||this.$(this.selectors.apikeyInput).addClass("error")}}),SwaggerUi.Views.AuthButtonView=Backbone.View.extend({events:{"click .authorize__btn":"authorizeBtnClick"},tpls:{popup:Handlebars.templates.popup,authBtn:Handlebars.templates.auth_button,authBtnOperation:Handlebars.templates.auth_button_operation},initialize:function(e){this.options=e||{},this.options.data=this.options.data||{},this.isOperation=this.options.isOperation,this.model=this.model||{},this.router=this.options.router,this.auths=this.options.data.oauth2.concat(this.options.data.auths)},render:function(){var e=this.isOperation?"authBtnOperation":"authBtn";return this.$authEl=this.renderAuths(this.auths),this.$el.html(this.tpls[e](this.model)),this},authorizeBtnClick:function(e){var t;e.preventDefault(),t={title:"Available authorizations",content:this.$authEl},this.render(),this.popup=new SwaggerUi.Views.PopupView({model:t}),this.popup.render()},renderAuths:function(e){var t=$("<div>"),n=!1;return e.forEach(function(e){var r=new SwaggerUi.Views.AuthView({data:e,router:this.router}),i=r.render().el;t.append(i),r.isLogout&&(n=!0)},this),this.model.isLogout=n,t}}),SwaggerUi.Collections.AuthsCollection=Backbone.Collection.extend({constructor:function(){var e=Array.prototype.slice.call(arguments);e[0]=this.parse(e[0]),Backbone.Collection.apply(this,e)},add:function(e){var t=Array.prototype.slice.call(arguments);Array.isArray(e)?t[0]=_.map(e,function(e){return this.handleOne(e)},this):t[0]=this.handleOne(e),Backbone.Collection.prototype.add.apply(this,t)},handleOne:function(e){var t=e;if(!(e instanceof Backbone.Model))switch(e.type){case"oauth2":t=new SwaggerUi.Models.Oauth2Model(e);break;case"basic":t=new SwaggerUi.Models.BasicAuthModel(e);break;case"apiKey":t=new SwaggerUi.Models.ApiKeyAuthModel(e);break;default:t=new Backbone.Model(e)}return t},isValid:function(){var e=!0;return this.models.forEach(function(t){t.validate()||(e=!1)}),e},isAuthorized:function(){return this.length===this.where({isLogout:!0}).length},isPartiallyAuthorized:function(){return this.where({isLogout:!0}).length>0},parse:function(e){var t={};return"undefined"!=typeof window.swaggerUi&&(t=Object.assign({},window.swaggerUi.api.clientAuthorizations.authz)),_.map(e,function(e,n){var r=t[n]&&"basic"===e.type&&t[n].username&&t[n].password;return _.extend(e,{title:n}),(t[n]||r)&&_.extend(e,{isLogout:!0,value:r?void 0:t[n].value,username:r?t[n].username:void 0,password:r?t[n].password:void 0,valid:!0}),e})}}),SwaggerUi.Views.AuthsCollectionView=Backbone.View.extend({initialize:function(e){this.options=e||{},this.options.data=this.options.data||{},this.router=this.options.router,this.collection=new SwaggerUi.Collections.AuthsCollection(e.data),this.$innerEl=$("<div>"),this.authViews=[]},render:function(){return this.collection.each(function(e){this.renderOneAuth(e)},this),this.$el.html(this.$innerEl.html()?this.$innerEl:""),this},renderOneAuth:function(e){var t,n,r,i=e.get("type");"apiKey"===i?r="ApiKeyAuthView":"basic"===i&&0===this.$innerEl.find(".basic_auth_container").length?r="BasicAuthView":"oauth2"===i&&(r="Oauth2View"),r&&(n=new SwaggerUi.Views[r]({model:e,router:this.router}),t=n.render().el,this.authViews.push(n)),this.$innerEl.append(t)},highlightInvalid:function(){this.authViews.forEach(function(e){e.highlightInvalid()},this)}}),SwaggerUi.Views.AuthView=Backbone.View.extend({events:{"click .auth_submit__button":"authorizeClick","click .auth_logout__button":"logoutClick"},tpls:{main:Handlebars.templates.auth_view},selectors:{innerEl:".auth_inner",authBtn:".auth_submit__button"},initialize:function(e){this.options=e||{},e.data=e.data||{},this.router=this.options.router,this.authsCollectionView=new SwaggerUi.Views.AuthsCollectionView({data:e.data}),this.$el.html(this.tpls.main({isLogout:this.authsCollectionView.collection.isAuthorized(),isAuthorized:this.authsCollectionView.collection.isPartiallyAuthorized()})),this.$innerEl=this.$(this.selectors.innerEl),this.isLogout=this.authsCollectionView.collection.isPartiallyAuthorized()},render:function(){return this.$innerEl.html(this.authsCollectionView.render().el),this},authorizeClick:function(e){e.preventDefault(),e.stopPropagation(),this.authsCollectionView.collection.isValid()?this.authorize():this.authsCollectionView.highlightInvalid()},authorize:function(){this.authsCollectionView.collection.forEach(function(e){var t,n,r=e.get("type");"apiKey"===r?(t=new SwaggerClient.ApiKeyAuthorization(e.get("name"),e.get("value"),e.get("in")),this.router.api.clientAuthorizations.add(e.get("title"),t)):"basic"===r?(n=new SwaggerClient.PasswordAuthorization(e.get("username"),e.get("password")),this.router.api.clientAuthorizations.add(e.get("title"),n)):"oauth2"===r&&this.handleOauth2Login(e)},this),this.router.load()},logoutClick:function(e){e.preventDefault(),this.authsCollectionView.collection.forEach(function(e){window.swaggerUi.api.clientAuthorizations.remove(e.get("title"))}),this.router.load()},handleOauth2Login:function(e){function t(e){return e.vendorExtensions["x-tokenName"]||e.tokenName}var n,r,i,a=window.location,o=location.pathname.substring(0,location.pathname.lastIndexOf("/")),s=a.protocol+"//"+a.host+o+"/o2c.html",l=window.oAuthRedirectUrl||s,u=null,c=_.map(e.get("scopes"),function(e){if(e.checked)return e.scope}),p=window.swaggerUiAuth||(window.swaggerUiAuth={});p.OAuthSchemeKey=e.get("title"),window.enabledScopes=c;var h=e.get("flow");if("oauth2"!==e.get("type")||!h||"implicit"!==h&&"accessCode"!==h){if("oauth2"===e.get("type")&&h&&"application"===h)return r=e.attributes,p.tokenName=t(r)||"access_token",void this.clientCredentialsFlow(c,r,p.OAuthSchemeKey);if("oauth2"===e.get("type")&&h&&"password"===h)return r=e.attributes,p.tokenName=t(r)||"access_token",void this.passwordFlow(c,r,p.OAuthSchemeKey);if(e.get("grantTypes")){var f=e.get("grantTypes");for(var d in f)f.hasOwnProperty(d)&&"implicit"===d?(r=f[d],i=r.loginEndpoint.url,u=r.loginEndpoint.url+"?response_type=token",p.tokenName=t(r)):f.hasOwnProperty(d)&&"accessCode"===d&&(r=f[d],i=r.tokenRequestEndpoint.url,u=r.tokenRequestEndpoint.url+"?response_type=code",p.tokenName=t(r))}}else r=e.attributes,u=r.authorizationUrl+"?response_type="+("implicit"===h?"token":"code"),p.tokenName=t(r)||"access_token",p.tokenUrl="accessCode"===h?r.tokenUrl:null,n=p.OAuthSchemeKey;redirect_uri=l,u+="&redirect_uri="+encodeURIComponent(l),u+="&realm="+encodeURIComponent(realm),u+="&client_id="+encodeURIComponent(clientId),u+="&scope="+encodeURIComponent(c.join(scopeSeparator)),u+="&state="+encodeURIComponent(n);for(var m in additionalQueryStringParams)u+="&"+m+"="+encodeURIComponent(additionalQueryStringParams[m]);window.open(u)},clientCredentialsFlow:function(e,t,n){this.accessTokenRequest(e,t,n,"client_credentials")},passwordFlow:function(e,t,n){this.accessTokenRequest(e,t,n,"password",{username:t.username,password:t.password})},accessTokenRequest:function(e,t,n,r,i){i=$.extend({},{scope:e.join(" "),grant_type:r},i);var a={};switch(t.clientAuthenticationType){case"basic":a.Authorization="Basic "+btoa(t.clientId+":"+t.clientSecret);break;case"request-body":i.client_id=t.clientId,i.client_secret=t.clientSecret}$.ajax({url:t.tokenUrl,type:"POST",data:i,headers:a,success:function(e){onOAuthComplete(e,n)},error:function(){onOAuthComplete("")}})}}),SwaggerUi.Models.BasicAuthModel=Backbone.Model.extend({defaults:{username:"",password:"",title:"basic"},initialize:function(){this.on("change",this.validate)},validate:function(){var e=!!this.get("password")&&!!this.get("username");return this.set("valid",e),e}}),SwaggerUi.Views.BasicAuthView=Backbone.View.extend({initialize:function(e){this.options=e||{},this.router=this.options.router},events:{"change .auth_input":"inputChange"},selectors:{usernameInput:".basic_auth__username",passwordInput:".basic_auth__password"},cls:{error:"error"},template:Handlebars.templates.basic_auth,render:function(){return $(this.el).html(this.template(this.model.toJSON())),this},inputChange:function(e){var t=$(e.target),n=t.val(),r=t.prop("name");n&&t.removeClass(this.cls.error),this.model.set(r,n)},isValid:function(){return this.model.validate()},highlightInvalid:function(){this.model.get("username")||this.$(this.selectors.usernameInput).addClass(this.cls.error)}}),SwaggerUi.Views.ContentTypeView=Backbone.View.extend({initialize:function(){},render:function(){return this.model.contentTypeId="ct"+Math.random(),$(this.el).html(Handlebars.templates.content_type(this.model)),this}}),SwaggerUi.Views.HeaderView=Backbone.View.extend({events:{"click #show-pet-store-icon":"showPetStore","click #explore":"showCustom","submit #api_selector":"showCustom","keyup #input_baseUrl":"showCustomOnKeyup","keyup #input_apiKey":"showCustomOnKeyup"},initialize:function(){},showPetStore:function(){this.trigger("update-swagger-ui",{url:"http://petstore.swagger.io/v2/swagger.json"})},showCustomOnKeyup:function(e){13===e.keyCode&&this.showCustom()},showCustom:function(e){e&&e.preventDefault(),this.trigger("update-swagger-ui",{url:$("#input_baseUrl").val()})},update:function(e,t,n){void 0===n&&(n=!1),$("#input_baseUrl").val(e),n&&this.trigger("update-swagger-ui",{url:e})}}),SwaggerUi.Views.MainView=Backbone.View.extend({apisSorter:{alpha:function(e,t){return e.name.localeCompare(t.name)}},operationsSorters:{alpha:function(e,t){return e.path.localeCompare(t.path)},method:function(e,t){return e.method.localeCompare(t.method)}},initialize:function(e){var t,n,r,i;if(e=e||{},this.router=e.router,e.swaggerOptions.apisSorter&&(t=e.swaggerOptions.apisSorter,n=_.isFunction(t)?t:this.apisSorter[t],_.isFunction(n)&&this.model.apisArray.sort(n)),e.swaggerOptions.operationsSorter&&(t=e.swaggerOptions.operationsSorter,n=_.isFunction(t)?t:this.operationsSorters[t],_.isFunction(n)))for(r in this.model.apisArray)this.model.apisArray[r].operationsArray.sort(n);this.model.auths=[];for(r in this.model.securityDefinitions)i=this.model.securityDefinitions[r],this.model.auths.push({name:r,type:i.type,value:i});"validatorUrl"in e.swaggerOptions?this.model.validatorUrl=e.swaggerOptions.validatorUrl:this.model.url.indexOf("localhost")>0||this.model.url.indexOf("127.0.0.1")>0?this.model.validatorUrl=null:this.model.validatorUrl="//online.swagger.io/validator";var a;for(a in this.model.definitions)this.model.definitions[a].type||(this.model.definitions[a].type="object")},render:function(){$(this.el).html(Handlebars.templates.main(this.model)),this.info=this.$(".info")[0],this.info&&this.info.addEventListener("click",this.onLinkClick,!0),this.model.securityDefinitions=this.model.securityDefinitions||{};for(var e={},t=0,n=0;n<this.model.apisArray.length;n++){for(var r=this.model.apisArray[n],i=r.name;"undefined"!=typeof e[i];)i=i+"_"+t,t+=1;r.id=sanitizeHtml(i),e[i]=r,this.addResource(r,this.model.auths)}return $(".propWrap").hover(function(){$(".optionsWrapper",$(this)).show()},function(){$(".optionsWrapper",$(this)).hide()}),this},addResource:function(e,t){e.id=e.id.replace(/[^a-zA-Z\d]/g,function(e){return e.charCodeAt(0)}),e.definitions=this.model.definitions;var n=new SwaggerUi.Views.ResourceView({model:e,router:this.router,tagName:"li",id:"resource_"+e.id,className:"resource",auths:t,swaggerOptions:this.options.swaggerOptions});$("#resources",this.el).append(n.render().el)},clear:function(){$(this.el).html("")},onLinkClick:function(e){var t=e.target;"A"===t.tagName&&t.href&&!t.target&&(e.preventDefault(),window.open(t.href,"_blank"))}}),SwaggerUi.Models.Oauth2Model=Backbone.Model.extend({defaults:{scopes:{},isPasswordFlow:!1,clientAuthenticationType:"none"},initialize:function(){if(this.attributes&&this.attributes.scopes){var e,t=_.cloneDeep(this.attributes),n=[];for(e in t.scopes){var r=t.scopes[e];"string"==typeof r.description&&(n[r]=t.scopes[e],n.push(t.scopes[e]))}t.scopes=n,this.attributes=t}if(this.attributes&&this.attributes.flow){var i=this.attributes.flow;this.set("isPasswordFlow","password"===i),this.set("requireClientAuthentication","application"===i),this.set("clientAuthentication","password"===i||"application"===i)}this.on("change",this.validate)},setScopes:function(e,t){var n=_.extend({},this.attributes),r=_.findIndex(n.scopes,function(t){return t.scope===e});n.scopes[r].checked=t,this.set(n),this.validate()},validate:function(){var e=!1;if(this.get("isPasswordFlow")&&!this.get("username"))return!1;if(this.get("clientAuthenticationType")in["basic","request-body"]&&!this.get("clientId"))return!1;var t=this.get("scopes"),n=_.findIndex(t,function(e){return e.checked===!0});return t.length>0&&n>=0&&(e=!0),0===t.length&&(e=!0),this.set("valid",e),e}}),SwaggerUi.Views.Oauth2View=Backbone.View.extend({events:{"change .oauth-scope":"scopeChange","change .oauth-username":"setUsername","change .oauth-password":"setPassword","change .oauth-client-authentication-type":"setClientAuthenticationType","change .oauth-client-id":"setClientId","change .oauth-client-secret":"setClientSecret"},template:Handlebars.templates.oauth2,cls:{error:"error"},render:function(){return this.$el.html(this.template(this.model.toJSON())),this},scopeChange:function(e){var t=$(e.target).prop("checked"),n=$(e.target).data("scope");this.model.setScopes(n,t)},setUsername:function(e){var t=$(e.target).val();this.model.set("username",t),t&&$(e.target).removeClass(this.cls.error)},setPassword:function(e){this.model.set("password",$(e.target).val())},setClientAuthenticationType:function(e){var t=$(e.target).val(),n=this.$el;switch(this.model.set("clientAuthenticationType",t),t){case"none":n.find(".oauth-client-authentication").hide();break;case"basic":case"request-body":n.find(".oauth-client-id").removeClass(this.cls.error),n.find(".oauth-client-authentication").show()}},setClientId:function(e){var t=$(e.target).val();this.model.set("clientId",t),t&&$(e.target).removeClass(this.cls.error)},setClientSecret:function(e){this.model.set("clientSecret",$(e.target).val()),$(e.target).removeClass("error")},highlightInvalid:function(){this.model.get("username")||this.$el.find(".oauth-username").addClass(this.cls.error),this.model.get("clientId")||this.$el.find(".oauth-client-id").addClass(this.cls.error)}}),SwaggerUi.Views.OperationView=Backbone.View.extend({invocationUrl:null,events:{"submit .sandbox":"submitOperation","click .submit":"submitOperation","click .response_hider":"hideResponse","click .toggleOperation":"toggleOperationContent","mouseenter .api-ic":"mouseEnter","dblclick .curl":"selectText","change [name=responseContentType]":"showSnippet"},initialize:function(e){return e=e||{},this.router=e.router,this.auths=e.auths,this.parentId=this.model.parentId,this.nickname=this.model.nickname,this.model.encodedParentId=encodeURIComponent(this.parentId),e.swaggerOptions&&(this.model.defaultRendering=e.swaggerOptions.defaultModelRendering,e.swaggerOptions.showRequestHeaders&&(this.model.showRequestHeaders=!0),e.swaggerOptions.showOperationIds&&(this.model.showOperationIds=!0)),
+this},selectText:function(e){var t,n,r=document,i=e.target.firstChild;r.body.createTextRange?(t=document.body.createTextRange(),t.moveToElementText(i),t.select()):window.getSelection&&(n=window.getSelection(),t=document.createRange(),t.selectNodeContents(i),n.removeAllRanges(),n.addRange(t))},mouseEnter:function(e){var t=$(this.el).find(".content"),n=e.pageX,r=e.pageY,i=$(window).scrollLeft(),a=$(window).scrollTop(),o=i+$(window).width(),s=a+$(window).height(),l=t.width(),u=t.height();n+l>o&&(n=o-l),n<i&&(n=i),r+u>s&&(r=s-u),r<a&&(r=a);var c={};c.top=r,c.left=n,t.css(c)},render:function(){var e,t,n,r,i,a,o,s,l,u,c,p,h,f,d,m,g,y,v,b,w,x,A,S,j,E,O,k,T,C,I,D,L,M,R,U,P,q,B,z,N;if(a=jQuery.inArray(this.model.method,this.model.supportedSubmitMethods())>=0,a||(this.model.isReadOnly=!0),this.model.description=this.model.description||this.model.notes,this.model.oauth=null,m=this.model.authorizations||this.model.security)if(Array.isArray(m))for(l=0,u=m.length;l<u;l++){n=m[l];for(s in n)for(e in this.auths)if(t=this.auths[e],s===t.name&&"oauth2"===t.type){this.model.oauth={},this.model.oauth.scopes=[],A=t.value.scopes;for(o in A)P=A[o],D=n[s].indexOf(o),D>=0&&(y={scope:o,description:P},this.model.oauth.scopes.push(y))}}else for(o in m)if(P=m[o],"oauth2"===o)for(null===this.model.oauth&&(this.model.oauth={}),void 0===this.model.oauth.scopes&&(this.model.oauth.scopes=[]),d=0,c=P.length;d<c;d++)y=P[d],this.model.oauth.scopes.push(y);if("undefined"!=typeof this.model.responses){this.model.responseMessages=[],S=this.model.responses;for(r in S)q=S[r],C=null,I=this.model.responses[r].schema,I&&I.$ref&&(C=I.$ref,C.indexOf("#/definitions/")!==-1&&(C=C.replace(/^.*#\/definitions\//,""))),this.model.responseMessages.push({code:r,message:q.description,responseModel:C,headers:q.headers,schema:I})}if("undefined"==typeof this.model.responseMessages&&(this.model.responseMessages=[]),L=null,B=this.model.produces,z=this.contains(B,"xml"),N=!z||this.contains(B,"json"),this.model.successResponse){R=this.model.successResponse;for(s in R)q=R[s],this.model.successCode=s,"object"==typeof q&&"function"==typeof q.createJSONSample?(this.model.successDescription=q.description,this.model.headers=this.parseResponseHeaders(q.headers),L={sampleJSON:!!N&&JSON.stringify(SwaggerUi.partials.signature.createJSONSample(q),void 0,2),isParam:!1,sampleXML:!!z&&SwaggerUi.partials.signature.createXMLSample(q.name,q.definition,q.models),signature:SwaggerUi.partials.signature.getModelSignature(q.name,q.definition,q.models,q.modelPropertyMacro)}):L={signature:SwaggerUi.partials.signature.getPrimitiveSignature(q)}}else this.model.responseClassSignature&&"string"!==this.model.responseClassSignature&&(L={sampleJSON:this.model.responseSampleJSON,isParam:!1,signature:this.model.responseClassSignature});for($(this.el).html(Handlebars.templates.operation(this.model)),L?(L.defaultRendering=this.model.defaultRendering,T=new SwaggerUi.Views.SignatureView({model:L,router:this.router,tagName:"div"}),$(".model-signature",$(this.el)).append(T.render().el)):(this.model.responseClassSignature="string",$(".model-signature",$(this.el)).html(this.model.type)),i={isParam:!1},i.consumes=this.model.consumes,i.produces=this.model.produces,j=this.model.parameters,g=0,p=j.length;g<p;g++)b=j[g],U=b.type||b.dataType||"","undefined"==typeof U&&(C=b.schema,C&&C.$ref&&(x=C.$ref,U=0===x.indexOf("#/definitions/")?x.substring("#/definitions/".length):x)),U&&"file"===U.toLowerCase()&&(i.consumes||(i.consumes="multipart/form-data")),b.type=U;for(k=new SwaggerUi.Views.ResponseContentTypeView({model:i,router:this.router}),$(".response-content-type",$(this.el)).append(k.render().el),E=this.model.parameters,v=0,h=E.length;v<h;v++)b=E[v],this.addParameter(b,i.consumes);for(O=this.model.responseMessages,w=0,f=O.length;w<f;w++)M=O[w],M.isXML=z,M.isJSON=N,_.isUndefined(M.headers)||(M.headers=this.parseHeadersType(M.headers)),this.addStatusCode(M);if(Array.isArray(this.model.security)){var F=SwaggerUi.utils.parseSecurityDefinitions(this.model.security,this.model.parent.securityDefinitions);F.isLogout=!_.isEmpty(this.model.clientAuthorizations.authz),this.authView=new SwaggerUi.Views.AuthButtonView({data:F,router:this.router,isOperation:!0,model:{scopes:F.scopes}}),this.$(".authorize-wrapper").append(this.authView.render().el)}return this.showSnippet(),this},parseHeadersType:function(e){var t={string:{"date-time":"dateTime",date:"date"}};return _.forEach(e,function(e){var n;e=e||{},n=t[e.type]&&t[e.type][e.format],_.isUndefined(n)||(e.type=n)}),e},contains:function(e,t){return e.filter(function(e){if(e.indexOf(t)>-1)return!0}).length},parseResponseHeaders:function(e){var t="; ",n=_.clone(e);return _.forEach(n,function(e){var n=[];_.forEach(e,function(e,t){var r=["type","description"];r.indexOf(t.toLowerCase())===-1&&n.push(t+": "+e)}),n.join(t),e.other=n}),n},addParameter:function(e,t){e.consumes=t,e.defaultRendering=this.model.defaultRendering,e.schema&&($.extend(!0,e.schema,this.model.definitions[e.type]),e.schema.definitions=this.model.definitions,e.schema.type||(e.schema.type="object"),e.schema.title||(e.schema.title=" "));var n=new SwaggerUi.Views.ParameterView({model:e,tagName:"tr",readOnly:this.model.isReadOnly,swaggerOptions:this.options.swaggerOptions});$(".operation-params",$(this.el)).append(n.render().el)},addStatusCode:function(e){e.defaultRendering=this.model.defaultRendering;var t=new SwaggerUi.Views.StatusCodeView({model:e,tagName:"tr",router:this.router});$(".operation-status",$(this.el)).append(t.render().el)},submitOperation:function(e){var t,n,r,i,a;if(null!==e&&e.preventDefault(),n=$(".sandbox",$(this.el)),t=!0,n.find("input.required").each(function(){$(this).removeClass("error"),""===jQuery.trim($(this).val())&&($(this).addClass("error"),$(this).wiggle({callback:function(e){return function(){$(e).focus()}}(this)}),t=!1)}),n.find("textarea.required:visible").each(function(){$(this).removeClass("error"),""===jQuery.trim($(this).val())&&($(this).addClass("error"),$(this).wiggle({callback:function(e){return function(){return $(e).focus()}}(this)}),t=!1)}),n.find("select.required").each(function(){$(this).removeClass("error"),this.selectedIndex===-1&&($(this).addClass("error"),$(this).wiggle({callback:function(e){return function(){$(e).focus()}}(this)}),t=!1)}),t){if(i=this.getInputMap(n),r=this.isFileUpload(n),a={parent:this},this.options.swaggerOptions)for(var o in this.options.swaggerOptions)a[o]=this.options.swaggerOptions[o];var s;for(s=0;s<this.model.parameters.length;s++){var l=this.model.parameters[s];if(l.jsonEditor&&l.jsonEditor.isEnabled()){var u=l.jsonEditor.getValue();i[l.name]=JSON.stringify(u)}}return a.responseContentType=$("div select[name=responseContentType]",$(this.el)).val(),a.requestContentType=$("div select[name=parameterContentType]",$(this.el)).val(),$(".response_throbber",$(this.el)).show(),r?($(".request_url",$(this.el)).html("<pre></pre>"),$(".request_url pre",$(this.el)).text(this.invocationUrl),a.useJQuery=!0,i.parameterContentType="multipart/form-data",this.map=i,this.model.execute(i,a,this.showCompleteStatus,this.showErrorStatus,this)):(this.map=i,this.model.execute(i,a,this.showCompleteStatus,this.showErrorStatus,this))}},getInputMap:function(e){var t,n,r,i,a,o,s,l,u,c,p,h;for(t={},n=e.find("input"),r=0,i=n.length;r<i;r++)a=n[r],null!==a.value&&jQuery.trim(a.value).length>0&&(t[a.name]=a.value),"file"===a.type&&(t[a.name]=a.files[0]);for(o=e.find("textarea"),s=0,l=o.length;s<l;s++)a=o[s],u=this.getTextAreaValue(a),null!==u&&jQuery.trim(u).length>0&&(t[a.name]=u);for(c=e.find("select"),p=0,h=c.length;p<h;p++)a=c[p],u=this.getSelectedValue(a),null!==u&&jQuery.trim(u).length>0&&(t[a.name]=u);return t},isFileUpload:function(e){var t,n,r,i,a=!1;for(t=e.find("input"),n=0,r=t.length;n<r;n++)i=t[n],"file"===i.type&&(a=!0);return a},success:function(e,t){t.showCompleteStatus(e)},wrap:function(e){var t,n,r,i,a,o,s;for(r={},n=e.getAllResponseHeaders().split("\r"),a=0,o=n.length;a<o;a++)i=n[a],t=i.match(/^([^:]*?):(.*)$/),t||(t=[]),t.shift(),void 0!==t[0]&&void 0!==t[1]&&(r[t[0].trim()]=t[1].trim());return s={},s.content={},s.content.data=e.responseText,s.headers=r,s.request={},s.request.url=this.invocationUrl,s.status=e.status,s},getSelectedValue:function(e){if(e.multiple){for(var t=[],n=0,r=e.options.length;n<r;n++){var i=e.options[n];i.selected&&t.push(i.value)}return t.length>0?t:null}return e.value},hideResponse:function(e){e&&e.preventDefault(),$(".response",$(this.el)).slideUp(),$(".response_hider",$(this.el)).fadeOut()},showResponse:function(e){var t=JSON.stringify(e,null,"\t").replace(/\n/g,"<br>");$(".response_body",$(this.el)).html(_.escape(t))},showErrorStatus:function(e,t){t.showStatus(e)},showCompleteStatus:function(e,t){t.showStatus(e)},formatXml:function(e){var t,n,r,i,a,o,s,l,u,c,p,h,f;for(p=/(>)(<)(\/*)/g,f=/[ ]*(.*)[ ]+\n/g,t=/(<.+>)(.+\n)/g,e=e.replace(/\r\n/g,"\n").replace(p,"$1\n$2$3").replace(f,"$1\n").replace(t,"$1\n$2"),c=0,r="",l=e.split("\n"),i=0,o="other",h={"single->single":0,"single->closing":-1,"single->opening":0,"single->other":0,"closing->single":0,"closing->closing":-1,"closing->opening":0,"closing->other":0,"opening->single":1,"opening->closing":0,"opening->opening":1,"opening->other":1,"other->single":0,"other->closing":-1,"other->opening":0,"other->other":0},n=function(e){var t,n,a,s,l,u,c;u={single:Boolean(e.match(/<.+\/>/)),closing:Boolean(e.match(/<\/.+>/)),opening:Boolean(e.match(/<[^!?].*>/))},l=function(){var e;e=[];for(a in u)c=u[a],c&&e.push(a);return e}()[0],l=void 0===l?"other":l,t=o+"->"+l,o=l,s="",i+=h[t],s=function(){var e,t,r;for(r=[],n=e=0,t=i;0<=t?e<t:e>t;n=0<=t?++e:--e)r.push("  ");return r}().join(""),"opening->closing"===t?r=r.substr(0,r.length-1)+e+"\n":r+=s+e+"\n"},a=0,s=l.length;a<s;a++)u=l[a],n(u);return r},showStatus:function(e){var t,n;void 0===e.content?(n=e.data,t=e.url):(n=e.content.data,t=e.request.url);var r=e.headers;"string"==typeof n&&(n=jQuery.trim(n));var i=null;r&&(i=r["Content-Type"]||r["content-type"],i&&(i=i.split(";")[0].trim())),$(".response_body",$(this.el)).removeClass("json"),$(".response_body",$(this.el)).removeClass("xml");var a,o,s=function(e){var t=document.createElement("audio");return!(!t.canPlayType||!t.canPlayType(e).replace(/no/,""))},l=!1;if(n)if("application/octet-stream"===i||r["Content-Disposition"]&&/attachment/.test(r["Content-Disposition"])||r["content-disposition"]&&/attachment/.test(r["content-disposition"])||r["Content-Description"]&&/File Transfer/.test(r["Content-Description"])||r["content-description"]&&/File Transfer/.test(r["content-description"]))if("Blob"in window){var u,c=i||"text/html",p=document.createElement("a");if("[object Blob]"==={}.toString.apply(n))u=window.URL.createObjectURL(n);else{var h=[];h.push(n),u=window.URL.createObjectURL(new Blob(h,{type:c}))}var f=e.url.substr(e.url.lastIndexOf("/")+1),d=[c,f,u].join(":"),m=r["content-disposition"]||r["Content-Disposition"];if("undefined"!=typeof m){var g=/filename=([^;]*);?/.exec(m);null!==g&&g.length>1&&(d=g[1],f=d)}p.setAttribute("href",u),p.setAttribute("download",d),p.innerText="Download "+f,a=$("<div/>").append(p),l=!0}else a=$('<pre class="json" />').append("Download headers detected but your browser does not support downloading binary via XHR (Blob).");else if("application/json"===i||/\+json$/.test(i)){var y=null;try{y=JSON.stringify(JSON.parse(n),null,"  ")}catch(v){y="can't parse JSON.  Raw result:\n\n"+n}o=$("<code />").text(y),a=$('<pre class="json" />').append(o)}else if("application/xml"===i||/\+xml$/.test(i))o=$("<code />").text(this.formatXml(n)),a=$('<pre class="xml" />').append(o);else if("text/html"===i)o=$("<code />").html(_.escape(n)),a=$('<pre class="xml" />').append(o);else if(/text\/plain/.test(i))o=$("<code />").text(n),a=$('<pre class="plain" />').append(o);else if(/^image\//.test(i)){var b=window.URL||window.webkitURL,w=b.createObjectURL(n);a=$("<img>").attr("src",w)}else/^audio\//.test(i)&&s(i)?a=$("<audio controls>").append($("<source>").attr("src",t).attr("type",i)):r.location||r.Location?window.location=e.url:(o=$("<code />").text(n),a=$('<pre class="json" />').append(o));else o=$("<code />").text("no content"),a=$('<pre class="json" />').append(o);var x=a;$(".request_url",$(this.el)).html("<pre></pre>"),$(".request_url pre",$(this.el)).text(t),$(".response_code",$(this.el)).html("<pre>"+e.status+"</pre>"),$(".response_body",$(this.el)).html(x),$(".response_headers",$(this.el)).html("<pre>"+_.escape(JSON.stringify(e.headers,null,"  ")).replace(/\n/g,"<br>")+"</pre>"),$(".response",$(this.el)).slideDown(),$(".response_hider",$(this.el)).show(),$(".response_throbber",$(this.el)).hide();var A=this.model.asCurl(this.map,{responseContentType:i});A=A.replace("!","&#33;"),$("div.curl",$(this.el)).html("<pre>"+_.escape(A)+"</pre>");var S=this.options.swaggerOptions;if(S.showRequestHeaders){var j=$(".sandbox",$(this.el)),E=this.getInputMap(j),O=this.model.getHeaderParams(E);delete O["Content-Type"],$(".request_headers",$(this.el)).html("<pre>"+_.escape(JSON.stringify(O,null,"  ")).replace(/\n/g,"<br>")+"</pre>")}S.responseHooks&&S.responseHooks[this.nickname]&&S.responseHooks[this.nickname](e,this);var k=$(".response_body",$(this.el))[0];return S.highlightSizeThreshold&&"undefined"!=typeof e.data&&e.data.length>S.highlightSizeThreshold||l?k:hljs.highlightBlock(k)},toggleOperationContent:function(e){var t=$("#"+Docs.escapeResourceName(this.parentId+"_"+this.nickname+"_content"));t.is(":visible")?($.bbq.pushState("#/",2),e.preventDefault(),Docs.collapseOperation(t)):Docs.expandOperation(t)},getTextAreaValue:function(e){var t,n,r,i;if(null===e.value||0===jQuery.trim(e.value).length)return null;if(t=this.getParamByName(e.name),t&&t.type&&"array"===t.type.toLowerCase()){for(n=e.value.split("\n"),r=[],i=0;i<n.length;i++)null!==n[i]&&jQuery.trim(n[i]).length>0&&r.push(n[i]);return r.length>0?r:null}return e.value},showSnippet:function(){var e,t=this.$("[name=responseContentType]"),n=this.$(".operation-status .snippet_xml, .response-class .snippet_xml"),r=this.$(".operation-status .snippet_json, .response-class .snippet_json");t.length&&(e=t.val(),e.indexOf("xml")>-1?(n.show(),r.hide()):(r.show(),n.hide()))},getParamByName:function(e){var t;if(this.model.parameters)for(t=0;t<this.model.parameters.length;t++)if(this.model.parameters[t].name===e)return this.model.parameters[t];return null}}),SwaggerUi.Views.ParameterContentTypeView=Backbone.View.extend({initialize:function(){},render:function(){return this.model.parameterContentTypeId="pct"+Math.random(),$(this.el).html(Handlebars.templates.parameter_content_type(this.model)),this}}),SwaggerUi.Views.ParameterView=Backbone.View.extend({events:{"change [name=parameterContentType]":"toggleParameterSnippet"},initialize:function(){Handlebars.registerHelper("isArray",function(e,t){var n=e.type&&e.type.toLowerCase();return"array"===n||e.allowMultiple?t.fn(this):t.inverse(this)})},render:function(){var e,t,n=this.model.type||this.model.dataType,r=this.model.modelSignature.type,i=this.model.modelSignature.definitions,a=this.model.schema||{},o=this.model.consumes||[];if("undefined"==typeof n&&a.$ref){var s=a.$ref;n=0===s.indexOf("#/definitions/")?s.substring("#/definitions/".length):s}this.model.type=n,this.model.paramType=this.model["in"]||this.model.paramType,this.model.isBody="body"===this.model.paramType||"body"===this.model["in"],this.model.isFile=n&&"file"===n.toLowerCase(),"undefined"==typeof this.model["default"]&&(this.model["default"]=this.model.defaultValue),this.model.hasDefault="undefined"!=typeof this.model["default"],this.model.valueId="m"+this.model.name+Math.random(),this.model.allowableValues&&(this.model.isList=!0);var l=this.contains(o,"xml"),u=!l||this.contains(o,"json");e=SwaggerUi.partials.signature.createParameterJSONSample(r,i);var c=this.template();$(this.el).html(c(this.model));var p={sampleJSON:!!u&&e,sampleXML:!(!e||!l)&&SwaggerUi.partials.signature.createXMLSample("",a,i,!0),isParam:!0,signature:SwaggerUi.partials.signature.getParameterModelSignature(r,i),defaultRendering:this.model.defaultRendering};e?(t=new SwaggerUi.Views.SignatureView({model:p,tagName:"div"}),$(".model-signature",$(this.el)).append(t.render().el)):$(".model-signature",$(this.el)).html(this.model.signature);var h=!1;if(this.options.swaggerOptions.jsonEditor&&this.model.isBody&&this.model.schema){var f=$(this.el);this.model.jsonEditor=new JSONEditor($(".editor_holder",f)[0],{schema:this.model.schema,startval:this.model["default"],ajax:!0,disable_properties:!0,disable_edit_json:!0,iconlib:"swagger"}),p.jsonEditor=this.model.jsonEditor,$(".body-textarea",f).hide(),$(".editor_holder",f).show(),$(".parameter-content-type",f).change(function(e){"application/xml"===e.target.value?($(".body-textarea",f).show(),$(".editor_holder",f).hide(),this.model.jsonEditor.disable()):($(".body-textarea",f).hide(),$(".editor_holder",f).show(),this.model.jsonEditor.enable())})}this.model.isBody&&(h=!0);var d={isParam:h};if(d.consumes=this.model.consumes,h){var m=new SwaggerUi.Views.ParameterContentTypeView({model:d});$(".parameter-content-type",$(this.el)).append(m.render().el),this.toggleParameterSnippet()}else{var g=new SwaggerUi.Views.ResponseContentTypeView({model:d});$(".response-content-type",$(this.el)).append(g.render().el),this.toggleResponseSnippet()}return this},contains:function(e,t){return e.filter(function(e){if(e.indexOf(t)>-1)return!0}).length},toggleParameterSnippet:function(){var e=this.$("[name=parameterContentType]").val();this.toggleSnippet(e)},toggleResponseSnippet:function(){var e=this.$("[name=responseContentType]");e.length&&this.toggleSnippet(e.val())},toggleSnippet:function(e){e=e||"",e.indexOf("xml")>-1?(this.$(".snippet_xml").show(),this.$(".snippet_json").hide()):(this.$(".snippet_json").show(),this.$(".snippet_xml").hide())},template:function(){return this.model.isList?Handlebars.templates.param_list:this.options.readOnly?this.model.required?Handlebars.templates.param_readonly_required:Handlebars.templates.param_readonly:this.model.required?Handlebars.templates.param_required:Handlebars.templates.param}}),SwaggerUi.partials.signature=function(){function e(e){var t,i=e.name,a=e.definition,o=e.config,s=e.models,l=e.config.isParam,u=[],c=a.properties,p=a.additionalProperties,h=a.xml,f=b(h);return f&&u.push(f),c||p?(c=c||{},t=_.map(c,function(e,t){var n,i;return l&&e.readOnly?"":(n=e.xml||{},i=r(t,e,s,o),n.attribute?(u.push(i),""):i)}).join(""),p&&(t+="<!-- additional elements allowed -->"),y(i,t,u)):n()}function t(e,t){return y(e,"<!-- Infinite loop $ref:"+t+" -->")}function n(e){return e=e?": "+e:"","<!-- invalid XML"+e+" -->"}function r(r,i,s,l){var u,c,p=_.isObject(i)?i.$ref:null;l=l||{},l.modelsToIgnore=l.modelsToIgnore||[];var h=_.isString(p)?a(p,r,s,l):o(r,i,s,l);if(!h)return n();switch(h.type){case"array":u=w(h);break;case"object":u=e(h);break;case"loop":u=t(h.name,h.config.loopTo);break;default:u=A(h)}return p&&"loop"!==h.type&&(c=l.modelsToIgnore.indexOf(p),c>-1&&l.modelsToIgnore.splice(c,1)),u}function i(e,t,n,r,i){if(arguments.length<4)throw new Error;this.config=i||{},this.config.modelsToIgnore=this.config.modelsToIgnore||[],this.name=v(e,n.xml),this.definition=n,this.models=r,this.type=t}function a(e,t,n,r){var a=u(e),o=n[a]||{},s=o.definition&&o.definition.type?o.definition.type:"object";return t=o.definition&&o.definition.xml&&o.definition.xml.name?t||o.definition.xml.name||o.name:t||o.name,r.modelsToIgnore.indexOf(e)>-1?(s="loop",r.loopTo=a):r.modelsToIgnore.push(e),o.definition?new i(t,s,o.definition,n,r):null}function o(e,t,n,r){var a=t.type||"object";return t.xml&&t.xml.name&&(e=t.xml.name||e),t?new i(e,a,t,n,r):null}function s(e,t,n,i){var a='<?xml version="1.0"?>';return p(a+r(e,t,n,{isParam:i}))}var l=function(e){return _.isPlainObject(e.schema)&&(e=l(e.schema)),e},u=function(e){return"undefined"==typeof e?null:0===e.indexOf("#/definitions/")?e.substring("#/definitions/".length):e},c=function(e){if(/^Inline Model \d+$/.test(e)&&this.inlineModels){var t=parseInt(e.substr("Inline Model".length).trim(),10),n=this.inlineModels[t];return n}return null},p=function(e){var t,n,r,i,a,o,s,l,u,c,p,h,f;for(p=/(>)(<)(\/*)/g,f=/[ ]*(.*)[ ]+\n/g,t=/(<.+>)(.+\n)/g,e=e.replace(p,"$1\n$2$3").replace(f,"$1\n").replace(t,"$1\n$2"),c=0,r="",l=e.split("\n"),i=0,o="other",h={"single->single":0,"single->closing":-1,"single->opening":0,"single->other":0,"closing->single":0,"closing->closing":-1,"closing->opening":0,"closing->other":0,"opening->single":1,"opening->closing":0,"opening->opening":1,"opening->other":1,"other->single":0,"other->closing":-1,"other->opening":0,"other->other":0},n=function(e){var t,n,a,s,l,u,c;u={single:Boolean(e.match(/<.+\/>/)),closing:Boolean(e.match(/<\/.+>/)),opening:Boolean(e.match(/<[^!?].*>/))},l=function(){var e;e=[];for(a in u)c=u[a],c&&e.push(a);return e}()[0],l=void 0===l?"other":l,t=o+"->"+l,o=l,s="",i+=h[t],s=function(){var e,t,r;for(r=[],n=e=0,t=i;0<=t?e<t:e>t;n=0<=t?++e:--e)r.push("  ");return r}().join(""),"opening->closing"===t?r=r.substr(0,r.length-1)+e+"\n":r+=s+e+"\n"},a=0,s=l.length;a<s;a++)u=l[a],n(u);return r},h=function(e,t,n,r){function i(e,t,r){var i,a=t;return e.$ref?(a=e.title||u(e.$ref),i=n[u(e.$ref)]):_.isUndefined(t)&&(a=e.title||"Inline Model "+ ++m,i={definition:e}),r!==!0&&(f[a]=_.isUndefined(i)?{}:i.definition),a}function a(e){var t='<span class="propType">',n=e.type||"object";return e.$ref?t+=i(e,u(e.$ref)):"object"===n?t+=_.isUndefined(e.properties)?"object":i(e):"array"===n?(t+="Array[",_.isArray(e.items)?t+=_.map(e.items,i).join(","):_.isPlainObject(e.items)?t+=_.isUndefined(e.items.$ref)?_.isUndefined(e.items.type)||_.indexOf(["array","object"],e.items.type)!==-1?i(e.items):e.items.type:i(e.items,u(e.items.$ref)):(console.log("Array type's 'items' schema is not an array or an object, cannot process"),t+="object"),t+="]"):t+=e.type,t+="</span>"}function o(e,t){var n="",r=e.type||"object",i="array"===r;switch(_.isUndefined(e.description)||(t+=': <span class="propDesc">'+e.description+"</span>"),e["enum"]&&(t+=' = <span class="propVals">[\''+e["enum"].join("', '")+"']</span>"),i&&(r=_.isPlainObject(e.items)&&!_.isUndefined(e.items.type)?e.items.type:"object"),_.isUndefined(e["default"])||(n+=h("Default",e["default"])),r){case"string":e.minLength&&(n+=h("Min. Length",e.minLength)),e.maxLength&&(n+=h("Max. Length",e.maxLength)),e.pattern&&(n+=h("Reg. Exp.",e.pattern));break;case"integer":case"number":e.minimum&&(n+=h("Min. Value",e.minimum)),e.exclusiveMinimum&&(n+=h("Exclusive Min.","true")),e.maximum&&(n+=h("Max. Value",e.maximum)),e.exclusiveMaximum&&(n+=h("Exclusive Max.","true")),e.multipleOf&&(n+=h("Multiple Of",e.multipleOf))}if(i&&(e.minItems&&(n+=h("Min. Items",e.minItems)),e.maxItems&&(n+=h("Max. Items",e.maxItems)),e.uniqueItems&&(n+=h("Unique Items","true")),e.collectionFormat&&(n+=h("Coll. Format",e.collectionFormat))),_.isUndefined(e.items)&&_.isArray(e["enum"])){var a;a="number"===r||"integer"===r?e["enum"].join(", "):'"'+e["enum"].join('", "')+'"',n+=h("Enum",a)}return n.length>0&&(t='<span class="propWrap">'+t+'<table class="optionsWrapper"><tr><th colspan="2">'+r+"</th></tr>"+n+"</table></span>"),t}function s(e,t){var s,h=e.type||"object",f="array"===e.type,m=c+t+" "+(f?"[":"{")+p;return t&&d.push(t),f?_.isArray(e.items)?m+="<div>"+_.map(e.items,function(e){var t=e.type||"object";return _.isUndefined(e.$ref)?_.indexOf(["array","object"],t)>-1?"object"===t&&_.isUndefined(e.properties)?"object":i(e):o(e,t):i(e,u(e.$ref))}).join(",</div><div>"):_.isPlainObject(e.items)?m+=_.isUndefined(e.items.$ref)?_.indexOf(["array","object"],e.items.type||"object")>-1?(_.isUndefined(e.items.type)||"object"===e.items.type)&&_.isUndefined(e.items.properties)?"<div>object</div>":"<div>"+i(e.items)+"</div>":"<div>"+o(e.items,e.items.type)+"</div>":"<div>"+i(e.items,u(e.items.$ref))+"</div>":(console.log("Array type's 'items' property is not an array or an object, cannot process"),m+="<div>object</div>"):e.$ref?m+="<div>"+i(e,t)+"</div>":"object"===h?(_.isPlainObject(e.properties)&&(s=_.map(e.properties,function(t,i){var s,c=_.indexOf(e.required,i)>=0,p=_.cloneDeep(t),h=c?"required":"",f='<span class="propName '+h+'">'+i+"</span> (";return p["default"]=r(p),p=l(p),_.isUndefined(p.$ref)||(s=n[u(p.$ref)],_.isUndefined(s)||_.indexOf([void 0,"array","object"],s.definition.type)!==-1||(p=l(s.definition))),f+=a(p),c||(f+=', <span class="propOptKey">optional</span>'),t.readOnly&&(f+=', <span class="propReadOnly">read only</span>'),f+=")","<div"+(t.readOnly?' class="readOnly"':"")+">"+o(p,f)}).join(",</div>")),s&&(m+=s+"</div>")):m+="<div>"+o(e,h)+"</div>",m+c+(f?"]":"}")+p}var c='<span class="strong">',p="</span>",h=function(e,t){return'<tr><td class="optionName">'+e+":</td><td>"+t+"</td></tr>"};if(_.isObject(arguments[0])&&(e=void 0,t=arguments[0],n=arguments[1],r=arguments[2]),n=n||{},t=l(t),_.isEmpty(t))return c+"Empty"+p;if("string"==typeof t.$ref&&(e=u(t.$ref),t=n[e],"undefined"==typeof t))return c+e+" is not defined!"+p;"string"!=typeof e&&(e=t.title||"Inline Model"),t.definition&&(t=t.definition),"function"!=typeof r&&(r=function(e){return(e||{})["default"]});for(var f={},d=[],m=0,g=s(t,e);_.keys(f).length>0;)_.forEach(f,function(e,t){var n=_.indexOf(d,t)>-1;delete f[t],n||(d.push(t),g+="<br />"+s(e,t))});return g},f=function(e,t,n,r){e=l(e),"function"!=typeof r&&(r=function(e){return(e||{})["default"]}),n=n||{};var i,a,o=e.type||"object",s=e.format;return _.isUndefined(e.example)?_.isUndefined(e.items)&&_.isArray(e["enum"])&&(a=e["enum"][0]):a=e.example,_.isUndefined(a)&&(e.$ref?(i=t[u(e.$ref)],_.isUndefined(i)||(_.isUndefined(n[i.name])?(n[i.name]=i,a=f(i.definition,t,n,r),delete n[i.name]):a="array"===i.type?[]:{})):_.isUndefined(e["default"])?"string"===o?a="date-time"===s?(new Date).toISOString():"date"===s?(new Date).toISOString().split("T")[0]:"string":"integer"===o?a=0:"number"===o?a=0:"boolean"===o?a=!0:"object"===o?(a={},_.forEach(e.properties,function(e,i){var o=_.cloneDeep(e);o["default"]=r(e),a[i]=f(o,t,n,r)})):"array"===o&&(a=[],_.isArray(e.items)?_.forEach(e.items,function(e){a.push(f(e,t,n,r))}):_.isPlainObject(e.items)?a.push(f(e.items,t,n,r)):_.isUndefined(e.items)?a.push({}):console.log("Array type's 'items' property is not an array or an object, cannot process")):a=e["default"]),a},d=function(e,t){if(t=t||{},t[e.name]=e,e.examples&&_.isPlainObject(e.examples)){e=_.cloneDeep(e);var n=Object.keys(e.examples);_.forEach(n,function(n){if(0===n.indexOf("application/json")){var r=e.examples[n];return _.isString(r)&&(r=jsyaml.safeLoad(r)),e.definition.example=r,f(e.definition,r,t,e.modelPropertyMacro)}})}if(e.examples){e=_.cloneDeep(e);var r=e.examples;return _.isString(r)&&(r=jsyaml.safeLoad(r)),e.definition.example=r,f(e.definition,r,t,e.modelPropertyMacro)}return f(e.definition,e.models,t,e.modelPropertyMacro)},m=function(e,t){var n,r;return e instanceof Array&&(r=!0,e=e[0]),"undefined"==typeof e?(e="undefined",n=!0):t[e]?(e=t[e],n=!1):c(e)?(e=c(e),n=!1):n=!0,n?r?"Array["+e+"]":e.toString():r?"Array["+h(e.name,e.definition,e.models,e.modelPropertyMacro)+"]":h(e.name,e.definition,e.models,e.modelPropertyMacro)},g=function(e,t){var n,r,i;if(t=t||{},n=e instanceof Array,i=n?e[0]:e,t[i]?r=d(t[i]):c(i)&&(r=d(c(i))),r){if(r=n?[r]:r,"string"==typeof r)return r;if(_.isObject(r)){var a=r;if(r instanceof Array&&r.length>0&&(a=r[0]),a.nodeName&&"Node"==typeof a){var o=(new XMLSerializer).serializeToString(a);return p(o)}return JSON.stringify(r,null,2)}return r}},y=function(e,t,r){var i,a;return r=r||[],a=r.map(function(e){return" "+e.name+'="'+e.value+'"'}).join(""),e?(i=["<",e,a,">",t,"</",e,">"],i.join("")):n("Node name is not provided")},v=function(e,t){var n=e||"";return t=t||{},t.prefix&&(n=t.prefix+":"+n),n},b=function(e){var t="",n="xmlns";return e=e||{},e.namespace?(t=e.namespace,e.prefix&&(n+=":"+e.prefix),{name:n,value:t}):t},w=function(e){var t,i=e.name,a=e.config,o=e.definition,s=e.models,l=o.items,u=o.xml||{},c=b(u),p=[];if(!l)return n();var h=i;return l.xml&&l.xml.name&&(h=l.xml.name),t=r(h,l,s,a),c&&p.push(c),u.wrapped&&(t=y(i,t,p)),t},x=function(e){var t,n;switch(e=e||{},n=e.items||{},t=e.type||""){case"object":return"Object is not a primitive";case"array":return"Array["+(n.format||n.type)+"]";default:return e.format||t}},A=function(e){var t,r=e.name,i=e.definition,a={string:{date:new Date(1).toISOString().split("T")[0],"date-time":new Date(1).toISOString(),"default":"string"},integer:{"default":1},number:{"default":1.1},"boolean":{"default":!0}},o=i.type,s=i.format,l=i.xml||{},u=b(l),c=[];return _.keys(a).indexOf(o)<0?n():(t=_.isArray(i["enum"])?i["enum"][0]:i.example||a[o][s]||a[o]["default"],l.attribute?{name:r,value:t}:(u&&c.push(u),y(r,t,c)))};return{getModelSignature:h,createJSONSample:d,getParameterModelSignature:m,createParameterJSONSample:g,createSchemaXML:r,createXMLSample:s,getPrimitiveSignature:x}}(),SwaggerUi.Views.PopupView=Backbone.View.extend({events:{"click .api-popup-cancel":"cancelClick"},template:Handlebars.templates.popup,className:"api-popup-dialog",selectors:{content:".api-popup-content",main:"#swagger-ui-container"},initialize:function(){this.$el.html(this.template(this.model))},render:function(){return this.$(this.selectors.content).append(this.model.content),$(this.selectors.main).first().append(this.el),this.showPopup(),this},showPopup:function(){this.$el.show()},cancelClick:function(){this.remove()}}),SwaggerUi.Views.ResourceView=Backbone.View.extend({initialize:function(e){e=e||{},this.router=e.router,this.auths=e.auths,""===this.model.description&&(this.model.description=null),this.model.description&&(this.model.summary=this.model.description),this.number=0},render:function(){var e={};$(this.el).html(Handlebars.templates.resource(this.model));for(var t=0;t<this.model.operationsArray.length;t++){for(var n=this.model.operationsArray[t],r=0,i=n.nickname;"undefined"!=typeof e[i];)i=i+"_"+r,r+=1;e[i]=n,n.nickname=i,n.parentId=this.model.id,n.definitions=this.model.definitions,this.addOperation(n)}return $(".toggleEndpointList",this.el).click(this.callDocs.bind(this,"toggleEndpointListForResource")),$(".collapseResource",this.el).click(this.callDocs.bind(this,"collapseOperationsForResource")),$(".expandResource",this.el).click(this.callDocs.bind(this,"expandOperationsForResource")),this},addOperation:function(e){e.number=this.number;var t=new SwaggerUi.Views.OperationView({model:e,router:this.router,tagName:"li",className:"endpoint",swaggerOptions:this.options.swaggerOptions,auths:this.auths});$(".endpoints",$(this.el)).append(t.render().el),this.number++},callDocs:function(e,t){t.preventDefault(),Docs[e](t.currentTarget.getAttribute("data-id"))}}),SwaggerUi.Views.ResponseContentTypeView=Backbone.View.extend({initialize:function(){},render:function(){return this.model.responseContentTypeId="rct"+Math.random(),$(this.el).html(Handlebars.templates.response_content_type(this.model)),this}}),SwaggerUi.Views.SignatureView=Backbone.View.extend({events:{"click a.description-link":"switchToDescription","click a.snippet-link":"switchToSnippet","mousedown .snippet_json":"jsonSnippetMouseDown","mousedown .snippet_xml":"xmlSnippetMouseDown"},initialize:function(){},render:function(){return $(this.el).html(Handlebars.templates.signature(this.model)),"model"===this.model.defaultRendering?this.switchToDescription():this.switchToSnippet(),this},switchToDescription:function(e){e&&e.preventDefault(),$(".snippet",$(this.el)).hide(),$(".description",$(this.el)).show(),$(".description-link",$(this.el)).addClass("selected"),$(".snippet-link",$(this.el)).removeClass("selected")},switchToSnippet:function(e){e&&e.preventDefault(),$(".snippet",$(this.el)).show(),$(".description",$(this.el)).hide(),$(".snippet-link",$(this.el)).addClass("selected"),$(".description-link",$(this.el)).removeClass("selected")},snippetToTextArea:function(e){var t=$("textarea",$(this.el.parentNode.parentNode.parentNode));""!==$.trim(t.val())&&t.prop("placeholder")!==t.val()||(t.val(e),
+this.model.jsonEditor&&this.model.jsonEditor.isEnabled()&&this.model.jsonEditor.setValue(JSON.parse(this.model.sampleJSON)))},jsonSnippetMouseDown:function(e){this.model.isParam&&(e&&e.preventDefault(),this.snippetToTextArea(this.model.sampleJSON))},xmlSnippetMouseDown:function(e){this.model.isParam&&(e&&e.preventDefault(),this.snippetToTextArea(this.model.sampleXML))}}),SwaggerUi.Views.StatusCodeView=Backbone.View.extend({initialize:function(e){this.options=e||{},this.router=this.options.router},render:function(){var e,t,n=this.router.api.models[this.model.responseModel];return $(this.el).html(Handlebars.templates.status_code(this.model)),e=this.router.api.models.hasOwnProperty(this.model.responseModel)?{sampleJSON:JSON.stringify(SwaggerUi.partials.signature.createJSONSample(n),void 0,2),sampleXML:!!this.model.isXML&&SwaggerUi.partials.signature.createXMLSample("",this.model.schema,this.router.api.models),isParam:!1,signature:SwaggerUi.partials.signature.getModelSignature(this.model.responseModel,n,this.router.api.models),defaultRendering:this.model.defaultRendering}:{signature:SwaggerUi.partials.signature.getPrimitiveSignature(this.model.schema)},t=new SwaggerUi.Views.SignatureView({model:e,tagName:"div"}),$(".model-signature",this.$el).append(t.render().el),this}})}).call(this);
diff --git a/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/swagger.json b/ms/controllerblueprints/application/src/main/resources/swagger-ui/dist/swagger.json
new file mode 100644 (file)
index 0000000..da9859b
--- /dev/null
@@ -0,0 +1,1957 @@
+{\r
+  "swagger" : "2.0",\r
+  "info" : {\r
+    "version" : "0.3.0-SNAPSHOT",\r
+    "title" : "Controller Blueprint Service"\r
+  },\r
+  "basePath" : "/api/controller-blueprints/v1",\r
+  "schemes" : [ "http", "https" ],\r
+  "paths" : {\r
+    "/service/configmodel" : {\r
+      "post" : {\r
+        "summary" : "Provides Rest service to get Model Type by Tags",\r
+        "description" : "",\r
+        "operationId" : "saveConfigModel",\r
+        "consumes" : [ "application/json" ],\r
+        "produces" : [ "application/json" ],\r
+        "parameters" : [ {\r
+          "in" : "body",\r
+          "name" : "body",\r
+          "required" : true,\r
+          "schema" : {\r
+            "$ref" : "#/definitions/ConfigModel"\r
+          }\r
+        } ],\r
+        "responses" : {\r
+          "200" : {\r
+            "description" : "successful operation",\r
+            "schema" : {\r
+              "$ref" : "#/definitions/ServiceTemplate"\r
+            }\r
+          },\r
+          "404" : {\r
+            "description" : "Service not available"\r
+          },\r
+          "500" : {\r
+            "description" : "Unexpected Runtime error"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "/service/configmodel/{id}" : {\r
+      "get" : {\r
+        "summary" : "Provides Rest service to Search Service Template",\r
+        "description" : "",\r
+        "operationId" : "getConfigModel",\r
+        "consumes" : [ "application/json" ],\r
+        "produces" : [ "application/json" ],\r
+        "parameters" : [ {\r
+          "name" : "id",\r
+          "in" : "path",\r
+          "required" : true,\r
+          "type" : "integer",\r
+          "format" : "int64"\r
+        } ],\r
+        "responses" : {\r
+          "200" : {\r
+            "description" : "successful operation",\r
+            "schema" : {\r
+              "$ref" : "#/definitions/ConfigModel"\r
+            }\r
+          },\r
+          "404" : {\r
+            "description" : "Service not available"\r
+          },\r
+          "500" : {\r
+            "description" : "Unexpected Runtime error"\r
+          }\r
+        }\r
+      },\r
+      "delete" : {\r
+        "summary" : "Provides Rest service to delete ConfigModel.",\r
+        "description" : "",\r
+        "operationId" : "deleteConfigModel",\r
+        "consumes" : [ "application/json" ],\r
+        "produces" : [ "application/json" ],\r
+        "parameters" : [ {\r
+          "name" : "id",\r
+          "in" : "path",\r
+          "required" : true,\r
+          "type" : "integer",\r
+          "format" : "int64"\r
+        } ],\r
+        "responses" : {\r
+          "404" : {\r
+            "description" : "Service not available"\r
+          },\r
+          "500" : {\r
+            "description" : "Unexpected Runtime error"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "/service/configmodelbyname/{name}/version/{version}" : {\r
+      "get" : {\r
+        "summary" : "Provides Rest service to Search Service Template",\r
+        "description" : "",\r
+        "operationId" : "getConfigModelByNameAndVersion",\r
+        "consumes" : [ "application/json" ],\r
+        "produces" : [ "application/json" ],\r
+        "parameters" : [ {\r
+          "name" : "name",\r
+          "in" : "path",\r
+          "required" : true,\r
+          "type" : "string"\r
+        }, {\r
+          "name" : "version",\r
+          "in" : "path",\r
+          "required" : true,\r
+          "type" : "string"\r
+        } ],\r
+        "responses" : {\r
+          "200" : {\r
+            "description" : "successful operation",\r
+            "schema" : {\r
+              "$ref" : "#/definitions/ConfigModel"\r
+            }\r
+          },\r
+          "404" : {\r
+            "description" : "Service not available"\r
+          },\r
+          "500" : {\r
+            "description" : "Unexpected Runtime error"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "/service/configmodelclone/{id}" : {\r
+      "get" : {\r
+        "summary" : "Provides Rest service to create default Service Template",\r
+        "description" : "",\r
+        "operationId" : "getCloneConfigModel",\r
+        "consumes" : [ "application/json" ],\r
+        "produces" : [ "application/json" ],\r
+        "parameters" : [ {\r
+          "name" : "id",\r
+          "in" : "path",\r
+          "required" : true,\r
+          "type" : "integer",\r
+          "format" : "int64"\r
+        } ],\r
+        "responses" : {\r
+          "200" : {\r
+            "description" : "successful operation",\r
+            "schema" : {\r
+              "$ref" : "#/definitions/ConfigModel"\r
+            }\r
+          },\r
+          "404" : {\r
+            "description" : "Service not available"\r
+          },\r
+          "500" : {\r
+            "description" : "Unexpected Runtime error"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "/service/configmodelinitial/{name}" : {\r
+      "get" : {\r
+        "summary" : "Provides Rest service to create default Service Template",\r
+        "description" : "",\r
+        "operationId" : "getInitialConfigModel",\r
+        "consumes" : [ "application/json" ],\r
+        "produces" : [ "application/json" ],\r
+        "parameters" : [ {\r
+          "name" : "name",\r
+          "in" : "path",\r
+          "required" : true,\r
+          "type" : "string"\r
+        } ],\r
+        "responses" : {\r
+          "200" : {\r
+            "description" : "successful operation",\r
+            "schema" : {\r
+              "$ref" : "#/definitions/ConfigModel"\r
+            }\r
+          },\r
+          "404" : {\r
+            "description" : "Service not available"\r
+          },\r
+          "500" : {\r
+            "description" : "Unexpected Runtime error"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "/service/configmodelpublish/{id}" : {\r
+      "get" : {\r
+        "summary" : "Provides Rest service to get Model Type by Tags",\r
+        "description" : "",\r
+        "operationId" : "publishConfigModel",\r
+        "consumes" : [ "application/json" ],\r
+        "produces" : [ "application/json" ],\r
+        "parameters" : [ {\r
+          "name" : "id",\r
+          "in" : "path",\r
+          "required" : true,\r
+          "type" : "integer",\r
+          "format" : "int64"\r
+        } ],\r
+        "responses" : {\r
+          "200" : {\r
+            "description" : "successful operation",\r
+            "schema" : {\r
+              "$ref" : "#/definitions/ConfigModel"\r
+            }\r
+          },\r
+          "404" : {\r
+            "description" : "Service not available"\r
+          },\r
+          "500" : {\r
+            "description" : "Unexpected Runtime error"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "/service/configmodelsearch/{tags}" : {\r
+      "get" : {\r
+        "summary" : "Provides Rest service to Search Service Template",\r
+        "description" : "",\r
+        "operationId" : "searchConfigModels",\r
+        "consumes" : [ "application/json" ],\r
+        "produces" : [ "application/json" ],\r
+        "parameters" : [ {\r
+          "name" : "tags",\r
+          "in" : "path",\r
+          "required" : true,\r
+          "type" : "string"\r
+        } ],\r
+        "responses" : {\r
+          "200" : {\r
+            "description" : "successful operation",\r
+            "schema" : {\r
+              "$ref" : "#/definitions/ConfigModel"\r
+            }\r
+          },\r
+          "404" : {\r
+            "description" : "Service not available"\r
+          },\r
+          "500" : {\r
+            "description" : "Unexpected Runtime error"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "/service/dictionary" : {\r
+      "post" : {\r
+        "summary" : "Provides Rest service to Save Resource dictionary Type",\r
+        "description" : "",\r
+        "operationId" : "saveResourceDictionary",\r
+        "consumes" : [ "application/json" ],\r
+        "produces" : [ "application/json" ],\r
+        "parameters" : [ {\r
+          "in" : "body",\r
+          "name" : "body",\r
+          "required" : true,\r
+          "schema" : {\r
+            "$ref" : "#/definitions/ResourceDictionary"\r
+          }\r
+        } ],\r
+        "responses" : {\r
+          "200" : {\r
+            "description" : "successful operation",\r
+            "schema" : {\r
+              "$ref" : "#/definitions/ResourceDictionary"\r
+            }\r
+          },\r
+          "404" : {\r
+            "description" : "Service not available"\r
+          },\r
+          "500" : {\r
+            "description" : "Unexpected Runtime error"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "/service/dictionary/{name}" : {\r
+      "get" : {\r
+        "summary" : "Provides Rest service to get Resource dictionary",\r
+        "description" : "",\r
+        "operationId" : "getResourceDictionaryByName",\r
+        "consumes" : [ "application/json" ],\r
+        "produces" : [ "application/json" ],\r
+        "parameters" : [ {\r
+          "name" : "name",\r
+          "in" : "path",\r
+          "required" : true,\r
+          "type" : "string"\r
+        } ],\r
+        "responses" : {\r
+          "200" : {\r
+            "description" : "successful operation",\r
+            "schema" : {\r
+              "$ref" : "#/definitions/ResourceDictionary"\r
+            }\r
+          },\r
+          "404" : {\r
+            "description" : "Service not available"\r
+          },\r
+          "500" : {\r
+            "description" : "Unexpected Runtime error"\r
+          }\r
+        }\r
+      },\r
+      "delete" : {\r
+        "summary" : "Provides Rest service to delete ResourceDictionary Type",\r
+        "description" : "",\r
+        "operationId" : "deleteResourceDictionaryByName",\r
+        "consumes" : [ "application/json" ],\r
+        "produces" : [ "application/json" ],\r
+        "parameters" : [ {\r
+          "name" : "name",\r
+          "in" : "path",\r
+          "required" : true,\r
+          "type" : "string"\r
+        } ],\r
+        "responses" : {\r
+          "404" : {\r
+            "description" : "Service not available"\r
+          },\r
+          "500" : {\r
+            "description" : "Unexpected Runtime error"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "/service/dictionarybynames" : {\r
+      "post" : {\r
+        "summary" : "Provides Rest service to get ResourceDictionary Type by names",\r
+        "description" : "",\r
+        "operationId" : "searchResourceDictionaryByNames",\r
+        "consumes" : [ "application/json" ],\r
+        "produces" : [ "application/json" ],\r
+        "parameters" : [ {\r
+          "in" : "body",\r
+          "name" : "body",\r
+          "required" : true,\r
+          "schema" : {\r
+            "type" : "array",\r
+            "items" : {\r
+              "type" : "string"\r
+            }\r
+          }\r
+        } ],\r
+        "responses" : {\r
+          "200" : {\r
+            "description" : "successful operation",\r
+            "schema" : {\r
+              "type" : "array",\r
+              "items" : {\r
+                "$ref" : "#/definitions/ResourceDictionary"\r
+              }\r
+            }\r
+          },\r
+          "404" : {\r
+            "description" : "Service not available"\r
+          },\r
+          "500" : {\r
+            "description" : "Unexpected Runtime error"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "/service/dictionarysearch/{tags}" : {\r
+      "get" : {\r
+        "summary" : "Provides Rest service to search Resource dictionary by tags",\r
+        "description" : "",\r
+        "operationId" : "searchResourceDictionaryByTags",\r
+        "consumes" : [ "application/json" ],\r
+        "produces" : [ "application/json" ],\r
+        "parameters" : [ {\r
+          "name" : "tags",\r
+          "in" : "path",\r
+          "required" : true,\r
+          "type" : "string"\r
+        } ],\r
+        "responses" : {\r
+          "200" : {\r
+            "description" : "successful operation",\r
+            "schema" : {\r
+              "type" : "array",\r
+              "items" : {\r
+                "$ref" : "#/definitions/ResourceDictionary"\r
+              }\r
+            }\r
+          },\r
+          "404" : {\r
+            "description" : "Service not available"\r
+          },\r
+          "500" : {\r
+            "description" : "Unexpected Runtime error"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "/service/modeltype" : {\r
+      "post" : {\r
+        "summary" : "Provides Rest service to Save Model Type",\r
+        "description" : "",\r
+        "operationId" : "saveModelType",\r
+        "consumes" : [ "application/json" ],\r
+        "produces" : [ "application/json" ],\r
+        "parameters" : [ {\r
+          "in" : "body",\r
+          "name" : "body",\r
+          "required" : true,\r
+          "schema" : {\r
+            "$ref" : "#/definitions/ModelType"\r
+          }\r
+        } ],\r
+        "responses" : {\r
+          "200" : {\r
+            "description" : "successful operation",\r
+            "schema" : {\r
+              "$ref" : "#/definitions/ModelType"\r
+            }\r
+          },\r
+          "404" : {\r
+            "description" : "Service not available"\r
+          },\r
+          "500" : {\r
+            "description" : "Unexpected Runtime error"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "/service/modeltype/{name}" : {\r
+      "get" : {\r
+        "summary" : "Provides Rest service to get Model Type by id",\r
+        "description" : "",\r
+        "operationId" : "getModelTypeByName",\r
+        "consumes" : [ "application/json" ],\r
+        "produces" : [ "application/json" ],\r
+        "parameters" : [ {\r
+          "name" : "name",\r
+          "in" : "path",\r
+          "required" : true,\r
+          "type" : "string"\r
+        } ],\r
+        "responses" : {\r
+          "200" : {\r
+            "description" : "successful operation",\r
+            "schema" : {\r
+              "$ref" : "#/definitions/ModelType"\r
+            }\r
+          },\r
+          "404" : {\r
+            "description" : "Service not available"\r
+          },\r
+          "500" : {\r
+            "description" : "Unexpected Runtime error"\r
+          }\r
+        }\r
+      },\r
+      "delete" : {\r
+        "summary" : "Provides Rest service to delete Model Type",\r
+        "description" : "",\r
+        "operationId" : "deleteModelTypeByName",\r
+        "consumes" : [ "application/json" ],\r
+        "produces" : [ "application/json" ],\r
+        "parameters" : [ {\r
+          "name" : "name",\r
+          "in" : "path",\r
+          "required" : true,\r
+          "type" : "string"\r
+        } ],\r
+        "responses" : {\r
+          "404" : {\r
+            "description" : "Service not available"\r
+          },\r
+          "500" : {\r
+            "description" : "Unexpected Runtime error"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "/service/modeltypebydefinition/{definitionType}" : {\r
+      "get" : {\r
+        "summary" : "Provides Rest service to get Model Type by tags",\r
+        "description" : "",\r
+        "operationId" : "getModelTypeByDefinitionType",\r
+        "consumes" : [ "application/json" ],\r
+        "produces" : [ "application/json" ],\r
+        "parameters" : [ {\r
+          "name" : "definitionType",\r
+          "in" : "path",\r
+          "required" : true,\r
+          "type" : "string"\r
+        } ],\r
+        "responses" : {\r
+          "200" : {\r
+            "description" : "successful operation",\r
+            "schema" : {\r
+              "type" : "array",\r
+              "items" : {\r
+                "$ref" : "#/definitions/ModelType"\r
+              }\r
+            }\r
+          },\r
+          "404" : {\r
+            "description" : "Service not available"\r
+          },\r
+          "500" : {\r
+            "description" : "Unexpected Runtime error"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "/service/modeltypesearch/{tags}" : {\r
+      "get" : {\r
+        "summary" : "Provides Rest service to get Model Type by tags",\r
+        "description" : "",\r
+        "operationId" : "searchModelTypes",\r
+        "consumes" : [ "application/json" ],\r
+        "produces" : [ "application/json" ],\r
+        "parameters" : [ {\r
+          "name" : "tags",\r
+          "in" : "path",\r
+          "required" : true,\r
+          "type" : "string"\r
+        } ],\r
+        "responses" : {\r
+          "200" : {\r
+            "description" : "successful operation",\r
+            "schema" : {\r
+              "type" : "array",\r
+              "items" : {\r
+                "$ref" : "#/definitions/ModelType"\r
+              }\r
+            }\r
+          },\r
+          "404" : {\r
+            "description" : "Service not available"\r
+          },\r
+          "500" : {\r
+            "description" : "Unexpected Runtime error"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "/service/resourceassignment/automap" : {\r
+      "post" : {\r
+        "summary" : "Provides Rest service to auto map for the Resource assignments",\r
+        "description" : "",\r
+        "operationId" : "autoMap",\r
+        "consumes" : [ "application/json" ],\r
+        "produces" : [ "application/json" ],\r
+        "parameters" : [ {\r
+          "in" : "body",\r
+          "name" : "body",\r
+          "required" : true,\r
+          "schema" : {\r
+            "type" : "array",\r
+            "items" : {\r
+              "$ref" : "#/definitions/ResourceAssignment"\r
+            }\r
+          }\r
+        } ],\r
+        "responses" : {\r
+          "200" : {\r
+            "description" : "successful operation",\r
+            "schema" : {\r
+              "$ref" : "#/definitions/AutoMapResponse"\r
+            }\r
+          },\r
+          "404" : {\r
+            "description" : "Service not available"\r
+          },\r
+          "500" : {\r
+            "description" : "Unexpected Runtime error"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "/service/resourceassignment/generate" : {\r
+      "post" : {\r
+        "summary" : "Provides Rest service to auto map for the Resource Mapping",\r
+        "description" : "",\r
+        "operationId" : "generateResourceAssignments",\r
+        "consumes" : [ "application/json" ],\r
+        "produces" : [ "application/json" ],\r
+        "parameters" : [ {\r
+          "in" : "body",\r
+          "name" : "body",\r
+          "required" : true,\r
+          "schema" : {\r
+            "$ref" : "#/definitions/ConfigModelContent"\r
+          }\r
+        } ],\r
+        "responses" : {\r
+          "200" : {\r
+            "description" : "successful operation",\r
+            "schema" : {\r
+              "type" : "array",\r
+              "items" : {\r
+                "$ref" : "#/definitions/ResourceAssignment"\r
+              }\r
+            }\r
+          },\r
+          "404" : {\r
+            "description" : "Service not available"\r
+          },\r
+          "500" : {\r
+            "description" : "Unexpected Runtime error"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "/service/resourceassignment/validate" : {\r
+      "post" : {\r
+        "summary" : "Provides Rest service to validate Resource assignments",\r
+        "description" : "",\r
+        "operationId" : "validateResourceAssignments",\r
+        "consumes" : [ "application/json" ],\r
+        "produces" : [ "application/json" ],\r
+        "parameters" : [ {\r
+          "in" : "body",\r
+          "name" : "body",\r
+          "required" : true,\r
+          "schema" : {\r
+            "type" : "array",\r
+            "items" : {\r
+              "$ref" : "#/definitions/ResourceAssignment"\r
+            }\r
+          }\r
+        } ],\r
+        "responses" : {\r
+          "200" : {\r
+            "description" : "successful operation",\r
+            "schema" : {\r
+              "type" : "array",\r
+              "items" : {\r
+                "$ref" : "#/definitions/ResourceAssignment"\r
+              }\r
+            }\r
+          },\r
+          "404" : {\r
+            "description" : "Service not available"\r
+          },\r
+          "500" : {\r
+            "description" : "Unexpected Runtime error"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "/service/servicetemplate/enrich" : {\r
+      "post" : {\r
+        "summary" : "Provides Rest service to enrich service template",\r
+        "description" : "",\r
+        "operationId" : "enrichServiceTemplate",\r
+        "consumes" : [ "application/json" ],\r
+        "produces" : [ "application/json" ],\r
+        "parameters" : [ {\r
+          "in" : "body",\r
+          "name" : "body",\r
+          "required" : true,\r
+          "schema" : {\r
+            "$ref" : "#/definitions/ServiceTemplate"\r
+          }\r
+        } ],\r
+        "responses" : {\r
+          "200" : {\r
+            "description" : "successful operation",\r
+            "schema" : {\r
+              "$ref" : "#/definitions/ServiceTemplate"\r
+            }\r
+          },\r
+          "404" : {\r
+            "description" : "Service not available"\r
+          },\r
+          "500" : {\r
+            "description" : "Unexpected Runtime error"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "/service/servicetemplate/validate" : {\r
+      "post" : {\r
+        "summary" : "Provides Rest service to validate service template",\r
+        "description" : "",\r
+        "operationId" : "validateServiceTemplate",\r
+        "consumes" : [ "application/json" ],\r
+        "produces" : [ "application/json" ],\r
+        "parameters" : [ {\r
+          "in" : "body",\r
+          "name" : "body",\r
+          "required" : true,\r
+          "schema" : {\r
+            "$ref" : "#/definitions/ServiceTemplate"\r
+          }\r
+        } ],\r
+        "responses" : {\r
+          "200" : {\r
+            "description" : "successful operation",\r
+            "schema" : {\r
+              "$ref" : "#/definitions/ServiceTemplate"\r
+            }\r
+          },\r
+          "404" : {\r
+            "description" : "Service not available"\r
+          },\r
+          "500" : {\r
+            "description" : "Unexpected Runtime error"\r
+          }\r
+        }\r
+      }\r
+    }\r
+  },\r
+  "definitions" : {\r
+    "Activity" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "delegate" : {\r
+          "type" : "string"\r
+        },\r
+        "inlines" : {\r
+          "type" : "array",\r
+          "items" : {\r
+            "type" : "string"\r
+          }\r
+        },\r
+        "set_state" : {\r
+          "type" : "string"\r
+        },\r
+        "call_operation" : {\r
+          "type" : "string"\r
+        }\r
+      }\r
+    },\r
+    "ArtifactDefinition" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "type" : {\r
+          "type" : "string"\r
+        },\r
+        "file" : {\r
+          "type" : "string"\r
+        },\r
+        "repository" : {\r
+          "type" : "string"\r
+        },\r
+        "description" : {\r
+          "type" : "string"\r
+        },\r
+        "properties" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/JsonNode"\r
+          }\r
+        },\r
+        "content" : {\r
+          "type" : "string"\r
+        },\r
+        "mappingContent" : {\r
+          "type" : "string"\r
+        },\r
+        "deploy_Path" : {\r
+          "type" : "string"\r
+        }\r
+      }\r
+    },\r
+    "ArtifactType" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "description" : {\r
+          "type" : "string"\r
+        },\r
+        "version" : {\r
+          "type" : "string"\r
+        },\r
+        "metadata" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "type" : "string"\r
+          }\r
+        },\r
+        "attributes" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/AttributeDefinition"\r
+          }\r
+        },\r
+        "properties" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/PropertyDefinition"\r
+          }\r
+        },\r
+        "derived_from" : {\r
+          "type" : "string"\r
+        },\r
+        "mime_type" : {\r
+          "type" : "string"\r
+        },\r
+        "file_ext" : {\r
+          "type" : "array",\r
+          "items" : {\r
+            "type" : "string"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "AttributeDefinition" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "description" : {\r
+          "type" : "string"\r
+        },\r
+        "type" : {\r
+          "type" : "string"\r
+        },\r
+        "status" : {\r
+          "type" : "string"\r
+        },\r
+        "get_default" : {\r
+          "type" : "object"\r
+        },\r
+        "entry_schema" : {\r
+          "type" : "string"\r
+        }\r
+      }\r
+    },\r
+    "AutoMapResponse" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "resourceAssignments" : {\r
+          "type" : "array",\r
+          "items" : {\r
+            "$ref" : "#/definitions/ResourceAssignment"\r
+          }\r
+        },\r
+        "dataDictionaries" : {\r
+          "type" : "array",\r
+          "items" : {\r
+            "$ref" : "#/definitions/ResourceDictionary"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "CapabilityAssignment" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "attributes" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/JsonNode"\r
+          }\r
+        },\r
+        "properties" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/JsonNode"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "CapabilityDefinition" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "type" : {\r
+          "type" : "string"\r
+        },\r
+        "description" : {\r
+          "type" : "string"\r
+        },\r
+        "properties" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/PropertyDefinition"\r
+          }\r
+        },\r
+        "occurrences" : {\r
+          "type" : "array",\r
+          "items" : {\r
+            "type" : "object"\r
+          }\r
+        },\r
+        "valid_source_types" : {\r
+          "type" : "array",\r
+          "items" : {\r
+            "type" : "string"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "ConditionClause" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "and" : {\r
+          "type" : "array",\r
+          "items" : {\r
+            "type" : "object",\r
+            "additionalProperties" : {\r
+              "type" : "object"\r
+            }\r
+          }\r
+        },\r
+        "or" : {\r
+          "type" : "array",\r
+          "items" : {\r
+            "type" : "object",\r
+            "additionalProperties" : {\r
+              "type" : "object"\r
+            }\r
+          }\r
+        },\r
+        "assert" : {\r
+          "type" : "array",\r
+          "items" : {\r
+            "type" : "object",\r
+            "additionalProperties" : {\r
+              "type" : "object"\r
+            }\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "ConfigModel" : {\r
+      "type" : "object",\r
+      "required" : [ "artifactName", "artifactVersion", "published", "tags", "updatedBy" ],\r
+      "properties" : {\r
+        "id" : {\r
+          "type" : "integer",\r
+          "format" : "int64"\r
+        },\r
+        "serviceUUID" : {\r
+          "type" : "string"\r
+        },\r
+        "distributionId" : {\r
+          "type" : "string"\r
+        },\r
+        "serviceName" : {\r
+          "type" : "string"\r
+        },\r
+        "serviceDescription" : {\r
+          "type" : "string"\r
+        },\r
+        "resourceUUID" : {\r
+          "type" : "string"\r
+        },\r
+        "resourceInstanceName" : {\r
+          "type" : "string"\r
+        },\r
+        "resourceName" : {\r
+          "type" : "string"\r
+        },\r
+        "resourceVersion" : {\r
+          "type" : "string"\r
+        },\r
+        "resourceType" : {\r
+          "type" : "string"\r
+        },\r
+        "artifactUUId" : {\r
+          "type" : "string"\r
+        },\r
+        "artifactType" : {\r
+          "type" : "string"\r
+        },\r
+        "artifactVersion" : {\r
+          "type" : "string"\r
+        },\r
+        "artifactDescription" : {\r
+          "type" : "string"\r
+        },\r
+        "internalVersion" : {\r
+          "type" : "integer",\r
+          "format" : "int32"\r
+        },\r
+        "createdDate" : {\r
+          "type" : "string",\r
+          "format" : "date-time"\r
+        },\r
+        "artifactName" : {\r
+          "type" : "string"\r
+        },\r
+        "published" : {\r
+          "type" : "string"\r
+        },\r
+        "updatedBy" : {\r
+          "type" : "string"\r
+        },\r
+        "tags" : {\r
+          "type" : "string"\r
+        },\r
+        "configModelContents" : {\r
+          "type" : "array",\r
+          "items" : {\r
+            "$ref" : "#/definitions/ConfigModelContent"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "ConfigModelContent" : {\r
+      "type" : "object",\r
+      "required" : [ "content", "contentType", "name" ],\r
+      "properties" : {\r
+        "id" : {\r
+          "type" : "integer",\r
+          "format" : "int64"\r
+        },\r
+        "name" : {\r
+          "type" : "string"\r
+        },\r
+        "contentType" : {\r
+          "type" : "string"\r
+        },\r
+        "configModel" : {\r
+          "$ref" : "#/definitions/ConfigModel"\r
+        },\r
+        "description" : {\r
+          "type" : "string"\r
+        },\r
+        "content" : {\r
+          "type" : "string"\r
+        },\r
+        "creationDate" : {\r
+          "type" : "string",\r
+          "format" : "date-time"\r
+        }\r
+      }\r
+    },\r
+    "ConstraintClause" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "equal" : {\r
+          "type" : "object"\r
+        },\r
+        "greater_than" : {\r
+          "type" : "object"\r
+        },\r
+        "greater_or_equal" : {\r
+          "type" : "object"\r
+        },\r
+        "less_than" : {\r
+          "type" : "object"\r
+        },\r
+        "less_or_equal" : {\r
+          "type" : "object"\r
+        },\r
+        "in_range" : {\r
+          "type" : "object"\r
+        },\r
+        "valid_values" : {\r
+          "type" : "array",\r
+          "items" : {\r
+            "type" : "object"\r
+          }\r
+        },\r
+        "length" : {\r
+          "type" : "object"\r
+        },\r
+        "min_length" : {\r
+          "type" : "object"\r
+        },\r
+        "max_length" : {\r
+          "type" : "object"\r
+        },\r
+        "pattern" : {\r
+          "type" : "string"\r
+        }\r
+      }\r
+    },\r
+    "Credential" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "protocol" : {\r
+          "type" : "string"\r
+        },\r
+        "token" : {\r
+          "type" : "string"\r
+        },\r
+        "keys" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "type" : "string"\r
+          }\r
+        },\r
+        "user" : {\r
+          "type" : "string"\r
+        },\r
+        "token_type" : {\r
+          "type" : "string"\r
+        }\r
+      }\r
+    },\r
+    "DataType" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "description" : {\r
+          "type" : "string"\r
+        },\r
+        "version" : {\r
+          "type" : "string"\r
+        },\r
+        "metadata" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "type" : "string"\r
+          }\r
+        },\r
+        "attributes" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/AttributeDefinition"\r
+          }\r
+        },\r
+        "properties" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/PropertyDefinition"\r
+          }\r
+        },\r
+        "constraints" : {\r
+          "type" : "array",\r
+          "items" : {\r
+            "type" : "object",\r
+            "additionalProperties" : {\r
+              "type" : "object"\r
+            }\r
+          }\r
+        },\r
+        "derived_from" : {\r
+          "type" : "string"\r
+        }\r
+      }\r
+    },\r
+    "EntrySchema" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "type" : {\r
+          "type" : "string"\r
+        },\r
+        "constraints" : {\r
+          "type" : "array",\r
+          "items" : {\r
+            "type" : "object",\r
+            "additionalProperties" : {\r
+              "type" : "object"\r
+            }\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "Implementation" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "primary" : {\r
+          "type" : "string"\r
+        },\r
+        "dependencies" : {\r
+          "type" : "array",\r
+          "items" : {\r
+            "type" : "string"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "ImportDefinition" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "file" : {\r
+          "type" : "string"\r
+        },\r
+        "repository" : {\r
+          "type" : "string"\r
+        },\r
+        "namespace_uri" : {\r
+          "type" : "string"\r
+        },\r
+        "namespace_prefix" : {\r
+          "type" : "string"\r
+        }\r
+      }\r
+    },\r
+    "InterfaceAssignment" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "operations" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/OperationAssignment"\r
+          }\r
+        },\r
+        "inputs" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/JsonNode"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "InterfaceDefinition" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "type" : {\r
+          "type" : "string"\r
+        },\r
+        "operations" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/OperationDefinition"\r
+          }\r
+        },\r
+        "inputs" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/PropertyDefinition"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "JsonNode" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "array" : {\r
+          "type" : "boolean"\r
+        },\r
+        "null" : {\r
+          "type" : "boolean"\r
+        },\r
+        "float" : {\r
+          "type" : "boolean"\r
+        },\r
+        "nodeType" : {\r
+          "type" : "string",\r
+          "enum" : [ "ARRAY", "BINARY", "BOOLEAN", "MISSING", "NULL", "NUMBER", "OBJECT", "POJO", "STRING" ]\r
+        },\r
+        "number" : {\r
+          "type" : "boolean"\r
+        },\r
+        "valueNode" : {\r
+          "type" : "boolean"\r
+        },\r
+        "containerNode" : {\r
+          "type" : "boolean"\r
+        },\r
+        "missingNode" : {\r
+          "type" : "boolean"\r
+        },\r
+        "object" : {\r
+          "type" : "boolean"\r
+        },\r
+        "pojo" : {\r
+          "type" : "boolean"\r
+        },\r
+        "integralNumber" : {\r
+          "type" : "boolean"\r
+        },\r
+        "short" : {\r
+          "type" : "boolean"\r
+        },\r
+        "int" : {\r
+          "type" : "boolean"\r
+        },\r
+        "long" : {\r
+          "type" : "boolean"\r
+        },\r
+        "double" : {\r
+          "type" : "boolean"\r
+        },\r
+        "bigDecimal" : {\r
+          "type" : "boolean"\r
+        },\r
+        "bigInteger" : {\r
+          "type" : "boolean"\r
+        },\r
+        "textual" : {\r
+          "type" : "boolean"\r
+        },\r
+        "boolean" : {\r
+          "type" : "boolean"\r
+        },\r
+        "binary" : {\r
+          "type" : "boolean"\r
+        },\r
+        "floatingPointNumber" : {\r
+          "type" : "boolean"\r
+        }\r
+      }\r
+    },\r
+    "ModelType" : {\r
+      "type" : "object",\r
+      "required" : [ "definition", "definitionType", "derivedFrom", "description", "modelName", "tags", "updatedBy", "version" ],\r
+      "properties" : {\r
+        "modelName" : {\r
+          "type" : "string"\r
+        },\r
+        "derivedFrom" : {\r
+          "type" : "string"\r
+        },\r
+        "definitionType" : {\r
+          "type" : "string"\r
+        },\r
+        "definition" : {\r
+          "type" : "string"\r
+        },\r
+        "description" : {\r
+          "type" : "string"\r
+        },\r
+        "version" : {\r
+          "type" : "string"\r
+        },\r
+        "tags" : {\r
+          "type" : "string"\r
+        },\r
+        "creationDate" : {\r
+          "type" : "string",\r
+          "format" : "date-time"\r
+        },\r
+        "updatedBy" : {\r
+          "type" : "string"\r
+        }\r
+      }\r
+    },\r
+    "NodeFilterDefinition" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "properties" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/PropertyDefinition"\r
+          }\r
+        },\r
+        "capabilities" : {\r
+          "type" : "array",\r
+          "items" : {\r
+            "type" : "string"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "NodeTemplate" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "description" : {\r
+          "type" : "string"\r
+        },\r
+        "type" : {\r
+          "type" : "string"\r
+        },\r
+        "metadata" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "type" : "string"\r
+          }\r
+        },\r
+        "directives" : {\r
+          "type" : "array",\r
+          "items" : {\r
+            "type" : "string"\r
+          }\r
+        },\r
+        "properties" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/JsonNode"\r
+          }\r
+        },\r
+        "attributes" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/JsonNode"\r
+          }\r
+        },\r
+        "capabilities" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/CapabilityAssignment"\r
+          }\r
+        },\r
+        "requirements" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/RequirementAssignment"\r
+          }\r
+        },\r
+        "interfaces" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/InterfaceAssignment"\r
+          }\r
+        },\r
+        "artifacts" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/ArtifactDefinition"\r
+          }\r
+        },\r
+        "copy" : {\r
+          "type" : "string"\r
+        },\r
+        "node_filter" : {\r
+          "$ref" : "#/definitions/NodeFilterDefinition"\r
+        }\r
+      }\r
+    },\r
+    "NodeType" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "description" : {\r
+          "type" : "string"\r
+        },\r
+        "version" : {\r
+          "type" : "string"\r
+        },\r
+        "metadata" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "type" : "string"\r
+          }\r
+        },\r
+        "attributes" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/AttributeDefinition"\r
+          }\r
+        },\r
+        "properties" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/PropertyDefinition"\r
+          }\r
+        },\r
+        "capabilities" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/CapabilityDefinition"\r
+          }\r
+        },\r
+        "requirements" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/RequirementDefinition"\r
+          }\r
+        },\r
+        "interfaces" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/InterfaceDefinition"\r
+          }\r
+        },\r
+        "artifacts" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/ArtifactDefinition"\r
+          }\r
+        },\r
+        "derived_from" : {\r
+          "type" : "string"\r
+        }\r
+      }\r
+    },\r
+    "OperationAssignment" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "description" : {\r
+          "type" : "string"\r
+        },\r
+        "implementation" : {\r
+          "$ref" : "#/definitions/Implementation"\r
+        },\r
+        "inputs" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/JsonNode"\r
+          }\r
+        },\r
+        "outputs" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/JsonNode"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "OperationDefinition" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "description" : {\r
+          "type" : "string"\r
+        },\r
+        "implementation" : {\r
+          "$ref" : "#/definitions/Implementation"\r
+        },\r
+        "inputs" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/PropertyDefinition"\r
+          }\r
+        },\r
+        "outputs" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/PropertyDefinition"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "PolicyDefinition" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "type" : {\r
+          "type" : "string"\r
+        },\r
+        "description" : {\r
+          "type" : "string"\r
+        },\r
+        "metadata" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "type" : "string"\r
+          }\r
+        },\r
+        "properties" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/JsonNode"\r
+          }\r
+        },\r
+        "targets" : {\r
+          "type" : "array",\r
+          "items" : {\r
+            "type" : "string"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "PolicyType" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "description" : {\r
+          "type" : "string"\r
+        },\r
+        "version" : {\r
+          "type" : "string"\r
+        },\r
+        "metadata" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "type" : "string"\r
+          }\r
+        },\r
+        "attributes" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/AttributeDefinition"\r
+          }\r
+        },\r
+        "properties" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/PropertyDefinition"\r
+          }\r
+        },\r
+        "targets" : {\r
+          "type" : "array",\r
+          "items" : {\r
+            "type" : "string"\r
+          }\r
+        },\r
+        "derived_from" : {\r
+          "type" : "string"\r
+        }\r
+      }\r
+    },\r
+    "PreConditionDefinition" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "target" : {\r
+          "type" : "string"\r
+        },\r
+        "condition" : {\r
+          "type" : "array",\r
+          "items" : {\r
+            "$ref" : "#/definitions/ConditionClause"\r
+          }\r
+        },\r
+        "target_relationship" : {\r
+          "type" : "string"\r
+        }\r
+      }\r
+    },\r
+    "PropertyDefinition" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "description" : {\r
+          "type" : "string"\r
+        },\r
+        "required" : {\r
+          "type" : "boolean"\r
+        },\r
+        "type" : {\r
+          "type" : "string"\r
+        },\r
+        "status" : {\r
+          "type" : "string"\r
+        },\r
+        "constraints" : {\r
+          "type" : "array",\r
+          "items" : {\r
+            "$ref" : "#/definitions/ConstraintClause"\r
+          }\r
+        },\r
+        "value" : {\r
+          "type" : "object"\r
+        },\r
+        "default" : {\r
+          "type" : "object"\r
+        },\r
+        "entry_schema" : {\r
+          "$ref" : "#/definitions/EntrySchema"\r
+        }\r
+      }\r
+    },\r
+    "RelationshipTemplate" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "type" : {\r
+          "type" : "string"\r
+        },\r
+        "description" : {\r
+          "type" : "string"\r
+        },\r
+        "metadata" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "type" : "string"\r
+          }\r
+        },\r
+        "properties" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/PropertyDefinition"\r
+          }\r
+        },\r
+        "attributes" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/JsonNode"\r
+          }\r
+        },\r
+        "interfaces" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/InterfaceDefinition"\r
+          }\r
+        },\r
+        "copy" : {\r
+          "type" : "string"\r
+        }\r
+      }\r
+    },\r
+    "RepositoryDefinition" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "description" : {\r
+          "type" : "string"\r
+        },\r
+        "url" : {\r
+          "type" : "string"\r
+        },\r
+        "credential" : {\r
+          "$ref" : "#/definitions/Credential"\r
+        }\r
+      }\r
+    },\r
+    "RequirementAssignment" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "capability" : {\r
+          "type" : "string"\r
+        },\r
+        "node" : {\r
+          "type" : "string"\r
+        },\r
+        "relationship" : {\r
+          "type" : "string"\r
+        }\r
+      }\r
+    },\r
+    "RequirementDefinition" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "description" : {\r
+          "type" : "string"\r
+        },\r
+        "capability" : {\r
+          "type" : "string"\r
+        },\r
+        "node" : {\r
+          "type" : "string"\r
+        },\r
+        "relationship" : {\r
+          "type" : "string"\r
+        },\r
+        "occurrences" : {\r
+          "type" : "array",\r
+          "items" : {\r
+            "type" : "object"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "ResourceAssignment" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "name" : {\r
+          "type" : "string"\r
+        },\r
+        "property" : {\r
+          "$ref" : "#/definitions/PropertyDefinition"\r
+        },\r
+        "input-param" : {\r
+          "type" : "boolean"\r
+        },\r
+        "dictionary-name" : {\r
+          "type" : "string"\r
+        },\r
+        "dictionary-source" : {\r
+          "type" : "string"\r
+        },\r
+        "dependencies" : {\r
+          "type" : "array",\r
+          "items" : {\r
+            "type" : "string"\r
+          }\r
+        },\r
+        "version" : {\r
+          "type" : "integer",\r
+          "format" : "int32"\r
+        },\r
+        "status" : {\r
+          "type" : "string"\r
+        },\r
+        "message" : {\r
+          "type" : "string"\r
+        },\r
+        "updated-date" : {\r
+          "type" : "string",\r
+          "format" : "date-time"\r
+        },\r
+        "updated-by" : {\r
+          "type" : "string"\r
+        }\r
+      }\r
+    },\r
+    "ResourceDictionary" : {\r
+      "type" : "object",\r
+      "required" : [ "dataType", "definition", "description", "name", "resourcePath", "resourceType", "tags", "updatedBy" ],\r
+      "properties" : {\r
+        "name" : {\r
+          "type" : "string"\r
+        },\r
+        "resourcePath" : {\r
+          "type" : "string"\r
+        },\r
+        "resourceType" : {\r
+          "type" : "string"\r
+        },\r
+        "dataType" : {\r
+          "type" : "string"\r
+        },\r
+        "entrySchema" : {\r
+          "type" : "string"\r
+        },\r
+        "validValues" : {\r
+          "type" : "string"\r
+        },\r
+        "sampleValue" : {\r
+          "type" : "string"\r
+        },\r
+        "definition" : {\r
+          "type" : "string"\r
+        },\r
+        "description" : {\r
+          "type" : "string"\r
+        },\r
+        "tags" : {\r
+          "type" : "string"\r
+        },\r
+        "creationDate" : {\r
+          "type" : "string",\r
+          "format" : "date-time"\r
+        },\r
+        "updatedBy" : {\r
+          "type" : "string"\r
+        }\r
+      }\r
+    },\r
+    "ServiceTemplate" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "metadata" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "type" : "string"\r
+          }\r
+        },\r
+        "description" : {\r
+          "type" : "string"\r
+        },\r
+        "repositories" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/RepositoryDefinition"\r
+          }\r
+        },\r
+        "imports" : {\r
+          "type" : "array",\r
+          "items" : {\r
+            "$ref" : "#/definitions/ImportDefinition"\r
+          }\r
+        },\r
+        "tosca_definitions_version" : {\r
+          "type" : "string"\r
+        },\r
+        "dsl_definitions" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "type" : "object"\r
+          }\r
+        },\r
+        "artifact_types" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/ArtifactType"\r
+          }\r
+        },\r
+        "data_types" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/DataType"\r
+          }\r
+        },\r
+        "node_types" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/NodeType"\r
+          }\r
+        },\r
+        "policy_types" : {\r
+          "$ref" : "#/definitions/PolicyType"\r
+        },\r
+        "topology_template" : {\r
+          "$ref" : "#/definitions/TopologyTemplate"\r
+        }\r
+      }\r
+    },\r
+    "Step" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "description" : {\r
+          "type" : "string"\r
+        },\r
+        "target" : {\r
+          "type" : "string"\r
+        },\r
+        "activities" : {\r
+          "type" : "array",\r
+          "items" : {\r
+            "$ref" : "#/definitions/Activity"\r
+          }\r
+        },\r
+        "target_relationship" : {\r
+          "type" : "string"\r
+        },\r
+        "operation_host" : {\r
+          "type" : "string"\r
+        },\r
+        "on_success" : {\r
+          "type" : "array",\r
+          "items" : {\r
+            "type" : "string"\r
+          }\r
+        },\r
+        "on_failure" : {\r
+          "type" : "array",\r
+          "items" : {\r
+            "type" : "string"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "TopologyTemplate" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "description" : {\r
+          "type" : "string"\r
+        },\r
+        "inputs" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/PropertyDefinition"\r
+          }\r
+        },\r
+        "policies" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/PolicyDefinition"\r
+          }\r
+        },\r
+        "outputs" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/PropertyDefinition"\r
+          }\r
+        },\r
+        "workflows" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/Workflow"\r
+          }\r
+        },\r
+        "node_templates" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/NodeTemplate"\r
+          }\r
+        },\r
+        "relationship_templates" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/RelationshipTemplate"\r
+          }\r
+        },\r
+        "substitution_mappings" : {\r
+          "type" : "object"\r
+        }\r
+      }\r
+    },\r
+    "Workflow" : {\r
+      "type" : "object",\r
+      "properties" : {\r
+        "description" : {\r
+          "type" : "string"\r
+        },\r
+        "steps" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/Step"\r
+          }\r
+        },\r
+        "preconditions" : {\r
+          "type" : "array",\r
+          "items" : {\r
+            "$ref" : "#/definitions/PreConditionDefinition"\r
+          }\r
+        },\r
+        "inputs" : {\r
+          "type" : "object",\r
+          "additionalProperties" : {\r
+            "$ref" : "#/definitions/PropertyDefinition"\r
+          }\r
+        }\r
+      }\r
+    }\r
+  }\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/application/src/test/java/org/onap/ccsdk/apps/controllerblueprints/ControllerBluprintsApplicationTest.java b/ms/controllerblueprints/application/src/test/java/org/onap/ccsdk/apps/controllerblueprints/ControllerBluprintsApplicationTest.java
new file mode 100644 (file)
index 0000000..4bdbde0
--- /dev/null
@@ -0,0 +1,54 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints;\r
+\r
+import org.junit.Before;\r
+import org.junit.Test;\r
+import org.junit.runner.RunWith;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+import org.springframework.beans.factory.annotation.Autowired;\r
+import org.springframework.boot.test.context.SpringBootTest;\r
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;\r
+import org.springframework.boot.test.web.client.TestRestTemplate;\r
+import org.springframework.http.HttpStatus;\r
+import org.springframework.http.ResponseEntity;\r
+import org.springframework.test.context.junit4.SpringRunner;\r
+\r
+import static org.assertj.core.api.Assertions.assertThat;\r
+\r
+@RunWith(SpringRunner.class)\r
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)\r
+public class ControllerBluprintsApplicationTest {\r
+    private static Logger log = LoggerFactory.getLogger(ControllerBluprintsApplicationTest.class);\r
+\r
+    @Autowired\r
+    private TestRestTemplate restTemplate;\r
+\r
+    @Before\r
+    public void setUp(){\r
+\r
+    }\r
+\r
+    @Test\r
+    public void testConfigModel() {\r
+\r
+        ResponseEntity<String> entity = this.restTemplate\r
+                .getForEntity("/api/controller-blueprints/v1/service/configmodel/1", String.class);\r
+        assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);\r
+    }\r
+}\r
diff --git a/ms/controllerblueprints/application/src/test/resources/application.properties b/ms/controllerblueprints/application/src/test/resources/application.properties
new file mode 100644 (file)
index 0000000..c6057e5
--- /dev/null
@@ -0,0 +1,65 @@
+#\r
+# Copyright © 2017-2018 AT&T Intellectual Property.\r
+#\r
+# Licensed under the Apache License, Version 2.0 (the "License");\r
+# you may not use this file except in compliance with the License.\r
+# You may obtain a copy of the License at\r
+#\r
+#     http://www.apache.org/licenses/LICENSE-2.0\r
+#\r
+# Unless required by applicable law or agreed to in writing, software\r
+# distributed under the License is distributed on an "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+# See the License for the specific language governing permissions and\r
+# limitations under the License.\r
+#\r
+\r
+info.build.artifact=@project.artifactId@\r
+info.build.name=@project.name@\r
+info.build.description=@project.description@\r
+info.build.version=@project.version@\r
+info.build.groupId=@project.groupId@\r
+logging.level.root=info\r
+\r
+server.contextPath=/\r
+server.servlet-path=/\r
+spring.jersey.application-path=/api/controller-blueprints/v1\r
+server.routingPath=/api\r
+\r
+mots.application.acronym=MOTS_ID\r
+platform.identifier=AJSC7_JERSEY\r
+#spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration\r
+\r
+#logging.pattern.console=%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr($ threadId: {PID:- }){magenta} %clr(---){faint} %clr([ hostname: %X{hostname} serviceName: %X{serviceName} version: %X{version} transactionId: %X{transactionId} requestTimeStamp: %X{requestTimestamp}  responseTimeStamp: %X{responseTimestamp} duration: %X{duration}]){yellow} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wex\r
+\r
+#The max number of active threads in this pool\r
+server.tomcat.max-threads=200\r
+#The minimum number of threads always kept alive\r
+server.tomcat.min-Spare-Threads=25\r
+#The number of milliseconds before an idle thread shutsdown, unless the number of active threads are less or equal to minSpareThreads\r
+server.tomcat.max-idle-time=60000\r
+\r
+#for changing the tomcat port...\r
+#server.port=8081\r
+\r
+#Servlet context parameters\r
+server.context_parameters.p-name=value #context parameter with p-name as key and value as value.\r
+\r
+# make this true for AAF authentication and place cadi.properties into etc folder\r
+aaf.enabled=false\r
+\r
+# set to true to enable version proxy\r
+#ivp.enabled=false\r
+\r
+logging.level.org.springframework.web=INFO\r
+logging.level.org.hibernate.SQL=warn\r
+logging.level.org.hibernate.type.descriptor.sql=debug\r
+\r
+spring.jpa.properties.hibernate.show_sql=true\r
+spring.jpa.properties.hibernate.use_sql_comments=true\r
+spring.jpa.properties.hibernate.format_sql=true\r
+\r
+#Load Blueprints\r
+# blueprints.load.initial-data may be overridden by ENV variables\r
+blueprints.load.initial-data=true\r
+blueprints.load.path=load
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/load/blueprints/baseconfiguration/Definitions/activation-blueprint.json b/ms/controllerblueprints/modules/core/load/blueprints/baseconfiguration/Definitions/activation-blueprint.json
new file mode 100644 (file)
index 0000000..635e177
--- /dev/null
@@ -0,0 +1,411 @@
+{\r
+  "metadata": {\r
+    "template_author": "Brinda Santh Muthuramalingam",\r
+    "author-email": "brindasanth@gmail.com",\r
+    "user-groups" : "ADMIN, OPERATION",\r
+    "template_name": "baseconfiguration",\r
+    "template_version": "1.0.0",\r
+    "template_tags": "brinda, tosca"\r
+  },\r
+  "topology_template": {\r
+    "inputs": {\r
+      "request-id": {\r
+        "required": true,\r
+        "type": "string"\r
+      },\r
+      "action-name": {\r
+        "required": true,\r
+        "type": "string"\r
+      },\r
+      "scope-type": {\r
+        "required": true,\r
+        "type": "string"\r
+      },\r
+      "hostname": {\r
+        "required": true,\r
+        "type": "string"\r
+      }\r
+    },\r
+    "node_templates": {\r
+      "activate-process": {\r
+        "type": "bpmn-activate",\r
+        "properties": {\r
+          "process-name": { "get_input" : "action-name" },\r
+          "version" : { "get_property" : ["SELF", "process-name"] },\r
+          "content": { "get_artifact" : ["SELF", "activate-process"] }\r
+        },\r
+        "artifacts": {\r
+          "activate-process": {\r
+            "type": "artifact-bpmn-camunda",\r
+            "file": "Plans/ActivateProcess.bpmn"\r
+          }\r
+        }\r
+      },\r
+      "resource-assignment": {\r
+        "type": "component-resource-assignment",\r
+        "properties":{\r
+          "request-id": ["1234", "1234"]\r
+        },\r
+        "interfaces": {\r
+          "DefaultComponentNode": {\r
+            "operations": {\r
+              "process": {\r
+                "inputs": {\r
+                  "action-name": { "get_input" : "action-name" },\r
+                  "resource-type": "vnf-type",\r
+                  "request-id": { "get_input" : "request-id" },\r
+                  "resource-id": { "get_input" : "hostname" },\r
+                  "template-content": { "get_artifact" : ["SELF", "baseconfig-template"] },\r
+                  "mapping-content": { "get_artifact" : ["SELF", "baseconfig-mapping"] }\r
+                },\r
+                "outputs": {\r
+                  "resource-assignment-params": "",\r
+                  "status": ""\r
+                }\r
+              }\r
+            }\r
+          }\r
+        },\r
+        "artifacts": {\r
+          "baseconfig-template": {\r
+            "type": "artifact-template-velocity",\r
+            "file": "Templates/baseconfig-template.vtl"\r
+          },\r
+          "baseconfig-mapping": {\r
+            "type": "artifact-mapping-resource",\r
+            "file": "Mappings/baseconfig-mapping.json"\r
+          }\r
+        }\r
+      },\r
+      "resource-assignment-py": {\r
+        "type": "component-resource-assignment",\r
+        "properties":{\r
+          "request-id": ["1234", "1234"]\r
+        },\r
+        "interfaces": {\r
+          "DefaultComponentNode": {\r
+            "operations": {\r
+              "process": {\r
+                "implementation" :{\r
+                  "primary" : "component-script"\r
+                },\r
+                "inputs": {\r
+                  "action-name": { "get_input" : "action-name" }\r
+                },\r
+                "outputs": {\r
+                  "resource-assignment-params": "",\r
+                  "status": ""\r
+                }\r
+              }\r
+            }\r
+          }\r
+        },\r
+        "artifacts": {\r
+          "component-script": {\r
+            "type": "artifact-script-python",\r
+            "file": "Scripts/baseconfig-template.vtl"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "workflows":{\r
+      "activate-process":{\r
+        "steps" : {\r
+            "call-resource-assignment" : {\r
+              "description" : "Invoke Resource Assignment Component",\r
+              "target" : "resource-assignment",\r
+              "activities" : [\r
+                {\r
+                  "call_operation": "ResourceAssignmentNode.process"\r
+                }\r
+              ],\r
+              "on_success" : [\r
+                "download-baseconfig"\r
+              ]\r
+            },\r
+          "download-baseconfig" : {\r
+            "description" : "Call Download Base Config Component",\r
+            "target" : "activate-netconf",\r
+            "activities" : [\r
+              {\r
+                "call_operation": "NetconfTransactionNode.process"\r
+              }\r
+            ],\r
+            "on_success" : [\r
+              "download-licence"\r
+            ]\r
+          },\r
+          "download-licence" : {\r
+            "description" : "Call Download Licence Component",\r
+            "target" : "activate-netconf",\r
+            "activities" : [\r
+              {\r
+                "call_operation": "NetconfTransactionNode.process"\r
+              }\r
+            ]\r
+          }\r
+        }\r
+      }\r
+    }\r
+  },\r
+  "artifact_types": {\r
+    "artifact-template-velocity": {\r
+      "description": " Velocity Template used for Configuration",\r
+      "version": "1.0.0",\r
+      "file_ext": [\r
+        "vtl"\r
+      ],\r
+      "derived_from": "tosca.artifacts.Implementation"\r
+    },\r
+    "artifact-mapping-resource": {\r
+      "description": " Velocity Template Resource Mapping File used along with Configuration template",\r
+      "version": "1.0.0",\r
+      "file_ext": [\r
+        "json"\r
+      ],\r
+      "derived_from": "tosca.artifacts.Implementation"\r
+    },\r
+    "artifact-script-kotlin": {\r
+      "description": " Kotlin Script Template used for Configuration",\r
+      "version": "1.0.0",\r
+      "file_ext": [\r
+        "kt"\r
+      ],\r
+      "derived_from": "tosca.artifacts.Implementation"\r
+    },\r
+    "artifact-script-python": {\r
+      "description": " Kotlin Script Template used for Configuration",\r
+      "version": "1.0.0",\r
+      "file_ext": [\r
+        "py"\r
+      ],\r
+      "derived_from": "tosca.artifacts.Implementation"\r
+    },\r
+    "artifact-bpmn-camunda": {\r
+      "description": " Camunda BPM File",\r
+      "version": "1.0.0",\r
+      "file_ext": [\r
+        "bpmn"\r
+      ],\r
+      "derived_from": "tosca.artifacts.Implementation"\r
+    },\r
+    "artifact-component-jar": {\r
+      "description": "Component Jar",\r
+      "version": "1.0.0",\r
+      "file_ext": [\r
+        "jar"\r
+      ],\r
+      "derived_from": "tosca.artifacts.Implementation"\r
+    }\r
+  },\r
+  "node_types": {\r
+    "bpmn-activate": {\r
+      "description": "This is BPMN Activate node type",\r
+      "version": "1.0.0",\r
+      "properties": {\r
+        "content": {\r
+          "required": false,\r
+          "type": "string"\r
+        },\r
+        "process-name": {\r
+          "required": false,\r
+          "type": "string"\r
+        },\r
+        "version": {\r
+          "required": false,\r
+          "type": "string",\r
+          "default" : "LATEST"\r
+        }\r
+      },\r
+      "derived_from": "tosca.nodes.Component"\r
+    },\r
+    "tosca.nodes.Component": {\r
+      "description": "This is Resource Assignment Component API",\r
+      "version": "1.0.0",\r
+      "properties": {\r
+        "type": {\r
+          "description": "Request Id used to store the generated configuration, in the database along with the template-name",\r
+          "required": false,\r
+          "type": "string"\r
+        }\r
+      },\r
+      "interfaces": {\r
+        "DefaultOperation": {\r
+          "operations": {\r
+            "validate": {\r
+              "inputs": {\r
+                "action-name": {\r
+                  "description": "validate for action",\r
+                  "required": false,\r
+                  "type": "string"\r
+                }\r
+              }\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "artifacts" :{\r
+        "component-jar": {\r
+          "description": "Component Jar",\r
+          "type": "artifact-component-jar",\r
+          "file": "Component/basecomponent.jar"\r
+        }\r
+      },\r
+      "derived_from": "tosca.nodes.Root"\r
+    },\r
+    "tosca.nodes.component.Python": {\r
+      "description": "This is Resource Assignment Python Component API",\r
+      "version": "1.0.0",\r
+      "properties": {\r
+        "type": {\r
+          "description": "Request Id used to store the generated configuration, in the database along with the template-name",\r
+          "required": false,\r
+          "type": "string"\r
+        }\r
+      },\r
+      "interfaces": {\r
+        "DefaultOperation": {\r
+          "operations": {\r
+            "validate": {\r
+              "inputs": {\r
+                "action-name": {\r
+                  "description": "validate for action",\r
+                  "required": false,\r
+                  "type": "string"\r
+                }\r
+              }\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "artifacts" :{\r
+        "component-jar": {\r
+          "description": "Component Jar",\r
+          "type": "artifact-component-jar",\r
+          "file": "Component/basecomponent.jar"\r
+        }\r
+      },\r
+      "derived_from": "tosca.nodes.Root"\r
+    },\r
+    "component-resource-assignment": {\r
+      "description": "This is Resource Assignment Component API",\r
+      "version": "1.0.0",\r
+      "properties": {\r
+        "request-id": {\r
+          "description": "Request Id used to store the generated configuration, in the database along with the template-name",\r
+          "required": true,\r
+          "type": "string"\r
+        }\r
+      },\r
+      "interfaces": {\r
+        "DefaultComponentNode": {\r
+          "operations": {\r
+            "process": {\r
+              "inputs": {\r
+                "action-name": {\r
+                  "description": "Recipe Name to get from Database, Either (message & mask-info ) or ( resource-id & resource-type & action-name & template-name ) should be present. Message will be given higest priority",\r
+                  "required": false,\r
+                  "type": "string"\r
+                },\r
+                "resource-type": {\r
+                  "required": false,\r
+                  "type": "string"\r
+                },\r
+                "request-id": {\r
+                  "description": "Request Id used to store the generated configuration, in the database along with the template-name",\r
+                  "required": true,\r
+                  "type": "string"\r
+                },\r
+                "resource-id": {\r
+                  "description": "Id used to pull the data content from the data base. Either template-data or resource-id should be present",\r
+                  "required": true,\r
+                  "type": "string"\r
+                },\r
+                "template-content": {\r
+                  "description": "Id used to pull the data content from the data base. Either template-data or resource-id should be present",\r
+                  "required": true,\r
+                  "type": "string"\r
+                },\r
+                "mapping-content": {\r
+                  "description": "Id used to pull the data content from the data base. Either template-data or resource-id should be present",\r
+                  "required": true,\r
+                  "type": "string"\r
+                }\r
+              },\r
+              "outputs": {\r
+                "resource-assignment-params": {\r
+                  "required": true,\r
+                  "type": "string"\r
+                },\r
+                "status": {\r
+                  "required": true,\r
+                  "type": "string"\r
+                }\r
+              }\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "derived_from": "tosca.nodes.Component"\r
+    },\r
+    "component-resource-assignment-python": {\r
+      "description": "This is Resource Assignment Component API",\r
+      "version": "1.0.0",\r
+      "properties": {\r
+        "request-id": {\r
+          "description": "Request Id used to store the generated configuration, in the database along with the template-name",\r
+          "required": true,\r
+          "type": "string"\r
+        }\r
+      },\r
+      "interfaces": {\r
+        "DefaultComponentNode": {\r
+          "operations": {\r
+            "process": {\r
+              "inputs": {\r
+                "action-name": {\r
+                  "description": "Recipe Name to get from Database, Either (message & mask-info ) or ( resource-id & resource-type & action-name & template-name ) should be present. Message will be given higest priority",\r
+                  "required": false,\r
+                  "type": "string"\r
+                }\r
+              },\r
+              "outputs": {\r
+                "resource-assignment-params": {\r
+                  "required": true,\r
+                  "type": "string"\r
+                },\r
+                "status": {\r
+                  "required": true,\r
+                  "type": "string"\r
+                }\r
+              }\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "derived_from": "tosca.nodes.component.Python"\r
+    }\r
+  },\r
+  "data_types": {\r
+    "sample-property" : {\r
+      "description": "This is sample data type",\r
+      "version": "1.0.0",\r
+      "properties": {\r
+        "content": {\r
+          "required": false,\r
+          "type": "string"\r
+        },\r
+        "process-name": {\r
+          "required": false,\r
+          "type": "string"\r
+        },\r
+        "version": {\r
+          "required": false,\r
+          "type": "string",\r
+          "default" : "LATEST"\r
+        }\r
+      },\r
+      "derived_from" : "tosca.datatypes.Root"\r
+    }\r
+  }\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/load/blueprints/baseconfiguration/Mappings/baseconfig-mapping.json b/ms/controllerblueprints/modules/core/load/blueprints/baseconfiguration/Mappings/baseconfig-mapping.json
new file mode 100644 (file)
index 0000000..6abfb51
--- /dev/null
@@ -0,0 +1,3 @@
+{\r
+  "assignments": "Sample Assignments"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/load/blueprints/baseconfiguration/Plans/ActivateProcess.bpmn b/ms/controllerblueprints/modules/core/load/blueprints/baseconfiguration/Plans/ActivateProcess.bpmn
new file mode 100644 (file)
index 0000000..5e94c0f
--- /dev/null
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL"\r
+                  xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"\r
+                  xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"\r
+                  xmlns:camunda="http://camunda.org/schema/1.0/bpmn"\r
+                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1"\r
+                  targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="1.11.2">\r
+    <bpmn:process id="ActivateProcess" isExecutable="true">\r
+        <bpmn:startEvent id="StartEvent_1">\r
+            <bpmn:outgoing>SequenceFlow_0l0dq58</bpmn:outgoing>\r
+        </bpmn:startEvent>\r
+        <bpmn:endEvent id="EndEvent_1pr0kil">\r
+            <bpmn:incoming>SequenceFlow_1ay0k6p</bpmn:incoming>\r
+        </bpmn:endEvent>\r
+        <bpmn:sequenceFlow id="SequenceFlow_0l0dq58" sourceRef="StartEvent_1" targetRef="activate_device_task"/>\r
+        <bpmn:sequenceFlow id="SequenceFlow_1ay0k6p" sourceRef="activate_device_task" targetRef="EndEvent_1pr0kil"/>\r
+        <bpmn:serviceTask id="activate_device_task" name="Activate Device"\r
+                          camunda:delegateExpression="${componentDelegateService}">\r
+            <bpmn:extensionElements>\r
+                <camunda:inputOutput>\r
+                    <camunda:inputParameter name="selector"><![CDATA[resource-assignment\r
+]]></camunda:inputParameter>\r
+                </camunda:inputOutput>\r
+            </bpmn:extensionElements>\r
+            <bpmn:incoming>SequenceFlow_0l0dq58</bpmn:incoming>\r
+            <bpmn:outgoing>SequenceFlow_1ay0k6p</bpmn:outgoing>\r
+        </bpmn:serviceTask>\r
+    </bpmn:process>\r
+    <bpmndi:BPMNDiagram id="BPMNDiagram_1">\r
+        <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="ActivateProcess">\r
+            <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">\r
+                <dc:Bounds x="175" y="143" width="36" height="36"/>\r
+                <bpmndi:BPMNLabel>\r
+                    <dc:Bounds x="148" y="179" width="90" height="20"/>\r
+                </bpmndi:BPMNLabel>\r
+            </bpmndi:BPMNShape>\r
+            <bpmndi:BPMNShape id="EndEvent_1pr0kil_di" bpmnElement="EndEvent_1pr0kil">\r
+                <dc:Bounds x="575" y="114" width="36" height="36"/>\r
+                <bpmndi:BPMNLabel>\r
+                    <dc:Bounds x="593" y="154" width="0" height="12"/>\r
+                </bpmndi:BPMNLabel>\r
+            </bpmndi:BPMNShape>\r
+            <bpmndi:BPMNEdge id="SequenceFlow_0l0dq58_di" bpmnElement="SequenceFlow_0l0dq58">\r
+                <di:waypoint xsi:type="dc:Point" x="211" y="161"/>\r
+                <di:waypoint xsi:type="dc:Point" x="273" y="161"/>\r
+                <di:waypoint xsi:type="dc:Point" x="273" y="149"/>\r
+                <di:waypoint xsi:type="dc:Point" x="334" y="149"/>\r
+                <bpmndi:BPMNLabel>\r
+                    <dc:Bounds x="288" y="149" width="0" height="12"/>\r
+                </bpmndi:BPMNLabel>\r
+            </bpmndi:BPMNEdge>\r
+            <bpmndi:BPMNEdge id="SequenceFlow_1ay0k6p_di" bpmnElement="SequenceFlow_1ay0k6p">\r
+                <di:waypoint xsi:type="dc:Point" x="434" y="149"/>\r
+                <di:waypoint xsi:type="dc:Point" x="505" y="149"/>\r
+                <di:waypoint xsi:type="dc:Point" x="505" y="132"/>\r
+                <di:waypoint xsi:type="dc:Point" x="575" y="132"/>\r
+                <bpmndi:BPMNLabel>\r
+                    <dc:Bounds x="520" y="134.5" width="0" height="12"/>\r
+                </bpmndi:BPMNLabel>\r
+            </bpmndi:BPMNEdge>\r
+            <bpmndi:BPMNShape id="ServiceTask_0e8ek4f_di" bpmnElement="activate_device_task">\r
+                <dc:Bounds x="334" y="109" width="100" height="80"/>\r
+            </bpmndi:BPMNShape>\r
+        </bpmndi:BPMNPlane>\r
+    </bpmndi:BPMNDiagram>\r
+</bpmn:definitions>\r
diff --git a/ms/controllerblueprints/modules/core/load/blueprints/baseconfiguration/Scripts/SamplePythonComponentNode.py b/ms/controllerblueprints/modules/core/load/blueprints/baseconfiguration/Scripts/SamplePythonComponentNode.py
new file mode 100644 (file)
index 0000000..eb198c7
--- /dev/null
@@ -0,0 +1,8 @@
+from com.brvith.orchestrator.core.interfaces import ComponentNode\r
+\r
+class SamplePythonComponentNode(ComponentNode):\r
+    def prepare(self, context, componentContext):\r
+        return None\r
+\r
+    def prepare(self, context, componentContext):\r
+        return None
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/load/blueprints/baseconfiguration/Scripts/__init__.py b/ms/controllerblueprints/modules/core/load/blueprints/baseconfiguration/Scripts/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/ms/controllerblueprints/modules/core/load/blueprints/baseconfiguration/TOSCA-Metadata/TOSCA.meta b/ms/controllerblueprints/modules/core/load/blueprints/baseconfiguration/TOSCA-Metadata/TOSCA.meta
new file mode 100644 (file)
index 0000000..fb38c15
--- /dev/null
@@ -0,0 +1,8 @@
+TOSCA-Meta-File-Version: 1.0.0\r
+CSAR-Version: 1.0\r
+Created-By: Brinda Santh M\r
+Entry-Definitions: Definitions/activation-blueprint.json\r
+Template-Tags: Brinda Santh, activation-blueprint\r
+\r
+Name: Plans/ActivateProcess.bpmn\r
+Content-Type: application/vnd.oasis.bpmn\r
diff --git a/ms/controllerblueprints/modules/core/load/blueprints/baseconfiguration/Templates/baseconfig-template.vtl b/ms/controllerblueprints/modules/core/load/blueprints/baseconfiguration/Templates/baseconfig-template.vtl
new file mode 100644 (file)
index 0000000..026c591
--- /dev/null
@@ -0,0 +1 @@
+This is Sample Velocity Template
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/load/blueprints/baseconfiguration/__init__.py b/ms/controllerblueprints/modules/core/load/blueprints/baseconfiguration/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/ms/controllerblueprints/modules/core/load/blueprints/simple-baseconfig/Definitions/sample-nodetype.json b/ms/controllerblueprints/modules/core/load/blueprints/simple-baseconfig/Definitions/sample-nodetype.json
new file mode 100644 (file)
index 0000000..6d469ea
--- /dev/null
@@ -0,0 +1,34 @@
+{\r
+  "description": "This is Resource Assignment Component API",\r
+  "version": "1.0.0",\r
+  "properties": {\r
+    "type": {\r
+      "description": "Request Id used to store the generated configuration, in the database along with the template-name",\r
+      "required": false,\r
+      "type": "string"\r
+    }\r
+  },\r
+  "interfaces": {\r
+    "DefaultOperation": {\r
+      "operations": {\r
+        "validate": {\r
+          "inputs": {\r
+            "action-name": {\r
+              "description": "validate for action",\r
+              "required": false,\r
+              "type": "string"\r
+            }\r
+          }\r
+        }\r
+      }\r
+    }\r
+  },\r
+  "artifacts" :{\r
+    "component-jar": {\r
+      "description": "Component Jar",\r
+      "type": "artifact-component-jar",\r
+      "file": "Component/basecomponent.jar"\r
+    }\r
+  },\r
+  "derived_from": "tosca.nodes.Root"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/load/blueprints/simple-baseconfig/Definitions/simple-baseconfig.json b/ms/controllerblueprints/modules/core/load/blueprints/simple-baseconfig/Definitions/simple-baseconfig.json
new file mode 100644 (file)
index 0000000..e78f32f
--- /dev/null
@@ -0,0 +1,345 @@
+{\r
+  "metadata": {\r
+    "template_author": "Brinda Santh",\r
+    "template_name": "simple-baseconfig",\r
+    "template_version": "1.0.0",\r
+    "service-type": "Sample Service",\r
+    "release": "1806",\r
+    "vnf-type": "VPE"\r
+  },\r
+  "topology_template": {\r
+    "inputs": {\r
+      "request-id": {\r
+        "required": true,\r
+        "type": "string"\r
+      },\r
+      "service-instance-id": {\r
+        "required": true,\r
+        "type": "string"\r
+      },\r
+      "scope-type": {\r
+        "required": true,\r
+        "type": "string"\r
+      },\r
+      "action-name": {\r
+        "required": true,\r
+        "type": "string"\r
+      },\r
+      "hostname": {\r
+        "required": true,\r
+        "type": "string"\r
+      }\r
+    },\r
+    "node_templates": {\r
+      "vpe-netconf-device": {\r
+        "capabilities": {\r
+          "netconf": {\r
+            "properties": {\r
+              "login-key": "sdnc",\r
+              "login-account": "sndc-local",\r
+              "source": "local",\r
+              "target-ip-address": "{\"get_attribute\":\"lo0-local-ipv4-address\"}",\r
+              "port-number": 22,\r
+              "connection-time-out": 30\r
+            }\r
+          }\r
+        },\r
+        "type": "vnf-netconf-device"\r
+      },\r
+      "activate-netconf-component": {\r
+        "capabilities": {\r
+          "component-node": {}\r
+        },\r
+        "requirements": {\r
+          "netconf-connection": {\r
+            "capability": "netconf",\r
+            "node": "vpe-netconf-device",\r
+            "relationship": "tosca.relationships.ConnectsTo"\r
+          }\r
+        },\r
+        "interfaces": {\r
+          "org-openecomp-sdnc-netconf-adaptor-service-NetconfExecutorNode": {\r
+            "operations": {\r
+              "process": {\r
+                "inputs": {\r
+                  "action-name": "{ \"get_input\" : \"action-name\" }",\r
+                  "service-template-name": "{ \"get_attribute\" : \"template_name\" }",\r
+                  "service-template-version": "{ \"get_attribute\" : \"service-template-version\" }",\r
+                  "resource-type": "vnf-type",\r
+                  "request-id": "{ \"get_input\" : \"request-id\" }",\r
+                  "resource-id": "{ \"get_input\" : \"hostname\" }",\r
+                  "execution-script": "execution-script"\r
+                },\r
+                "outputs": {\r
+                  "response-data": "{ \"get_attribute\" : \"netconf-executor-baseconfig.response-data\" }",\r
+                  "status": "{ \"get_attribute\" : \"netconf-executor-baseconfig.status\" }"\r
+                },\r
+                "implementation" : {\r
+                  "primary" : "file://netconf_adaptor/DefaultBaseLicenceConfig.py"\r
+                }\r
+              }\r
+            }\r
+          }\r
+        },\r
+        "type": "component-netconf-executor"\r
+      },\r
+      "resource-assignment-ra-component": {\r
+        "capabilities": {\r
+          "component-node": {}\r
+        },\r
+        "interfaces": {\r
+          "org-openecomp-sdnc-config-assignment-service-ConfigAssignmentNode": {\r
+            "operations": {\r
+              "process": {\r
+                "inputs": {\r
+                  "template-names": [\r
+                    "base-config-template",\r
+                    "licence-template"\r
+                  ],\r
+                  "action-name": "{ \"get_input\" : \"action-name\" }",\r
+                  "service-template-name": "{ \"get_attribute\" : \"template_name\" }",\r
+                  "service-template-version": "{ \"get_attribute\" : \"service-template-version\" }",\r
+                  "resource-type": "vnf-type",\r
+                  "request-id": "{ \"get_input\" : \"request-id\" }",\r
+                  "resource-id": "{ \"get_input\" : \"hostname\" }"\r
+                },\r
+                "outputs": {\r
+                  "resource-assignment-params": "success",\r
+                  "status": "status"\r
+                }\r
+              }\r
+            }\r
+          }\r
+        },\r
+        "type": "component-resource-assignment"\r
+      },\r
+      "resource-assignment-action": {\r
+        "properties": {\r
+          "mode": "sync",\r
+          "version": "LATEST",\r
+          "is-start-flow": "false"\r
+        },\r
+        "requirements": {\r
+          "component-dependency": {\r
+            "capability": "component-node",\r
+            "node": "resource-assignment-ra-component",\r
+            "relationship": "tosca.relationships.DependsOn"\r
+          }\r
+        },\r
+        "capabilities": {\r
+          "dg-node": {},\r
+          "content": {\r
+            "properties": {\r
+              "type": "json"\r
+            }\r
+          }\r
+        },\r
+        "interfaces": {\r
+          "CONFIG": {\r
+            "operations": {\r
+              "ResourceAssignment": {\r
+                "inputs": {\r
+                  "params": []\r
+                }\r
+              }\r
+            }\r
+          }\r
+        },\r
+        "type": "dg-resource-assignment"\r
+      },\r
+      "activate-action": {\r
+        "properties": {\r
+          "mode": "sync",\r
+          "version": "LATEST",\r
+          "is-start-flow": "false"\r
+        },\r
+        "requirements": {\r
+          "component-dependency": {\r
+            "capability": "component-node",\r
+            "node": "activate-netconf-component",\r
+            "relationship": "tosca.relationships.DependsOn"\r
+          }\r
+        },\r
+        "capabilities": {\r
+          "dg-node": {},\r
+          "content": {\r
+            "properties": {\r
+              "type": "json"\r
+            }\r
+          }\r
+        },\r
+        "interfaces": {\r
+          "CONFIG": {\r
+            "operations": {\r
+              "ActivateNetconf": {\r
+                "inputs": {\r
+                  "params": []\r
+                }\r
+              }\r
+            }\r
+          }\r
+        },\r
+        "type": "dg-activate-netconf"\r
+      },\r
+      "base-config-template": {\r
+        "capabilities": {\r
+          "content": {\r
+            "properties": {\r
+              "content": "db://base-config-template"\r
+            }\r
+          },\r
+          "mapping": {\r
+            "properties": {\r
+              "mapping": [\r
+                {\r
+                  "name": "bundle-mac",\r
+                  "property": {\r
+                    "description": "",\r
+                    "required": true,\r
+                    "type": "string",\r
+                    "status": "",\r
+                    "constraints": [\r
+                      {}\r
+                    ],\r
+                    "entry_schema": {\r
+                      "type": ""\r
+                    }\r
+                  },\r
+                  "input-param": false,\r
+                  "dictionary-name": "bundle-mac",\r
+                  "dictionary-source": "db",\r
+                  "dependencies": [\r
+                    "hostname"\r
+                  ],\r
+                  "version": 0\r
+                },\r
+                {\r
+                  "name": "wan-aggregate-ipv4-addresses",\r
+                  "property": {\r
+                    "description": "",\r
+                    "required": true,\r
+                    "type": "list",\r
+                    "status": "",\r
+                    "constraints": [\r
+                      {}\r
+                    ],\r
+                    "entry_schema": {\r
+                      "type": "dt-v4-aggregate"\r
+                    }\r
+                  },\r
+                  "input-param": false,\r
+                  "dictionary-name": "wan-aggregate-ipv4-addresses",\r
+                  "dictionary-source": "mdsal",\r
+                  "dependencies": [\r
+                    "service-instance-id",\r
+                    "oam-network-role",\r
+                    "oam-v4-ip-type ",\r
+                    "oam-vm-type"\r
+                  ],\r
+                  "version": 0\r
+                },\r
+                {\r
+                  "name": "hostname",\r
+                  "property": {\r
+                    "required": true,\r
+                    "type": "string"\r
+                  },\r
+                  "dictionary-name": "hostname",\r
+                  "dictionary-source": "input",\r
+                  "version": 0,\r
+                  "input-param": false\r
+                },\r
+                {\r
+                  "name": "service",\r
+                  "property": {\r
+                    "required": true,\r
+                    "type": "string"\r
+                  },\r
+                  "dictionary-name": "service",\r
+                  "dictionary-source": "input",\r
+                  "version": 0,\r
+                  "input-param": false\r
+                },\r
+                {\r
+                  "name": "service-instance-id",\r
+                  "property": {\r
+                    "required": true,\r
+                    "type": "string"\r
+                  },\r
+                  "dictionary-name": "service-instance-id",\r
+                  "dictionary-source": "input",\r
+                  "version": 0,\r
+                  "input-param": false\r
+                }\r
+              ]\r
+            }\r
+          }\r
+        },\r
+        "properties": {\r
+          "action-names": [\r
+            "resource-assignment-action"\r
+          ]\r
+        },\r
+        "type": "artifact-config-template"\r
+      },\r
+      "licence-template": {\r
+        "capabilities": {\r
+          "content": {\r
+            "properties": {\r
+              "content": "db://licence-template"\r
+            }\r
+          },\r
+          "mapping": {\r
+            "properties": {\r
+              "mapping": [\r
+                {\r
+                  "name": "licenses",\r
+                  "property": {\r
+                    "description": "",\r
+                    "required": true,\r
+                    "type": "list",\r
+                    "status": "",\r
+                    "constraints": [\r
+                      {}\r
+                    ],\r
+                    "entry_schema": {\r
+                      "type": "dt-license-key"\r
+                    }\r
+                  },\r
+                  "input-param": false,\r
+                  "dictionary-name": "licenses",\r
+                  "dictionary-source": "mdsal",\r
+                  "dependencies": [\r
+                    "service-instance-id"\r
+                  ],\r
+                  "version": 0\r
+                },\r
+                {\r
+                  "name": "service-instance-id",\r
+                  "property": {\r
+                    "required": true,\r
+                    "type": "string"\r
+                  },\r
+                  "dictionary-name": "service-instance-id",\r
+                  "dictionary-source": "input",\r
+                  "version": 0,\r
+                  "input-param": false\r
+                }\r
+              ]\r
+            }\r
+          }\r
+        },\r
+        "properties": {\r
+          "action-names": [\r
+            "resource-assignment-action"\r
+          ]\r
+        },\r
+        "type": "artifact-config-template"\r
+      }\r
+    }\r
+  },\r
+  "node_types": {\r
+  },\r
+  "data_types": {\r
+  }\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/load/blueprints/simple-baseconfig/Mappings/baseconfig-mapping.json b/ms/controllerblueprints/modules/core/load/blueprints/simple-baseconfig/Mappings/baseconfig-mapping.json
new file mode 100644 (file)
index 0000000..6abfb51
--- /dev/null
@@ -0,0 +1,3 @@
+{\r
+  "assignments": "Sample Assignments"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/load/blueprints/simple-baseconfig/Plans/ActivateProcess.bpmn b/ms/controllerblueprints/modules/core/load/blueprints/simple-baseconfig/Plans/ActivateProcess.bpmn
new file mode 100644 (file)
index 0000000..5e94c0f
--- /dev/null
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL"\r
+                  xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"\r
+                  xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"\r
+                  xmlns:camunda="http://camunda.org/schema/1.0/bpmn"\r
+                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1"\r
+                  targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="1.11.2">\r
+    <bpmn:process id="ActivateProcess" isExecutable="true">\r
+        <bpmn:startEvent id="StartEvent_1">\r
+            <bpmn:outgoing>SequenceFlow_0l0dq58</bpmn:outgoing>\r
+        </bpmn:startEvent>\r
+        <bpmn:endEvent id="EndEvent_1pr0kil">\r
+            <bpmn:incoming>SequenceFlow_1ay0k6p</bpmn:incoming>\r
+        </bpmn:endEvent>\r
+        <bpmn:sequenceFlow id="SequenceFlow_0l0dq58" sourceRef="StartEvent_1" targetRef="activate_device_task"/>\r
+        <bpmn:sequenceFlow id="SequenceFlow_1ay0k6p" sourceRef="activate_device_task" targetRef="EndEvent_1pr0kil"/>\r
+        <bpmn:serviceTask id="activate_device_task" name="Activate Device"\r
+                          camunda:delegateExpression="${componentDelegateService}">\r
+            <bpmn:extensionElements>\r
+                <camunda:inputOutput>\r
+                    <camunda:inputParameter name="selector"><![CDATA[resource-assignment\r
+]]></camunda:inputParameter>\r
+                </camunda:inputOutput>\r
+            </bpmn:extensionElements>\r
+            <bpmn:incoming>SequenceFlow_0l0dq58</bpmn:incoming>\r
+            <bpmn:outgoing>SequenceFlow_1ay0k6p</bpmn:outgoing>\r
+        </bpmn:serviceTask>\r
+    </bpmn:process>\r
+    <bpmndi:BPMNDiagram id="BPMNDiagram_1">\r
+        <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="ActivateProcess">\r
+            <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">\r
+                <dc:Bounds x="175" y="143" width="36" height="36"/>\r
+                <bpmndi:BPMNLabel>\r
+                    <dc:Bounds x="148" y="179" width="90" height="20"/>\r
+                </bpmndi:BPMNLabel>\r
+            </bpmndi:BPMNShape>\r
+            <bpmndi:BPMNShape id="EndEvent_1pr0kil_di" bpmnElement="EndEvent_1pr0kil">\r
+                <dc:Bounds x="575" y="114" width="36" height="36"/>\r
+                <bpmndi:BPMNLabel>\r
+                    <dc:Bounds x="593" y="154" width="0" height="12"/>\r
+                </bpmndi:BPMNLabel>\r
+            </bpmndi:BPMNShape>\r
+            <bpmndi:BPMNEdge id="SequenceFlow_0l0dq58_di" bpmnElement="SequenceFlow_0l0dq58">\r
+                <di:waypoint xsi:type="dc:Point" x="211" y="161"/>\r
+                <di:waypoint xsi:type="dc:Point" x="273" y="161"/>\r
+                <di:waypoint xsi:type="dc:Point" x="273" y="149"/>\r
+                <di:waypoint xsi:type="dc:Point" x="334" y="149"/>\r
+                <bpmndi:BPMNLabel>\r
+                    <dc:Bounds x="288" y="149" width="0" height="12"/>\r
+                </bpmndi:BPMNLabel>\r
+            </bpmndi:BPMNEdge>\r
+            <bpmndi:BPMNEdge id="SequenceFlow_1ay0k6p_di" bpmnElement="SequenceFlow_1ay0k6p">\r
+                <di:waypoint xsi:type="dc:Point" x="434" y="149"/>\r
+                <di:waypoint xsi:type="dc:Point" x="505" y="149"/>\r
+                <di:waypoint xsi:type="dc:Point" x="505" y="132"/>\r
+                <di:waypoint xsi:type="dc:Point" x="575" y="132"/>\r
+                <bpmndi:BPMNLabel>\r
+                    <dc:Bounds x="520" y="134.5" width="0" height="12"/>\r
+                </bpmndi:BPMNLabel>\r
+            </bpmndi:BPMNEdge>\r
+            <bpmndi:BPMNShape id="ServiceTask_0e8ek4f_di" bpmnElement="activate_device_task">\r
+                <dc:Bounds x="334" y="109" width="100" height="80"/>\r
+            </bpmndi:BPMNShape>\r
+        </bpmndi:BPMNPlane>\r
+    </bpmndi:BPMNDiagram>\r
+</bpmn:definitions>\r
diff --git a/ms/controllerblueprints/modules/core/load/blueprints/simple-baseconfig/Scripts/SamplePythonComponentNode.py b/ms/controllerblueprints/modules/core/load/blueprints/simple-baseconfig/Scripts/SamplePythonComponentNode.py
new file mode 100644 (file)
index 0000000..eb198c7
--- /dev/null
@@ -0,0 +1,8 @@
+from com.brvith.orchestrator.core.interfaces import ComponentNode\r
+\r
+class SamplePythonComponentNode(ComponentNode):\r
+    def prepare(self, context, componentContext):\r
+        return None\r
+\r
+    def prepare(self, context, componentContext):\r
+        return None
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/load/blueprints/simple-baseconfig/Scripts/__init__.py b/ms/controllerblueprints/modules/core/load/blueprints/simple-baseconfig/Scripts/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/ms/controllerblueprints/modules/core/load/blueprints/simple-baseconfig/TOSCA-Metadata/TOSCA.meta b/ms/controllerblueprints/modules/core/load/blueprints/simple-baseconfig/TOSCA-Metadata/TOSCA.meta
new file mode 100644 (file)
index 0000000..d7ae5e8
--- /dev/null
@@ -0,0 +1,8 @@
+TOSCA-Meta-File-Version: 1.0.0\r
+CSAR-Version: 1.0\r
+Created-By: Brinda Santh M\r
+Entry-Definitions: Definitions/simple-baseconfig.json\r
+Template-Tags: vrr-test, Brinda Santh\r
+\r
+Name: Plans/ActivateProcess.bpmn\r
+Content-Type: application/vnd.oasis.bpmn\r
diff --git a/ms/controllerblueprints/modules/core/load/blueprints/simple-baseconfig/Templates/base-config-template.vtl b/ms/controllerblueprints/modules/core/load/blueprints/simple-baseconfig/Templates/base-config-template.vtl
new file mode 100644 (file)
index 0000000..92dba10
--- /dev/null
@@ -0,0 +1,40 @@
+ <config>\r
+               <configuration>\r
+                       <groups>\r
+                               <name>${group-name}</name>\r
+                               <routing-instances>\r
+                                       <instance>\r
+                                               <name>&lt;*&gt;</name>\r
+                                               <protocols>\r
+                                                       <pim>\r
+                                                               <dense-groups>\r
+                                                                       <dynamic-reject />\r
+                                                                       <pim-dense-group-type>\r
+                                                                               <name>224.0.1.40/32</name>\r
+                                                                       </pim-dense-group-type>\r
+                                                                       <pim-dense-group-type>\r
+                                                                               <name>224.0.1.39/32</name>\r
+                                                                       </pim-dense-group-type>\r
+                                                                       <pim-dense-group-type>\r
+                                                                               <name>224.0.0.0/4</name>\r
+                                                                               <reject />\r
+                                                                       </pim-dense-group-type>\r
+                                                               </dense-groups>\r
+                                                               <rp>\r
+                                                                       <auto-rp>\r
+                                                                               <discovery />\r
+                                                                       </auto-rp>\r
+                                                               </rp>\r
+                                                               <interface>\r
+                                                                       <name>&lt;*&gt;</name>\r
+                                                                       <disable />\r
+                                                                       <priority>1000</priority>\r
+                                                               </interface>\r
+                                                               <reset-tracking-bit />\r
+                                                       </pim>\r
+                                               </protocols>\r
+                                       </instance>\r
+                               </routing-instances>\r
+                       </groups>\r
+               </configuration>\r
+       </config>
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/load/blueprints/simple-baseconfig/Templates/baseconfig-template.vtl b/ms/controllerblueprints/modules/core/load/blueprints/simple-baseconfig/Templates/baseconfig-template.vtl
new file mode 100644 (file)
index 0000000..026c591
--- /dev/null
@@ -0,0 +1 @@
+This is Sample Velocity Template
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/load/blueprints/simple-baseconfig/Templates/licence-template.vtl b/ms/controllerblueprints/modules/core/load/blueprints/simple-baseconfig/Templates/licence-template.vtl
new file mode 100644 (file)
index 0000000..626974f
--- /dev/null
@@ -0,0 +1,4 @@
+ <config>\r
+               <configuration>\r
+               </configuration>\r
+                </config>\r
diff --git a/ms/controllerblueprints/modules/core/load/blueprints/simple-baseconfig/__init__.py b/ms/controllerblueprints/modules/core/load/blueprints/simple-baseconfig/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/ms/controllerblueprints/modules/core/load/model_type/artifact_type/artifact-mapping-resource.json b/ms/controllerblueprints/modules/core/load/model_type/artifact_type/artifact-mapping-resource.json
new file mode 100644 (file)
index 0000000..0a3261b
--- /dev/null
@@ -0,0 +1,8 @@
+{\r
+  "description": " Velocity Template Resource Mapping File used along with Configuration template",\r
+  "version": "1.0.0",\r
+  "file_ext": [\r
+    "json"\r
+  ],\r
+  "derived_from": "tosca.artifacts.Implementation"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/load/model_type/artifact_type/artifact-script-python.json b/ms/controllerblueprints/modules/core/load/model_type/artifact_type/artifact-script-python.json
new file mode 100644 (file)
index 0000000..b48d2b6
--- /dev/null
@@ -0,0 +1,8 @@
+{\r
+  "description": " Kotlin Script Template used for Configuration",\r
+  "version": "1.0.0",\r
+  "file_ext": [\r
+    "py"\r
+  ],\r
+  "derived_from": "tosca.artifacts.Implementation"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/load/model_type/artifact_type/artifact-template-velocity.json b/ms/controllerblueprints/modules/core/load/model_type/artifact_type/artifact-template-velocity.json
new file mode 100644 (file)
index 0000000..9395d39
--- /dev/null
@@ -0,0 +1,8 @@
+{\r
+  "description": " Velocity Template used for Configuration",\r
+  "version": "1.0.0",\r
+  "file_ext": [\r
+    "vtl"\r
+  ],\r
+  "derived_from": "tosca.artifacts.Implementation"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/load/model_type/artifact_type/tosca.artifacts.Implementation.json b/ms/controllerblueprints/modules/core/load/model_type/artifact_type/tosca.artifacts.Implementation.json
new file mode 100644 (file)
index 0000000..5a7c956
--- /dev/null
@@ -0,0 +1,5 @@
+{\r
+  "description": "TOSCA base type for implementation artifacts",\r
+  "version": "1.0.0",\r
+  "derived_from": "tosca.artifacts.Root"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/load/model_type/data_type/datatype-property.json b/ms/controllerblueprints/modules/core/load/model_type/data_type/datatype-property.json
new file mode 100644 (file)
index 0000000..5584b10
--- /dev/null
@@ -0,0 +1,27 @@
+{\r
+       "version": "1.0.0",\r
+       "description": "This is Entry point Input Data Type, which is dynamic datatype, The parameter names will be populated during the Design time for each inputs",\r
+       "properties": {\r
+               "type": {\r
+                       "required": true,\r
+                       "type": "string"\r
+               },\r
+               "description": {\r
+                       "required": false,\r
+                       "type": "string"\r
+               },\r
+               "required": {\r
+                       "required": false,\r
+                       "type": "boolean"\r
+               },\r
+               "default": {\r
+                       "required": false,\r
+                       "type": "string"\r
+               },\r
+               "entry_schema": {\r
+                       "required": false,\r
+                       "type": "string"\r
+               }\r
+       },\r
+       "derived_from": "tosca.datatypes.Root"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/load/model_type/data_type/datatype-resource-assignment.json b/ms/controllerblueprints/modules/core/load/model_type/data_type/datatype-resource-assignment.json
new file mode 100644 (file)
index 0000000..cc9816e
--- /dev/null
@@ -0,0 +1,46 @@
+{\r
+       "version": "1.0.0",\r
+       "description": "This is Resource Assignment Data Type",\r
+       "properties": {\r
+               "property": {\r
+                       "required": true,\r
+                       "type": "datatype-property"\r
+               },\r
+               "input-param": {\r
+                       "required": true,\r
+                       "type": "boolean"\r
+               },\r
+               "dictionary-name": {\r
+                       "required": false,\r
+                       "type": "string"\r
+               },\r
+               "dictionary-source": {\r
+                       "required": false,\r
+                       "type": "string"\r
+               },\r
+               "dependencies": {\r
+                       "required": true,\r
+                       "type": "list",\r
+                       "entry_schema": {\r
+                               "type": "string"\r
+                       }\r
+               },\r
+               "status": {\r
+                       "required": false,\r
+                       "type": "string"\r
+               },\r
+               "message": {\r
+                       "required": false,\r
+                       "type": "string"\r
+               },\r
+               "updated-date": {\r
+                       "required": false,\r
+                       "type": "string"\r
+               },\r
+               "updated-by": {\r
+                       "required": false,\r
+                       "type": "string"\r
+               }\r
+       },\r
+       "derived_from": "tosca.datatypes.Root"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/load/model_type/data_type/dt-license-key.json b/ms/controllerblueprints/modules/core/load/model_type/data_type/dt-license-key.json
new file mode 100644 (file)
index 0000000..e9c312b
--- /dev/null
@@ -0,0 +1,11 @@
+{\r
+       "version": "1.0.0",\r
+       "description": "This is dt-plicense-key Data Type",\r
+       "properties": {\r
+               "license-key": {\r
+                       "required": true,\r
+                       "type": "string"\r
+               }\r
+       },\r
+       "derived_from": "tosca.datatypes.Root"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/load/model_type/data_type/dt-v4-aggregate.json b/ms/controllerblueprints/modules/core/load/model_type/data_type/dt-v4-aggregate.json
new file mode 100644 (file)
index 0000000..842a7f8
--- /dev/null
@@ -0,0 +1,15 @@
+{\r
+       "version": "1.0.0",\r
+       "description": "This is dt-v4-aggregate Data Type",\r
+       "properties": {\r
+               "ipv4-address": {\r
+                       "required": true,\r
+                       "type": "string"\r
+               },\r
+               "ipv4-plen": {\r
+                       "required": false,\r
+                       "type": "integer"\r
+               }\r
+       },\r
+       "derived_from": "tosca.datatypes.Root"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/load/model_type/data_type/tosca.datatypes.Credential.json b/ms/controllerblueprints/modules/core/load/model_type/data_type/tosca.datatypes.Credential.json
new file mode 100644 (file)
index 0000000..820a551
--- /dev/null
@@ -0,0 +1,31 @@
+{\r
+  "version": "1.0.0",\r
+  "description": "Credential",\r
+  "properties": {\r
+    "protocol": {\r
+      "required": false,\r
+      "type": "string"\r
+    },\r
+    "token_type": {\r
+      "required": true,\r
+      "type": "string",\r
+      "default" : "password"\r
+    },\r
+    "token": {\r
+      "required": false,\r
+      "type": "string"\r
+    },\r
+    "keys": {\r
+      "required": false,\r
+      "type": "list",\r
+      "entry_schema": {\r
+        "type": "string"\r
+      }\r
+    },\r
+    "user": {\r
+      "required": false,\r
+      "type": "string"\r
+    }\r
+  },\r
+  "derived_from": "tosca.datatypes.Root"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/load/model_type/node_type/artifact-config-template.json b/ms/controllerblueprints/modules/core/load/model_type/node_type/artifact-config-template.json
new file mode 100644 (file)
index 0000000..be9bbfc
--- /dev/null
@@ -0,0 +1,37 @@
+{\r
+       "description": "This is Configuration Velocity Template",\r
+       "version": "1.0.0",\r
+       "properties": {\r
+               "action-names": {\r
+                       "required": true,\r
+                       "type": "list",\r
+                       "entry_schema": {\r
+                               "type": "string"\r
+                       }\r
+               }\r
+       },\r
+       "capabilities": {\r
+               "content": {\r
+                       "type": "tosca.capability.Content",\r
+                       "properties": {\r
+                               "content": {\r
+                                       "required": true,\r
+                                       "type": "string"\r
+                               }\r
+                       }\r
+               },\r
+               "mapping": {\r
+                       "type": "tosca.capability.Mapping",\r
+                       "properties": {\r
+                               "mapping": {\r
+                                       "required": false,\r
+                                       "type": "list",\r
+                                       "entry_schema": {\r
+                                               "type": "datatype-resource-assignment"\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       },\r
+       "derived_from": "tosca.nodes.Artifact"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/load/model_type/node_type/component-config-generator.json b/ms/controllerblueprints/modules/core/load/model_type/node_type/component-config-generator.json
new file mode 100644 (file)
index 0000000..764f9e8
--- /dev/null
@@ -0,0 +1,72 @@
+{\r
+       "description": "This is Generate Configuration Component API",\r
+       "version": "1.0.0",\r
+       "capabilities": {\r
+               "component-node": {\r
+                       "type": "tosca.capabilities.Node"\r
+               }\r
+       },\r
+       "interfaces": {\r
+               "org-openecomp-sdnc-config-generator-service-ConfigGeneratorNode": {\r
+                       "operations": {\r
+                               "process": {\r
+                                       "inputs": {\r
+                                               "template-data": {\r
+                                                       "description": "Conditional : JSON string which is used to mash with template. Either template-data or ( resource-id and resource-type ) should be present",\r
+                                                       "required": false,\r
+                                                       "type": "string"\r
+                                               },\r
+                                               "template-content": {\r
+                                                       "description": "Conditional : Dynamic Template used to generate Configuration.",\r
+                                                       "required": false,\r
+                                                       "type": "string"\r
+                                               },\r
+                                               "resource-type": {\r
+                                                       "description": "Conditional : resource-type used to pull the data content from the data base. Either template-data or ( resource-id and resource-type ) should be present",\r
+                                                       "required": false,\r
+                                                       "type": "string"\r
+                                               },\r
+                                               "request-id": {\r
+                                                       "description": "Request Id used to store the generated configuration, in the database along with the template-name",\r
+                                                       "required": true,\r
+                                                       "type": "string"\r
+                                               },\r
+                                               "resource-id": {\r
+                                                       "description": "Conditional : Id used to pull the data content from the data base. Either template-data or ( resource-id and resource-type ) should be present",\r
+                                                       "required": false,\r
+                                                       "type": "string"\r
+                                               },\r
+                                               "action-name": {\r
+                                                       "description": "Conditional : Action Name to get from Database, Either (message & mask-info ) or ( resource-id & resource-type & action-name & template-name ) should be present. Message will be given higest priority",\r
+                                                       "required": false,\r
+                                                       "type": "string"\r
+                                               },\r
+                                               "template-name": {\r
+                                                       "description": "Conditional : Name of the Artifact Node Template, to get the template Content. If template-content is present, then content wont be reterived from the Artifact Node Template.",\r
+                                                       "required": true,\r
+                                                       "type": "string"\r
+                                               }\r
+                                       },\r
+                                       "outputs": {\r
+                                               "generated-config": {\r
+                                                       "description": "Generated Configuration for the Template adn Resource Data",\r
+                                                       "required": true,\r
+                                                       "type": "string"\r
+                                               },\r
+                                               "mask-info": {\r
+                                                       "description": "If template contains mask encription keys, then this mask-info field will be generated, This JSON Content alligns to the bean org.onap.ccsdk.apps.controllerblueprints.core.data.custom.MaskInfo ",\r
+                                                       "required": false,\r
+                                                       "type": "string"\r
+                                               },\r
+                                               "status": {\r
+                                                       "description": "Status of the Component Execution ( success or failure )",\r
+                                                       "required": true,\r
+                                                       "type": "string"\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       },\r
+       "derived_from": "tosca.nodes.Component"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/load/model_type/node_type/component-netconf-executor.json b/ms/controllerblueprints/modules/core/load/model_type/node_type/component-netconf-executor.json
new file mode 100644 (file)
index 0000000..aed667a
--- /dev/null
@@ -0,0 +1,79 @@
+{\r
+  "description": "This is Netconf Transaction Configuration Component API",\r
+  "version": "1.0.0",\r
+  "capabilities": {\r
+    "component-node": {\r
+      "type": "tosca.capabilities.Node"\r
+    }\r
+  },\r
+  "requirements": {\r
+    "netconf-connection": {\r
+      "capability": "netconf",\r
+      "node": "vnf-netconf-device",\r
+      "relationship": "tosca.relationships.ConnectsTo"\r
+    }\r
+  },\r
+  "interfaces": {\r
+    "org-openecomp-sdnc-netconf-adaptor-service-NetconfExecutorNode": {\r
+      "operations": {\r
+        "process": {\r
+          "inputs": {\r
+            "request-id": {\r
+              "description": "Request Id used to store the generated configuration, in the database along with the template-name",\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "service-template-name": {\r
+              "description": "Service Template Name",\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "service-template-version": {\r
+              "description": "Service Template Version",\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "action-name": {\r
+              "description": "Action Name to get from Database, Either (message & mask-info ) or ( resource-id & resource-type & action-name & template-name ) should be present. Message will be given higest priority",\r
+              "required": false,\r
+              "type": "string"\r
+            },\r
+            "resource-type": {\r
+              "description": "Resource Type to get from Database, Either (message & mask-info ) or( resource-id & resource-type & action-name & template-name ) should be present. Message will be given higest priority",\r
+              "required": false,\r
+              "type": "string"\r
+            },\r
+            "resource-id": {\r
+              "description": "Resource Id to get from Database, Either (message & mask-info ) or ( resource-id & resource-type & action-name & template-name ) should be present. Message will be given higest priority",\r
+              "required": false,\r
+              "type": "string"\r
+            },\r
+            "reservation-id": {\r
+                               "description": "Reservation Id used to send to NPM",\r
+                               "required": false,\r
+                               "type": "string"\r
+                       },\r
+            "execution-script": {\r
+              "description": "Python Script to Execute for this Component action, It should refer any one of Prython Artifact Definition for this Node Template.",\r
+              "required": true,\r
+              "type": "string"\r
+            }\r
+          },\r
+          "outputs": {\r
+            "response-data": {\r
+              "description": "Execution Response Data in JSON format.",\r
+              "required": false,\r
+              "type": "string"\r
+            },\r
+            "status": {\r
+              "description": "Status of the Component Execution ( success or failure )",\r
+              "required": true,\r
+              "type": "string"\r
+            }\r
+          }\r
+        }\r
+      }\r
+    }\r
+  },\r
+  "derived_from": "tosca.nodes.Component"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/load/model_type/node_type/component-resource-assignment.json b/ms/controllerblueprints/modules/core/load/model_type/node_type/component-resource-assignment.json
new file mode 100644 (file)
index 0000000..34c0284
--- /dev/null
@@ -0,0 +1,68 @@
+{\r
+  "description": "This is Resource Assignment Component API",\r
+  "version": "1.0.0",\r
+  "capabilities": {\r
+    "component-node": {\r
+      "type": "tosca.capabilities.Node"\r
+    }\r
+  },\r
+  "interfaces": {\r
+    "org-openecomp-sdnc-config-assignment-service-ConfigAssignmentNode": {\r
+      "operations": {\r
+        "process": {\r
+          "inputs": {\r
+            "service-template-name": {\r
+              "description": "Service Template Name.",\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "service-template-version": {\r
+              "description": "Service Template Version.",\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "resource-type": {\r
+              "description": "Request type.",\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "template-names": {\r
+              "description": "Name of the artifact Node Templates, to get the template Content.",\r
+              "required": true,\r
+              "type": "list",\r
+              "entry_schema": {\r
+                "type": "string"\r
+              }\r
+            },\r
+            "request-id": {\r
+              "description": "Request Id, Unique Id for the request.",\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "resource-id": {\r
+              "description": "Resource Id.",\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "action-name": {\r
+              "description": "Action Name of the process",\r
+              "required": true,\r
+              "type": "string"\r
+            }\r
+          },\r
+          "outputs": {\r
+            "resource-assignment-params": {\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "status": {\r
+              "required": true,\r
+              "type": "string"\r
+            }\r
+          }\r
+        }\r
+      }\r
+    }\r
+  },\r
+  "derived_from": "tosca.nodes.Component"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/load/model_type/node_type/dg-activate-netconf.json b/ms/controllerblueprints/modules/core/load/model_type/node_type/dg-activate-netconf.json
new file mode 100644 (file)
index 0000000..c638df0
--- /dev/null
@@ -0,0 +1,66 @@
+{
+       "description": "This is Download Netconf Directed Graph",
+       "version": "1.0.0",
+       "properties": {
+               "mode": {
+                       "required": false,
+                       "type": "string",
+                       "default": "sync"
+               },
+               "version": {
+                       "required": false,
+                       "type": "string",
+                       "default": "LATEST"
+               },
+               "is-start-flow": {
+                       "required": false,
+                       "type": "boolean",
+                       "default": "false"
+               }
+       },
+       "capabilities": {
+               "dg-node": {
+                       "type": "tosca.capabilities.Node"
+               },
+               "content": {
+                       "type": "tosca.capability.Content",
+                       "properties": {
+                               "type": {
+                                       "required": false,
+                                       "type": "string",
+                                       "default": "json"
+                               },
+                               "content": {
+                                       "required": true,
+                                       "type": "string"
+                               }
+                       }
+               }
+       },
+       "requirements": {
+               "component-dependency": {
+                       "capability": "component-node",
+                       "node": "component-netconf-executor",
+                       "relationship": "tosca.relationships.DependsOn"
+               }
+       },
+       "interfaces": {
+               "CONFIG": {
+                       "operations": {
+                               "ActivateNetconf": {
+                                       "inputs": {
+                                               "params": {
+                                                       "required": false,
+                                                       "type": "list",
+                                                       "entry_schema": {
+                                                               "type": "datatype-property"
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+       },
+       
+       "derived_from": "tosca.nodes.DG"
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/load/model_type/node_type/dg-config-generator.json b/ms/controllerblueprints/modules/core/load/model_type/node_type/dg-config-generator.json
new file mode 100644 (file)
index 0000000..28bace0
--- /dev/null
@@ -0,0 +1,65 @@
+{\r
+       "description": "This is Activate DG for Config Generator Directed Graph",\r
+       "version": "1.0.0",\r
+       "properties": {\r
+               "mode": {\r
+                       "required": false,\r
+                       "type": "string",\r
+                       "default": "sync"\r
+               },\r
+               "version": {\r
+                       "required": false,\r
+                       "type": "string",\r
+                       "default": "LATEST"\r
+               },\r
+               "is-start-flow": {\r
+                       "required": false,\r
+                       "type": "boolean",\r
+                       "default": "false"\r
+               }\r
+       },\r
+       "capabilities": {\r
+               "dg-node": {\r
+                       "type": "tosca.capabilities.Node"\r
+               },\r
+               "content": {\r
+                       "type": "tosca.capability.Content",\r
+                       "properties": {\r
+                               "type": {\r
+                                       "required": false,\r
+                                       "type": "string",\r
+                                       "default": "json"\r
+                               },\r
+                               "content": {\r
+                                       "required": true,\r
+                                       "type": "string"\r
+                               }\r
+                       }\r
+               }\r
+       },\r
+       "requirements": {\r
+               "component-dependency": {\r
+                       "capability": "component-node",\r
+                       "node": "component-config-generator",\r
+                       "relationship": "tosca.relationships.DependsOn"\r
+               }\r
+       },\r
+       "interfaces": {\r
+               "CONFIG": {\r
+                       "operations": {\r
+                               "GenerateConfiguration": {\r
+                                       "inputs": {\r
+                                               "params": {\r
+                                                       "required": false,\r
+                                                       "type": "list",\r
+                                                       "entry_schema": {\r
+                                                               "type": "datatype-property"\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       },\r
+       "derived_from": "tosca.nodes.DG"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/load/model_type/node_type/dg-resource-assign-activate.json b/ms/controllerblueprints/modules/core/load/model_type/node_type/dg-resource-assign-activate.json
new file mode 100644 (file)
index 0000000..e98fa5a
--- /dev/null
@@ -0,0 +1,70 @@
+{\r
+       "description": "This is Resource Assign and Activate Netconf Directed Graph",\r
+       "version": "1.0.0",\r
+       "properties": {\r
+               "mode": {\r
+                       "required": false,\r
+                       "type": "string",\r
+                       "default": "sync"\r
+               },\r
+               "version": {\r
+                       "required": false,\r
+                       "type": "string",\r
+                       "default": "LATEST"\r
+               },\r
+               "is-start-flow": {\r
+                       "required": false,\r
+                       "type": "boolean",\r
+                       "default": "false"\r
+               }\r
+       },\r
+       "capabilities": {\r
+               "dg-node": {\r
+                       "type": "tosca.capabilities.Node"\r
+               },\r
+               "content": {\r
+                       "type": "tosca.capability.Content",\r
+                       "properties": {\r
+                               "type": {\r
+                                       "required": false,\r
+                                       "type": "string",\r
+                                       "default": "json"\r
+                               },\r
+                               "content": {\r
+                                       "required": false,\r
+                                       "type": "string"\r
+                               }\r
+                       }\r
+               }\r
+       },\r
+       "requirements": {\r
+               "ra-component": {\r
+                       "capability": "component-node",\r
+                       "node": "component-resource-assignment",\r
+                       "relationship": "tosca.relationships.DependsOn"\r
+               },\r
+               "netconf-component": {\r
+                       "capability": "component-node",\r
+                       "node": "component-netconf-executor",\r
+                       "relationship": "tosca.relationships.DependsOn"\r
+               }\r
+       },\r
+       "interfaces": {\r
+               "CONFIG": {\r
+                       "operations": {\r
+                               "ResourceAssignAndActivate": {\r
+                                       "inputs": {\r
+                                               "params": {\r
+                                                       "required": false,\r
+                                                       "type": "list",\r
+                                                       "entry_schema": {\r
+                                                               "type": "datatype-property"\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       },\r
+       "derived_from": "tosca.nodes.DG"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/load/model_type/node_type/dg-resource-assignment.json b/ms/controllerblueprints/modules/core/load/model_type/node_type/dg-resource-assignment.json
new file mode 100644 (file)
index 0000000..36fbb68
--- /dev/null
@@ -0,0 +1,65 @@
+{\r
+       "description": "This is Resource Assignment Directed Graph",\r
+       "version": "1.0.0",\r
+       "properties": {\r
+               "mode": {\r
+                       "required": false,\r
+                       "type": "string",\r
+                       "default": "sync"\r
+               },\r
+               "version": {\r
+                       "required": false,\r
+                       "type": "string",\r
+                       "default": "LATEST"\r
+               },\r
+               "is-start-flow": {\r
+                       "required": false,\r
+                       "type": "boolean",\r
+                       "default": "false"\r
+               }\r
+       },\r
+       "capabilities": {\r
+               "dg-node": {\r
+                       "type": "tosca.capabilities.Node"\r
+               },\r
+               "content": {\r
+                       "type": "tosca.capability.Content",\r
+                       "properties": {\r
+                               "type": {\r
+                                       "required": false,\r
+                                       "type": "string",\r
+                                       "default": "json"\r
+                               },\r
+                               "content": {\r
+                                       "required": false,\r
+                                       "type": "string"\r
+                               }\r
+                       }\r
+               }\r
+       },\r
+       "requirements": {\r
+               "component-dependency": {\r
+                       "capability": "component-node",\r
+                       "node": "component-resource-assignment",\r
+                       "relationship": "tosca.relationships.DependsOn"\r
+               }\r
+       },\r
+       "interfaces": {\r
+               "CONFIG": {\r
+                       "operations": {\r
+                               "ResourceAssignment": {\r
+                                       "inputs": {\r
+                                               "params": {\r
+                                                       "required": false,\r
+                                                       "type": "list",\r
+                                                       "entry_schema": {\r
+                                                               "type": "datatype-property"\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       },\r
+       "derived_from": "tosca.nodes.DG"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/load/model_type/node_type/vnf-netconf-device.json b/ms/controllerblueprints/modules/core/load/model_type/node_type/vnf-netconf-device.json
new file mode 100644 (file)
index 0000000..54573ba
--- /dev/null
@@ -0,0 +1,42 @@
+{\r
+       "description": "This is VNF Device with Netconf  Capability",\r
+       "version": "1.0.0",\r
+       "capabilities": {\r
+               "netconf": {\r
+                       "type": "tosca.capability.Netconf",\r
+                       "properties": {\r
+                               "login-key": {\r
+                                       "required": true,\r
+                                       "type": "string",\r
+                                       "default": "sdnc"\r
+                               },\r
+                               "login-account": {\r
+                                       "required": true,\r
+                                       "type": "string",\r
+                                       "default": "sdnc-tacacs"\r
+                               },\r
+                               "source": {\r
+                                       "required": true,\r
+                                       "type": "string",\r
+                                       "default": "npm"\r
+                               },\r
+                               "target-ip-address": {\r
+                                       "required": true,\r
+                                       "type": "string"\r
+                               },\r
+                               "port-number": {\r
+                                       "required": true,\r
+                                       "type": "integer",\r
+                                       "default": 830\r
+                               },\r
+                               "connection-time-out": {\r
+                                       "required": false,\r
+                                       "type": "integer",\r
+                                       "default": 30\r
+                               }\r
+                       }\r
+               }\r
+       },\r
+       "derived_from": "tosca.nodes.Vnf"\r
+       \r
+}\r
diff --git a/ms/controllerblueprints/modules/core/pom.xml b/ms/controllerblueprints/modules/core/pom.xml
new file mode 100644 (file)
index 0000000..0e88dd2
--- /dev/null
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+  ~ Copyright © 2017-2018 AT&T Intellectual Property.\r
+  ~\r
+  ~ Licensed under the Apache License, Version 2.0 (the "License");\r
+  ~ you may not use this file except in compliance with the License.\r
+  ~ You may obtain a copy of the License at\r
+  ~\r
+  ~     http://www.apache.org/licenses/LICENSE-2.0\r
+  ~\r
+  ~ Unless required by applicable law or agreed to in writing, software\r
+  ~ distributed under the License is distributed on an "AS IS" BASIS,\r
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+  ~ See the License for the specific language governing permissions and\r
+  ~ limitations under the License.\r
+  -->\r
+\r
+<project\r
+        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"\r
+        xmlns="http://maven.apache.org/POM/4.0.0"\r
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
+    <modelVersion>4.0.0</modelVersion>\r
+    <parent>\r
+        <groupId>org.onap.ccsdk.apps</groupId>\r
+        <artifactId>controllerblueprints-modules</artifactId>\r
+        <version>0.3.0-SNAPSHOT</version>\r
+    </parent>\r
+    <artifactId>controllerblueprints-core</artifactId>\r
+    <name>Controller Blueprints Core</name>\r
+\r
+    <dependencies>\r
+        <dependency>\r
+            <groupId>org.jetbrains.kotlin</groupId>\r
+            <artifactId>kotlin-stdlib</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.jetbrains.kotlin</groupId>\r
+            <artifactId>kotlin-reflect</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>com.fasterxml.jackson.module</groupId>\r
+            <artifactId>jackson-module-kotlin</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>com.fasterxml.jackson.core</groupId>\r
+            <artifactId>jackson-databind</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>com.fasterxml.jackson.core</groupId>\r
+            <artifactId>jackson-annotations</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>com.fasterxml.jackson.core</groupId>\r
+            <artifactId>jackson-core</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>com.fasterxml.jackson.dataformat</groupId>\r
+            <artifactId>jackson-dataformat-xml</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>com.fasterxml.jackson.dataformat</groupId>\r
+            <artifactId>jackson-dataformat-yaml</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>com.fasterxml.jackson.module</groupId>\r
+            <artifactId>jackson-module-jsonSchema</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.apache.commons</groupId>\r
+            <artifactId>commons-lang3</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>commons-collections</groupId>\r
+            <artifactId>commons-collections</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>commons-io</groupId>\r
+            <artifactId>commons-io</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>com.google.guava</groupId>\r
+            <artifactId>guava</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.yaml</groupId>\r
+            <artifactId>snakeyaml</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>com.jayway.jsonpath</groupId>\r
+            <artifactId>json-path</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>junit</groupId>\r
+            <artifactId>junit</artifactId>\r
+            <scope>test</scope>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.jetbrains.kotlin</groupId>\r
+            <artifactId>kotlin-test</artifactId>\r
+            <scope>test</scope>\r
+        </dependency>\r
+<!--        <dependency>\r
+            <groupId>org.slf4j</groupId>\r
+            <artifactId>slf4j-simple</artifactId>\r
+        </dependency>-->\r
+    </dependencies>\r
+\r
+</project>\r
+\r
diff --git a/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/BluePrintConstants.kt b/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/BluePrintConstants.kt
new file mode 100644 (file)
index 0000000..1bdd530
--- /dev/null
@@ -0,0 +1,125 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core\r
+/**\r
+ *\r
+ *\r
+ * @author Brinda Santh\r
+ */\r
+object BluePrintConstants {\r
+\r
+    const val TYPE_DEFAULT: String = "default"\r
+\r
+    const val DATA_TYPE_STRING: String = "string"\r
+    const val DATA_TYPE_INTEGER: String = "integer"\r
+    const val DATA_TYPE_FLOAT: String = "float"\r
+    const val DATA_TYPE_BOOLEAN: String = "boolean"\r
+    const val DATA_TYPE_TIMESTAMP: String = "timestamp"\r
+    const val DATA_TYPE_NULL: String = "null"\r
+    const val DATA_TYPE_LIST: String = "list"\r
+    const val DATA_TYPE_MAP: String = "map"\r
+\r
+    const val USER_SYSTEM: String = "System"\r
+\r
+    const val MODEL_CONTENT_TYPE_JSON: String = "JSON"\r
+    const val MODEL_CONTENT_TYPE_YAML: String = "YAML"\r
+    const val MODEL_CONTENT_TYPE_YANG: String = "YANG"\r
+    const val MODEL_CONTENT_TYPE_SCHEMA: String = "SCHEMA"\r
+\r
+    const val PATH_DIVIDER: String = "/"\r
+    const val PATH_INPUTS: String = "inputs"\r
+    const val PATH_NODE_WORKFLOWS: String = "workflows"\r
+    const val PATH_NODE_TEMPLATES: String = "node_templates"\r
+    const val PATH_CAPABILITIES: String = "capabilities"\r
+    const val PATH_REQUIREMENTS: String = "requirements"\r
+    const val PATH_INTERFACES: String = "interfaces"\r
+    const val PATH_OPERATIONS: String = "operations"\r
+    const val PATH_OUTPUTS: String = "outputs"\r
+    const val PATH_PROPERTIES: String = "properties"\r
+    const val PATH_ATTRIBUTES: String = "attributes"\r
+    const val PATH_ARTIFACTS: String = "artifacts"\r
+\r
+    const val MODEL_DEFINITION_TYPE_NODE_TYPE: String = "node_type"\r
+    const val MODEL_DEFINITION_TYPE_ARTIFACT_TYPE: String = "artifact_type"\r
+    const val MODEL_DEFINITION_TYPE_CAPABILITY_TYPE: String = "capability_type"\r
+    const val MODEL_DEFINITION_TYPE_RELATIONSHIP_TYPE: String = "relationship_type"\r
+    const val MODEL_DEFINITION_TYPE_DATA_TYPE: String = "data_type"\r
+\r
+    const val MODEL_TYPE_DATATYPES_ROOT: String = "tosca.datatypes.Root"\r
+    const val MODEL_TYPE_NODES_ROOT: String = "tosca.nodes.Root"\r
+    const val MODEL_TYPE_GROUPS_ROOT: String = "tosca.groups.Root"\r
+    const val MODEL_TYPE_RELATIONSHIPS_ROOT: String = "tosca.relationships.Root"\r
+    const val MODEL_TYPE_ARTIFACTS_ROOT: String = "tosca.artifacts.Root"\r
+    const val MODEL_TYPE_CAPABILITIES_ROOT: String = "tosca.capabilities.Root"\r
+    const val MODEL_TYPE_INTERFACES_ROOT: String = "tosca.interfaces.Root"\r
+\r
+    const val MODEL_TYPE_RELATIONSHIPS_DEPENDS_ON = "tosca.relationships.DependsOn"\r
+    const val MODEL_TYPE_RELATIONSHIPS_HOSTED_ON = "tosca.relationships.HostedOn"\r
+    const val MODEL_TYPE_RELATIONSHIPS_CONNECTS_TO = "tosca.relationships.ConnectsTo"\r
+    const val MODEL_TYPE_RELATIONSHIPS_ATTACH_TO = "tosca.relationships.AttachesTo"\r
+    const val MODEL_TYPE_RELATIONSHIPS_ROUTES_TO = "tosca.relationships.RoutesTo"\r
+\r
+    const val MODEL_TYPE_NODES_COMPONENT_JAVA: String = "tosca.nodes.component.Java"\r
+    const val MODEL_TYPE_NODES_COMPONENT_BUNDLE: String = "tosca.nodes.component.Bundle"\r
+    const val MODEL_TYPE_NODES_COMPONENT_SCRIPT: String = "tosca.nodes.component.Script"\r
+    const val MODEL_TYPE_NODES_COMPONENT_PYTHON: String = "tosca.nodes.component.Python"\r
+    const val MODEL_TYPE_NODES_COMPONENT_JAVA_SCRIPT: String = "tosca.nodes.component.JavaScript"\r
+\r
+    const val EXPRESSION_GET_INPUT: String = "get_input"\r
+    const val EXPRESSION_GET_ATTRIBUTE: String = "get_attribute"\r
+    const val EXPRESSION_GET_ARTIFACT: String = "get_artifact"\r
+    const val EXPRESSION_GET_PROPERTY: String = "get_property"\r
+    const val EXPRESSION_GET_OPERATION_OUTPUT: String = "get_operation_output"\r
+    const val EXPRESSION_GET_NODE_OF_TYPE: String = "get_nodes_of_type"\r
+\r
+    const val PROPERTY_BLUEPRINT_PROCESS_ID: String = "blueprint-process-id"\r
+    const val PROPERTY_BLUEPRINT_BASE_PATH: String = "blueprint-basePath"\r
+    const val PROPERTY_BLUEPRINT_RUNTIME: String = "blueprint-runtime"\r
+    const val PROPERTY_BLUEPRINT_INPUTS_DATA: String = "blueprint-inputs-data"\r
+    const val PROPERTY_BLUEPRINT_CONTEXT: String = "blueprint-context"\r
+    const val PROPERTY_BLUEPRINT_NAME: String = "template_name"\r
+    const val PROPERTY_BLUEPRINT_VERSION: String = "template_version"\r
+\r
+    const val TOSCA_METADATA_ENTRY_DEFINITION_FILE: String = "TOSCA-Metadata/TOSCA.meta"\r
+    const val TOSCA_PLANS_DIR: String = "Plans"\r
+    const val TOSCA_SCRIPTS_DIR: String = "Scripts"\r
+    const val TOSCA_MAPPINGS_DIR: String = "Mappings"\r
+    const val TOSCA_TEMPLATES_DIR: String = "Templates"\r
+\r
+    const val METADATA_USER_GROUPS = "user-groups"\r
+    const val METADATA_TEMPLATE_NAME = "template_name"\r
+    const val METADATA_TEMPLATE_VERSION = "template_version"\r
+    const val METADATA_TEMPLATE_AUTHOR = "template_author"\r
+    const val METADATA_TEMPLATE_TAGS = "template_tags"\r
+\r
+    const val PAYLOAD_CONTENT = "payload-content"\r
+    const val PAYLOAD_DATA = "payload-data"\r
+    const val SELECTOR = "selector"\r
+    const val PROPERTY_CURRENT_INTERFACE = "current-interface"\r
+    const val PROPERTY_CURRENT_OPERATION = "current-operation"\r
+    const val PROPERTY_CURRENT_IMPLEMENTATION = "current-implementation"\r
+\r
+    const val PROPERTY_ACTION_NAME = "action"\r
+\r
+    const val OPERATION_PROCESS = "process"\r
+    const val OPERATION_PREPARE = "prepare"\r
+\r
+    const val BLUEPRINT_RETRIEVE_TYPE_DB = "db"\r
+    const val BLUEPRINT_RETRIEVE_TYPE_FILE = "file"\r
+    const val BLUEPRINT_RETRIEVE_TYPE_REPO = "repo"\r
+\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/BluePrintException.kt b/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/BluePrintException.kt
new file mode 100644 (file)
index 0000000..5c386c2
--- /dev/null
@@ -0,0 +1,49 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core\r
+/**\r
+ *\r
+ *\r
+ * @author Brinda Santh\r
+ */\r
+class BluePrintException : Exception {\r
+\r
+    var code: Int = 100\r
+\r
+    constructor(cause: Throwable) : super(cause)\r
+    constructor(message: String) : super(message)\r
+    constructor(message: String, cause: Throwable) : super(message, cause)\r
+    constructor(cause: Throwable, message: String, vararg args: Any?) : super(String.format(message, *args), cause)\r
+\r
+    constructor(code: Int, cause: Throwable) : super(cause) {\r
+        this.code = code\r
+    }\r
+\r
+    constructor(code: Int, message: String) : super(message) {\r
+        this.code = code\r
+    }\r
+\r
+    constructor(code: Int, message: String, cause: Throwable) : super(message, cause) {\r
+        this.code = code\r
+    }\r
+\r
+    constructor(code: Int, cause: Throwable, message: String, vararg args: Any?)\r
+            : super(String.format(message, *args), cause) {\r
+        this.code = code\r
+    }\r
+}\r
+\r
diff --git a/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/BluePrintTypes.kt b/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/BluePrintTypes.kt
new file mode 100644 (file)
index 0000000..33c811f
--- /dev/null
@@ -0,0 +1,91 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core\r
+\r
+/**\r
+ *\r
+ *\r
+ * @author Brinda Santh\r
+ */\r
+object BluePrintTypes {\r
+\r
+    @JvmStatic\r
+    fun validModelTypes(): List<String> {\r
+        val validTypes: MutableList<String> = arrayListOf()\r
+        validTypes.add(BluePrintConstants.MODEL_DEFINITION_TYPE_DATA_TYPE)\r
+        validTypes.add(BluePrintConstants.MODEL_DEFINITION_TYPE_ARTIFACT_TYPE)\r
+        validTypes.add(BluePrintConstants.MODEL_DEFINITION_TYPE_NODE_TYPE)\r
+        validTypes.add(BluePrintConstants.MODEL_DEFINITION_TYPE_CAPABILITY_TYPE)\r
+        validTypes.add(BluePrintConstants.MODEL_DEFINITION_TYPE_RELATIONSHIP_TYPE)\r
+        return validTypes\r
+    }\r
+\r
+    @JvmStatic\r
+    fun validPropertyTypes(): List<String> {\r
+        val validTypes: MutableList<String> = arrayListOf()\r
+        validTypes.add(BluePrintConstants.DATA_TYPE_STRING)\r
+        validTypes.add(BluePrintConstants.DATA_TYPE_INTEGER)\r
+        validTypes.add(BluePrintConstants.DATA_TYPE_FLOAT)\r
+        validTypes.add(BluePrintConstants.DATA_TYPE_BOOLEAN)\r
+        validTypes.add(BluePrintConstants.DATA_TYPE_TIMESTAMP)\r
+        validTypes.add(BluePrintConstants.DATA_TYPE_NULL)\r
+        validTypes.add(BluePrintConstants.DATA_TYPE_LIST)\r
+        return validTypes\r
+    }\r
+\r
+    @JvmStatic\r
+    fun validPrimitiveTypes(): List<String> {\r
+        val validTypes: MutableList<String> = arrayListOf()\r
+        validTypes.add(BluePrintConstants.DATA_TYPE_STRING)\r
+        validTypes.add(BluePrintConstants.DATA_TYPE_INTEGER)\r
+        validTypes.add(BluePrintConstants.DATA_TYPE_FLOAT)\r
+        validTypes.add(BluePrintConstants.DATA_TYPE_BOOLEAN)\r
+        validTypes.add(BluePrintConstants.DATA_TYPE_TIMESTAMP)\r
+        validTypes.add(BluePrintConstants.DATA_TYPE_NULL)\r
+        return validTypes\r
+    }\r
+\r
+    @JvmStatic\r
+    fun validCollectionTypes(): List<String> {\r
+        val validTypes: MutableList<String> = arrayListOf()\r
+        validTypes.add(BluePrintConstants.DATA_TYPE_LIST)\r
+        validTypes.add(BluePrintConstants.DATA_TYPE_MAP)\r
+        return validTypes\r
+    }\r
+\r
+    @JvmStatic\r
+    fun validCommands(): List<String> {\r
+        return listOf(BluePrintConstants.EXPRESSION_GET_INPUT,\r
+                BluePrintConstants.EXPRESSION_GET_ATTRIBUTE,\r
+                BluePrintConstants.EXPRESSION_GET_PROPERTY,\r
+                BluePrintConstants.EXPRESSION_GET_ARTIFACT,\r
+                BluePrintConstants.EXPRESSION_GET_OPERATION_OUTPUT,\r
+                BluePrintConstants.EXPRESSION_GET_NODE_OF_TYPE)\r
+    }\r
+\r
+    @JvmStatic\r
+    fun rootNodeTypes(): List<String> {\r
+        return listOf(BluePrintConstants.MODEL_TYPE_NODES_ROOT)\r
+    }\r
+\r
+    @JvmStatic\r
+    fun rootDataTypes(): List<String> {\r
+        return listOf(BluePrintConstants.MODEL_TYPE_DATATYPES_ROOT)\r
+    }\r
+\r
+\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/ConfigModelConstant.kt b/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/ConfigModelConstant.kt
new file mode 100644 (file)
index 0000000..bb5a78f
--- /dev/null
@@ -0,0 +1,52 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core\r
+\r
+/**\r
+ *\r
+ *\r
+ * @author Brinda Santh\r
+ */\r
+object ConfigModelConstant {\r
+\r
+    const val MODEL_CONTENT_TYPE_TOSCA_JSON = "TOSCA_JSON"\r
+    const val MODEL_CONTENT_TYPE_TEMPLATE = "TEMPLATE"\r
+\r
+    const val MODEL_TYPE_DATA_TYPE = "tosca.datatypes.Root"\r
+    const val MODEL_TYPE_DATA_TYPE_DYNAMIC = "tosca.datatypes.Dynamic"\r
+\r
+    const val MODEL_TYPE_NODE_DG = "tosca.nodes.DG"\r
+    const val MODEL_TYPE_NODE_COMPONENT = "tosca.nodes.Component"\r
+    const val MODEL_TYPE_NODE_VNF = "tosca.nodes.Vnf"\r
+    const val MODEL_TYPE_NODE_ARTIFACT = "tosca.nodes.Artifact"\r
+\r
+    const val MODEL_TYPE_CAPABILITY_NETCONF = "tosca.capability.Netconf"\r
+    const val MODEL_TYPE_CAPABILITY_SSH = "tosca.capability.Ssh"\r
+    const val MODEL_TYPE_CAPABILITY_SFTP = "tosca.capability.Sftp"\r
+    const val MODEL_TYPE_CAPABILITY_CHEF = "tosca.capability.Chef"\r
+    const val MODEL_TYPE_CAPABILITY_ANSIBLEF = "tosca.capability.Ansible"\r
+\r
+    const val CAPABILITY_PROPERTY_MAPPING = "mapping"\r
+\r
+    const val SOURCE_INPUT = "input"\r
+    const val SOURCE_DEFAULT = "default"\r
+    const val SOURCE_MDSAL = "mdsal"\r
+    const val SOURCE_DB = "db"\r
+\r
+    const val PROPERTY_RECIPE_NAMES = "action-names"\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/CustomFunctions.kt b/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/CustomFunctions.kt
new file mode 100644 (file)
index 0000000..7302f2b
--- /dev/null
@@ -0,0 +1,75 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core\r
+\r
+import org.slf4j.helpers.MessageFormatter\r
+import java.io.File\r
+import java.io.InputStream\r
+import kotlin.reflect.KClass\r
+\r
+/**\r
+ *\r
+ *\r
+ * @author Brinda Santh\r
+ */\r
+\r
+fun format(message: String, vararg args: Any?) : String{\r
+    if(args != null && args.isNotEmpty()){\r
+        return MessageFormatter.arrayFormat(message, args).message\r
+    }\r
+   return message\r
+}\r
+\r
+fun <T : Any> MutableMap<String, *>.getCastOptionalValue(key: String, valueType: KClass<T>): T? {\r
+    if (containsKey(key)) {\r
+        return get(key) as? T\r
+    } else {\r
+        return null\r
+    }\r
+}\r
+\r
+fun <T : Any> MutableMap<String, *>.getCastValue(key: String, valueType: KClass<T>): T {\r
+    if (containsKey(key)) {\r
+        return get(key) as T\r
+    } else {\r
+        throw BluePrintException("couldn't find the key " + key)\r
+    }\r
+}\r
+\r
+fun checkNotEmpty(value : String?) : Boolean{\r
+    return value != null && value.isNotEmpty()\r
+}\r
+\r
+fun checkNotEmptyNThrow(value : String?, message : String? = value.plus(" is null/empty ")) : Boolean{\r
+    val notEmpty = value != null && value.isNotEmpty()\r
+    if(!notEmpty){\r
+        throw BluePrintException(message!!)\r
+    }\r
+    return notEmpty\r
+}\r
+\r
+fun InputStream.toFile(path: String) : File {\r
+    val file = File(path)\r
+    file.outputStream().use { this.copyTo(it) }\r
+    return file\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
diff --git a/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/OrchestratorException.kt b/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/OrchestratorException.kt
new file mode 100644 (file)
index 0000000..68abad1
--- /dev/null
@@ -0,0 +1,48 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core\r
+/**\r
+ *\r
+ *\r
+ * @author Brinda Santh\r
+ */\r
+class OrchestratorException : Exception {\r
+    var code: Int = 100\r
+\r
+    constructor(message: String, cause: Throwable) : super(message, cause)\r
+    constructor(message: String) : super(message)\r
+    constructor(cause: Throwable) : super(cause)\r
+    constructor(cause: Throwable, message: String, vararg args: Any?) : super(format(message, *args), cause)\r
+\r
+    constructor(code: Int, cause: Throwable) : super(cause) {\r
+        this.code = code\r
+    }\r
+\r
+    constructor(code: Int, message: String) : super(message) {\r
+        this.code = code\r
+    }\r
+\r
+    constructor(code: Int, message: String, cause: Throwable) : super(message, cause) {\r
+        this.code = code\r
+    }\r
+\r
+    constructor(code: Int, cause: Throwable, message: String, vararg args: Any?)\r
+            : super(String.format(message, *args), cause) {\r
+        this.code = code\r
+    }\r
+}\r
+\r
diff --git a/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/data/BluePrintExpressionData.kt b/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/data/BluePrintExpressionData.kt
new file mode 100644 (file)
index 0000000..c0eb13f
--- /dev/null
@@ -0,0 +1,70 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core.data\r
+\r
+import com.fasterxml.jackson.databind.JsonNode\r
+import com.fasterxml.jackson.databind.node.ObjectNode\r
+/**\r
+ *\r
+ *\r
+ * @author Brinda Santh\r
+ */\r
+data class ExpressionData(\r
+        var isExpression: Boolean = false,\r
+        var valueNode: JsonNode,\r
+        var expressionNode: ObjectNode? = null,\r
+        var inputExpression: InputExpression? = null,\r
+        var propertyExpression: PropertyExpression? = null,\r
+        var attributeExpression: AttributeExpression? = null,\r
+        var artifactExpression: ArtifactExpression? = null,\r
+        var operationOutputExpression: OperationOutputExpression? = null,\r
+        var command: String? = null\r
+)\r
+\r
+data class InputExpression(\r
+        var propertyName: String\r
+)\r
+\r
+data class PropertyExpression(\r
+        var modelableEntityName: String = "SELF",\r
+        var reqOrCapEntityName: String? = null,\r
+        var propertyName: String,\r
+        var subPropertyName: String?  = null\r
+)\r
+\r
+data class AttributeExpression(\r
+        var modelableEntityName: String = "SELF",\r
+        var reqOrCapEntityName: String? = null,\r
+        var attributeName: String,\r
+        var subAttributeName: String? = null\r
+)\r
+\r
+data class ArtifactExpression(\r
+        val modelableEntityName: String = "SELF",\r
+        val artifactName: String,\r
+        val location: String? =  "LOCAL_FILE",\r
+        val remove: Boolean? = false\r
+)\r
+\r
+data class OperationOutputExpression(\r
+        val modelableEntityName: String = "SELF",\r
+        val interfaceName: String,\r
+        val operationName: String,\r
+        val propertyName: String\r
+)\r
+\r
+\r
diff --git a/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/data/BluePrintModel.kt b/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/data/BluePrintModel.kt
new file mode 100644 (file)
index 0000000..6d677ff
--- /dev/null
@@ -0,0 +1,604 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core.data\r
+\r
+import com.fasterxml.jackson.annotation.JsonIgnore\r
+import com.fasterxml.jackson.annotation.JsonProperty\r
+import com.fasterxml.jackson.databind.JsonNode\r
+\r
+/**\r
+ *\r
+ *\r
+ * @author Brinda Santh\r
+ */\r
+open class EntityType {\r
+    @get:JsonIgnore\r
+    var id: String? = null\r
+    var description: String? = null\r
+    var version: String = "1.0.0"\r
+    var metadata: MutableMap<String, String>? = null\r
+    @get:JsonProperty("derived_from")\r
+    lateinit var derivedFrom: String\r
+    var attributes: MutableMap<String, AttributeDefinition>? = null\r
+    var properties: MutableMap<String, PropertyDefinition>? = null\r
+}\r
+\r
+/*\r
+ 5.3.2 tosca.datatypes.org.onap.ccsdk.apps.controllerblueprints.core.data.Credential\r
+ The org.onap.ccsdk.apps.controllerblueprints.core.data.Credential type is a complex TOSCA data Type used when describing\r
+ authorization credentials used to access network accessible resources.\r
+ */\r
+class Credential {\r
+    @get:JsonIgnore\r
+    var id: String? = null\r
+    var protocol: String? = null\r
+    @get:JsonProperty("token_type")\r
+    lateinit var tokenType: String\r
+    lateinit var token: String\r
+    var keys: MutableMap<String, String>? = null\r
+    lateinit var user: String\r
+}\r
+\r
+/*\r
+3.5.2 Constraint clause\r
+A constraint clause defines an operation along with one or more compatible values that can be used to define a constraint on a property or parameter’s allowed values when it is defined in a TOSCA Service Template or one of its entities.\r
+ */\r
+class ConstraintClause {\r
+    @get:JsonProperty("equal")\r
+    var equal: Any? = null\r
+    @get:JsonProperty("greater_than")\r
+    var greaterThan: Any? = null\r
+    @get:JsonProperty("greater_or_equal")\r
+    var greaterOrEqual: Any? = null\r
+    @get:JsonProperty("less_than")\r
+    var lessThan: Any? = null\r
+    @get:JsonProperty("less_or_equal")\r
+    var lessOrEqual: Any? = null\r
+    @get:JsonProperty("in_range")\r
+    var inRange: Any? = null\r
+    @get:JsonProperty("valid_values")\r
+    var validValues: MutableList<Any>? = null\r
+    @get:JsonProperty("length")\r
+    var length: Any? = null\r
+    @get:JsonProperty("min_length")\r
+    var minLength: Any? = null\r
+    @get:JsonProperty("max_length")\r
+    var maxLength: Any? = null\r
+    @get:JsonProperty("pattern")\r
+    var pattern: String? = null\r
+}\r
+\r
+/*\r
+3.5.4 Node Filter definition\r
+A node filter definition defines criteria for selection of a TOSCA Node Template based upon the template’s property values, capabilities and capability properties.\r
+ */\r
+\r
+class NodeFilterDefinition {\r
+    var properties: MutableMap<String, PropertyDefinition>? = null\r
+    var capabilities : MutableList<String>? = null\r
+}\r
+\r
+/*\r
+3.5.5 Repository definition\r
+ A repository definition defines a named external repository which contains deployment\r
+ and implementation artifacts that are referenced within the TOSCA Service Template.\r
+*/\r
+class RepositoryDefinition {\r
+    @get:JsonIgnore\r
+    var id: String? = null\r
+    var description: String? = null\r
+    lateinit var url: String\r
+    var credential: Credential? = null\r
+}\r
+\r
+\r
+/*\r
+3.5.6 Artifact definition\r
+An artifact definition defines a named, typed file that can be associated with Node Type\r
+or Node Template and used by orchestration engine to facilitate deployment and implementation of interface operations.\r
+ */\r
+class ArtifactDefinition {\r
+    @get:JsonIgnore\r
+    var id: String? = null\r
+    var type: String? = null\r
+    var file: String? = null\r
+    var repository: String? = null\r
+    var description: String? = null\r
+    @get:JsonProperty("deploy_Path")\r
+    var deployPath: String? = null\r
+    var properties: MutableMap<String, JsonNode>? = null\r
+    var content: String? = null\r
+    @Deprecated("Mapping content is define by the Type")\r
+    var mappingContent: String? = null\r
+}\r
+\r
+\r
+/*\r
+3.5.7 Import definition\r
+An import definition is used within a TOSCA Service Template to locate and uniquely name\r
+another TOSCA Service Template file which has type and template definitions to be imported (included)\r
+and referenced within another Service Template.\r
+ */\r
+class ImportDefinition {\r
+    @get:JsonIgnore\r
+    var id: String? = null\r
+    lateinit var file: String\r
+    var repository: String? = null\r
+    @get:JsonProperty("namespace_uri")\r
+    var namespaceUri: String? = null\r
+    @get:JsonProperty("namespace_prefix")\r
+    var namespacePrefix: String? = null\r
+}\r
+\r
+/*\r
+3.5.8 Property definition A property definition defines a named, typed value and related data that can be associated with an\r
+entity defined in this specification (e.g., Node Types, Relationship Types, Capability Types, etc.).\r
+Properties are used by template authors to provide input values to TOSCA entities which indicate their “desired state” when they are\r
+instantiated. The value of a property can be retrieved using the get_property function within TOSCA Service Templates.\r
+ */\r
+class PropertyDefinition {\r
+    @get:JsonIgnore\r
+    var id: String? = null\r
+    var description: String? = null\r
+    var required: Boolean? = null\r
+    var type: String? = null\r
+    @get:JsonProperty("default")\r
+    var defaultValue: Any? = null\r
+    var status: String? = null\r
+    var constraints: MutableList<ConstraintClause>? = null\r
+    @get:JsonProperty("entry_schema")\r
+    var entrySchema: EntrySchema? = null\r
+    var value: Any? = null\r
+}\r
+\r
+\r
+/*\r
+3.5.10 Attribute definition\r
+\r
+An attribute definition defines a named, typed value that can be associated with an entity defined in this\r
+specification (e.g., a Node, Relationship or Capability Type).  Specifically, it is used to expose the\r
+“actual state” of some property of a TOSCA entity after it has been deployed and instantiated\r
+(as set by the TOSCA orchestrator). Attribute values can be retrieved via the get_attribute function\r
+from the instance model and used as values to other entities within TOSCA Service Templates.\r
+ */\r
+\r
+class AttributeDefinition {\r
+    @get:JsonIgnore\r
+    var id: String? = null\r
+    var description: String? = null\r
+    lateinit var type: String\r
+    @JsonProperty("default")\r
+    var _default: Any? = null\r
+    var status: String? = null\r
+    @JsonProperty("entry_schema")\r
+    var entry_schema: String? = null\r
+}\r
+\r
+/*\r
+3.5.13 Operation definition\r
+An operation definition defines a named function or procedure that can be bound to an implementation artifact (e.g., a script).\r
+ */\r
+class OperationDefinition {\r
+    @get:JsonIgnore\r
+    var id: String? = null\r
+    var description: String? = null\r
+    var implementation: Implementation? = null\r
+    var inputs: MutableMap<String, PropertyDefinition>? = null\r
+    var outputs: MutableMap<String, PropertyDefinition>? = null\r
+}\r
+\r
+class Implementation {\r
+    var primary: String? = null\r
+    var dependencies: MutableList<String>? = null\r
+}\r
+\r
+/*\r
+3.5.14 Interface definition\r
+An interface definition defines a named interface that can be associated with a Node or Relationship Type\r
+ */\r
+class InterfaceDefinition {\r
+    @get:JsonIgnore\r
+    var id: String? = null\r
+    var type: String? = null\r
+    var operations: MutableMap<String, OperationDefinition>? = null\r
+    var inputs: MutableMap<String, PropertyDefinition>? = null\r
+}\r
+\r
+/*\r
+3.5.15 Event Filter definition\r
+An event filter definition defines criteria for selection of an attribute, for the purpose of monitoring it, within a TOSCA entity, or one its capabilities.\r
+ */\r
+class EventFilterDefinition {\r
+    @get:JsonIgnore\r
+    var id: String? = null\r
+    lateinit var node: String\r
+    var requirement: String? = null\r
+    var capability: String? = null\r
+}\r
+\r
+/*\r
+3.5.16 Trigger definition TODO\r
+A trigger definition defines the event, condition and action that is used to “trigger” a policy it is associated with.\r
+ */\r
+class TriggerDefinition {\r
+    @get:JsonIgnore\r
+    var id: String? = null\r
+    var description: String? = null\r
+    @get:JsonProperty("event_type")\r
+    lateinit var eventType: String\r
+    lateinit var action: String\r
+}\r
+\r
+/*\r
+    3.5.17 org.onap.ccsdk.apps.controllerblueprints.core.data.Workflow activity definition\r
+    A workflow activity defines an operation to be performed in a TOSCA workflow. Activities allows to:\r
+    · Delegate the workflow for a node expected to be provided        by the orchestrator\r
+    · Set the state of a node\r
+    · Call an operation       defined on a TOSCA interface of a node, relationship or group\r
+    · Inline another workflow defined in the topology (to allow reusability)\r
+ */\r
+class Activity {\r
+    var delegate: String? = null\r
+    @get:JsonProperty("set_state")\r
+    var setState: String? = null\r
+    @get:JsonProperty("call_operation")\r
+    var callOperation: String? = null\r
+    var inlines: ArrayList<String>? = null\r
+}\r
+\r
+/*\r
+3.5.20 org.onap.ccsdk.apps.controllerblueprints.core.data.Workflow precondition definition\r
+A workflow condition can be used as a filter or precondition to check if a workflow can be processed or not based on the state of the instances of a TOSCA topology deployment. When not met, the workflow will not be triggered.\r
+ */\r
+class PreConditionDefinition {\r
+    @get:JsonIgnore\r
+    var id: String? = null\r
+    lateinit var target: String\r
+    @get:JsonProperty("target_relationship")\r
+    lateinit var targetRelationship: String\r
+    lateinit var condition: ArrayList<ConditionClause>\r
+}\r
+\r
+/*\r
+3.5.21 org.onap.ccsdk.apps.controllerblueprints.core.data.Workflow step definition\r
+A workflow step allows to define one or multiple sequenced activities in a workflow and how they are connected to other steps in the workflow. They are the building blocks of a declarative workflow.\r
+ */\r
+class Step {\r
+    @get:JsonIgnore\r
+    var id: String? = null\r
+    var description: String? = null\r
+    var target: String? = null\r
+    @JsonProperty("target_relationship")\r
+    var targetRelationship: String? = null\r
+    @JsonProperty("operation_host")\r
+    var operationHost: String? = null\r
+    var activities: ArrayList<Activity>? = null\r
+    @get:JsonProperty("on_success")\r
+    var onSuccess: ArrayList<String>? = null\r
+    @get:JsonProperty("on_failure")\r
+    var onFailure: ArrayList<String>? = null\r
+}\r
+\r
+/*\r
+3.6.2 Capability definition\r
+A capability definition defines a named, typed set of data that can be associated with Node Type or Node Template to describe a transparent capability or feature of the software component the node describes.\r
+ */\r
+\r
+class CapabilityDefinition {\r
+    @get:JsonIgnore\r
+    var id: String? = null\r
+    var type: String? = null\r
+    var description: String? = null\r
+    var properties: MutableMap<String, PropertyDefinition>? = null\r
+    @get:JsonProperty("valid_source_types")\r
+    var validSourceTypes: MutableList<String>? = null\r
+    var occurrences: MutableList<Any>? = null\r
+}\r
+\r
+/*\r
+3.6.3 Requirement definition\r
+The Requirement definition describes a named requirement (dependencies) of a TOSCA Node Type or Node template which needs to be fulfilled by a matching Capability definition declared by another TOSCA modelable entity.  The requirement definition may itself include the specific name of the fulfilling entity (explicitly) or provide an abstract type, along with additional filtering characteristics, that a TOSCA orchestrator can use to fulfill the capability at runtime (implicitly).\r
+ */\r
+class RequirementDefinition {\r
+    @get:JsonIgnore\r
+    var id: String? = null\r
+    var description: String? = null\r
+    var capability: String? = null\r
+    var node: String? = null\r
+    var relationship: String? = null\r
+    var occurrences: MutableList<Any>? = null\r
+}\r
+\r
+/*\r
+3.6.4 Artifact Type\r
+An Artifact Type is a reusable entity that defines the type of one or more files that are used to define implementation or deployment artifacts that are referenced by nodes or relationships on their operations.\r
+ */\r
+class ArtifactType : EntityType() {\r
+    @get:JsonProperty("mime_type")\r
+    var mimeType: String? = null\r
+    @get:JsonProperty("file_ext")\r
+    var fileExt: MutableList<String>? = null\r
+\r
+}\r
+\r
+/*\r
+3.6.6 Data Type\r
+A Data Type definition defines the schema for new named datatypes in TOSCA.\r
+ */\r
+\r
+class DataType : EntityType(){\r
+    var constraints: MutableList<MutableMap<String, Any>>? = null\r
+}\r
+\r
+/*\r
+3.6.9 Node Type\r
+A Node Type is a reusable entity that defines the type of one or more Node Templates. As such, a Node Type defines the structure of observable properties via a Properties Definition, the Requirements and Capabilities of the node as well as its supported interfaces.\r
+\r
+ */\r
+\r
+class NodeType : EntityType() {\r
+    var capabilities: MutableMap<String, CapabilityDefinition>? = null\r
+    var requirements: MutableMap<String, RequirementDefinition>? = null\r
+    var interfaces: MutableMap<String, InterfaceDefinition>? = null\r
+    var artifacts: MutableMap<String, ArtifactDefinition>? = null\r
+}\r
+\r
+/*\r
+3.6.8 Requirement Type\r
+A Requirement Type is a reusable entity that describes a kind of requirement that a Node Type can declare to expose.  The TOSCA Simple Profile seeks to simplify the need for declaring specific Requirement Types from nodes and instead rely upon nodes declaring their features sets using TOSCA Capability Types along with a named Feature notation.\r
+ */\r
+\r
+class RequirementType : EntityType() {\r
+    var requirements: MutableMap<String, RequirementDefinition>? = null\r
+    var capabilities: MutableMap<String, CapabilityDefinition>? = null\r
+    var interfaces: MutableMap<String, InterfaceDefinition>? = null\r
+    var artifacts: MutableMap<String, ArtifactDefinition>? = null\r
+}\r
+\r
+/*\r
+3.6.10 Relationship Type\r
+A Relationship Type is a reusable entity that defines the type of one or more relationships between Node Types or Node Templates.\r
+*/\r
+\r
+class RelationshipType : EntityType() {\r
+    var interfaces: MutableMap<String, InterfaceDefinition>? = null\r
+    @get:JsonProperty("valid_target_types")\r
+    var validTargetTypes: ArrayList<String>? = null\r
+}\r
+\r
+/*\r
+3.6.11 Group Type\r
+A Group Type defines logical grouping types for nodes, typically for different management purposes.\r
+Groups can effectively be viewed as logical nodes that are not part of the physical deployment topology\r
+ of an application, yet can have capabilities and the ability to attach policies and interfaces\r
+ that can be applied (depending on the group type) to its member nodes.\r
+ */\r
+\r
+class GroupType : EntityType() {\r
+    var members: MutableList<String>? = null\r
+    var requirements: ArrayList<RequirementDefinition>? = null\r
+    var capabilities: MutableMap<String, CapabilityDefinition>? = null\r
+    var interfaces: MutableMap<String, InterfaceDefinition>? = null\r
+\r
+}\r
+\r
+/*\r
+    3.6.12 Policy Type\r
+    A Policy Type defines a type of requirement that affects or governs an application or service’s\r
+    topology at some stage of its lifecycle, but is not explicitly part of the topology itself\r
+    (i.e., it does not prevent the application or service from being deployed or run if it did not exist).\r
+ */\r
+class PolicyType : EntityType(){\r
+    lateinit var targets: MutableList<String>\r
+}\r
+\r
+/*\r
+3.7.1 Capability assignment\r
+A capability assignment allows node template authors to assign values to properties and attributes for a named capability definition that is part of a Node Template’s type definition.\r
+ */\r
+class CapabilityAssignment {\r
+    @get:JsonIgnore\r
+    var id: String? = null\r
+    var attributes: MutableMap<String, JsonNode>? = null\r
+    var properties: MutableMap<String, JsonNode>? = null\r
+}\r
+\r
+/*\r
+3.7.4 Relationship Template\r
+A Relationship Template specifies the occurrence of a manageable relationship between node templates as part of an application’s topology model that is defined in a TOSCA Service Template.  A Relationship template is an instance of a specified Relationship Type and can provide customized properties, constraints or operations which override the defaults provided by its Relationship Type and its implementations.\r
+ */\r
+class GroupDefinition {\r
+    @get:JsonIgnore\r
+    var id: String? = null\r
+    lateinit var type: String\r
+    var description: String? = null\r
+    var metadata : MutableMap<String, String>? = null\r
+    var properties : MutableMap<String, JsonNode>? = null\r
+    var members = ArrayList<String>()\r
+    var interfaces : MutableMap<String, InterfaceDefinition>?= null\r
+}\r
+\r
+/*\r
+3.7.6 Policy definition\r
+A policy definition defines a policy that can be associated with a TOSCA topology or top-level entity definition (e.g., group definition, node template, etc.).\r
+ */\r
+class PolicyDefinition {\r
+    @get:JsonIgnore\r
+    var id: String? = null\r
+    lateinit var type: String\r
+    var description: String? = null\r
+    var metadata: MutableMap<String, String>? = null\r
+    var properties: MutableMap<String, JsonNode>? = null\r
+    var targets: MutableList<String>? = null\r
+}\r
+\r
+\r
+/*\r
+3.8 Topology Template definition\r
+This section defines the topology template of a cloud application. The main ingredients of the topology template are node templates representing components of the application and relationship templates representing links between the components. These elements are defined in the nested node_templates section and the nested relationship_templates sections, respectively.  Furthermore, a topology template allows for defining input parameters, output parameters as well as grouping of node templates.\r
+ */\r
+class TopologyTemplate {\r
+    @get:JsonIgnore\r
+    var id: String? = null\r
+    var description: String? = null\r
+    var inputs: MutableMap<String, PropertyDefinition>? = null\r
+    @get:JsonProperty("node_templates")\r
+    var nodeTemplates: MutableMap<String, NodeTemplate>? = null\r
+    @get:JsonProperty("relationship_templates")\r
+    var relationshipTemplates: MutableMap<String, RelationshipTemplate>? = null\r
+    var policies: MutableMap<String, PolicyDefinition>? = null\r
+    var outputs: MutableMap<String, PropertyDefinition>? = null\r
+    @get:JsonProperty("substitution_mappings")\r
+    var substitutionMappings: Any? = null\r
+    var workflows: MutableMap<String, Workflow>? = null\r
+}\r
+\r
+class SubstitutionMapping {\r
+    @get:JsonProperty("node_type")\r
+    lateinit var nodeType: String\r
+    lateinit var capabilities: ArrayList<String>\r
+    lateinit var requirements: ArrayList<String>\r
+}\r
+\r
+class EntrySchema {\r
+    lateinit var type: String\r
+    var constraints: MutableList<MutableMap<String, Any>>? = null\r
+}\r
+\r
+class InterfaceAssignment {\r
+    @get:JsonIgnore\r
+    var id: String? = null\r
+    var operations: MutableMap<String, OperationAssignment>? = null\r
+    var inputs: MutableMap<String, JsonNode>? = null\r
+}\r
+\r
+/*\r
+3.7.3 Node Template\r
+A Node Template specifies the occurrence of a manageable software component as part of an application’s topology model which is defined in a TOSCA Service Template.  A Node template is an instance of a specified Node Type and can provide customized properties, constraints or operations which override the defaults provided by its Node Type and its implementations.\r
+ */\r
+\r
+class NodeTemplate {\r
+    @get:JsonIgnore\r
+    var id: String? = null\r
+    var description: String? = null\r
+    lateinit var type: String\r
+    var metadata: MutableMap<String, String>? = null\r
+    var directives: MutableList<String>? = null\r
+    //@get:JsonSerialize(using = PropertyDefinitionValueSerializer::class)\r
+    var properties: MutableMap<String, JsonNode>? = null\r
+    var attributes: MutableMap<String, JsonNode>? = null\r
+    var capabilities: MutableMap<String, CapabilityAssignment>? = null\r
+    var requirements: MutableMap<String, RequirementAssignment>? = null\r
+    var interfaces: MutableMap<String, InterfaceAssignment>? = null\r
+    var artifacts: MutableMap<String, ArtifactDefinition>? = null\r
+    @get:JsonProperty("node_filter")\r
+    var nodeFilter: NodeFilterDefinition? = null\r
+    var copy: String? = null\r
+}\r
+\r
+class OperationAssignment {\r
+    @get:JsonIgnore\r
+    var id: String? = null\r
+    var description: String? = null\r
+    var implementation: Implementation? = null\r
+    var inputs: MutableMap<String, JsonNode>? = null\r
+    var outputs: MutableMap<String, JsonNode>? = null\r
+}\r
+\r
+/*\r
+3.7.4 Relationship Template\r
+A Relationship Template specifies the occurrence of a manageable relationship between node templates as part of an application’s topology model that is defined in a TOSCA Service Template.  A Relationship template is an instance of a specified Relationship Type and can provide customized properties, constraints or operations which override the defaults provided by its Relationship Type and its implementations.\r
+ */\r
+\r
+class RelationshipTemplate {\r
+    var type: String? = null\r
+    var description: String? = null\r
+    var metadata: MutableMap<String, String>? = null\r
+    var properties: MutableMap<String, PropertyDefinition>? = null\r
+    var attributes: MutableMap<String, JsonNode>? = null\r
+    var interfaces: MutableMap<String, InterfaceDefinition>? = null\r
+    var copy: String? = null\r
+}\r
+\r
+/*\r
+3.7.2 Requirement assignment\r
+A Requirement assignment allows template authors to provide either concrete names of TOSCA templates or provide abstract selection criteria for providers to use to find matching TOSCA templates that are used to fulfill a named requirement’s declared TOSCA Node Type.\r
+ */\r
+\r
+class RequirementAssignment {\r
+    @get:JsonIgnore\r
+    var id: String? = null\r
+    var capability: String? = null\r
+    var node: String? = null\r
+    //Relationship Type or Relationship Template\r
+    var relationship: String? = null\r
+}\r
+\r
+\r
+class Workflow {\r
+    @get:JsonIgnore\r
+    var id: String? = null\r
+    var description: String? = null\r
+    var steps: MutableMap<String, Step>? = null\r
+    var preconditions: ArrayList<PreConditionDefinition>? = null\r
+    var inputs: MutableMap<String, PropertyDefinition>? = null\r
+}\r
+\r
+\r
+class ConditionClause {\r
+    var and: ArrayList<MutableMap<String, Any>>? = null\r
+    var or: ArrayList<MutableMap<String, Any>>? = null\r
+    @get:JsonProperty("assert")\r
+    var assertConditions: ArrayList<MutableMap<String, Any>>? = null\r
+}\r
+\r
+/*\r
+3.9 Service Template definition\r
+A TOSCA Service Template (YAML) document contains element definitions of building blocks for cloud application, or complete models of cloud applications. This section describes the top-level structural elements (TOSCA keynames) along with their grammars, which are allowed to appear in a TOSCA Service Template document.\r
+ */\r
+\r
+class ServiceTemplate {\r
+    @get:JsonIgnore\r
+    var id: String? = null\r
+    @get:JsonProperty("tosca_definitions_version")\r
+    var toscaDefinitionsVersion: String = "controller_blueprint_1_0_0"\r
+    var metadata: MutableMap<String, String>? = null\r
+    var description: String? = null\r
+    @get:JsonProperty("dsl_definitions")\r
+    var dslDefinitions: MutableMap<String, Any>? = null\r
+    var repositories: MutableMap<String, RepositoryDefinition>? = null\r
+    var imports: MutableList<ImportDefinition>? = null\r
+    @get:JsonProperty("artifact_types")\r
+    var artifactTypes: MutableMap<String, ArtifactType>? = null\r
+    @get:JsonProperty("data_types")\r
+    var dataTypes: MutableMap<String, DataType>? = null\r
+    @get:JsonProperty("node_types")\r
+    var nodeTypes: MutableMap<String, NodeType>? = null\r
+    @get:JsonProperty("policy_types")\r
+    var policyTypes: PolicyType? = null\r
+    @get:JsonProperty("topology_template")\r
+    var topologyTemplate: TopologyTemplate? = null\r
+}\r
+\r
+class ToscaMetaData {\r
+    lateinit var toscaMetaFileVersion: String\r
+    lateinit var csarVersion: String\r
+    lateinit var createdBy: String\r
+    lateinit var entityDefinitions: String\r
+    var templateTags: String? = null\r
+}\r
+\r
diff --git a/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/factory/BluePrintEnhancerFactory.kt b/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/factory/BluePrintEnhancerFactory.kt
new file mode 100644 (file)
index 0000000..2a29635
--- /dev/null
@@ -0,0 +1,45 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core.factory\r
+\r
+import org.onap.ccsdk.apps.controllerblueprints.core.service.BluePrintEnhancerService\r
+import org.slf4j.Logger\r
+import org.slf4j.LoggerFactory\r
+\r
+\r
+/**\r
+ * BluePrintEnhancerFactory\r
+ * @author Brinda Santh\r
+ *\r
+ */\r
+\r
+object BluePrintEnhancerFactory {\r
+    private val logger: Logger = LoggerFactory.getLogger(this::class.toString())\r
+\r
+    var bluePrintEnhancerServices: MutableMap<String, BluePrintEnhancerService> = HashMap()\r
+\r
+    fun register(key: String, bluePrintEnhancerService: BluePrintEnhancerService) {\r
+        bluePrintEnhancerServices[key] = bluePrintEnhancerService\r
+    }\r
+\r
+    /**\r
+     * Called by clients to get a Blueprint Parser for the Blueprint parser type\r
+     */\r
+    fun instance(key: String): BluePrintEnhancerService? {\r
+        return bluePrintEnhancerServices.get(key)\r
+    }\r
+}\r
diff --git a/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/factory/BluePrintParserFactory.kt b/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/factory/BluePrintParserFactory.kt
new file mode 100644 (file)
index 0000000..10eb0e6
--- /dev/null
@@ -0,0 +1,51 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core.factory\r
+\r
+import org.onap.ccsdk.apps.controllerblueprints.core.service.BluePrintParserDefaultService\r
+import org.onap.ccsdk.apps.controllerblueprints.core.service.BluePrintParserService\r
+import org.slf4j.Logger\r
+import org.slf4j.LoggerFactory\r
+\r
+/**\r
+ *\r
+ * BluePrintParserFactory\r
+ * @author Brinda Santh\r
+ */\r
+\r
+object BluePrintParserFactory {\r
+    private val logger: Logger = LoggerFactory.getLogger(this::class.toString())\r
+\r
+    var bluePrintParserServices: MutableMap<String, BluePrintParserService> = HashMap()\r
+\r
+    init {\r
+        logger.info("Initialised default BluePrintParser Service ")\r
+        bluePrintParserServices.put(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.TYPE_DEFAULT, BluePrintParserDefaultService())\r
+    }\r
+\r
+    fun register(key:String, bluePrintParserService: BluePrintParserService){\r
+        bluePrintParserServices.put(key, bluePrintParserService)\r
+    }\r
+\r
+    /**\r
+     * Called by clients to get a Blueprint Parser for the Blueprint parser type\r
+     */\r
+    fun instance(key : String) : BluePrintParserService? {\r
+        return bluePrintParserServices.get(key)\r
+    }\r
+}\r
+\r
diff --git a/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/factory/BluePrintValidatorFactory.kt b/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/factory/BluePrintValidatorFactory.kt
new file mode 100644 (file)
index 0000000..63f788a
--- /dev/null
@@ -0,0 +1,45 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core.factory\r
+\r
+\r
+import org.onap.ccsdk.apps.controllerblueprints.core.service.BluePrintValidatorDefaultService\r
+import org.onap.ccsdk.apps.controllerblueprints.core.service.BluePrintValidatorService\r
+\r
+/**\r
+ *\r
+ *\r
+ * @author Brinda Santh\r
+ */\r
+\r
+object BluePrintValidatorFactory {\r
+\r
+    var bluePrintValidatorServices: MutableMap<String, BluePrintValidatorService> = HashMap()\r
+\r
+    init {\r
+        bluePrintValidatorServices[org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.TYPE_DEFAULT] = BluePrintValidatorDefaultService()\r
+    }\r
+\r
+    fun register(key:String, bluePrintValidatorService: BluePrintValidatorService){\r
+        bluePrintValidatorServices[key] = bluePrintValidatorService\r
+    }\r
+\r
+    fun instance(key : String) : BluePrintValidatorService?{\r
+        return bluePrintValidatorServices[key]\r
+    }\r
+\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintChainedService.kt b/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintChainedService.kt
new file mode 100644 (file)
index 0000000..0651763
--- /dev/null
@@ -0,0 +1,117 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core.service\r
+\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintTypes\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.*\r
+/**\r
+ *\r
+ *\r
+ * @author Brinda Santh\r
+ */\r
+class BluePrintChainedService {\r
+    var bpc : BluePrintContext\r
+\r
+    constructor(bpc : BluePrintContext){\r
+        this.bpc = bpc\r
+    }\r
+\r
+    fun nodeTypeChained(nodeTypeName: String): NodeType {\r
+\r
+        val nodeType: NodeType = bpc.nodeTypeByName(nodeTypeName)\r
+        val attributes = hashMapOf<String, AttributeDefinition>()\r
+        val properties = hashMapOf<String, PropertyDefinition>()\r
+        val requirements = hashMapOf<String, RequirementDefinition>()\r
+        val capabilities = hashMapOf<String, CapabilityDefinition>()\r
+        val interfaces = hashMapOf<String, InterfaceDefinition>()\r
+        val artifacts = hashMapOf<String, ArtifactDefinition>()\r
+\r
+        recNodeTypesChained(nodeTypeName).forEach { nodeType ->\r
+\r
+            val subAttributes =  bpc.nodeTypeByName(nodeType.id!!).attributes\r
+            if (subAttributes != null) {\r
+                attributes.putAll(subAttributes)\r
+            }\r
+\r
+            val subProperties =  bpc.nodeTypeByName(nodeType.id!!).properties\r
+            if (subProperties != null) {\r
+                properties.putAll(subProperties)\r
+            }\r
+\r
+            val subRequirements =  bpc.nodeTypeByName(nodeType.id!!).requirements\r
+            if (subRequirements != null) {\r
+                requirements.putAll(subRequirements)\r
+            }\r
+            val subCapabilities =  bpc.nodeTypeByName(nodeType.id!!).capabilities\r
+            if (subCapabilities != null) {\r
+                capabilities.putAll(subCapabilities)\r
+            }\r
+            val subInterfaces =  bpc.nodeTypeByName(nodeType.id!!).interfaces\r
+            if (subInterfaces != null) {\r
+                interfaces.putAll(subInterfaces)\r
+            }\r
+\r
+            val subArtifacts =  bpc.nodeTypeByName(nodeType.id!!).artifacts\r
+            if (subArtifacts != null) {\r
+                artifacts.putAll(subArtifacts)\r
+            }\r
+        }\r
+        nodeType.attributes = attributes\r
+        nodeType.properties = properties\r
+        nodeType.requirements = requirements\r
+        nodeType.capabilities = capabilities\r
+        nodeType.interfaces = interfaces\r
+        nodeType.artifacts = artifacts\r
+        return nodeType\r
+    }\r
+\r
+    fun nodeTypeChainedProperties(nodeTypeName: String): MutableMap<String, PropertyDefinition>? {\r
+        val nodeType =  bpc.nodeTypeByName(nodeTypeName)\r
+        val properties = hashMapOf<String, PropertyDefinition>()\r
+\r
+        recNodeTypesChained(nodeTypeName).forEach { nodeType ->\r
+            val subProperties =  bpc.nodeTypeByName(nodeType.id!!).properties\r
+            if (subProperties != null) {\r
+                properties.putAll(subProperties)\r
+            }\r
+        }\r
+        return properties\r
+    }\r
+\r
+    private fun recNodeTypesChained(nodeTypeName: String, nodeTypes: MutableList<NodeType>? = arrayListOf()): MutableList<NodeType> {\r
+        val nodeType: NodeType =  bpc.nodeTypeByName(nodeTypeName)\r
+        nodeType.id = nodeTypeName\r
+        val derivedFrom: String = nodeType.derivedFrom\r
+        if (!BluePrintTypes.rootNodeTypes().contains(derivedFrom)) {\r
+            recNodeTypesChained(derivedFrom, nodeTypes)\r
+        }\r
+        nodeTypes!!.add(nodeType)\r
+        return nodeTypes\r
+    }\r
+\r
+    private fun recDataTypesChained(dataTypeName: String, dataTypes: MutableList<DataType>? = arrayListOf()): MutableList<DataType> {\r
+        val dataType: DataType =  bpc.dataTypeByName(dataTypeName)!!\r
+        dataType.id = dataTypeName\r
+        val derivedFrom: String = dataType.derivedFrom\r
+        if (!BluePrintTypes.rootDataTypes().contains(derivedFrom)) {\r
+            recDataTypesChained(derivedFrom, dataTypes)\r
+        }\r
+        dataTypes!!.add(dataType)\r
+        return dataTypes\r
+    }\r
+\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintContext.kt b/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintContext.kt
new file mode 100644 (file)
index 0000000..dde1d58
--- /dev/null
@@ -0,0 +1,177 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core.service\r
+\r
+import com.fasterxml.jackson.databind.JsonNode\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.*\r
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils\r
+import org.slf4j.Logger\r
+import org.slf4j.LoggerFactory\r
+/**\r
+ *\r
+ *\r
+ * @author Brinda Santh\r
+ */\r
+class BluePrintContext(serviceTemplate: ServiceTemplate) {\r
+\r
+    private val logger: Logger = LoggerFactory.getLogger(this::class.toString())\r
+\r
+    val serviceTemplate: ServiceTemplate = serviceTemplate\r
+\r
+    val imports: List<ImportDefinition>? = serviceTemplate.imports\r
+\r
+    val metadata: MutableMap<String, String>? = serviceTemplate.metadata\r
+\r
+    val dataTypes: MutableMap<String, DataType>? = serviceTemplate.dataTypes\r
+\r
+    val inputs: MutableMap<String, PropertyDefinition>? = serviceTemplate.topologyTemplate?.inputs\r
+\r
+    val workflows: MutableMap<String, Workflow>? = serviceTemplate.topologyTemplate?.workflows\r
+\r
+    fun blueprintJson(pretty: Boolean = false): String = print("json", pretty)\r
+\r
+    fun blueprintYaml(pretty: Boolean = false): String = print("yaml", pretty)\r
+\r
+    private fun print(type: String? = "json", pretty: Boolean = false): String {\r
+        return JacksonUtils.getJson(serviceTemplate, pretty)\r
+    }\r
+\r
+    // Workflow\r
+    fun workflowByName(name: String): Workflow? = workflows?.get(name)\r
+\r
+    // Data Type\r
+    fun dataTypeByName(name: String): DataType? = dataTypes?.get(name)\r
+\r
+    // Artifact Type\r
+    val artifactTypes: MutableMap<String, ArtifactType>? = serviceTemplate.artifactTypes\r
+\r
+    // Node Type Methods\r
+    val nodeTypes: MutableMap<String, NodeType>? = serviceTemplate.nodeTypes\r
+\r
+    fun nodeTypeByName(name: String): NodeType =\r
+            nodeTypes?.get(name) ?: throw BluePrintException(String.format("Failed to get node type for the name : %s", name))\r
+\r
+    fun nodeTypeDerivedFrom(name: String): MutableMap<String, NodeType>? {\r
+        return nodeTypes?.filterValues { nodeType -> nodeType.derivedFrom == name }?.toMutableMap()\r
+    }\r
+\r
+    fun nodeTypeInterface(nodeTypeName: String, interfaceName: String): InterfaceDefinition? {\r
+        return nodeTypeByName(nodeTypeName).interfaces?.values?.first()\r
+    }\r
+\r
+    fun nodeTypeInterfaceOperation(nodeTypeName: String, interfaceName: String, operationName: String): OperationDefinition? {\r
+        return nodeTypeInterface(nodeTypeName, interfaceName)?.operations?.get(operationName)\r
+    }\r
+\r
+    fun interfaceNameForNodeType(nodeTypeName: String): String? {\r
+        return nodeTypeByName(nodeTypeName).interfaces?.keys?.first()\r
+    }\r
+\r
+    fun nodeTypeInterfaceOperationInputs(nodeTypeName: String, interfaceName: String, operationName: String): MutableMap<String, PropertyDefinition>? {\r
+        return nodeTypeInterfaceOperation(nodeTypeName, interfaceName, operationName)?.inputs\r
+    }\r
+\r
+    fun nodeTypeInterfaceOperationOutputs(nodeTypeName: String, interfaceName: String, operationName: String): MutableMap<String, PropertyDefinition>? {\r
+        return nodeTypeInterfaceOperation(nodeTypeName, interfaceName, operationName)?.outputs\r
+    }\r
+\r
+    // Node Template Methods\r
+    val nodeTemplates: MutableMap<String, NodeTemplate>? = serviceTemplate.topologyTemplate?.nodeTemplates\r
+\r
+    fun nodeTemplateByName(name: String): NodeTemplate =\r
+            nodeTemplates?.get(name) ?: throw BluePrintException("Failed to get node template for the name " + name)\r
+\r
+    fun nodeTemplateForNodeType(name: String): MutableMap<String, NodeTemplate>? {\r
+        return nodeTemplates?.filterValues { nodeTemplate -> nodeTemplate.type == name }?.toMutableMap()\r
+    }\r
+\r
+    fun nodeTemplateNodeType(nodeTemplateName: String): NodeType {\r
+        val nodeTemplateType: String = nodeTemplateByName(nodeTemplateName).type\r
+        return nodeTypeByName(nodeTemplateType)\r
+    }\r
+\r
+    fun nodeTemplateProperty(nodeTemplateName: String, propertyName: String): Any? {\r
+        return nodeTemplateByName(nodeTemplateName).properties?.get(propertyName)\r
+    }\r
+\r
+    fun nodeTemplateArtifacts(nodeTemplateName: String): MutableMap<String, ArtifactDefinition>? {\r
+        return nodeTemplateByName(nodeTemplateName).artifacts\r
+    }\r
+\r
+    fun nodeTemplateArtifact(nodeTemplateName: String, artifactName: String): ArtifactDefinition? {\r
+        return nodeTemplateArtifacts(nodeTemplateName)?.get(artifactName)\r
+    }\r
+\r
+    fun nodeTemplateFirstInterface(nodeTemplateName: String): InterfaceAssignment? {\r
+        return nodeTemplateByName(nodeTemplateName).interfaces?.values?.first()\r
+    }\r
+\r
+    fun nodeTemplateFirstInterfaceName(nodeTemplateName: String): String? {\r
+        return nodeTemplateByName(nodeTemplateName).interfaces?.keys?.first()\r
+    }\r
+\r
+    fun nodeTemplateFirstInterfaceFirstOperationName(nodeTemplateName: String): String? {\r
+        return nodeTemplateFirstInterface(nodeTemplateName)?.operations?.keys?.first()\r
+    }\r
+\r
+    fun nodeTemplateInterfaceOperationInputs(nodeTemplateName: String, interfaceName: String, operationName: String): MutableMap<String, JsonNode>? {\r
+        return nodeTemplateByName(nodeTemplateName).interfaces?.get(interfaceName)?.operations?.get(operationName)?.inputs\r
+    }\r
+\r
+    fun nodeTemplateInterfaceOperationOutputs(nodeTemplateName: String, interfaceName: String, operationName: String): MutableMap<String, JsonNode>? {\r
+        return nodeTemplateByName(nodeTemplateName).interfaces?.get(interfaceName)?.operations?.get(operationName)?.outputs\r
+    }\r
+\r
+    fun nodeTemplateInterface(nodeTemplateName: String, interfaceName: String): InterfaceAssignment? {\r
+        return nodeTemplateByName(nodeTemplateName).interfaces?.get(interfaceName)\r
+    }\r
+\r
+\r
+    fun nodeTemplateInterfaceOperation(nodeTemplateName: String, interfaceName: String, operationName: String): OperationAssignment? {\r
+        return nodeTemplateInterface(nodeTemplateName, interfaceName)?.operations?.get(operationName)\r
+    }\r
+\r
+    fun nodeTemplateCapability(nodeTemplateName: String, capabilityName: String): CapabilityAssignment? {\r
+        return nodeTemplateByName(nodeTemplateName).capabilities?.get(capabilityName)\r
+    }\r
+\r
+    fun nodeTemplateRequirement(nodeTemplateName: String, requirementName: String): RequirementAssignment? {\r
+        return nodeTemplateByName(nodeTemplateName).requirements?.get(requirementName)\r
+    }\r
+\r
+    fun nodeTemplateRequirementNode(nodeTemplateName: String, requirementName: String): NodeTemplate {\r
+        val nodeTemplateName: String = nodeTemplateByName(nodeTemplateName).requirements?.get(requirementName)?.node\r
+                ?: throw BluePrintException(String.format("failed to get node name for node template's (%s) requirement's (%s) " + nodeTemplateName, requirementName))\r
+        return nodeTemplateByName(nodeTemplateName)\r
+    }\r
+\r
+    fun nodeTemplateCapabilityProperty(nodeTemplateName: String, capabilityName: String, propertyName: String): Any? {\r
+        return nodeTemplateCapability(nodeTemplateName, capabilityName)?.properties?.get(propertyName)\r
+    }\r
+\r
+    // Chained Functions\r
+\r
+    fun nodeTypeChained(nodeTypeName: String): NodeType {\r
+        return BluePrintChainedService(this).nodeTypeChained(nodeTypeName)\r
+    }\r
+\r
+    fun nodeTypeChainedProperties(nodeTypeName: String): MutableMap<String, PropertyDefinition>? {\r
+        return BluePrintChainedService(this).nodeTypeChainedProperties(nodeTypeName)\r
+    }\r
+\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintEnhancerRepoService.kt b/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintEnhancerRepoService.kt
new file mode 100644 (file)
index 0000000..5369d50
--- /dev/null
@@ -0,0 +1,92 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core.service\r
+\r
+import org.apache.commons.io.FileUtils\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.*\r
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils\r
+import java.io.File\r
+import java.io.Serializable\r
+import java.nio.charset.Charset\r
+\r
+/**\r
+ * BluePrintEnhancerRepoFileService\r
+ * @author Brinda Santh\r
+ *\r
+ */\r
+\r
+interface BluePrintEnhancerRepoService : Serializable {\r
+\r
+    @Throws(BluePrintException::class)\r
+    fun getNodeType(nodeTypeName: String): NodeType?\r
+\r
+    @Throws(BluePrintException::class)\r
+    fun getDataType(dataTypeName: String): DataType?\r
+\r
+    @Throws(BluePrintException::class)\r
+    fun getArtifactType(artifactTypeName: String): ArtifactType?\r
+\r
+    @Throws(BluePrintException::class)\r
+    fun getRelationshipType(relationshipTypeName: String): RelationshipType?\r
+\r
+    @Throws(BluePrintException::class)\r
+    fun getCapabilityDefinition(capabilityDefinitionName: String): CapabilityDefinition?\r
+\r
+}\r
+\r
+\r
+class BluePrintEnhancerRepoFileService(val basePath: String) : BluePrintEnhancerRepoService {\r
+\r
+    val dataTypePath = basePath.plus(BluePrintConstants.PATH_DIVIDER).plus(BluePrintConstants.MODEL_DEFINITION_TYPE_DATA_TYPE)\r
+    val nodeTypePath = basePath.plus(BluePrintConstants.PATH_DIVIDER).plus(BluePrintConstants.MODEL_DEFINITION_TYPE_NODE_TYPE)\r
+    val artifactTypePath = basePath.plus(BluePrintConstants.PATH_DIVIDER).plus(BluePrintConstants.MODEL_DEFINITION_TYPE_ARTIFACT_TYPE)\r
+    val capabilityTypePath = basePath.plus(BluePrintConstants.PATH_DIVIDER).plus(BluePrintConstants.MODEL_DEFINITION_TYPE_CAPABILITY_TYPE)\r
+    val relationshipTypePath = basePath.plus(BluePrintConstants.PATH_DIVIDER).plus(BluePrintConstants.MODEL_DEFINITION_TYPE_RELATIONSHIP_TYPE)\r
+    val extension = ".json"\r
+\r
+    override fun getDataType(dataTypeName: String): DataType? {\r
+        val content = FileUtils.readFileToString(File(dataTypePath.plus(BluePrintConstants.PATH_DIVIDER)\r
+                .plus(dataTypeName).plus(extension)), Charset.defaultCharset())\r
+        return JacksonUtils.readValue(content)\r
+    }\r
+\r
+    override fun getNodeType(nodeTypeName: String): NodeType? {\r
+        val content = FileUtils.readFileToString(File(nodeTypePath.plus(BluePrintConstants.PATH_DIVIDER)\r
+                .plus(nodeTypeName).plus(extension)), Charset.defaultCharset())\r
+        return JacksonUtils.readValue(content)\r
+    }\r
+\r
+    override fun getArtifactType(artifactTypeName: String): ArtifactType? {\r
+        val content = FileUtils.readFileToString(File(artifactTypePath.plus(BluePrintConstants.PATH_DIVIDER)\r
+                .plus(artifactTypeName).plus(extension)), Charset.defaultCharset())\r
+        return JacksonUtils.readValue(content)\r
+    }\r
+\r
+    override fun getRelationshipType(relationshipTypeName: String): RelationshipType? {\r
+        val content = FileUtils.readFileToString(File(relationshipTypePath.plus(BluePrintConstants.PATH_DIVIDER)\r
+                .plus(relationshipTypeName).plus(extension)), Charset.defaultCharset())\r
+        return JacksonUtils.readValue(content)\r
+    }\r
+\r
+    override fun getCapabilityDefinition(capabilityDefinitionName: String): CapabilityDefinition? {\r
+        val content = FileUtils.readFileToString(File(capabilityTypePath.plus(BluePrintConstants.PATH_DIVIDER)\r
+                .plus(capabilityDefinitionName).plus(extension)), Charset.defaultCharset())\r
+        return JacksonUtils.readValue(content)\r
+    }\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintEnhancerService.kt b/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintEnhancerService.kt
new file mode 100644 (file)
index 0000000..8f17287
--- /dev/null
@@ -0,0 +1,240 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core.service\r
+\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintTypes\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.*\r
+import org.onap.ccsdk.apps.controllerblueprints.core.format\r
+import org.slf4j.Logger\r
+import org.slf4j.LoggerFactory\r
+import java.io.Serializable\r
+\r
+/**\r
+ * BluePrintEnhancerService\r
+ * @author Brinda Santh\r
+ *\r
+ */\r
+interface BluePrintEnhancerService : Serializable {\r
+\r
+    @Throws(BluePrintException::class)\r
+    fun enhance(content: String): ServiceTemplate\r
+\r
+    @Throws(BluePrintException::class)\r
+    fun enhance(serviceTemplate: ServiceTemplate): ServiceTemplate\r
+\r
+    /**\r
+     * Read Blueprint from CSAR structure Directory\r
+     */\r
+    @Throws(BluePrintException::class)\r
+    fun enhance(fileName: String, basePath: String): ServiceTemplate\r
+}\r
+\r
+open class BluePrintEnhancerDefaultService(val bluePrintEnhancerRepoService: BluePrintEnhancerRepoService) : BluePrintEnhancerService {\r
+\r
+    private val log: Logger = LoggerFactory.getLogger(BluePrintEnhancerDefaultService::class.java)\r
+\r
+    lateinit var serviceTemplate: ServiceTemplate\r
+\r
+    override fun enhance(content: String): ServiceTemplate {\r
+        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.\r
+    }\r
+\r
+    override fun enhance(fileName: String, basePath: String): ServiceTemplate {\r
+        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.\r
+    }\r
+\r
+    override fun enhance(serviceTemplate: ServiceTemplate): ServiceTemplate {\r
+        this.serviceTemplate = serviceTemplate\r
+        initialCleanUp()\r
+        enrichTopologyTemplate(serviceTemplate)\r
+\r
+       // log.info("Enriched Blueprint :\n {}", JacksonUtils.getJson(serviceTemplate, true))\r
+        return this.serviceTemplate\r
+    }\r
+\r
+    open fun initialCleanUp() {\r
+        serviceTemplate.artifactTypes?.clear()\r
+        serviceTemplate.nodeTypes?.clear()\r
+        serviceTemplate.dataTypes?.clear()\r
+\r
+        serviceTemplate.artifactTypes = HashMap()\r
+        serviceTemplate.nodeTypes = HashMap()\r
+        serviceTemplate.dataTypes = HashMap()\r
+\r
+    }\r
+\r
+    open fun enrichTopologyTemplate(serviceTemplate: ServiceTemplate) {\r
+        serviceTemplate.topologyTemplate?.let { topologyTemplate ->\r
+            enrichTopologyTemplateInputs(topologyTemplate)\r
+            enrichTopologyTemplateNodeTemplates(topologyTemplate)\r
+        }\r
+    }\r
+\r
+    open fun enrichTopologyTemplateInputs(topologyTemplate: TopologyTemplate) {\r
+        topologyTemplate.inputs?.let { inputs ->\r
+            enrichPropertyDefinitions(inputs)\r
+        }\r
+    }\r
+\r
+    open fun enrichTopologyTemplateNodeTemplates(topologyTemplate: TopologyTemplate) {\r
+        topologyTemplate.nodeTemplates?.forEach { nodeTemplateName, nodeTemplate ->\r
+            enrichNodeTemplate(nodeTemplateName, nodeTemplate)\r
+        }\r
+    }\r
+\r
+    @Throws(BluePrintException::class)\r
+    open fun enrichNodeTemplate(nodeTemplateName: String, nodeTemplate: NodeTemplate) {\r
+        val nodeTypeName = nodeTemplate.type\r
+        // Get NodeType from Repo and Update Service Template\r
+        val nodeType = populateNodeType(nodeTypeName)\r
+\r
+        // Enrich NodeType\r
+        enrichNodeType(nodeTypeName, nodeType)\r
+\r
+        //Enrich Node Template Artifacts\r
+        enrichNodeTemplateArtifactDefinition(nodeTemplateName, nodeTemplate)\r
+    }\r
+\r
+    open fun enrichNodeType(nodeTypeName: String, nodeType: NodeType) {\r
+\r
+        // NodeType Property Definitions\r
+        enrichNodeTypeProperties(nodeTypeName, nodeType)\r
+\r
+        //NodeType Requirement\r
+        enrichNodeTypeRequirements(nodeTypeName, nodeType)\r
+\r
+        //NodeType Capability\r
+        enrichNodeTypeCapabilityProperties(nodeTypeName, nodeType)\r
+\r
+        //NodeType Interface\r
+        enrichNodeTypeInterfaces(nodeTypeName, nodeType)\r
+    }\r
+\r
+    open fun enrichNodeTypeProperties(nodeTypeName: String, nodeType: NodeType) {\r
+        nodeType.properties?.let { enrichPropertyDefinitions(nodeType.properties!!) }\r
+    }\r
+\r
+    open fun enrichNodeTypeRequirements(nodeTypeName: String, nodeType: NodeType) {\r
+\r
+        nodeType.requirements?.forEach { requirementDefinitionName, requirementDefinition ->\r
+            // Populate Requirement Node\r
+            requirementDefinition.node?.let { requirementNodeTypeName ->\r
+                // Get Requirement NodeType from Repo and Update Service Template\r
+                val requirementNodeType = populateNodeType(requirementNodeTypeName)\r
+\r
+                enrichNodeType(requirementNodeTypeName, requirementNodeType)\r
+            }\r
+        }\r
+    }\r
+\r
+    open fun enrichNodeTypeCapabilityProperties(nodeTypeName: String, nodeType: NodeType) {\r
+        nodeType.capabilities?.forEach { capabilityDefinitionName, capabilityDefinition ->\r
+            capabilityDefinition.properties?.let { properties ->\r
+                enrichPropertyDefinitions(properties)\r
+            }\r
+        }\r
+    }\r
+\r
+    open fun enrichNodeTypeInterfaces(nodeTypeName: String, nodeType: NodeType) {\r
+        nodeType.interfaces?.forEach { interfaceName, interfaceObj ->\r
+            // Populate Node type Interface Operation\r
+            log.info("*** ** Enriching NodeType: {} Interface {}", nodeTypeName, interfaceName)\r
+            populateNodeTypeInterfaceOperation(nodeTypeName, interfaceName, interfaceObj)\r
+\r
+        }\r
+    }\r
+\r
+    open fun populateNodeTypeInterfaceOperation(nodeTypeName: String, interfaceName: String, interfaceObj: InterfaceDefinition) {\r
+\r
+        interfaceObj.operations?.forEach { operationName, operation ->\r
+            enrichNodeTypeInterfaceOperationInputs(nodeTypeName, operationName, operation)\r
+            enrichNodeTypeInterfaceOperationOputputs(nodeTypeName, operationName, operation)\r
+        }\r
+    }\r
+\r
+    open fun enrichNodeTypeInterfaceOperationInputs(nodeTypeName: String, operationName: String, operation: OperationDefinition) {\r
+        operation.inputs?.let { inputs ->\r
+            enrichPropertyDefinitions(inputs)\r
+        }\r
+    }\r
+\r
+    open fun enrichNodeTypeInterfaceOperationOputputs(nodeTypeName: String, operationName: String, operation: OperationDefinition) {\r
+        operation.outputs?.let { inputs ->\r
+            enrichPropertyDefinitions(inputs)\r
+        }\r
+    }\r
+\r
+    open fun enrichPropertyDefinitions(properties: MutableMap<String, PropertyDefinition>) {\r
+\r
+        properties.forEach { propertyName, propertyDefinition ->\r
+            enrichPropertyDefinition(propertyName, propertyDefinition)\r
+        }\r
+    }\r
+\r
+    open fun enrichPropertyDefinition(propertyName: String, propertyDefinition: PropertyDefinition) {\r
+        val propertyType = propertyDefinition.type\r
+                ?: throw BluePrintException(format("Property type is missing for property : {}", propertyName))\r
+        if (BluePrintTypes.validPrimitiveTypes().contains(propertyType)) {\r
+\r
+        } else if (BluePrintTypes.validCollectionTypes().contains(propertyType)) {\r
+            val entrySchema = propertyDefinition.entrySchema\r
+                    ?: throw BluePrintException(format("Entry Schema is missing for collection property : {}", propertyName))\r
+\r
+            if (!BluePrintTypes.validPrimitiveTypes().contains(entrySchema.type)) {\r
+                populateDataTypes(entrySchema.type)\r
+            }\r
+        } else {\r
+            populateDataTypes(propertyType)\r
+        }\r
+\r
+    }\r
+\r
+    open fun enrichNodeTemplateArtifactDefinition(nodeTemplateName: String, nodeTemplate: NodeTemplate) {\r
+\r
+        nodeTemplate.artifacts?.forEach { artifactDefinitionName, artifactDefinition ->\r
+            val artifactTypeName = artifactDefinition.type\r
+                    ?: throw BluePrintException(format("Artifact type is missing for NodeTemplate({}) artifact({})", nodeTemplateName, artifactDefinitionName))\r
+\r
+            // Populate Artifact Type\r
+            populateArtifactType(artifactTypeName)\r
+        }\r
+    }\r
+\r
+    open fun populateNodeType(nodeTypeName: String): NodeType {\r
+        val nodeType = bluePrintEnhancerRepoService.getNodeType(nodeTypeName)\r
+                ?: throw BluePrintException(format("Couldn't get NodeType({}) from repo.", nodeTypeName))\r
+        serviceTemplate.nodeTypes?.put(nodeTypeName, nodeType)\r
+        return nodeType\r
+    }\r
+\r
+    open fun populateArtifactType(artifactTypeName: String): ArtifactType {\r
+        val artifactType = bluePrintEnhancerRepoService.getArtifactType(artifactTypeName)\r
+                ?: throw BluePrintException(format("Couldn't get ArtifactType({}) from repo.", artifactTypeName))\r
+        serviceTemplate.artifactTypes?.put(artifactTypeName, artifactType)\r
+        return artifactType\r
+    }\r
+\r
+    open fun populateDataTypes(dataTypeName: String): DataType {\r
+        val dataType = bluePrintEnhancerRepoService.getDataType(dataTypeName)\r
+                ?: throw BluePrintException(format("Couldn't get DataType({}) from repo.", dataTypeName))\r
+        serviceTemplate.dataTypes?.put(dataTypeName, dataType)\r
+        return dataType\r
+    }\r
+\r
+}\r
+\r
diff --git a/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintExpressionService.kt b/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintExpressionService.kt
new file mode 100644 (file)
index 0000000..36959c4
--- /dev/null
@@ -0,0 +1,174 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core.service\r
+\r
+import com.fasterxml.jackson.databind.JsonNode\r
+import com.fasterxml.jackson.databind.node.ArrayNode\r
+import com.fasterxml.jackson.databind.node.ObjectNode\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintTypes\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.*\r
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils\r
+import org.slf4j.Logger\r
+import org.slf4j.LoggerFactory\r
+/**\r
+ *\r
+ *\r
+ * @author Brinda Santh\r
+ */\r
+object BluePrintExpressionService {\r
+    val logger: Logger = LoggerFactory.getLogger(this::class.toString())\r
+\r
+    @JvmStatic\r
+    fun getExpressionData(propertyAssignment: Any): ExpressionData {\r
+        val propertyAssignmentNode: JsonNode = JacksonUtils.jsonNodeFromObject(propertyAssignment)\r
+        return getExpressionData(propertyAssignmentNode)\r
+    }\r
+\r
+    @JvmStatic\r
+    fun getExpressionData(propertyAssignmentNode: JsonNode): ExpressionData {\r
+        logger.trace("Assignment Data/Expression : {}", propertyAssignmentNode)\r
+        val expressionData = ExpressionData(valueNode = propertyAssignmentNode)\r
+        if (propertyAssignmentNode is ObjectNode) {\r
+\r
+            val commands: Set<String> = propertyAssignmentNode.fieldNames().asSequence().toList().intersect(BluePrintTypes.validCommands())\r
+            if (commands.isNotEmpty()) {\r
+                expressionData.isExpression = true\r
+                expressionData.command = commands.first()\r
+                expressionData.expressionNode = propertyAssignmentNode\r
+\r
+                when (expressionData.command) {\r
+                    org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.EXPRESSION_GET_INPUT -> {\r
+                        expressionData.inputExpression = populateInputExpression(propertyAssignmentNode)\r
+                    }\r
+                    org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.EXPRESSION_GET_ATTRIBUTE -> {\r
+                        expressionData.attributeExpression = populateAttributeExpression(propertyAssignmentNode)\r
+                    }\r
+                    org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.EXPRESSION_GET_PROPERTY -> {\r
+                        expressionData.propertyExpression = populatePropertyExpression(propertyAssignmentNode)\r
+                    }\r
+                    org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.EXPRESSION_GET_OPERATION_OUTPUT -> {\r
+                        expressionData.operationOutputExpression = populateOperationOutputExpression(propertyAssignmentNode)\r
+                    }\r
+                    org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.EXPRESSION_GET_ARTIFACT -> {\r
+                        expressionData.artifactExpression = populateArtifactExpression(propertyAssignmentNode)\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        return expressionData\r
+    }\r
+\r
+    @JvmStatic\r
+    fun populateInputExpression(jsonNode: JsonNode): InputExpression {\r
+        return InputExpression(propertyName = jsonNode.first().textValue())\r
+    }\r
+\r
+    @JvmStatic\r
+    fun populatePropertyExpression(jsonNode: JsonNode): PropertyExpression {\r
+        val arrayNode: ArrayNode = jsonNode.first() as ArrayNode\r
+        check(arrayNode.size() >= 2) {\r
+            throw BluePrintException(String.format("missing property expression, " +\r
+                    "it should be [ <modelable_entity_name>, <optional_req_or_cap_name>, <property_name>, " +\r
+                    "<nested_property_name_or_index_1>, ..., <nested_property_name_or_index_n> ] , but present {}", jsonNode))\r
+        }\r
+        var reqOrCapEntityName: String? = null\r
+        var propertyName = ""\r
+        var subProperty: String? = null\r
+        if (arrayNode.size() == 2) {\r
+            propertyName = arrayNode[1].textValue()\r
+        } else if (arrayNode.size() == 3) {\r
+            reqOrCapEntityName = arrayNode[1].textValue()\r
+            propertyName = arrayNode[2].textValue()\r
+        } else if (arrayNode.size() > 3) {\r
+            reqOrCapEntityName = arrayNode[1].textValue()\r
+            propertyName = arrayNode[2].textValue()\r
+            val propertyPaths: List<String> = arrayNode.filterIndexed { index, obj ->\r
+                index >= 3\r
+            }.map { it.textValue() }\r
+            subProperty = propertyPaths.joinToString("/")\r
+        }\r
+\r
+        return PropertyExpression(modelableEntityName = arrayNode[0].asText(),\r
+                reqOrCapEntityName = reqOrCapEntityName,\r
+                propertyName = propertyName,\r
+                subPropertyName = subProperty\r
+        )\r
+    }\r
+\r
+    @JvmStatic\r
+    fun populateAttributeExpression(jsonNode: JsonNode): AttributeExpression {\r
+        val arrayNode: ArrayNode = jsonNode.first() as ArrayNode\r
+        check(arrayNode.size() >= 3) {\r
+            throw BluePrintException(String.format("missing attribute expression, " +\r
+                    "it should be [ <modelable_entity_name>, <optional_req_or_cap_name>, <attribute_name>," +\r
+                    " <nested_attribute_name_or_index_1>, ..., <nested_attribute_name_or_index_n> ] , but present {}", jsonNode))\r
+        }\r
+\r
+        var reqOrCapEntityName: String? = null\r
+        var propertyName: String = ""\r
+        var subProperty: String? = null\r
+        if (arrayNode.size() == 2) {\r
+            propertyName = arrayNode[1].textValue()\r
+        } else if (arrayNode.size() == 3) {\r
+            reqOrCapEntityName = arrayNode[1].textValue()\r
+            propertyName = arrayNode[2].textValue()\r
+        } else if (arrayNode.size() > 3) {\r
+            reqOrCapEntityName = arrayNode[1].textValue()\r
+            propertyName = arrayNode[2].textValue()\r
+            val propertyPaths: List<String> = arrayNode.filterIndexed { index, obj ->\r
+                index >= 3\r
+            }.map { it.textValue() }\r
+            subProperty = propertyPaths.joinToString("/")\r
+        }\r
+        return AttributeExpression(modelableEntityName = arrayNode[0].asText(),\r
+                reqOrCapEntityName = reqOrCapEntityName,\r
+                attributeName = propertyName,\r
+                subAttributeName = subProperty\r
+        )\r
+    }\r
+\r
+    @JvmStatic\r
+    fun populateOperationOutputExpression(jsonNode: JsonNode): OperationOutputExpression {\r
+        val arrayNode: ArrayNode = jsonNode.first() as ArrayNode\r
+\r
+        check(arrayNode.size() >= 4) {\r
+            throw BluePrintException(String.format("missing operation output expression, " +\r
+                    "it should be (<modelable_entity_name>, <interface_name>, <operation_name>, <output_variable_name>) , but present {}", jsonNode))\r
+        }\r
+        return OperationOutputExpression(modelableEntityName = arrayNode[0].asText(),\r
+                interfaceName = arrayNode[1].asText(),\r
+                operationName = arrayNode[2].asText(),\r
+                propertyName = arrayNode[3].asText()\r
+        )\r
+    }\r
+\r
+    @JvmStatic\r
+    fun populateArtifactExpression(jsonNode: JsonNode): ArtifactExpression {\r
+        val arrayNode: ArrayNode = jsonNode.first() as ArrayNode\r
+\r
+        check(arrayNode.size() >= 2) {\r
+            throw BluePrintException(String.format("missing artifact expression, " +\r
+                    "it should be [ <modelable_entity_name>, <artifact_name>, <location>, <remove> ] , but present {}", jsonNode))\r
+        }\r
+        return ArtifactExpression(modelableEntityName = arrayNode[0].asText(),\r
+                artifactName = arrayNode[1].asText(),\r
+                location = arrayNode[2]?.asText() ?: "LOCAL_FILE",\r
+                remove = arrayNode[3]?.asBoolean() ?: false\r
+        )\r
+    }\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintParserService.kt b/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintParserService.kt
new file mode 100644 (file)
index 0000000..3b91720
--- /dev/null
@@ -0,0 +1,62 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core.service\r
+\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.ServiceTemplate\r
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.ServiceTemplateUtils\r
+import org.slf4j.Logger\r
+import org.slf4j.LoggerFactory\r
+import java.io.File\r
+import java.io.Serializable\r
+\r
+/**\r
+ *\r
+ *\r
+ * @author Brinda Santh\r
+ */\r
+interface BluePrintParserService : Serializable {\r
+    fun readBlueprint(content: String) : BluePrintContext\r
+    fun readBlueprintFile(fileName: String) : BluePrintContext\r
+    /**\r
+     * Read Blueprint from CSAR structure Directory\r
+     */\r
+    fun readBlueprintFile(fileName: String, basePath : String) : BluePrintContext\r
+}\r
+\r
+class BluePrintParserDefaultService : BluePrintParserService {\r
+\r
+    private val logger: Logger = LoggerFactory.getLogger(this::class.toString())\r
+\r
+    var basePath : String = javaClass.classLoader.getResource(".").path\r
+\r
+    override fun readBlueprint(content: String): BluePrintContext {\r
+        return BluePrintContext(ServiceTemplateUtils.getServiceTemplateFromContent(content))\r
+    }\r
+\r
+    override fun readBlueprintFile(fileName: String): BluePrintContext {\r
+        return readBlueprintFile(fileName, basePath )\r
+    }\r
+\r
+    override fun readBlueprintFile(fileName: String, basePath : String): BluePrintContext {\r
+        val rootFilePath: String = StringBuilder().append(basePath).append(File.separator).append(fileName).toString()\r
+        val rootServiceTemplate : ServiceTemplate = ServiceTemplateUtils.getServiceTemplate(rootFilePath)\r
+        // TODO("Nested Lookup Implementation based on Import files")\r
+        return BluePrintContext(rootServiceTemplate)\r
+    }\r
+\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintRuntimeService.kt b/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintRuntimeService.kt
new file mode 100644 (file)
index 0000000..213f5f4
--- /dev/null
@@ -0,0 +1,274 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core.service\r
+\r
+\r
+import com.fasterxml.jackson.databind.JsonNode\r
+import com.fasterxml.jackson.databind.node.NullNode\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException\r
+import org.onap.ccsdk.apps.controllerblueprints.core.OrchestratorException\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.ArtifactDefinition\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.NodeTemplate\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.PropertyDefinition\r
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils\r
+import org.slf4j.Logger\r
+import org.slf4j.LoggerFactory\r
+/**\r
+ *\r
+ *\r
+ * @author Brinda Santh\r
+ */\r
+class BluePrintRuntimeService(var bluePrintContext: BluePrintContext, var context: MutableMap<String, Any> = hashMapOf()) {\r
+\r
+    private val logger: Logger = LoggerFactory.getLogger(this::class.toString())\r
+\r
+    /*\r
+        Get the Node Type Definition for the Node Template, Then iterate Node Type Properties and resolve the expressing\r
+     */\r
+    fun resolveNodeTemplateProperties(nodeTemplateName: String): MutableMap<String, Any?> {\r
+        logger.info("resolveNodeTemplatePropertyValues for node template ({})", nodeTemplateName)\r
+        val propertyAssignmentValue: MutableMap<String, Any?> = hashMapOf()\r
+\r
+        val nodeTemplate: NodeTemplate = bluePrintContext.nodeTemplateByName(nodeTemplateName)\r
+\r
+        val propertyAssignments: MutableMap<String, Any?> =\r
+                nodeTemplate.properties as MutableMap<String, Any?>\r
+\r
+        // Get the Node Type Definitions\r
+        val nodeTypeProperties: MutableMap<String, PropertyDefinition> =\r
+                bluePrintContext.nodeTypeChainedProperties(nodeTemplate.type)!!\r
+\r
+        // Iterate Node Type Properties\r
+        nodeTypeProperties.forEach { nodeTypePropertyName, nodeTypeProperty ->\r
+            // Get the Express or Value for the Node Template\r
+            val propertyAssignment: Any? = propertyAssignments[nodeTypePropertyName]\r
+\r
+            var resolvedValue: JsonNode = NullNode.getInstance()\r
+            if (propertyAssignment != null) {\r
+                // Resolve the Expressing\r
+                val propertyAssignmentExpression = PropertyAssignmentService(context, this)\r
+                resolvedValue = propertyAssignmentExpression.resolveAssignmentExpression(nodeTemplateName, nodeTypePropertyName, propertyAssignment)\r
+            } else {\r
+                // Assign default value to the Operation\r
+                nodeTypeProperty.defaultValue?.let {\r
+                    resolvedValue = JacksonUtils.jsonNodeFromObject(nodeTypeProperty.defaultValue!!)\r
+                }\r
+            }\r
+            // Set for Return of method\r
+            propertyAssignmentValue[nodeTypePropertyName] = resolvedValue\r
+        }\r
+        logger.info("resolved property definition for node template ({}), values ({})", nodeTemplateName, propertyAssignmentValue)\r
+        return propertyAssignmentValue\r
+    }\r
+\r
+    fun resolveNodeTemplateInterfaceOperationInputs(nodeTemplateName: String,\r
+                                                    interfaceName: String, operationName: String): MutableMap<String, Any?> {\r
+        logger.info("nodeTemplateInterfaceOperationInputsResolvedExpression for node template ({}),interface name ({}), " +\r
+                "operationName({})", nodeTemplateName, interfaceName, operationName)\r
+\r
+        val propertyAssignmentValue: MutableMap<String, Any?> = hashMapOf()\r
+\r
+        val propertyAssignments: MutableMap<String, Any> =\r
+                bluePrintContext.nodeTemplateInterfaceOperationInputs(nodeTemplateName, interfaceName, operationName) as? MutableMap<String, Any>\r
+                        ?: throw BluePrintException(String.format("failed to get input definitions for node template (%s), " +\r
+                                "interface name (%s), operationName(%s)", nodeTemplateName, interfaceName, operationName))\r
+\r
+        val nodeTypeName = bluePrintContext.nodeTemplateByName(nodeTemplateName).type\r
+\r
+        val nodeTypeInterfaceOperationInputs: MutableMap<String, PropertyDefinition> =\r
+                bluePrintContext.nodeTypeInterfaceOperationInputs(nodeTypeName, interfaceName, operationName)\r
+                        ?: throw BluePrintException(String.format("failed to get input definitions for node type (%s), " +\r
+                                "interface name (%s), operationName(%s)", nodeTypeName, interfaceName, operationName))\r
+\r
+        logger.info("input definition for node template ({}), values ({})", nodeTemplateName, propertyAssignments)\r
+\r
+        // Iterate Node Type Properties\r
+        nodeTypeInterfaceOperationInputs.forEach { nodeTypePropertyName, nodeTypeProperty ->\r
+            // Get the Express or Value for the Node Template\r
+            val propertyAssignment: Any? = propertyAssignments[nodeTypePropertyName]\r
+\r
+            var resolvedValue: JsonNode = NullNode.getInstance()\r
+            if (propertyAssignment != null) {\r
+                // Resolve the Expressing\r
+                val propertyAssignmentExpression = PropertyAssignmentService( context, this)\r
+                resolvedValue = propertyAssignmentExpression.resolveAssignmentExpression(nodeTemplateName, nodeTypePropertyName, propertyAssignment)\r
+            } else {\r
+                // Assign default value to the Operation\r
+                nodeTypeProperty.defaultValue?.let {\r
+                    resolvedValue = JacksonUtils.jsonNodeFromObject(nodeTypeProperty.defaultValue!!)\r
+                }\r
+            }\r
+            // Set for Return of method\r
+            propertyAssignmentValue[nodeTypePropertyName] = resolvedValue\r
+        }\r
+        logger.info("resolved input assignments for node template ({}), values ({})", nodeTemplateName, propertyAssignmentValue)\r
+\r
+        return propertyAssignmentValue\r
+    }\r
+\r
+\r
+    fun resolveNodeTemplateInterfaceOperationOutputs(nodeTemplateName: String,\r
+                                                     interfaceName: String, operationName: String, componentContext: MutableMap<String, Any?>): Unit {\r
+        logger.info("nodeTemplateInterfaceOperationInputsResolvedExpression for node template ({}),interface name ({}), " +\r
+                "operationName({})", nodeTemplateName, interfaceName, operationName)\r
+\r
+        val nodeTypeName = bluePrintContext.nodeTemplateByName(nodeTemplateName).type\r
+\r
+        val nodeTypeInterfaceOperationOutputs: MutableMap<String, PropertyDefinition> =\r
+                bluePrintContext.nodeTypeInterfaceOperationOutputs(nodeTypeName, interfaceName, operationName)\r
+                        ?: throw BluePrintException(String.format("failed to get input definitions for node type (%s), " +\r
+                                "interface name (%s), operationName(%s)", nodeTypeName, interfaceName, operationName))\r
+\r
+        // Iterate Node Type Properties\r
+        nodeTypeInterfaceOperationOutputs.forEach { nodeTypePropertyName, nodeTypeProperty ->\r
+\r
+            val operationOutputPropertyName: String = StringBuilder().append(nodeTemplateName)\r
+                    .append(".").append(interfaceName)\r
+                    .append(".").append(operationName)\r
+                    .append(".").append(nodeTypePropertyName).toString()\r
+            // Get the Value from component context\r
+            val resolvedValue: JsonNode = componentContext[operationOutputPropertyName] as? JsonNode\r
+                    ?: NullNode.getInstance()\r
+            // Store  operation output values into context\r
+            setNodeTemplateOperationPropertyValue(nodeTemplateName, interfaceName, operationName, nodeTypePropertyName, resolvedValue)\r
+            logger.debug("resolved output assignments for node template ({}), property name ({}), value ({})", nodeTemplateName, nodeTypePropertyName, resolvedValue)\r
+        }\r
+    }\r
+\r
+    fun resolveNodeTemplateArtifact(nodeTemplateName: String,\r
+                                    artifactName: String): String {\r
+        val nodeTemplate = bluePrintContext.nodeTemplateByName(nodeTemplateName)\r
+\r
+        val artifactDefinition: ArtifactDefinition = nodeTemplate.artifacts?.get(artifactName)\r
+                ?: throw OrchestratorException(String.format("failed to get artifat definition {} from the node template"\r
+                        , artifactName))\r
+        val propertyAssignmentExpression = PropertyAssignmentService( context, this)\r
+        return propertyAssignmentExpression.artifactContent(artifactDefinition)\r
+    }\r
+\r
+\r
+    fun setInputValue(propertyName: String, propertyDefinition: PropertyDefinition, value: JsonNode): Unit {\r
+        val path = StringBuilder(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_INPUTS)\r
+                .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()\r
+        logger.trace("setting input path ({}), values ({})", path, value)\r
+        context[path] = value\r
+    }\r
+\r
+    fun setWorkflowInputValue(workflowName: String, propertyName: String, value: JsonNode): Unit {\r
+        val path: String = StringBuilder(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_NODE_WORKFLOWS).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(workflowName)\r
+                .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_INPUTS)\r
+                .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_PROPERTIES)\r
+                .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()\r
+        context[path] = value\r
+    }\r
+\r
+    fun setNodeTemplatePropertyValue(nodeTemplateName: String, propertyName: String, value: JsonNode): Unit {\r
+\r
+        val path: String = StringBuilder(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_NODE_TEMPLATES).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)\r
+                .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_PROPERTIES)\r
+                .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()\r
+        context[path] = value\r
+    }\r
+\r
+    fun setNodeTemplateOperationPropertyValue(nodeTemplateName: String, interfaceName: String, operationName: String, propertyName: String,\r
+                                              value: JsonNode): Unit {\r
+        val path: String = StringBuilder(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_NODE_TEMPLATES).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)\r
+                .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_INTERFACES).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(interfaceName)\r
+                .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_OPERATIONS).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(operationName)\r
+                .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_PROPERTIES)\r
+                .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()\r
+        logger.trace("setting operation property path ({}), values ({})", path, value)\r
+        context[path] = value\r
+    }\r
+\r
+    fun setNodeTemplateOperationInputValue(nodeTemplateName: String, interfaceName: String, operationName: String, propertyName: String,\r
+                                           value: JsonNode): Unit {\r
+        val path: String = StringBuilder(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_NODE_TEMPLATES).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)\r
+                .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_INTERFACES).append(interfaceName)\r
+                .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_OPERATIONS).append(operationName)\r
+                .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_INPUTS)\r
+                .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_PROPERTIES)\r
+                .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()\r
+        context[path] = value\r
+    }\r
+\r
+    fun setNodeTemplateOperationOutputValue(nodeTemplateName: String, interfaceName: String, operationName: String, propertyName: String,\r
+                                            value: JsonNode): Unit {\r
+        val path: String = StringBuilder(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_NODE_TEMPLATES).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)\r
+                .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_INTERFACES).append(interfaceName)\r
+                .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_OPERATIONS).append(operationName)\r
+                .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_OUTPUTS)\r
+                .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_PROPERTIES)\r
+                .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()\r
+        context[path] = value\r
+    }\r
+\r
+\r
+    fun getInputValue(propertyName: String): JsonNode {\r
+        val path = StringBuilder(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_INPUTS)\r
+                .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()\r
+        return context[path] as? JsonNode ?: NullNode.instance\r
+    }\r
+\r
+    fun getNodeTemplateOperationOutputValue(nodeTemplateName: String, interfaceName: String, operationName: String, propertyName: String): JsonNode {\r
+        val path: String = StringBuilder(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_NODE_TEMPLATES).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)\r
+                .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_INTERFACES).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(interfaceName)\r
+                .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_OPERATIONS).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(operationName)\r
+                .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_PROPERTIES)\r
+                .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()\r
+        return context[path] as JsonNode\r
+    }\r
+\r
+    fun getPropertyValue(nodeTemplateName: String, propertyName: String): JsonNode? {\r
+        val path: String = StringBuilder(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_NODE_TEMPLATES).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)\r
+                .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_PROPERTIES)\r
+                .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()\r
+        return context[path] as JsonNode\r
+    }\r
+\r
+    fun getRequirementPropertyValue(nodeTemplateName: String, requirementName: String, propertyName: String): JsonNode? {\r
+        val path: String = StringBuilder(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_NODE_TEMPLATES).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)\r
+                .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_REQUIREMENTS).append(requirementName)\r
+                .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_PROPERTIES)\r
+                .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()\r
+        return context[path] as JsonNode\r
+    }\r
+\r
+    fun getCapabilityPropertyValue(nodeTemplateName: String, capabilityName: String, propertyName: String): JsonNode? {\r
+        val path: String = StringBuilder(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_NODE_TEMPLATES).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(nodeTemplateName)\r
+                .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_CAPABILITIES).append(capabilityName)\r
+                .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_PROPERTIES)\r
+                .append(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PATH_DIVIDER).append(propertyName).toString()\r
+        return context[path] as JsonNode\r
+    }\r
+\r
+    fun assignInputs(jsonNode: JsonNode): Unit {\r
+        logger.info("assignInputs from input JSON ({})", jsonNode.toString())\r
+        bluePrintContext.inputs?.forEach { propertyName, property ->\r
+            val valueNode: JsonNode = jsonNode.at("/" + propertyName) ?: NullNode.getInstance()\r
+            setInputValue(propertyName, property, valueNode)\r
+        }\r
+    }\r
+\r
+    fun assignWorkflowInputs(workflowName: String, jsonNode: JsonNode): Unit {\r
+        logger.info("assign workflow {} input value ({})", workflowName, jsonNode.toString())\r
+        bluePrintContext.workflowByName(workflowName)?.inputs?.forEach { propertyName, property ->\r
+            val valueNode: JsonNode = jsonNode.at("/" + propertyName) ?: NullNode.getInstance()\r
+            setWorkflowInputValue(workflowName, propertyName, valueNode)\r
+        }\r
+    }\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintValidatorService.kt b/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintValidatorService.kt
new file mode 100644 (file)
index 0000000..2383a65
--- /dev/null
@@ -0,0 +1,353 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core.service\r
+\r
+import com.fasterxml.jackson.databind.JsonNode\r
+import com.google.common.base.Preconditions\r
+import org.apache.commons.lang3.StringUtils\r
+import org.onap.ccsdk.apps.controllerblueprints.core.*\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.*\r
+import org.slf4j.Logger\r
+import org.slf4j.LoggerFactory\r
+import java.io.Serializable\r
+\r
+/**\r
+ *\r
+ *\r
+ * @author Brinda Santh\r
+ */\r
+interface BluePrintValidatorService : Serializable {\r
+\r
+    @Throws(BluePrintException::class)\r
+    fun validateBlueprint(bluePrintContext: BluePrintContext, properties: MutableMap<String, Any>)\r
+\r
+    @Throws(BluePrintException::class)\r
+    fun validateBlueprint(serviceTemplate: ServiceTemplate, properties: MutableMap<String, Any>)\r
+}\r
+\r
+open class BluePrintValidatorDefaultService : BluePrintValidatorService {\r
+\r
+    val logger: Logger = LoggerFactory.getLogger(BluePrintValidatorDefaultService::class.toString())\r
+\r
+    lateinit var bluePrintContext: BluePrintContext\r
+    lateinit var serviceTemplate: ServiceTemplate\r
+    lateinit var properties: MutableMap<String, Any>\r
+    var message: StringBuilder = StringBuilder()\r
+    val seperator: String = "/"\r
+    var paths: MutableList<String> = arrayListOf()\r
+\r
+    @Throws(BluePrintException::class)\r
+    override fun validateBlueprint(bluePrintContext: BluePrintContext, properties: MutableMap<String, Any>) {\r
+        validateBlueprint(bluePrintContext.serviceTemplate,properties)\r
+    }\r
+\r
+    @Throws(BluePrintException::class)\r
+    override fun validateBlueprint(serviceTemplate: ServiceTemplate, properties: MutableMap<String, Any>) {\r
+        this.bluePrintContext = BluePrintContext(serviceTemplate)\r
+        this.serviceTemplate = serviceTemplate\r
+        this.properties = properties\r
+        try {\r
+            message.appendln("-> Config Blueprint")\r
+            serviceTemplate.metadata?.let { validateMetadata(serviceTemplate.metadata!!) }\r
+            serviceTemplate.artifactTypes?.let { validateArtifactTypes(serviceTemplate.artifactTypes!!) }\r
+            serviceTemplate.dataTypes?.let { validateDataTypes(serviceTemplate.dataTypes!!) }\r
+            serviceTemplate.nodeTypes?.let { validateNodeTypes(serviceTemplate.nodeTypes!!) }\r
+            serviceTemplate.topologyTemplate?.let { validateTopologyTemplate(serviceTemplate.topologyTemplate!!) }\r
+        } catch (e: Exception) {\r
+            logger.error("validation failed in the path : {}", paths.joinToString(seperator), e)\r
+            logger.error("validation trace message :{} ", message)\r
+            throw BluePrintException(e,\r
+                    format("failed to validate blueprint on path ({}) with message {}"\r
+                            , paths.joinToString(seperator), e.message))\r
+        }\r
+    }\r
+\r
+    @Throws(BluePrintException::class)\r
+    open fun validateMetadata(metaDataMap: MutableMap<String, String>) {\r
+        paths.add("metadata")\r
+        Preconditions.checkArgument(StringUtils.isNotBlank(metaDataMap[BluePrintConstants.METADATA_TEMPLATE_NAME]), "failed to get template name metadata")\r
+        Preconditions.checkArgument(StringUtils.isNotBlank(metaDataMap[BluePrintConstants.METADATA_TEMPLATE_VERSION]), "failed to get template version metadata")\r
+        Preconditions.checkArgument(StringUtils.isNotBlank(metaDataMap[BluePrintConstants.METADATA_TEMPLATE_TAGS]), "failed to get template tags metadata")\r
+        Preconditions.checkArgument(StringUtils.isNotBlank(metaDataMap[BluePrintConstants.METADATA_TEMPLATE_AUTHOR]), "failed to get template author metadata")\r
+        Preconditions.checkArgument(StringUtils.isNotBlank(metaDataMap[BluePrintConstants.METADATA_USER_GROUPS]), "failed to get user groups metadata")\r
+        paths.removeAt(paths.lastIndex)\r
+    }\r
+\r
+    @Throws(BluePrintException::class)\r
+    open fun validateArtifactTypes(artifactTypes: MutableMap<String, ArtifactType>) {\r
+        paths.add("artifact_types")\r
+        artifactTypes.forEach { artifactName, artifactType ->\r
+            paths.add(artifactName)\r
+            message.appendln("--> Artifact Type :" + paths.joinToString(seperator))\r
+            artifactType.properties?.let { validatePropertyDefinitions(artifactType.properties!!) }\r
+            paths.removeAt(paths.lastIndex)\r
+        }\r
+        paths.removeAt(paths.lastIndex)\r
+    }\r
+\r
+    @Throws(BluePrintException::class)\r
+    open fun validateDataTypes(dataTypes: MutableMap<String, DataType>) {\r
+        paths.add("dataTypes")\r
+        dataTypes.forEach { dataTypeName, dataType ->\r
+            paths.add(dataTypeName)\r
+            message.appendln("--> Data Type :" + paths.joinToString(seperator))\r
+            dataType.properties?.let { validatePropertyDefinitions(dataType.properties!!) }\r
+            paths.removeAt(paths.lastIndex)\r
+        }\r
+        paths.removeAt(paths.lastIndex)\r
+    }\r
+\r
+    @Throws(BluePrintException::class)\r
+    open fun validateNodeTypes(nodeTypes: MutableMap<String, NodeType>) {\r
+        paths.add("nodeTypes")\r
+        nodeTypes.forEach { nodeTypeName, nodeType ->\r
+            // Validate Single Node Type\r
+            validateNodeType(nodeTypeName,nodeType)\r
+        }\r
+        paths.removeAt(paths.lastIndex)\r
+    }\r
+\r
+    @Throws(BluePrintException::class)\r
+    open fun validateNodeType(nodeTypeName: String, nodeType: NodeType) {\r
+        paths.add(nodeTypeName)\r
+        message.appendln("--> Node Type :" + paths.joinToString(seperator))\r
+        val derivedFrom: String = nodeType.derivedFrom\r
+        //Check Derived From\r
+        checkValidNodeTypesDerivedFrom(derivedFrom)\r
+\r
+        nodeType.properties?.let { validatePropertyDefinitions(nodeType.properties!!) }\r
+        nodeType.interfaces?.let { validateInterfaceDefinitions(nodeType.interfaces!!) }\r
+        paths.removeAt(paths.lastIndex)\r
+    }\r
+\r
+    @Throws(BluePrintException::class)\r
+    open fun validateTopologyTemplate(topologyTemplate: TopologyTemplate) {\r
+        paths.add("topology")\r
+        message.appendln("--> Topology Template")\r
+        topologyTemplate.inputs?.let { validateInputs(topologyTemplate.inputs!!) }\r
+        topologyTemplate.nodeTemplates?.let { validateNodeTemplates(topologyTemplate.nodeTemplates!!) }\r
+        topologyTemplate.workflows?.let { validateWorkFlows(topologyTemplate.workflows!!) }\r
+        paths.removeAt(paths.lastIndex)\r
+    }\r
+\r
+    @Throws(BluePrintException::class)\r
+    open fun validateInputs(inputs: MutableMap<String, PropertyDefinition>) {\r
+        paths.add("inputs")\r
+        message.appendln("---> Input :" + paths.joinToString(seperator))\r
+        validatePropertyDefinitions(inputs)\r
+        paths.removeAt(paths.lastIndex)\r
+    }\r
+\r
+    @Throws(BluePrintException::class)\r
+    open fun validateNodeTemplates(nodeTemplates: MutableMap<String, NodeTemplate>) {\r
+        paths.add("nodeTemplates")\r
+        nodeTemplates.forEach { nodeTemplateName, nodeTemplate ->\r
+            validateNodeTemplate(nodeTemplateName, nodeTemplate)\r
+        }\r
+        paths.removeAt(paths.lastIndex)\r
+    }\r
+\r
+    @Throws(BluePrintException::class)\r
+    open fun validateNodeTemplate(nodeTemplateName : String, nodeTemplate: NodeTemplate) {\r
+        paths.add(nodeTemplateName)\r
+        message.appendln("---> Node Template :" + paths.joinToString(seperator))\r
+        val type: String = nodeTemplate.type\r
+\r
+        val nodeType: NodeType = serviceTemplate.nodeTypes?.get(type)\r
+                ?: throw BluePrintException(format("Failed to get node type definition  for node template : {}", nodeTemplateName))\r
+\r
+        nodeTemplate.artifacts?.let { validateArtifactDefinitions(nodeTemplate.artifacts!!) }\r
+        nodeTemplate.properties?.let { validatePropertyAssignments(nodeType.properties!!, nodeTemplate.properties!!) }\r
+        nodeTemplate.capabilities?.let { validateCapabilityAssignments(nodeTemplate.capabilities!!) }\r
+        nodeTemplate.requirements?.let { validateRequirementAssignments(nodeTemplate.requirements!!) }\r
+        nodeTemplate.interfaces?.let { validateInterfaceAssignments(nodeTemplate.interfaces!!) }\r
+        paths.removeAt(paths.lastIndex)\r
+    }\r
+\r
+    @Throws(BluePrintException::class)\r
+    open fun validateWorkFlows(workflows: MutableMap<String, Workflow>) {\r
+        paths.add("workflows")\r
+        workflows.forEach { workflowName, workflow ->\r
+\r
+            // Validate Single workflow\r
+            validateWorkFlow(workflowName, workflow)\r
+        }\r
+        paths.removeAt(paths.lastIndex)\r
+    }\r
+\r
+    @Throws(BluePrintException::class)\r
+    open fun validateWorkFlow(workflowName:String, workflow: Workflow) {\r
+        paths.add(workflowName)\r
+        message.appendln("---> Workflow :" + paths.joinToString(seperator))\r
+        // Step Validation Start\r
+        paths.add("steps")\r
+        workflow.steps?.forEach { stepName, step ->\r
+            paths.add(stepName)\r
+            message.appendln("----> Steps :" + paths.joinToString(seperator))\r
+            paths.removeAt(paths.lastIndex)\r
+        }\r
+        paths.removeAt(paths.lastIndex)\r
+        // Step Validation Ends\r
+        paths.removeAt(paths.lastIndex)\r
+    }\r
+\r
+    @Throws(BluePrintException::class)\r
+    open fun validatePropertyDefinitions(properties: MutableMap<String, PropertyDefinition>) {\r
+        paths.add("properties")\r
+        properties.forEach { propertyName, propertyDefinition ->\r
+            paths.add(propertyName)\r
+            val dataType: String = propertyDefinition.type!!\r
+            if (BluePrintTypes.validPrimitiveTypes().contains(dataType)) {\r
+                // Do Nothing\r
+            } else if (BluePrintTypes.validCollectionTypes().contains(dataType)) {\r
+                val entrySchemaType: String = propertyDefinition.entrySchema?.type\r
+                        ?: throw BluePrintException(format("Entry schema for data type ({}) for the property ({}) not found", dataType, propertyName))\r
+                checkPrimitiveOrComplex(entrySchemaType, propertyName)\r
+            } else {\r
+                checkPropertyDataType(dataType, propertyName)\r
+            }\r
+            message.appendln("property " + paths.joinToString(seperator) + " of type " + dataType)\r
+            paths.removeAt(paths.lastIndex)\r
+        }\r
+        paths.removeAt(paths.lastIndex)\r
+    }\r
+\r
+    @Throws(BluePrintException::class)\r
+    open fun validatePropertyAssignments(nodeTypeProperties: MutableMap<String, PropertyDefinition>,\r
+                                         properties: MutableMap<String, JsonNode>) {\r
+        properties.forEach { propertyName, propertyAssignment ->\r
+            val propertyDefinition: PropertyDefinition = nodeTypeProperties[propertyName]\r
+                    ?: throw BluePrintException(format("failed to get definition for the property ({})", propertyName))\r
+            // Check and Validate if Expression Node\r
+            val expressionData = BluePrintExpressionService.getExpressionData(propertyAssignment)\r
+            if (!expressionData.isExpression) {\r
+                checkPropertyValue(propertyDefinition, propertyAssignment)\r
+            }\r
+        }\r
+    }\r
+\r
+    @Throws(BluePrintException::class)\r
+    open fun validateArtifactDefinitions(artifacts: MutableMap<String, ArtifactDefinition>) {\r
+        paths.add("artifacts")\r
+        artifacts.forEach { artifactName, artifactDefinition ->\r
+            paths.add(artifactName)\r
+            message.appendln("Validating artifact " + paths.joinToString(seperator))\r
+            val type: String = artifactDefinition.type\r
+                    ?: throw BluePrintException("type is missing for artifact definition :" + artifactName)\r
+            // Check Artifact Type\r
+            checkValidArtifactType(type)\r
+\r
+            val file: String = artifactDefinition.file\r
+                    ?: throw BluePrintException(format("file is missing for artifact definition : {}", artifactName))\r
+\r
+            paths.removeAt(paths.lastIndex)\r
+        }\r
+        paths.removeAt(paths.lastIndex)\r
+    }\r
+\r
+    @Throws(BluePrintException::class)\r
+    open fun validateCapabilityAssignments(capabilities: MutableMap<String, CapabilityAssignment>) {\r
+\r
+    }\r
+\r
+    @Throws(BluePrintException::class)\r
+    open fun validateRequirementAssignments(requirements: MutableMap<String, RequirementAssignment>) {\r
+\r
+    }\r
+\r
+    @Throws(BluePrintException::class)\r
+    open fun validateInterfaceAssignments(interfaces: MutableMap<String, InterfaceAssignment>) {\r
+\r
+    }\r
+\r
+    @Throws(BluePrintException::class)\r
+    open fun validateInterfaceDefinitions(interfaces: MutableMap<String, InterfaceDefinition>) {\r
+        paths.add("interfaces")\r
+        interfaces.forEach { interfaceName, interfaceDefinition ->\r
+            paths.add(interfaceName)\r
+            message.appendln("Validating : " + paths.joinToString(seperator))\r
+            interfaceDefinition.operations?.let { validateOperationDefinitions(interfaceDefinition.operations!!) }\r
+            paths.removeAt(paths.lastIndex)\r
+        }\r
+        paths.removeAt(paths.lastIndex)\r
+    }\r
+\r
+    @Throws(BluePrintException::class)\r
+    open fun validateOperationDefinitions(operations: MutableMap<String, OperationDefinition>) {\r
+        paths.add("operations")\r
+        operations.forEach { opertaionName, operationDefinition ->\r
+            paths.add(opertaionName)\r
+            message.appendln("Validating : " + paths.joinToString(seperator))\r
+            operationDefinition.implementation?.let { validateImplementation(operationDefinition.implementation!!) }\r
+            operationDefinition.inputs?.let { validatePropertyDefinitions(operationDefinition.inputs!!) }\r
+            operationDefinition.outputs?.let { validatePropertyDefinitions(operationDefinition.outputs!!) }\r
+            paths.removeAt(paths.lastIndex)\r
+        }\r
+        paths.removeAt(paths.lastIndex)\r
+    }\r
+\r
+    @Throws(BluePrintException::class)\r
+    open fun validateImplementation(implementation: Implementation) {\r
+        checkNotEmptyNThrow(implementation.primary)\r
+    }\r
+\r
+    @Throws(BluePrintException::class)\r
+    open fun checkValidNodeType(nodeType : String) {\r
+\r
+    }\r
+\r
+    @Throws(BluePrintException::class)\r
+    open fun checkValidArtifactType(artifactType: String) {\r
+\r
+        serviceTemplate.artifactTypes?.containsKey(artifactType)\r
+                ?: throw BluePrintException(format("Failed to node type definition for artifact definition : {}", artifactType))\r
+    }\r
+\r
+    @Throws(BluePrintException::class)\r
+    open fun checkValidNodeTypesDerivedFrom(derivedFrom: String) {\r
+\r
+    }\r
+\r
+    private fun checkPropertyValue(propertyDefinition: PropertyDefinition, jsonNode: JsonNode) {\r
+        //logger.info("validating path ({}), Property {}, value ({})", paths, propertyDefinition, jsonNode)\r
+    }\r
+\r
+    private fun checkPropertyDataType(dataType: String, propertyName: String): Boolean {\r
+        if (checkDataType(dataType)) {\r
+            return true\r
+        } else {\r
+            throw BluePrintException(format("Data type ({}) for the property ({}) not found", dataType, propertyName))\r
+        }\r
+    }\r
+\r
+    private fun checkPrimitiveOrComplex(dataType: String, propertyName: String): Boolean {\r
+        if (BluePrintTypes.validPrimitiveTypes().contains(dataType) || checkDataType(dataType)) {\r
+            return true\r
+        } else {\r
+            throw BluePrintException(format("Data type ({}) for the property ({}) is not valid", dataType))\r
+        }\r
+    }\r
+\r
+    private fun checkDataType(key: String): Boolean {\r
+        return serviceTemplate.dataTypes?.containsKey(key) ?: false\r
+    }\r
+\r
+    private fun checkNodeType(key: String): Boolean {\r
+        return serviceTemplate.nodeTypes?.containsKey(key) ?: false\r
+    }\r
+\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/PropertyAssignmentService.kt b/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/PropertyAssignmentService.kt
new file mode 100644 (file)
index 0000000..9389a6f
--- /dev/null
@@ -0,0 +1,198 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core.service\r
+\r
+\r
+import com.fasterxml.jackson.databind.JsonNode\r
+import com.fasterxml.jackson.databind.node.NullNode\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.*\r
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils\r
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.ResourceResolverUtils\r
+import org.slf4j.Logger\r
+import org.slf4j.LoggerFactory\r
+/**\r
+ *\r
+ *\r
+ * @author Brinda Santh\r
+ */\r
+class PropertyAssignmentService(var context: MutableMap<String, Any>,\r
+                                var bluePrintRuntimeService: BluePrintRuntimeService) {\r
+    private val logger: Logger = LoggerFactory.getLogger(this::class.toString())\r
+\r
+    private var bluePrintContext: BluePrintContext = bluePrintRuntimeService.bluePrintContext\r
+\r
+/*\r
+\r
+If Property Assignment is Expression.\r
+    Get the Expression\r
+    Recurssely resolve the expression\r
+ */\r
+\r
+    fun resolveAssignmentExpression(nodeTemplateName: String, assignmentName: String,\r
+                                            assignment: Any): JsonNode {\r
+        var valueNode: JsonNode = NullNode.getInstance()\r
+        logger.trace("Assignment ({})", assignment)\r
+        val expressionData = BluePrintExpressionService.getExpressionData(assignment)\r
+\r
+        if (expressionData.isExpression) {\r
+            valueNode = resolveExpression(nodeTemplateName, assignmentName, expressionData)\r
+        } else {\r
+            valueNode = expressionData.valueNode\r
+        }\r
+        return valueNode\r
+    }\r
+\r
+    fun resolveExpression(nodeTemplateName: String, propName: String, expressionData: ExpressionData): JsonNode {\r
+\r
+        var valueNode: JsonNode = NullNode.getInstance()\r
+\r
+        if(expressionData.isExpression) {\r
+            val command = expressionData.command!!\r
+\r
+            when(command){\r
+                org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.EXPRESSION_GET_INPUT ->{\r
+                    valueNode = bluePrintRuntimeService.getInputValue(expressionData.inputExpression?.propertyName!!)\r
+                }\r
+                org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.EXPRESSION_GET_ATTRIBUTE ->{\r
+                    valueNode = resolveAttributeExpression(nodeTemplateName, expressionData.attributeExpression!!)\r
+                }\r
+                org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.EXPRESSION_GET_PROPERTY ->{\r
+                    valueNode = resolvePropertyExpression(nodeTemplateName, expressionData.propertyExpression!!)\r
+                }\r
+                org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.EXPRESSION_GET_OPERATION_OUTPUT ->{\r
+                    valueNode = resolveOperationOutputExpression(nodeTemplateName, expressionData.operationOutputExpression!!)\r
+                }\r
+                org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.EXPRESSION_GET_ARTIFACT ->{\r
+                    valueNode = resolveArtifactExpression(nodeTemplateName, expressionData.artifactExpression!!)\r
+                }\r
+                org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.EXPRESSION_GET_NODE_OF_TYPE ->{\r
+\r
+                }\r
+                else ->{\r
+                    throw BluePrintException(String.format("for property ({}), command ({}) is not supported ", propName, command))\r
+                }\r
+            }\r
+        }\r
+        return valueNode\r
+    }\r
+\r
+    /*\r
+    get_property: [ <modelable_entity_name>, <optional_req_or_cap_name>, <property_name>,\r
+    <nested_property_name_or_index_1>, ..., <nested_property_name_or_index_n> ]\r
+ */\r
+    fun resolveAttributeExpression(nodeTemplateName: String, attributeExpression: AttributeExpression): JsonNode {\r
+        var valueNode: JsonNode = NullNode.getInstance()\r
+\r
+        val attributeName = attributeExpression.attributeName\r
+        val subAttributeName: String? = attributeExpression.subAttributeName\r
+\r
+        var attributeNodeTemplateName = nodeTemplateName\r
+        if (!attributeExpression.modelableEntityName.equals("SELF", true)) {\r
+            attributeNodeTemplateName = attributeExpression.modelableEntityName\r
+        }\r
+\r
+        val attributeExpression = bluePrintContext.nodeTemplateByName(attributeNodeTemplateName).attributes?.get(attributeName)\r
+                ?: throw BluePrintException(String.format("failed to get property definitions for node template ({})'s property name ({}) ", nodeTemplateName, attributeName))\r
+\r
+        var propertyDefinition: AttributeDefinition = bluePrintContext.nodeTemplateNodeType(attributeNodeTemplateName).attributes?.get(attributeName)!!\r
+\r
+        logger.info("template name ({}), property Name ({}) resolved value ({})", attributeNodeTemplateName, attributeName, attributeExpression)\r
+\r
+        // Check it it is a nested expression\r
+        valueNode = resolveAssignmentExpression(attributeNodeTemplateName, attributeName, attributeExpression)\r
+\r
+//        subPropertyName?.let {\r
+//            valueNode = valueNode.at(JsonPointer.valueOf(subPropertyName))\r
+//        }\r
+        return valueNode\r
+    }\r
+\r
+    /*\r
+        get_property: [ <modelable_entity_name>, <optional_req_or_cap_name>, <property_name>,\r
+        <nested_property_name_or_index_1>, ..., <nested_property_name_or_index_n> ]\r
+     */\r
+    fun resolvePropertyExpression(nodeTemplateName: String, propertyExpression: PropertyExpression): JsonNode {\r
+        var valueNode: JsonNode = NullNode.getInstance()\r
+\r
+        val propertyName = propertyExpression.propertyName\r
+        val subPropertyName: String? = propertyExpression.subPropertyName\r
+\r
+        var propertyNodeTemplateName = nodeTemplateName\r
+        if (!propertyExpression.modelableEntityName.equals("SELF", true)) {\r
+            propertyNodeTemplateName = propertyExpression.modelableEntityName\r
+        }\r
+\r
+        val propertyExpression = bluePrintContext.nodeTemplateByName(propertyNodeTemplateName).properties?.get(propertyName)\r
+                ?: throw BluePrintException(String.format("failed to get property definitions for node template ({})'s property name ({}) ", nodeTemplateName, propertyName))\r
+\r
+        var propertyDefinition: PropertyDefinition = bluePrintContext.nodeTemplateNodeType(propertyNodeTemplateName).properties?.get(propertyName)!!\r
+\r
+        logger.info("template name ({}), property Name ({}) resolved value ({})", propertyNodeTemplateName, propertyName, propertyExpression)\r
+\r
+        // Check it it is a nested expression\r
+        valueNode = resolveAssignmentExpression(propertyNodeTemplateName, propertyName, propertyExpression)\r
+\r
+//        subPropertyName?.let {\r
+//            valueNode = valueNode.at(JsonPointer.valueOf(subPropertyName))\r
+//        }\r
+        return valueNode\r
+    }\r
+\r
+    /*\r
+    get_operation_output: <modelable_entity_name>, <interface_name>, <operation_name>, <output_variable_name>\r
+     */\r
+    fun resolveOperationOutputExpression(nodeTemplateName: String, operationOutputExpression: OperationOutputExpression): JsonNode {\r
+        var outputNodeTemplateName = nodeTemplateName\r
+        if (!operationOutputExpression.modelableEntityName.equals("SELF", true)) {\r
+            outputNodeTemplateName = operationOutputExpression.modelableEntityName\r
+        }\r
+        return bluePrintRuntimeService.getNodeTemplateOperationOutputValue(outputNodeTemplateName,\r
+                operationOutputExpression.interfaceName, operationOutputExpression.operationName,\r
+                operationOutputExpression.propertyName)\r
+    }\r
+\r
+    /*\r
+    get_artifact: [ <modelable_entity_name>, <artifact_name>, <location>, <remove> ]\r
+     */\r
+    fun resolveArtifactExpression(nodeTemplateName: String,  artifactExpression: ArtifactExpression): JsonNode {\r
+\r
+        var artifactNodeTemplateName = nodeTemplateName\r
+        if (!artifactExpression.modelableEntityName.equals("SELF", true)) {\r
+            artifactNodeTemplateName = artifactExpression.modelableEntityName\r
+        }\r
+        val artifactDefinition: ArtifactDefinition = bluePrintContext.nodeTemplateByName(artifactNodeTemplateName)\r
+                .artifacts?.get(artifactExpression.artifactName)\r
+                ?: throw BluePrintException(String.format("failed to get artifact definitions for node template ({})'s " +\r
+                        "artifact name ({}) ", nodeTemplateName, artifactExpression.artifactName))\r
+\r
+        return JacksonUtils.jsonNodeFromObject(artifactContent(artifactDefinition))\r
+    }\r
+\r
+    fun artifactContent(artifactDefinition: ArtifactDefinition): String {\r
+        val bluePrintBasePath: String = context[org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PROPERTY_BLUEPRINT_BASE_PATH] as? String\r
+                ?: throw BluePrintException(String.format("failed to get property (%s) from context", org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.PROPERTY_BLUEPRINT_BASE_PATH))\r
+\r
+        if (artifactDefinition.repository != null) {\r
+            TODO()\r
+        } else if (artifactDefinition.file != null) {\r
+            return ResourceResolverUtils.getFileContent(artifactDefinition.file!!, bluePrintBasePath)\r
+        }\r
+        return ""\r
+    }\r
+}\r
+\r
diff --git a/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/BluePrintMetadataUtils.kt b/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/BluePrintMetadataUtils.kt
new file mode 100644 (file)
index 0000000..a9236f6
--- /dev/null
@@ -0,0 +1,95 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core.utils\r
+\r
+\r
+import org.apache.commons.io.FileUtils\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.ToscaMetaData\r
+import org.slf4j.Logger\r
+import org.slf4j.LoggerFactory\r
+import java.io.File\r
+import java.nio.charset.Charset\r
+\r
+object BluePrintMetadataUtils {\r
+    private val logger: Logger = LoggerFactory.getLogger(this::class.toString())\r
+\r
+    @JvmStatic\r
+    fun toscaMetaData(basePath: String): ToscaMetaData {\r
+        val toscaMetaPath = basePath.plus(BluePrintConstants.PATH_DIVIDER).plus("TOSCA-Metadata/TOSCA.meta")\r
+        return toscaMetaDataFromMetaFile(toscaMetaPath)\r
+    }\r
+\r
+    @JvmStatic\r
+    fun toscaMetaDataFromMetaFile(metaFilePath: String): ToscaMetaData {\r
+        val toscaMetaData = ToscaMetaData()\r
+        val lines: MutableList<String> = FileUtils.readLines(File(metaFilePath), Charset.defaultCharset())\r
+        lines.forEach { line ->\r
+            if (line.contains(":")) {\r
+                val keyValue = line.split(":")\r
+                if (keyValue.size == 2) {\r
+                    val value: String = keyValue[1].trim()\r
+                    when (keyValue[0]) {\r
+                        "TOSCA-Meta-File-Version" -> toscaMetaData.toscaMetaFileVersion = value\r
+                        "CSAR-Version" -> toscaMetaData.csarVersion = value\r
+                        "Created-By" -> toscaMetaData.createdBy = value\r
+                        "Entry-Definitions" -> toscaMetaData.entityDefinitions = value\r
+                        "Template-Tags" -> toscaMetaData.templateTags = value\r
+                    }\r
+                }\r
+            }\r
+\r
+        }\r
+        return toscaMetaData\r
+    }\r
+\r
+    /*\r
+    fun getBluePrintContext(blueprintBasePath: String): BluePrintContext {\r
+\r
+        val metaDataFile = StringBuilder().append(blueprintBasePath).append(File.separator)\r
+                .append(BluePrintConstants.DEFAULT_TOSCA_METADATA_ENTRY_DEFINITION_FILE).toString()\r
+\r
+        val toscaMetaData: ToscaMetaData = BluePrintMetadataUtils.toscaMetaData(metaDataFile)\r
+\r
+        logger.info("Processing blueprint base path ({}) and entry definition file ({})", blueprintBasePath, toscaMetaData.entityDefinitions)\r
+\r
+        return BluePrintParserFactory.instance(BluePrintConstants.TYPE_DEFAULT)!!\r
+                .readBlueprintFile(toscaMetaData.entityDefinitions!!, blueprintBasePath)\r
+    }\r
+\r
+    fun getBluePrintRuntime(requestId: String, blueprintBasePath: String): BluePrintRuntimeService {\r
+\r
+        val metaDataFile = StringBuilder().append(blueprintBasePath).append(File.separator)\r
+                .append(BluePrintConstants.DEFAULT_TOSCA_METADATA_ENTRY_DEFINITION_FILE).toString()\r
+\r
+        val toscaMetaData: ToscaMetaData = BluePrintMetadataUtils.toscaMetaData(metaDataFile)\r
+\r
+        logger.info("Processing blueprint base path ({}) and entry definition file ({})", blueprintBasePath, toscaMetaData.entityDefinitions)\r
+\r
+        val bluePrintContext: BluePrintContext = BluePrintParserFactory.instance(BluePrintConstants.TYPE_DEFAULT)!!\r
+                .readBlueprintFile(toscaMetaData.entityDefinitions!!, blueprintBasePath)\r
+\r
+        val context: MutableMap<String, Any> = hashMapOf()\r
+        context[BluePrintConstants.PROPERTY_BLUEPRINT_BASE_PATH] = blueprintBasePath\r
+        context[BluePrintConstants.PROPERTY_BLUEPRINT_PROCESS_ID] = requestId\r
+\r
+        val bluePrintRuntimeService: BluePrintRuntimeService = BluePrintRuntimeService(bluePrintContext, context)\r
+\r
+        return bluePrintRuntimeService\r
+    }\r
+    */\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/BluePrintRuntimeUtils.kt b/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/BluePrintRuntimeUtils.kt
new file mode 100644 (file)
index 0000000..bad9201
--- /dev/null
@@ -0,0 +1,55 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core.utils\r
+\r
+import com.fasterxml.jackson.databind.JsonNode\r
+import com.fasterxml.jackson.databind.node.NullNode\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants\r
+import org.onap.ccsdk.apps.controllerblueprints.core.service.BluePrintContext\r
+import org.slf4j.Logger\r
+import org.slf4j.LoggerFactory\r
+\r
+/**\r
+ *\r
+ *\r
+ * @author Brinda Santh\r
+ */\r
+object BluePrintRuntimeUtils {\r
+    private val logger: Logger = LoggerFactory.getLogger(this::class.toString())\r
+\r
+    fun assignInputsFromFile(bluePrintContext: BluePrintContext, fileName: String, context: MutableMap<String, Any>) {\r
+        val jsonNode: JsonNode = JacksonUtils.jsonNodeFromFile(fileName)\r
+        return assignInputs(bluePrintContext, jsonNode, context)\r
+    }\r
+\r
+    fun assignInputsFromContent(bluePrintContext: BluePrintContext, content: String, context: MutableMap<String, Any>) {\r
+        val jsonNode: JsonNode = JacksonUtils.jsonNode(content)\r
+        return assignInputs(bluePrintContext, jsonNode, context)\r
+    }\r
+\r
+    fun assignInputs(bluePrintContext: BluePrintContext, jsonNode: JsonNode, context: MutableMap<String, Any>) {\r
+        logger.info("assignInputs from input JSON ({})", jsonNode.toString())\r
+        bluePrintContext.inputs?.forEach { propertyName, property ->\r
+            val valueNode: JsonNode = jsonNode.at("/".plus(propertyName)) ?: NullNode.getInstance()\r
+\r
+            val path = BluePrintConstants.PATH_INPUTS.plus(BluePrintConstants.PATH_DIVIDER).plus(propertyName)\r
+            logger.trace("setting input path ({}), values ({})", path, valueNode)\r
+            context[path] = valueNode\r
+        }\r
+    }\r
+\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/JacksonUtils.kt b/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/JacksonUtils.kt
new file mode 100644 (file)
index 0000000..95b2af7
--- /dev/null
@@ -0,0 +1,179 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core.utils\r
+\r
+import com.fasterxml.jackson.annotation.JsonInclude\r
+import com.fasterxml.jackson.core.type.TypeReference\r
+import com.fasterxml.jackson.databind.JsonNode\r
+import com.fasterxml.jackson.databind.SerializationFeature\r
+import com.fasterxml.jackson.databind.node.ArrayNode\r
+import com.fasterxml.jackson.databind.node.NullNode\r
+import com.fasterxml.jackson.databind.node.ObjectNode\r
+import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper\r
+import org.apache.commons.io.FileUtils\r
+import org.apache.commons.io.IOUtils\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintTypes\r
+import org.onap.ccsdk.apps.controllerblueprints.core.format\r
+import org.slf4j.LoggerFactory\r
+import java.io.File\r
+import java.nio.charset.Charset\r
+\r
+/**\r
+ *\r
+ *\r
+ * @author Brinda Santh\r
+ */\r
+object JacksonUtils {\r
+    private val log = LoggerFactory.getLogger(JacksonUtils::class.java)\r
+\r
+    inline fun <reified T : Any> readValue(content: String): T =\r
+            jacksonObjectMapper().readValue(content, T::class.java)\r
+\r
+    @JvmStatic\r
+    fun <T> readValue(content: String, valueType: Class<T>): T? {\r
+        return jacksonObjectMapper().readValue(content, valueType)\r
+    }\r
+\r
+    @JvmStatic\r
+    fun jsonNodeFromObject(from: kotlin.Any): JsonNode = jacksonObjectMapper().convertValue(from, JsonNode::class.java)\r
+\r
+    @JvmStatic\r
+    fun jsonNodeFromClassPathFile(fileName: String): JsonNode {\r
+        val content: String = IOUtils.toString(JacksonUtils::class.java.classLoader.getResourceAsStream(fileName), Charset.defaultCharset())\r
+                ?: throw BluePrintException(String.format("Failed to read json file : %s", fileName))\r
+        return jsonNode(content)\r
+    }\r
+\r
+    @JvmStatic\r
+    fun jsonNodeFromFile(fileName: String): JsonNode {\r
+        val content: String = FileUtils.readFileToString(File(fileName), Charset.defaultCharset())\r
+                ?: throw BluePrintException(format("Failed to read json file : {}", fileName))\r
+        return jsonNode(content)\r
+    }\r
+\r
+    @JvmStatic\r
+    fun jsonNode(content: String): JsonNode {\r
+        return jacksonObjectMapper().readTree(content)\r
+    }\r
+\r
+    @JvmStatic\r
+    fun getJson(any: kotlin.Any): String {\r
+        return getJson(any, false)\r
+    }\r
+\r
+    @JvmStatic\r
+    fun getJson(any: kotlin.Any, pretty: Boolean = false): String {\r
+        val objectMapper = jacksonObjectMapper()\r
+        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)\r
+        if (pretty) {\r
+            objectMapper.enable(SerializationFeature.INDENT_OUTPUT)\r
+        }\r
+        return objectMapper.writeValueAsString(any)\r
+    }\r
+\r
+    @JvmStatic\r
+    fun <T> getListFromJson(content: String, valueType: Class<T>): List<T>? {\r
+        val objectMapper = jacksonObjectMapper()\r
+        val javaType = objectMapper.typeFactory.constructCollectionType(List::class.java, valueType)\r
+        return objectMapper.readValue<List<T>>(content, javaType)\r
+    }\r
+\r
+    @JvmStatic\r
+    fun <T> getMapFromJson(content: String, valueType: Class<T>): MutableMap<String, T>? {\r
+        val objectMapper = jacksonObjectMapper()\r
+        val typeRef = object : TypeReference<MutableMap<String, T>>() {}\r
+        return objectMapper.readValue(content, typeRef)\r
+    }\r
+\r
+    @JvmStatic\r
+    fun populatePrimitiveValues(key: String, value: Any, primitiveType: String, objectNode: ObjectNode) {\r
+        if (org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.DATA_TYPE_BOOLEAN == primitiveType) {\r
+            objectNode.put(key, value as Boolean)\r
+        } else if (org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.DATA_TYPE_INTEGER == primitiveType) {\r
+            objectNode.put(key, value as Int)\r
+        } else if (org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.DATA_TYPE_FLOAT == primitiveType) {\r
+            objectNode.put(key, value as Float)\r
+        } else if (org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.DATA_TYPE_TIMESTAMP == primitiveType) {\r
+            objectNode.put(key, value as String)\r
+        } else {\r
+            objectNode.put(key, value as String)\r
+        }\r
+    }\r
+\r
+    @JvmStatic\r
+    fun populatePrimitiveValues(value: Any, primitiveType: String, objectNode: ArrayNode) {\r
+        if (org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.DATA_TYPE_BOOLEAN == primitiveType) {\r
+            objectNode.add(value as Boolean)\r
+        } else if (org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.DATA_TYPE_INTEGER == primitiveType) {\r
+            objectNode.add(value as Int)\r
+        } else if (org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.DATA_TYPE_FLOAT == primitiveType) {\r
+            objectNode.add(value as Float)\r
+        } else if (org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.DATA_TYPE_TIMESTAMP == primitiveType) {\r
+            objectNode.add(value as String)\r
+        } else {\r
+            objectNode.add(value as String)\r
+        }\r
+    }\r
+\r
+    @JvmStatic\r
+    fun populatePrimitiveDefaultValues(key: String, primitiveType: String, objectNode: ObjectNode) {\r
+        if (org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.DATA_TYPE_BOOLEAN == primitiveType) {\r
+            objectNode.put(key, false)\r
+        } else if (org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.DATA_TYPE_INTEGER == primitiveType) {\r
+            objectNode.put(key, 0)\r
+        } else if (org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.DATA_TYPE_FLOAT == primitiveType) {\r
+            objectNode.put(key, 0.0)\r
+        } else {\r
+            objectNode.put(key, "")\r
+        }\r
+    }\r
+\r
+    @JvmStatic\r
+    fun populatePrimitiveDefaultValuesForArrayNode(primitiveType: String, arrayNode: ArrayNode) {\r
+        if (org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.DATA_TYPE_BOOLEAN == primitiveType) {\r
+            arrayNode.add(false)\r
+        } else if (org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.DATA_TYPE_INTEGER == primitiveType) {\r
+            arrayNode.add(0)\r
+        } else if (org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.DATA_TYPE_FLOAT == primitiveType) {\r
+            arrayNode.add(0.0)\r
+        } else {\r
+            arrayNode.add("")\r
+        }\r
+    }\r
+\r
+    @JvmStatic\r
+    fun populateJsonNodeValues(key: String, nodeValue: JsonNode?, type: String, objectNode: ObjectNode) {\r
+        if (nodeValue == null || nodeValue is NullNode) {\r
+            objectNode.set(key, nodeValue)\r
+        } else if (BluePrintTypes.validPrimitiveTypes().contains(type)) {\r
+            if (org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.DATA_TYPE_BOOLEAN == type) {\r
+                objectNode.put(key, nodeValue.asBoolean())\r
+            } else if (org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.DATA_TYPE_INTEGER == type) {\r
+                objectNode.put(key, nodeValue.asInt())\r
+            } else if (org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.DATA_TYPE_FLOAT == type) {\r
+                objectNode.put(key, nodeValue.floatValue())\r
+            } else if (org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.DATA_TYPE_TIMESTAMP == type) {\r
+                objectNode.put(key, nodeValue.asText())\r
+            } else {\r
+                objectNode.put(key, nodeValue.asText())\r
+            }\r
+        } else {\r
+            objectNode.set(key, nodeValue)\r
+        }\r
+    }\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/ResourceResolverUtils.kt b/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/ResourceResolverUtils.kt
new file mode 100644 (file)
index 0000000..a267455
--- /dev/null
@@ -0,0 +1,62 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core.utils\r
+\r
+import org.apache.commons.io.FileUtils\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException\r
+import org.onap.ccsdk.apps.controllerblueprints.core.checkNotEmpty\r
+import org.slf4j.Logger\r
+import org.slf4j.LoggerFactory\r
+import java.io.File\r
+import java.net.URL\r
+import java.nio.charset.Charset\r
+/**\r
+ *\r
+ *\r
+ * @author Brinda Santh\r
+ */\r
+object ResourceResolverUtils {\r
+    private val logger: Logger = LoggerFactory.getLogger(this::class.toString())\r
+\r
+    @JvmStatic\r
+    fun getFileContent(filename : String, basePath : String?): String {\r
+        logger.trace("file ({}), basePath ({}) ", filename, basePath)\r
+        try{\r
+            var resolvedFileName : String = filename\r
+            if(filename.startsWith("http", true)\r
+                    || filename.startsWith("https", true)){\r
+                val givenUrl : String = URL(filename).toString()\r
+                val systemUrl : String = File(".").toURI().toURL().toString()\r
+                logger.trace("givenUrl ({}), systemUrl ({}) ", givenUrl, systemUrl)\r
+                if(givenUrl.startsWith(systemUrl)){\r
+\r
+                }\r
+            }else{\r
+                if(!filename.startsWith("/")){\r
+                    if (checkNotEmpty(basePath)) {\r
+                        resolvedFileName = basePath.plus(File.separator).plus(filename)\r
+                    }else{\r
+                        resolvedFileName = javaClass.classLoader.getResource(".").path.plus(filename)\r
+                    }\r
+                }\r
+            }\r
+            return FileUtils.readFileToString(File(resolvedFileName), Charset.defaultCharset())\r
+        }catch (e : Exception){\r
+            throw BluePrintException(e, "failed to file (%s), basePath (%s) ", filename, basePath)\r
+        }\r
+    }\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/ServiceTemplateUtils.kt b/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/ServiceTemplateUtils.kt
new file mode 100644 (file)
index 0000000..2fcb9b2
--- /dev/null
@@ -0,0 +1,44 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core.utils\r
+\r
+import org.apache.commons.io.FileUtils\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.ServiceTemplate\r
+import java.io.File\r
+import java.nio.charset.Charset\r
+\r
+/**\r
+ *\r
+ *\r
+ * @author Brinda Santh\r
+ */\r
+object ServiceTemplateUtils {\r
+\r
+    @JvmStatic\r
+    fun getServiceTemplate(fileName: String): ServiceTemplate {\r
+        val content: String = FileUtils.readFileToString(File(fileName), Charset.defaultCharset())\r
+        return getServiceTemplateFromContent(content)\r
+    }\r
+\r
+\r
+    @JvmStatic\r
+    fun getServiceTemplateFromContent(content: String): ServiceTemplate {\r
+        return JacksonUtils.readValue<ServiceTemplate>(content)\r
+    }\r
+\r
+\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/TopologicalSortingUtils.kt b/ms/controllerblueprints/modules/core/src/main/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/TopologicalSortingUtils.kt
new file mode 100644 (file)
index 0000000..dcafa97
--- /dev/null
@@ -0,0 +1,131 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core.utils\r
+\r
+import java.util.*\r
+\r
+/**\r
+ *\r
+ *\r
+ * @author Brinda Santh\r
+ */\r
+class TopologicalSortingUtils<V> {\r
+\r
+    private val neighbors: MutableMap<V, MutableList<V>> = hashMapOf()\r
+\r
+    val isDag: Boolean\r
+        get() = topSort() != null\r
+\r
+    override fun toString(): String {\r
+        val s = StringBuffer()\r
+        for (v in neighbors.keys)\r
+            s.append("\n    " + v + " -> " + neighbors[v])\r
+        return s.toString()\r
+    }\r
+\r
+    fun getNeighbors(): Map<V, List<V>> {\r
+        return neighbors\r
+    }\r
+\r
+    fun add(vertex: V) {\r
+        if (neighbors.containsKey(vertex))\r
+            return\r
+        neighbors[vertex] = arrayListOf()\r
+    }\r
+\r
+    operator fun contains(vertex: V): Boolean {\r
+        return neighbors.containsKey(vertex)\r
+    }\r
+\r
+    fun add(from: V, to: V) {\r
+        this.add(from)\r
+        this.add(to)\r
+        neighbors[from]?.add(to)\r
+    }\r
+\r
+    fun remove(from: V, to: V) {\r
+        if (!(this.contains(from) && this.contains(to)))\r
+            throw IllegalArgumentException("Nonexistent vertex")\r
+        neighbors[from]?.remove(to)\r
+    }\r
+\r
+    fun outDegree(): Map<V, Int> {\r
+        var result: MutableMap<V, Int> = hashMapOf()\r
+        for (v in neighbors.keys)\r
+            result[v] = neighbors[v]!!.size\r
+        return result\r
+    }\r
+\r
+\r
+    fun inDegree(): MutableMap<V, Int> {\r
+        val result = HashMap<V, Int>()\r
+        for (v in neighbors.keys)\r
+            result[v] = 0       // All in-degrees are 0\r
+        for (from in neighbors.keys) {\r
+            for (to in neighbors[from]!!) {\r
+                result[to] = result[to]!! + 1           // Increment in-degree\r
+            }\r
+        }\r
+        return result\r
+    }\r
+\r
+    fun topSort(): List<V>? {\r
+        val degree = inDegree()\r
+        // Determine all vertices with zero in-degree\r
+        val zeroVerts = Stack<V>()        // Stack as good as any here\r
+        for (v in degree.keys) {\r
+            if (degree[v] == 0) zeroVerts.push(v)\r
+        }\r
+        // Determine the topological order\r
+        val result = ArrayList<V>()\r
+        while (!zeroVerts.isEmpty()) {\r
+            val v = zeroVerts.pop()                  // Choose a vertex with zero in-degree\r
+            result.add(v)                          // Vertex v is next in topol order\r
+            // "Remove" vertex v by updating its neighbors\r
+            for (neighbor in neighbors[v]!!) {\r
+                degree[neighbor] = degree[neighbor]!! - 1\r
+                // Remember any vertices that now have zero in-degree\r
+                if (degree[neighbor] == 0) zeroVerts.push(neighbor)\r
+            }\r
+        }\r
+        // Check that we have used the entire graph (if not, there was a cycle)\r
+        return if (result.size != neighbors.size) null else result\r
+    }\r
+\r
+\r
+    fun bfsDistance(start: V): Map<*, *> {\r
+        var distance: MutableMap<V, Int> = hashMapOf()\r
+        // Initially, all distance are infinity, except start node\r
+        for (v in neighbors.keys)\r
+            distance[v] = -1\r
+        distance[start] = 0\r
+        // Process nodes in queue order\r
+        val queue = LinkedList<V>()\r
+        queue.offer(start)                                    // Place start node in queue\r
+        while (!queue.isEmpty()) {\r
+            val v = queue.remove()\r
+            val vDist = distance[v]!!\r
+            // Update neighbors\r
+            for (neighbor in neighbors[v]!!) {\r
+                if (distance[neighbor] != null) continue  // Ignore if already done\r
+                distance[neighbor] = vDist + 1\r
+                queue.offer(neighbor)\r
+            }\r
+        }\r
+        return distance\r
+    }\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/CustomFunctionsTest.kt b/ms/controllerblueprints/modules/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/CustomFunctionsTest.kt
new file mode 100644 (file)
index 0000000..128b7f5
--- /dev/null
@@ -0,0 +1,35 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core\r
+\r
+import org.junit.Test\r
+import kotlin.test.assertEquals\r
+/**\r
+ *\r
+ *\r
+ * @author Brinda Santh\r
+ */\r
+class CustomFunctionsTest {\r
+    @Test\r
+    fun testFormat(): Unit {\r
+        val returnValue : String = format("This is {} for times {}", "test", 2)\r
+        assertEquals("This is test for times 2", returnValue, "Failed to format String")\r
+\r
+        val returnValue1 : String = format("This is test for times 2")\r
+        assertEquals("This is test for times 2", returnValue1, "Failed to format empty args")\r
+    }\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintContextTest.kt b/ms/controllerblueprints/modules/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintContextTest.kt
new file mode 100644 (file)
index 0000000..0b2b39c
--- /dev/null
@@ -0,0 +1,70 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core.service\r
+\r
+\r
+import org.apache.commons.io.FileUtils\r
+import org.junit.Before\r
+import org.junit.Test\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants\r
+import org.onap.ccsdk.apps.controllerblueprints.core.factory.BluePrintParserFactory\r
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils\r
+import org.slf4j.Logger\r
+import org.slf4j.LoggerFactory\r
+import java.io.File\r
+import java.nio.charset.Charset\r
+import kotlin.test.assertNotNull\r
+/**\r
+ *\r
+ *\r
+ * @author Brinda Santh\r
+ */\r
+class BluePrintContextTest {\r
+\r
+    private val logger: Logger = LoggerFactory.getLogger(this::class.toString())\r
+\r
+    lateinit var bluePrintContext: BluePrintContext\r
+\r
+    @Before\r
+    fun setUp() {\r
+\r
+        val basepath = "load/blueprints"\r
+\r
+        bluePrintContext = BluePrintParserFactory.instance(BluePrintConstants.TYPE_DEFAULT)!!\r
+                .readBlueprintFile("baseconfiguration/Definitions/activation-blueprint.json", basepath)\r
+        assertNotNull(bluePrintContext, "Failed to populate Blueprint context")\r
+    }\r
+\r
+    @Test\r
+    fun testBluePrintContextFromContent() {\r
+        val fileName = "load/blueprints/baseconfiguration/Definitions/activation-blueprint.json"\r
+        val content : String = FileUtils.readFileToString(File(fileName), Charset.defaultCharset())\r
+        val bpContext  = BluePrintParserFactory.instance(BluePrintConstants.TYPE_DEFAULT)!!\r
+                .readBlueprint(content)\r
+        assertNotNull(bpContext, "Failed to get blueprint content")\r
+        assertNotNull(bpContext.serviceTemplate, "Failed to get blueprint content's service template")\r
+    }\r
+\r
+    @Test\r
+    fun testChainedProperty() {\r
+        val nodeType = bluePrintContext.nodeTypeChained("component-resource-assignment")\r
+        assertNotNull(nodeType, "Failed to get chained node type")\r
+        logger.trace("Properties {}", JacksonUtils.getJson(nodeType, true))\r
+    }\r
+\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintEnhancerRepoFileServiceTest.kt b/ms/controllerblueprints/modules/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintEnhancerRepoFileServiceTest.kt
new file mode 100644 (file)
index 0000000..ef4384f
--- /dev/null
@@ -0,0 +1,51 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core.service\r
+\r
+import org.junit.Test\r
+import kotlin.test.assertNotNull\r
+\r
+/**\r
+ * BluePrintEnhancerRepoFileServiceTest\r
+ * @author Brinda Santh\r
+ *\r
+ */\r
+class BluePrintEnhancerRepoFileServiceTest {\r
+\r
+    val basePath = "load/model_type"\r
+\r
+    @Test\r
+    fun testGetDataType() {\r
+        val bluePrintEnhancerRepoFileService = BluePrintEnhancerRepoFileService(basePath)\r
+        val dataType = bluePrintEnhancerRepoFileService.getDataType("dt-v4-aggregate")\r
+        assertNotNull(dataType, "Failed to get DataType from repo")\r
+    }\r
+\r
+    @Test\r
+    fun testGetNodeType() {\r
+        val bluePrintEnhancerRepoFileService = BluePrintEnhancerRepoFileService(basePath)\r
+        val nodeType = bluePrintEnhancerRepoFileService.getNodeType("component-resource-assignment")\r
+        assertNotNull(nodeType, "Failed to get NodeType from repo")\r
+    }\r
+\r
+    @Test\r
+    fun testGetArtifactType() {\r
+        val bluePrintEnhancerRepoFileService = BluePrintEnhancerRepoFileService(basePath)\r
+        val nodeType = bluePrintEnhancerRepoFileService.getArtifactType("artifact-template-velocity")\r
+        assertNotNull(nodeType, "Failed to get ArtifactType from repo")\r
+    }\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintEnhancerServiceTest.kt b/ms/controllerblueprints/modules/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintEnhancerServiceTest.kt
new file mode 100644 (file)
index 0000000..6fc1853
--- /dev/null
@@ -0,0 +1,40 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core.service\r
+\r
+import org.junit.Test\r
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.ServiceTemplateUtils\r
+\r
+/**\r
+ * BluePrintEnhancerServiceTest\r
+ * @author Brinda Santh\r
+ *\r
+ */\r
+\r
+class BluePrintEnhancerServiceTest {\r
+    val basePath = "load/model_type"\r
+\r
+    @Test\r
+    fun testEnrichBlueprint() {\r
+        val bluePrintEnhancerRepoFileService = BluePrintEnhancerRepoFileService(basePath)\r
+        val bluePrintEnhancerService: BluePrintEnhancerService = BluePrintEnhancerDefaultService(bluePrintEnhancerRepoFileService)\r
+\r
+        val serviceTemplate = ServiceTemplateUtils.getServiceTemplate("load/blueprints/simple-baseconfig/Definitions/simple-baseconfig.json")\r
+        bluePrintEnhancerService.enhance(serviceTemplate)\r
+\r
+    }\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintExpressionServiceTest.kt b/ms/controllerblueprints/modules/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintExpressionServiceTest.kt
new file mode 100644 (file)
index 0000000..911a891
--- /dev/null
@@ -0,0 +1,109 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core.service\r
+\r
+import com.fasterxml.jackson.databind.JsonNode\r
+import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper\r
+import org.junit.Test\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.ExpressionData\r
+import kotlin.test.assertEquals\r
+import kotlin.test.assertNotNull\r
+/**\r
+ *\r
+ *\r
+ * @author Brinda Santh\r
+ */\r
+class BluePrintExpressionServiceTest {\r
+    @Test\r
+    fun testInputExpression() {\r
+        val node : JsonNode = jacksonObjectMapper().readTree("{ \"get_input\" : \"input-name\" }")\r
+        val expressionData : ExpressionData = BluePrintExpressionService.getExpressionData(node)\r
+        assertNotNull(expressionData, " Failed to populate expression data")\r
+        assertEquals(expressionData.isExpression, true, "Failed to identify as expression")\r
+        assertNotNull(expressionData.inputExpression, " Failed to populate input expression data")\r
+        assertEquals("input-name", expressionData.inputExpression?.propertyName, "Failed to get propertyName from expression data")\r
+    }\r
+\r
+    @Test\r
+    fun testPropertyExpression() {\r
+        val node : JsonNode = jacksonObjectMapper().readTree("{ \"get_property\" : [\"SELF\", \"property-name\"] }")\r
+        val expressionData : ExpressionData = BluePrintExpressionService.getExpressionData(node)\r
+        assertNotNull(expressionData, " Failed to populate expression data")\r
+        assertEquals(expressionData.isExpression, true, "Failed to identify as expression")\r
+        assertNotNull(expressionData.propertyExpression, " Failed to populate property expression data")\r
+        assertEquals("SELF", expressionData.propertyExpression?.modelableEntityName, " Failed to get expected modelableEntityName")\r
+        assertEquals("property-name", expressionData.propertyExpression?.propertyName, " Failed to get expected propertyName")\r
+\r
+        val node1 : JsonNode = jacksonObjectMapper().readTree("{ \"get_property\" : [\"SELF\", \"\",\"property-name\", \"resource\", \"name\"] }")\r
+        val expressionData1  : ExpressionData  = BluePrintExpressionService.getExpressionData(node1)\r
+        assertNotNull(expressionData1, " Failed to populate expression data")\r
+        assertEquals(expressionData1.isExpression, true, "Failed to identify as nested property expression")\r
+        assertNotNull(expressionData1.propertyExpression, " Failed to populate nested property expression data")\r
+        assertEquals("SELF", expressionData1.propertyExpression?.modelableEntityName, " Failed to get expected modelableEntityName")\r
+        assertEquals("property-name", expressionData1.propertyExpression?.propertyName, " Failed to get expected propertyName")\r
+        assertEquals("resource/name",expressionData1.propertyExpression?.subPropertyName, " Failed to populate nested subPropertyName expression data")\r
+    }\r
+\r
+    @Test\r
+    fun testAttributeExpression() {\r
+        val node : JsonNode = jacksonObjectMapper().readTree("{ \"get_attribute\" : [\"SELF\", \"\",\"attribute-name\", \"resource\", \"name\"] }")\r
+        val expressionData : ExpressionData = BluePrintExpressionService.getExpressionData(node)\r
+        assertNotNull(expressionData, " Failed to populate expression data")\r
+        assertEquals(expressionData.isExpression, true, "Failed to identify as expression")\r
+        assertNotNull(expressionData.attributeExpression, " Failed to populate attribute expression data")\r
+        assertEquals("SELF", expressionData.attributeExpression?.modelableEntityName, " Failed to get expected modelableEntityName")\r
+        assertEquals("attribute-name", expressionData.attributeExpression?.attributeName, " Failed to get expected attributeName")\r
+        assertEquals("resource/name",expressionData.attributeExpression?.subAttributeName, " Failed to populate nested subAttributeName expression data")\r
+    }\r
+\r
+\r
+    @Test\r
+    fun testOutputOperationExpression() {\r
+        val node : JsonNode = jacksonObjectMapper().readTree("{ \"get_operation_output\": [\"SELF\", \"interface-name\", \"operation-name\", \"output-property-name\"] }")\r
+        val expressionData : ExpressionData = BluePrintExpressionService.getExpressionData(node)\r
+        assertNotNull(expressionData, " Failed to populate expression data")\r
+        assertEquals(expressionData.isExpression, true, "Failed to identify as expression")\r
+        assertNotNull(expressionData.operationOutputExpression, " Failed to populate output expression data")\r
+        assertEquals("SELF", expressionData.operationOutputExpression?.modelableEntityName, " Failed to get expected modelableEntityName")\r
+        assertEquals("interface-name", expressionData.operationOutputExpression?.interfaceName, " Failed to get expected interfaceName")\r
+        assertEquals("operation-name", expressionData.operationOutputExpression?.operationName, " Failed to get expected operationName")\r
+        assertEquals("output-property-name", expressionData.operationOutputExpression?.propertyName, " Failed to get expected propertyName")\r
+    }\r
+\r
+\r
+    @Test\r
+    fun testArtifactExpression() {\r
+        val node : JsonNode = jacksonObjectMapper().readTree("{ \"get_artifact\" : [\"SELF\", \"artifact-template\"] }")\r
+        val expressionData : ExpressionData = BluePrintExpressionService.getExpressionData(node)\r
+        assertNotNull(expressionData, " Failed to populate expression data")\r
+        assertEquals(expressionData.isExpression, true, "Failed to identify as expression")\r
+        assertNotNull(expressionData.artifactExpression, " Failed to populate Artifact expression data")\r
+        assertEquals("SELF", expressionData.artifactExpression?.modelableEntityName, " Failed to get expected modelableEntityName")\r
+        assertEquals("artifact-template", expressionData.artifactExpression?.artifactName, " Failed to get expected artifactName")\r
+\r
+\r
+        val node1 : JsonNode = jacksonObjectMapper().readTree("{ \"get_artifact\" : [\"SELF\", \"artifact-template\", \"location\", true] }")\r
+        val expressionData1 : ExpressionData = BluePrintExpressionService.getExpressionData(node1)\r
+        assertNotNull(expressionData1, " Failed to populate expression data")\r
+        assertEquals(expressionData1.isExpression, true, "Failed to identify as expression")\r
+        assertNotNull(expressionData1.artifactExpression, " Failed to populate Artifact expression data")\r
+        assertEquals("SELF", expressionData1.artifactExpression?.modelableEntityName, " Failed to get expected modelableEntityName")\r
+        assertEquals("artifact-template", expressionData1.artifactExpression?.artifactName, " Failed to get expected artifactName")\r
+        assertEquals("location", expressionData1.artifactExpression?.location, " Failed to get expected location")\r
+        assertEquals(true, expressionData1.artifactExpression?.remove, " Failed to get expected remove")\r
+    }\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintParserFactoryTest.kt b/ms/controllerblueprints/modules/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintParserFactoryTest.kt
new file mode 100644 (file)
index 0000000..0f211ab
--- /dev/null
@@ -0,0 +1,42 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core.service\r
+\r
+import org.junit.Test\r
+import org.onap.ccsdk.apps.controllerblueprints.core.factory.BluePrintParserFactory\r
+import org.slf4j.Logger\r
+import org.slf4j.LoggerFactory\r
+import kotlin.test.assertNotNull\r
+\r
+/**\r
+ *\r
+ *\r
+ * @author Brinda Santh\r
+ */\r
+class BluePrintParserFactoryTest {\r
+    private val logger: Logger = LoggerFactory.getLogger(this::class.toString())\r
+\r
+    @Test\r
+    fun testBluePrintJson() {\r
+        val basepath = "load/blueprints"\r
+\r
+        val bluePrintContext: BluePrintContext = BluePrintParserFactory.instance(org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants.TYPE_DEFAULT)!!\r
+                .readBlueprintFile("baseconfiguration/Definitions/activation-blueprint.json", basepath)\r
+        assertNotNull(bluePrintContext, "Failed to populate Blueprint context")\r
+        logger.trace("Blue Print {}",bluePrintContext.blueprintJson(true))\r
+    }\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintRuntimeServiceTest.kt b/ms/controllerblueprints/modules/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintRuntimeServiceTest.kt
new file mode 100644 (file)
index 0000000..8ed161a
--- /dev/null
@@ -0,0 +1,131 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core.service\r
+\r
+import com.fasterxml.jackson.databind.JsonNode\r
+import com.fasterxml.jackson.databind.node.NullNode\r
+import org.junit.Before\r
+import org.junit.Test\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants\r
+import org.onap.ccsdk.apps.controllerblueprints.core.factory.BluePrintParserFactory\r
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.BluePrintRuntimeUtils\r
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils.jsonNodeFromFile\r
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils.jsonNodeFromObject\r
+import org.slf4j.Logger\r
+import org.slf4j.LoggerFactory\r
+import kotlin.test.assertEquals\r
+import kotlin.test.assertNotNull\r
+\r
+/**\r
+ *\r
+ *\r
+ * @author Brinda Santh\r
+ */\r
+class BluePrintRuntimeServiceTest {\r
+    private val logger: Logger = LoggerFactory.getLogger(this::class.toString())\r
+    val basepath = "load/blueprints"\r
+\r
+\r
+    @Before\r
+    fun setUp(): Unit {\r
+\r
+    }\r
+\r
+    @Test\r
+    fun testResolveNodeTemplateProperties() {\r
+        logger.info("************************ testResolveNodeTemplateProperties **********************")\r
+        val bluePrintContext: BluePrintContext = BluePrintParserFactory.instance(BluePrintConstants.TYPE_DEFAULT)!!\r
+                .readBlueprintFile("baseconfiguration/Definitions/activation-blueprint.json", basepath)\r
+\r
+        val context: MutableMap<String, Any> = hashMapOf()\r
+        context[BluePrintConstants.PROPERTY_BLUEPRINT_BASE_PATH] = basepath.plus("/simple-baseconfig")\r
+        val bluePrintRuntimeService = BluePrintRuntimeService(bluePrintContext, context)\r
+\r
+        val inputDataPath =  "src/test/resources/data/default-context.json"\r
+\r
+        val inputNode: JsonNode = jsonNodeFromFile(inputDataPath)\r
+        bluePrintRuntimeService.assignInputs(inputNode)\r
+\r
+        val propContext: MutableMap<String, Any?> = bluePrintRuntimeService.resolveNodeTemplateProperties("activate-process")\r
+        logger.info("Context {}" ,bluePrintRuntimeService.context)\r
+\r
+        assertNotNull(propContext, "Failed to populate interface property values")\r
+        assertEquals(propContext.get("process-name"), jsonNodeFromObject("sample-action"), "Failed to populate parameter process-name")\r
+        assertEquals(propContext.get("version"), jsonNodeFromObject("sample-action"), "Failed to populate parameter version")\r
+    }\r
+\r
+    @Test\r
+    fun testResolveNodeTemplateInterfaceOperationInputs() {\r
+        logger.info("************************ testResolveNodeTemplateInterfaceOperationInputs **********************")\r
+        val bluePrintContext: BluePrintContext = BluePrintParserFactory.instance(BluePrintConstants.TYPE_DEFAULT)!!\r
+                .readBlueprintFile("baseconfiguration/Definitions/activation-blueprint.json", basepath)\r
+        assertNotNull(bluePrintContext, "Failed to populate Blueprint context")\r
+\r
+        val context: MutableMap<String, Any> = hashMapOf()\r
+        context[BluePrintConstants.PROPERTY_BLUEPRINT_BASE_PATH] = basepath.plus("/simple-baseconfig")\r
+\r
+        val inputDataPath =  "src/test/resources/data/default-context.json"\r
+        BluePrintRuntimeUtils.assignInputsFromFile(bluePrintContext, inputDataPath, context)\r
+\r
+\r
+        val bluePrintRuntimeService = BluePrintRuntimeService(bluePrintContext, context)\r
+\r
+        logger.info("Prepared Context {}" ,context)\r
+\r
+        val inContext: MutableMap<String, Any?> = bluePrintRuntimeService.resolveNodeTemplateInterfaceOperationInputs("resource-assignment",\r
+                "DefaultComponentNode", "process")\r
+\r
+        logger.trace("In Context {}" ,inContext)\r
+\r
+        assertNotNull(inContext, "Failed to populate interface input property values")\r
+        assertEquals(inContext.get("action-name"), jsonNodeFromObject("sample-action"), "Failed to populate parameter action-name")\r
+        assertEquals(inContext.get("request-id"), jsonNodeFromObject("12345"), "Failed to populate parameter action-name")\r
+        assertEquals(inContext.get("template-content"), jsonNodeFromObject("This is Sample Velocity Template"), "Failed to populate parameter action-name")\r
+\r
+    }\r
+\r
+    @Test\r
+    fun testResolveNodeTemplateInterfaceOperationOutputs() {\r
+        logger.info("************************ testResolveNodeTemplateInterfaceOperationOutputs **********************")\r
+        val bluePrintContext: BluePrintContext = BluePrintParserFactory.instance(BluePrintConstants.TYPE_DEFAULT)!!\r
+                .readBlueprintFile("baseconfiguration/Definitions/activation-blueprint.json", basepath)\r
+        assertNotNull(bluePrintContext, "Failed to populate Blueprint context")\r
+\r
+        val context: MutableMap<String, Any> = hashMapOf()\r
+        context[BluePrintConstants.PROPERTY_BLUEPRINT_BASE_PATH] =  basepath.plus("/simple-baseconfig")\r
+\r
+        val bluePrintRuntimeService = BluePrintRuntimeService(bluePrintContext, context)\r
+\r
+        val componentContext: MutableMap<String, Any?> = hashMapOf()\r
+        val successValue : JsonNode= jsonNodeFromObject("Success")\r
+        componentContext["resource-assignment.DefaultComponentNode.process.status"] = successValue\r
+        componentContext["resource-assignment.DefaultComponentNode.process.resource-assignment-params"] = null\r
+\r
+        bluePrintRuntimeService.resolveNodeTemplateInterfaceOperationOutputs("resource-assignment",\r
+                "DefaultComponentNode", "process", componentContext)\r
+\r
+        assertEquals(NullNode.instance,\r
+                context.get("node_templates/resource-assignment/interfaces/DefaultComponentNode/operations/process/properties/resource-assignment-params"),\r
+                "Failed to get operation property resource-assignment-params")\r
+\r
+        assertEquals(successValue,\r
+                context.get("node_templates/resource-assignment/interfaces/DefaultComponentNode/operations/process/properties/status"),\r
+                "Failed to get operation property status")\r
+\r
+\r
+    }\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintValidatorDefaultServiceTest.kt b/ms/controllerblueprints/modules/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/service/BluePrintValidatorDefaultServiceTest.kt
new file mode 100644 (file)
index 0000000..bccd946
--- /dev/null
@@ -0,0 +1,48 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core.service\r
+\r
+import org.junit.Before\r
+import org.junit.Test\r
+import org.onap.ccsdk.apps.controllerblueprints.core.factory.BluePrintParserFactory\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants\r
+import org.slf4j.Logger\r
+import org.slf4j.LoggerFactory\r
+/**\r
+ *\r
+ *\r
+ * @author Brinda Santh\r
+ */\r
+class BluePrintValidatorDefaultServiceTest {\r
+    private val logger: Logger = LoggerFactory.getLogger(this::class.toString())\r
+    val basepath = "load/blueprints"\r
+\r
+    @Before\r
+    fun setUp(): Unit {\r
+\r
+    }\r
+\r
+    @Test\r
+    fun testValidateBluePrint() {\r
+        val bluePrintContext: BluePrintContext = BluePrintParserFactory.instance(BluePrintConstants.TYPE_DEFAULT)!!\r
+                .readBlueprintFile("baseconfiguration/Definitions/activation-blueprint.json",  basepath)\r
+        val properties : MutableMap<String, Any> = hashMapOf()\r
+        val validatorService = BluePrintValidatorDefaultService()\r
+        validatorService.validateBlueprint(bluePrintContext.serviceTemplate,properties)\r
+        logger.info("Validation Message {}", properties)\r
+    }\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/BluePrintMetadataUtilsTest.kt b/ms/controllerblueprints/modules/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/BluePrintMetadataUtilsTest.kt
new file mode 100644 (file)
index 0000000..ddb39a2
--- /dev/null
@@ -0,0 +1,40 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core.utils\r
+\r
+\r
+import org.junit.Test\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.ToscaMetaData\r
+import kotlin.test.assertNotNull\r
+\r
+class BluePrintMetadataUtilsTest {\r
+    \r
+    @Test\r
+    fun testToscaMetaData(){\r
+\r
+        val basePath : String = "load/blueprints/baseconfiguration"\r
+\r
+        val toscaMetaData : ToscaMetaData =  BluePrintMetadataUtils.toscaMetaData(basePath)\r
+        assertNotNull(toscaMetaData, "Missing Tosca Definition Object")\r
+        assertNotNull(toscaMetaData.toscaMetaFileVersion, "Missing Tosca Metadata Version")\r
+        assertNotNull(toscaMetaData.csarVersion, "Missing CSAR version")\r
+        assertNotNull(toscaMetaData.createdBy, "Missing Created by")\r
+        assertNotNull(toscaMetaData.entityDefinitions, "Missing Tosca Entity Definition")\r
+        assertNotNull(toscaMetaData.templateTags, "Missing Template Tags")\r
+\r
+    }\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/JacksonUtilsTest.kt b/ms/controllerblueprints/modules/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/JacksonUtilsTest.kt
new file mode 100644 (file)
index 0000000..28f3b39
--- /dev/null
@@ -0,0 +1,71 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core.utils\r
+\r
+import com.fasterxml.jackson.databind.JsonNode\r
+import org.junit.Test\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.ServiceTemplate\r
+import org.slf4j.Logger\r
+import org.slf4j.LoggerFactory\r
+import kotlin.test.assertEquals\r
+import kotlin.test.assertNotNull\r
+\r
+/**\r
+ * JacksonUtilsTest\r
+ * @author Brinda Santh\r
+ * ${DATA}\r
+ */\r
+class JacksonUtilsTest {\r
+\r
+    private val logger: Logger = LoggerFactory.getLogger(this::class.toString())\r
+\r
+    val basePath = "load/blueprints"\r
+\r
+    @Test\r
+    fun testReadValues() {\r
+        val content = ResourceResolverUtils.getFileContent("baseconfiguration/Definitions/activation-blueprint.json", basePath)\r
+        val serviceTemplate = JacksonUtils.readValue(content, ServiceTemplate::class.java)\r
+        assertNotNull(serviceTemplate, "Failed to simple transform Service Template")\r
+        assertEquals(true, serviceTemplate is ServiceTemplate, "failed to get Service Template instance")\r
+\r
+        val jsonContent = JacksonUtils.getJson(serviceTemplate!!, true)\r
+        assertNotNull(jsonContent, "Failed to get json content")\r
+    }\r
+\r
+    @Test\r
+    fun testJsonNodeFromClassPathFile() {\r
+        val filePath = "data/default-context.json"\r
+        val jsonNode = JacksonUtils.jsonNodeFromClassPathFile(filePath)\r
+        assertNotNull(jsonNode, "Failed to get json node from file")\r
+        assertEquals(true, jsonNode is JsonNode, "failed to get JSON node instance")\r
+    }\r
+\r
+    @Test\r
+    fun testJsonNodeFromFile() {\r
+        val filePath =  basePath + "/baseconfiguration/Definitions/activation-blueprint.json"\r
+        val jsonNode = JacksonUtils.jsonNodeFromFile(filePath)\r
+        assertNotNull(jsonNode, "Failed to get json node from file")\r
+        assertEquals(true, jsonNode is JsonNode, "failed to get JSON node instance")\r
+    }\r
+\r
+    @Test\r
+    fun testGetListFromJson() {\r
+        val content = "[\"good\",\"boy\" ]"\r
+        val nodeType = JacksonUtils.getListFromJson(content, String::class.java)\r
+        assertNotNull(nodeType, "Failed to get String array from content")\r
+    }\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/TopologicalSortingUtilsTest.kt b/ms/controllerblueprints/modules/core/src/test/kotlin/org/onap/ccsdk/apps/controllerblueprints/core/utils/TopologicalSortingUtilsTest.kt
new file mode 100644 (file)
index 0000000..907eb2e
--- /dev/null
@@ -0,0 +1,36 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.core.utils\r
+\r
+import org.junit.Test\r
+\r
+class TopologicalSortingUtilsTest {\r
+    \r
+    @Test\r
+    fun testSorting(): Unit {\r
+        val graph: TopologicalSortingUtils<String> = TopologicalSortingUtils<String>()\r
+        graph.add("bundle-id", "bundle-mac")\r
+        graph.add("bundle-id", "bundle-ip")\r
+        graph.add("bundle-mac", "bundle-ip")\r
+        graph.add("bundle-ip", "bundle-mac")\r
+\r
+        println("The current graph: " + graph)\r
+        println("In-degrees: " + graph.inDegree())\r
+        println("Out-degrees: " + graph.outDegree())\r
+        println("A topological sort of the vertices: " + graph.topSort())\r
+    }\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/src/test/resources/componentnode/default.json b/ms/controllerblueprints/modules/core/src/test/resources/componentnode/default.json
new file mode 100644 (file)
index 0000000..b7265fc
--- /dev/null
@@ -0,0 +1,100 @@
+{\r
+       "metadata": {\r
+               "template_author": "bs2796",\r
+               "vendor": "Juniper",\r
+               "os": "XXX",\r
+               "service-type": "AVPN",\r
+               "vnf-type": "VRR",\r
+               "action": "Base Configuration",\r
+               "sub-action": "Generate Configuration",\r
+               "template_name": "VRR-baseconfiguration",\r
+               "template_version": "1.0.0"\r
+       },\r
+       "topology_template": {\r
+               "inputs": {\r
+                       "service-instance-id": {\r
+                               "required": true,\r
+                               "type": "string"\r
+                       },\r
+                       "vnf-id": {\r
+                               "required": true,\r
+                               "type": "string"\r
+                       },\r
+                       "service": {\r
+                               "required": true,\r
+                               "type": "string"\r
+                       },\r
+                       "region": {\r
+                               "required": true,\r
+                               "type": "string"\r
+                       },\r
+                       "bundle-id": {\r
+                               "required": true,\r
+                               "type": "string"\r
+                       },\r
+                       "bundle-mac": {\r
+                               "required": true,\r
+                               "type": "string"\r
+                       }\r
+               },\r
+               "node_templates": {\r
+                       "generate-configuration": {\r
+                               "type": "mock-component-generateConfig",\r
+                               "interfaces": {\r
+                                       "org-openecomp-sdnc-config-params-service-MockComponentNode": {\r
+                                               "operations": {\r
+                                                       "process": {\r
+                                                               "inputs": {\r
+                                                                       "entity-type": "vnf-type",\r
+                                                                       "template-content": "sample-template",\r
+                                                                       "entity-id": "{ \"get_input\" : \"vnf-id\" }"\r
+                                                               },\r
+                                                               "outputs": {\r
+                                                                       "mergedData": "merged Data",\r
+                                                                       "status": "status"\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       },\r
+       "node_types": {\r
+               "mock-component-generateConfig": {\r
+                       "interfaces": {\r
+                               "org-openecomp-sdnc-config-params-service-MockComponentNode": {\r
+                                       "operations": {\r
+                                               "process": {\r
+                                                       "inputs": {\r
+                                                               "entity-type": {\r
+                                                                       "required": false,\r
+                                                                       "type": "string"\r
+                                                               },\r
+                                                               "template-content": {\r
+                                                                       "required": false,\r
+                                                                       "type": "string"\r
+                                                               },\r
+                                                               "entity-id": {\r
+                                                                       "required": true,\r
+                                                                       "type": "string"\r
+                                                               }\r
+                                                       },\r
+                                                       "outputs": {\r
+                                                               "generated-config": {\r
+                                                                       "required": true,\r
+                                                                       "type": "string"\r
+                                                               },\r
+                                                               "status": {\r
+                                                                       "required": true,\r
+                                                                       "type": "string"\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+                       },\r
+                       "derived_from": "tosca.nodes.Component"\r
+               }\r
+       }\r
+}\r
diff --git a/ms/controllerblueprints/modules/core/src/test/resources/data/default-context.json b/ms/controllerblueprints/modules/core/src/test/resources/data/default-context.json
new file mode 100644 (file)
index 0000000..fcd4cbe
--- /dev/null
@@ -0,0 +1,5 @@
+{\r
+  "request-id" : "12345",\r
+  "hostname" : "localhost",\r
+  "action-name" : "sample-action"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/core/src/test/resources/dictionary/dictionary_schema.json b/ms/controllerblueprints/modules/core/src/test/resources/dictionary/dictionary_schema.json
new file mode 100644 (file)
index 0000000..d031700
--- /dev/null
@@ -0,0 +1,261 @@
+{\r
+       "type": "object",\r
+       "properties": {\r
+               "resource-path": {\r
+                       "type": "string",\r
+                       "required": true\r
+               },\r
+               "description": {\r
+                       "type": "string"\r
+               },\r
+               "updated-by": {\r
+                       "type": "string"\r
+               },\r
+               "data-type": {\r
+                       "type": "string",\r
+                       "required": true\r
+               },\r
+               "source": {\r
+                       "type": "object",\r
+                       "required": true,\r
+                       "properties": {\r
+                               "input": {\r
+                                       "type": "object",\r
+                                       "properties": {\r
+                                               "key": {\r
+                                                       "type": "string"\r
+                                               }\r
+                                       }\r
+                               },\r
+                               "component": {\r
+                                       "type": "object",\r
+                                       "properties": {\r
+                                               "name": {\r
+                                                       "type": "string",\r
+                                                       "required": true\r
+                                               },\r
+                                               "input-key-mapping": {\r
+                                                       "type": "object",\r
+                                                       "additionalProperties": {\r
+                                                               "type": "string"\r
+                                                       }\r
+                                               },\r
+                                               "output-key-mapping": {\r
+                                                       "type": "object",\r
+                                                       "additionalProperties": {\r
+                                                               "type": "string"\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               },\r
+                               "default": {\r
+                                       "type": "any"\r
+                               },\r
+                               "aai": {\r
+                                       "type": "any"\r
+                               },\r
+                               "mdsal": {\r
+                                       "type": "object",\r
+                                       "properties": {\r
+                                               "path": {\r
+                                                       "type": "string",\r
+                                                       "required": true\r
+                                               },\r
+                                               "url-path": {\r
+                                                       "type": "string",\r
+                                                       "required": true\r
+                                               },\r
+                                               "input-key-mapping": {\r
+                                                       "type": "object",\r
+                                                       "additionalProperties": {\r
+                                                               "type": "string"\r
+                                                       }\r
+                                               },\r
+                                               "type": {\r
+                                                       "type": "string",\r
+                                                       "required": true\r
+                                               },\r
+                                               "output-key-mapping": {\r
+                                                       "type": "object",\r
+                                                       "additionalProperties": {\r
+                                                               "type": "string"\r
+                                                       }\r
+                                               },\r
+                                               "base": {\r
+                                                       "type": "string",\r
+                                                       "required": true\r
+                                               }\r
+                                       }\r
+                               },\r
+                               "network-resource-discovery": {\r
+                                       "type": "object",\r
+                                       "properties": {\r
+                                               "input-key-mapping": {\r
+                                                       "type": "object",\r
+                                                       "additionalProperties": {\r
+                                                               "type": "string"\r
+                                                       }\r
+                                               },\r
+                                               "output-key-mapping": {\r
+                                                       "type": "object",\r
+                                                       "additionalProperties": {\r
+                                                               "type": "string"\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               },\r
+                               "db": {\r
+                                       "type": "object",\r
+                                       "properties": {\r
+                                               "query": {\r
+                                                       "type": "string",\r
+                                                       "required": true\r
+                                               },\r
+                                               "input-key-mapping": {\r
+                                                       "type": "object",\r
+                                                       "additionalProperties": {\r
+                                                               "type": "string"\r
+                                                       }\r
+                                               },\r
+                                               "type": {\r
+                                                       "type": "string",\r
+                                                       "required": true\r
+                                               },\r
+                                               "output-key-mapping": {\r
+                                                       "type": "object",\r
+                                                       "additionalProperties": {\r
+                                                               "type": "string"\r
+                                                       }\r
+                                               },\r
+                                               "base": {\r
+                                                       "type": "string",\r
+                                                       "required": true\r
+                                               }\r
+                                       }\r
+                               },\r
+                               "policy": {\r
+                                       "type": "object",\r
+                                       "properties": {\r
+                                               "input-key-mapping": {\r
+                                                       "type": "object",\r
+                                                       "additionalProperties": {\r
+                                                               "type": "string"\r
+                                                       }\r
+                                               },\r
+                                               "output-key-mapping": {\r
+                                                       "type": "object",\r
+                                                       "additionalProperties": {\r
+                                                               "type": "string"\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+               },\r
+               "candidate-dependency": {\r
+                       "type": "object",\r
+                       "properties": {\r
+                               "input": {\r
+                                       "type": "object",\r
+                                       "properties": {\r
+                                               "names": {\r
+                                                       "type": "array",\r
+                                                       "items": {\r
+                                                               "type": "string"\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               },\r
+                               "component": {\r
+                                       "type": "object",\r
+                                       "properties": {\r
+                                               "names": {\r
+                                                       "type": "array",\r
+                                                       "items": {\r
+                                                               "type": "string"\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               },\r
+                               "aai": {\r
+                                       "type": "object",\r
+                                       "properties": {\r
+                                               "names": {\r
+                                                       "type": "array",\r
+                                                       "items": {\r
+                                                               "type": "string"\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               },\r
+                               "mdsal": {\r
+                                       "type": "object",\r
+                                       "properties": {\r
+                                               "names": {\r
+                                                       "type": "array",\r
+                                                       "items": {\r
+                                                               "type": "string"\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               },\r
+                               "network-resource-discovery": {\r
+                                       "type": "object",\r
+                                       "properties": {\r
+                                               "names": {\r
+                                                       "type": "array",\r
+                                                       "items": {\r
+                                                               "type": "string"\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               },\r
+                               "db": {\r
+                                       "type": "object",\r
+                                       "properties": {\r
+                                               "names": {\r
+                                                       "type": "array",\r
+                                                       "items": {\r
+                                                               "type": "string"\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               },\r
+                               "policy": {\r
+                                       "type": "object",\r
+                                       "properties": {\r
+                                               "names": {\r
+                                                       "type": "array",\r
+                                                       "items": {\r
+                                                               "type": "string"\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+               },\r
+               "tags": {\r
+                       "type": "string"\r
+               },\r
+               "default": {\r
+                       "type": "any"\r
+               },\r
+               "name": {\r
+                       "type": "string",\r
+                       "required": true\r
+               },\r
+               "valid-values": {\r
+                       "type": "string"\r
+               },\r
+               "resource-type": {\r
+                       "type": "string",\r
+                       "required": true\r
+               },\r
+               "sample-value": {\r
+                       "type": "string"\r
+               },\r
+               "entry-schema": {\r
+                       "type": "string"\r
+               }\r
+       }\r
+}\r
diff --git a/ms/controllerblueprints/modules/core/src/test/resources/properties/convert.json b/ms/controllerblueprints/modules/core/src/test/resources/properties/convert.json
new file mode 100644 (file)
index 0000000..cb7d08e
--- /dev/null
@@ -0,0 +1,33 @@
+{\r
+       "type": "sdnc-component-getResourceAssignment",\r
+       "interfaces": {\r
+               "ResourceAssignmentService": {\r
+                       "operations": {\r
+                               "getResourceAssignment": {\r
+                                       "inputs": {\r
+                                               "assignment-mappings": [\r
+                                                       {\r
+                                                               "name": "service-name",\r
+                                                               "mapping-field": "service",\r
+                                                               "mapping-category": "SDN",\r
+                                                               "required": true\r
+                                                       },\r
+                                                       {\r
+                                                               "name": "region-name",\r
+                                                               "mapping-field": "region",\r
+                                                               "mapping-category": "SDN",\r
+                                                               "required": true\r
+                                                       }\r
+                                               ],\r
+                                               "pre-data": "{ \"get_attribute\" : \"get-resource-assignment.config-params\" }",\r
+                                               "prifix": "get-resource-assignment"\r
+                                       },\r
+                                       "outputs": {\r
+                                               "resource-assignment-status": "success",\r
+                                               "resource-assignment-params": "{ \"set_value\" : \"get-resource-assignment.config-params\" }"\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+}\r
diff --git a/ms/controllerblueprints/modules/core/src/test/resources/properties/default.json b/ms/controllerblueprints/modules/core/src/test/resources/properties/default.json
new file mode 100644 (file)
index 0000000..0ac97f9
--- /dev/null
@@ -0,0 +1,16 @@
+{\r
+       "default": "{ \"get_input\" : \"loopback-default\" }",\r
+       "domain": "ethernet",\r
+       "criteria": [\r
+               {\r
+                       "value": "attga301me1",\r
+                       "type": "complex",\r
+                       "nodeString": "layer3-service-list[].service-data.l3sdn-vnf-fields.vnf-name"\r
+               },\r
+               {\r
+                       "value": "{ \"get_input\" : \"host-ip-address\" }",\r
+                       "type": "simple",\r
+                       "nodeString": "layer3-service-list[].service-data.l3sdn-vnf-fields.vnf-name"\r
+               }\r
+       ]\r
+}\r
diff --git a/ms/controllerblueprints/modules/pom.xml b/ms/controllerblueprints/modules/pom.xml
new file mode 100644 (file)
index 0000000..9e7215b
--- /dev/null
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+  ~ Copyright © 2017-2018 AT&T Intellectual Property.\r
+  ~\r
+  ~ Licensed under the Apache License, Version 2.0 (the "License");\r
+  ~ you may not use this file except in compliance with the License.\r
+  ~ You may obtain a copy of the License at\r
+  ~\r
+  ~     http://www.apache.org/licenses/LICENSE-2.0\r
+  ~\r
+  ~ Unless required by applicable law or agreed to in writing, software\r
+  ~ distributed under the License is distributed on an "AS IS" BASIS,\r
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+  ~ See the License for the specific language governing permissions and\r
+  ~ limitations under the License.\r
+  -->\r
+\r
+<project\r
+        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"\r
+        xmlns="http://maven.apache.org/POM/4.0.0"\r
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
+    <modelVersion>4.0.0</modelVersion>\r
+    <parent>\r
+        <groupId>org.onap.ccsdk.apps</groupId>\r
+        <artifactId>controllerblueprints-parent</artifactId>\r
+        <version>0.3.0-SNAPSHOT</version>\r
+        <relativePath>../parent</relativePath>\r
+    </parent>\r
+    <artifactId>controllerblueprints-modules</artifactId>\r
+    <name>Controller Blueprints Modules</name>\r
+    <packaging>pom</packaging>\r
+\r
+    <modules>\r
+        <module>core</module>\r
+        <module>resource-dict</module>\r
+        <module>service</module>\r
+    </modules>\r
+\r
+    <build>\r
+        <plugins>\r
+            <plugin>\r
+                <artifactId>maven-compiler-plugin</artifactId>\r
+                <version>3.1</version>\r
+                <configuration>\r
+                    <!-- <skip>${skip.compile}</skip>-->\r
+                    <source>1.8</source>\r
+                    <target>1.8</target>\r
+                </configuration>\r
+            </plugin>\r
+        </plugins>\r
+    </build>\r
+\r
+</project>\r
+\r
diff --git a/ms/controllerblueprints/modules/resource-dict/pom.xml b/ms/controllerblueprints/modules/resource-dict/pom.xml
new file mode 100644 (file)
index 0000000..a0d1be6
--- /dev/null
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+  ~ Copyright © 2017-2018 AT&T Intellectual Property.\r
+  ~\r
+  ~ Licensed under the Apache License, Version 2.0 (the "License");\r
+  ~ you may not use this file except in compliance with the License.\r
+  ~ You may obtain a copy of the License at\r
+  ~\r
+  ~     http://www.apache.org/licenses/LICENSE-2.0\r
+  ~\r
+  ~ Unless required by applicable law or agreed to in writing, software\r
+  ~ distributed under the License is distributed on an "AS IS" BASIS,\r
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+  ~ See the License for the specific language governing permissions and\r
+  ~ limitations under the License.\r
+  -->\r
+\r
+<project\r
+        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"\r
+        xmlns="http://maven.apache.org/POM/4.0.0"\r
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
+    <modelVersion>4.0.0</modelVersion>\r
+    <parent>\r
+        <groupId>org.onap.ccsdk.apps</groupId>\r
+        <artifactId>controllerblueprints-modules</artifactId>\r
+        <version>0.3.0-SNAPSHOT</version>\r
+    </parent>\r
+    <artifactId>controllerblueprints-resource-dict</artifactId>\r
+    <name>Controller Blueprints Resource Dictionary</name>\r
+\r
+    <dependencies>\r
+        <dependency>\r
+            <groupId>org.onap.ccsdk.apps</groupId>\r
+            <artifactId>controllerblueprints-core</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>junit</groupId>\r
+            <artifactId>junit</artifactId>\r
+            <scope>test</scope>\r
+        </dependency>\r
+\r
+\r
+    </dependencies>\r
+\r
+\r
+</project>\r
+\r
diff --git a/ms/controllerblueprints/modules/resource-dict/src/main/java/org/onap/ccsdk/apps/controllerblueprints/resource/dict/ResourceAssignment.java b/ms/controllerblueprints/modules/resource-dict/src/main/java/org/onap/ccsdk/apps/controllerblueprints/resource/dict/ResourceAssignment.java
new file mode 100644 (file)
index 0000000..15576b9
--- /dev/null
@@ -0,0 +1,167 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.resource.dict;\r
+\r
+import com.fasterxml.jackson.annotation.JsonFormat;\r
+import com.fasterxml.jackson.annotation.JsonProperty;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.PropertyDefinition;\r
+\r
+import java.util.Date;\r
+import java.util.List;\r
+\r
+/**\r
+ * ResourceAssignment.java Purpose: Provide ResourceAssignment Custom TOSCO Model POJO bean.\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+public class ResourceAssignment {\r
+\r
+    private String name;\r
+\r
+    @JsonProperty("property")\r
+    private PropertyDefinition property;\r
+\r
+    @JsonProperty("input-param")\r
+    private Boolean inputParameter;\r
+\r
+    @JsonProperty("dictionary-name")\r
+    private String dictionaryName;\r
+\r
+    @JsonProperty("dictionary-source")\r
+    private String dictionarySource;\r
+\r
+    @JsonProperty("dependencies")\r
+    private List<String> dependencies;\r
+\r
+    @JsonProperty("version")\r
+    private int version;\r
+\r
+    @JsonProperty("status")\r
+    private String status;\r
+\r
+    @JsonProperty("message")\r
+    private String message;\r
+\r
+    @JsonProperty("updated-date")\r
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy hh:mm:ss")\r
+    private Date updatedDate;\r
+\r
+    @JsonProperty("updated-by")\r
+    private String updatedBy;\r
+\r
+    @Override\r
+    public String toString() {\r
+        StringBuilder builder = new StringBuilder("[");\r
+        builder.append("name = " + name);\r
+        builder.append(", source = " + dictionarySource);\r
+        if (dependencies != null) {\r
+            builder.append(", dependencies = " + dependencies);\r
+        }\r
+        builder.append("]");\r
+        return builder.toString();\r
+    }\r
+\r
+    public String getName() {\r
+        return name;\r
+    }\r
+\r
+    public void setName(String name) {\r
+        this.name = name;\r
+    }\r
+\r
+    public PropertyDefinition getProperty() {\r
+        return property;\r
+    }\r
+\r
+    public void setProperty(PropertyDefinition property) {\r
+        this.property = property;\r
+    }\r
+\r
+    public Boolean getInputParameter() {\r
+        return inputParameter;\r
+    }\r
+\r
+    public void setInputParameter(Boolean inputParameter) {\r
+        this.inputParameter = inputParameter;\r
+    }\r
+\r
+    public String getDictionaryName() {\r
+        return dictionaryName;\r
+    }\r
+\r
+    public void setDictionaryName(String dictionaryName) {\r
+        this.dictionaryName = dictionaryName;\r
+    }\r
+\r
+    public String getDictionarySource() {\r
+        return dictionarySource;\r
+    }\r
+\r
+    public void setDictionarySource(String dictionarySource) {\r
+        this.dictionarySource = dictionarySource;\r
+    }\r
+\r
+    public List<String> getDependencies() {\r
+        return dependencies;\r
+    }\r
+\r
+    public void setDependencies(List<String> dependencies) {\r
+        this.dependencies = dependencies;\r
+    }\r
+\r
+    public int getVersion() {\r
+        return version;\r
+    }\r
+\r
+    public void setVersion(int version) {\r
+        this.version = version;\r
+    }\r
+\r
+    public String getStatus() {\r
+        return status;\r
+    }\r
+\r
+    public void setStatus(String status) {\r
+        this.status = status;\r
+    }\r
+\r
+    public String getMessage() {\r
+        return message;\r
+    }\r
+\r
+    public void setMessage(String message) {\r
+        this.message = message;\r
+    }\r
+\r
+    public Date getUpdatedDate() {\r
+        return updatedDate;\r
+    }\r
+\r
+    public void setUpdatedDate(Date updatedDate) {\r
+        this.updatedDate = updatedDate;\r
+    }\r
+\r
+    public String getUpdatedBy() {\r
+        return updatedBy;\r
+    }\r
+\r
+    public void setUpdatedBy(String updatedBy) {\r
+        this.updatedBy = updatedBy;\r
+    }\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/resource-dict/src/main/java/org/onap/ccsdk/apps/controllerblueprints/resource/dict/data/DecryptionRule.java b/ms/controllerblueprints/modules/resource-dict/src/main/java/org/onap/ccsdk/apps/controllerblueprints/resource/dict/data/DecryptionRule.java
new file mode 100644 (file)
index 0000000..be43524
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.resource.dict.data;\r
+\r
+import com.fasterxml.jackson.annotation.JsonProperty;\r
+\r
+import java.util.List;\r
+/**\r
+ *\r
+ * DecryptionRule.java Purpose:\r
+ * @author Brinda Santh\r
+ */\r
+public class DecryptionRule {\r
+\r
+    private List<String> sources = null;\r
+    private String path;\r
+    private String rule;\r
+    @JsonProperty("decrypt-type")\r
+    private String decryptType;\r
+\r
+    public List<String> getSources() {\r
+        return sources;\r
+    }\r
+\r
+    public void setSources(List<String> sources) {\r
+        this.sources = sources;\r
+    }\r
+\r
+    public String getPath() {\r
+        return path;\r
+    }\r
+\r
+    public void setPath(String path) {\r
+        this.path = path;\r
+    }\r
+\r
+    public String getRule() {\r
+        return rule;\r
+    }\r
+\r
+    public void setRule(String rule) {\r
+        this.rule = rule;\r
+    }\r
+\r
+    public String getDecryptType() {\r
+        return decryptType;\r
+    }\r
+\r
+    public void setDecryptType(String decryptType) {\r
+        this.decryptType = decryptType;\r
+    }\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/resource-dict/src/main/java/org/onap/ccsdk/apps/controllerblueprints/resource/dict/data/DictionaryDefinition.java b/ms/controllerblueprints/modules/resource-dict/src/main/java/org/onap/ccsdk/apps/controllerblueprints/resource/dict/data/DictionaryDefinition.java
new file mode 100644 (file)
index 0000000..4dc9c89
--- /dev/null
@@ -0,0 +1,181 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.resource.dict.data;\r
+\r
+import com.fasterxml.jackson.annotation.JsonProperty;\r
+import com.fasterxml.jackson.databind.JsonNode;\r
+\r
+import java.util.List;\r
+import java.util.Map;\r
+/**\r
+ *\r
+ * DictionaryDefinition.java Purpose:\r
+ * @author Brinda Santh\r
+ */\r
+public class DictionaryDefinition {\r
+    @JsonProperty(value = "name", required = true)\r
+    private String name;\r
+    @JsonProperty(value = "description")\r
+    private String description;\r
+\r
+    @JsonProperty(value = "valid-values")\r
+    private String validValues;\r
+\r
+    @JsonProperty(value = "sample-value")\r
+    private String sampleValue;\r
+\r
+    private String tags;\r
+    @JsonProperty(value = "updated-by")\r
+    private String updatedBy;\r
+\r
+    @JsonProperty(value = "resource-type", required = true)\r
+    private String resourceType;\r
+\r
+    @JsonProperty(value = "resource-path", required = true)\r
+    private String resourcePath;\r
+\r
+    @JsonProperty(value = "data-type", required = true)\r
+    private String dataType;\r
+\r
+    @JsonProperty("entry-schema")\r
+    private String entrySchema;\r
+\r
+    @JsonProperty(value = "default")\r
+    private Object defaultValue;\r
+\r
+    @JsonProperty(value = "source", required = true)\r
+    private Map<String, JsonNode> source;\r
+\r
+    @JsonProperty("candidate-dependency")\r
+    private Map<String, DictionaryDependency> dependency;\r
+\r
+    @JsonProperty("decryption-rules")\r
+    private List<DecryptionRule> decryptionRules;\r
+\r
+    public String getName() {\r
+        return name;\r
+    }\r
+\r
+    public void setName(String name) {\r
+        this.name = name;\r
+    }\r
+\r
+    public String getDescription() {\r
+        return description;\r
+    }\r
+\r
+    public void setDescription(String description) {\r
+        this.description = description;\r
+    }\r
+\r
+    public String getValidValues() {\r
+        return validValues;\r
+    }\r
+\r
+    public void setValidValues(String validValues) {\r
+        this.validValues = validValues;\r
+    }\r
+\r
+    public String getSampleValue() {\r
+        return sampleValue;\r
+    }\r
+\r
+    public void setSampleValue(String sampleValue) {\r
+        this.sampleValue = sampleValue;\r
+    }\r
+\r
+    public String getTags() {\r
+        return tags;\r
+    }\r
+\r
+    public void setTags(String tags) {\r
+        this.tags = tags;\r
+    }\r
+\r
+    public String getUpdatedBy() {\r
+        return updatedBy;\r
+    }\r
+\r
+    public void setUpdatedBy(String updatedBy) {\r
+        this.updatedBy = updatedBy;\r
+    }\r
+\r
+    public String getResourceType() {\r
+        return resourceType;\r
+    }\r
+\r
+    public void setResourceType(String resourceType) {\r
+        this.resourceType = resourceType;\r
+    }\r
+\r
+    public String getResourcePath() {\r
+        return resourcePath;\r
+    }\r
+\r
+    public void setResourcePath(String resourcePath) {\r
+        this.resourcePath = resourcePath;\r
+    }\r
+\r
+    public String getDataType() {\r
+        return dataType;\r
+    }\r
+\r
+    public void setDataType(String dataType) {\r
+        this.dataType = dataType;\r
+    }\r
+\r
+    public String getEntrySchema() {\r
+        return entrySchema;\r
+    }\r
+\r
+    public void setEntrySchema(String entrySchema) {\r
+        this.entrySchema = entrySchema;\r
+    }\r
+\r
+    public Object getDefaultValue() {\r
+        return defaultValue;\r
+    }\r
+\r
+    public void setDefaultValue(Object defaultValue) {\r
+        this.defaultValue = defaultValue;\r
+    }\r
+\r
+    public Map<String, JsonNode> getSource() {\r
+        return source;\r
+    }\r
+\r
+    public void setSource(Map<String, JsonNode> source) {\r
+        this.source = source;\r
+    }\r
+\r
+    public Map<String, DictionaryDependency> getDependency() {\r
+        return dependency;\r
+    }\r
+\r
+    public void setDependency(Map<String, DictionaryDependency> dependency) {\r
+        this.dependency = dependency;\r
+    }\r
+\r
+    public List<DecryptionRule> getDecryptionRules() {\r
+        return decryptionRules;\r
+    }\r
+\r
+    public void setDecryptionRules(List<DecryptionRule> decryptionRules) {\r
+        this.decryptionRules = decryptionRules;\r
+    }\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/resource-dict/src/main/java/org/onap/ccsdk/apps/controllerblueprints/resource/dict/data/DictionaryDependency.java b/ms/controllerblueprints/modules/resource-dict/src/main/java/org/onap/ccsdk/apps/controllerblueprints/resource/dict/data/DictionaryDependency.java
new file mode 100644 (file)
index 0000000..acb7105
--- /dev/null
@@ -0,0 +1,36 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.resource.dict.data;\r
+\r
+import java.util.List;\r
+/**\r
+ *\r
+ * DictionaryDependency\r
+ * @author Brinda Santh\r
+ */\r
+public class DictionaryDependency {\r
+    private List<String> names;\r
+\r
+    public List<String> getNames() {\r
+        return names;\r
+    }\r
+\r
+    public void setNames(List<String> names) {\r
+        this.names = names;\r
+    }\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/resource-dict/src/main/java/org/onap/ccsdk/apps/controllerblueprints/resource/dict/data/SourceDb.java b/ms/controllerblueprints/modules/resource-dict/src/main/java/org/onap/ccsdk/apps/controllerblueprints/resource/dict/data/SourceDb.java
new file mode 100644 (file)
index 0000000..23d4046
--- /dev/null
@@ -0,0 +1,83 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.resource.dict.data;\r
+\r
+import com.fasterxml.jackson.annotation.JsonProperty;\r
+\r
+import java.util.Map;\r
+/**\r
+ *\r
+ * SourceDb\r
+ * @author Brinda Santh\r
+ */\r
+public class SourceDb {\r
+    @JsonProperty(value = "base", required = true)\r
+    private String base;\r
+    @JsonProperty(value = "type", required = true)\r
+    private String type; // SQL | PLSQL\r
+    @JsonProperty(value = "query", required = true)\r
+    private String query;\r
+\r
+    @JsonProperty("input-key-mapping")\r
+    private Map<String, String> inputKeyMapping;\r
+\r
+    @JsonProperty("output-key-mapping")\r
+    private Map<String, String> outputKeyMapping;\r
+\r
+    public String getBase() {\r
+        return base;\r
+    }\r
+\r
+    public void setBase(String base) {\r
+        this.base = base;\r
+    }\r
+\r
+    public String getType() {\r
+        return type;\r
+    }\r
+\r
+    public void setType(String type) {\r
+        this.type = type;\r
+    }\r
+\r
+    public String getQuery() {\r
+        return query;\r
+    }\r
+\r
+    public void setQuery(String query) {\r
+        this.query = query;\r
+    }\r
+\r
+    public Map<String, String> getInputKeyMapping() {\r
+        return inputKeyMapping;\r
+    }\r
+\r
+    public void setInputKeyMapping(Map<String, String> inputKeyMapping) {\r
+        this.inputKeyMapping = inputKeyMapping;\r
+    }\r
+\r
+    public Map<String, String> getOutputKeyMapping() {\r
+        return outputKeyMapping;\r
+    }\r
+\r
+    public void setOutputKeyMapping(Map<String, String> outputKeyMapping) {\r
+        this.outputKeyMapping = outputKeyMapping;\r
+    }\r
+\r
+\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/resource-dict/src/main/java/org/onap/ccsdk/apps/controllerblueprints/resource/dict/data/SourceDefault.java b/ms/controllerblueprints/modules/resource-dict/src/main/java/org/onap/ccsdk/apps/controllerblueprints/resource/dict/data/SourceDefault.java
new file mode 100644 (file)
index 0000000..0a4351c
--- /dev/null
@@ -0,0 +1,36 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.resource.dict.data;\r
+/**\r
+ *\r
+ * SourceDefault\r
+ * @author Brinda Santh\r
+ */\r
+public class SourceDefault {\r
+\r
+    private String key;\r
+\r
+    public String getKey() {\r
+        return key;\r
+    }\r
+\r
+    public void setKey(String key) {\r
+        this.key = key;\r
+    }\r
+\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/resource-dict/src/main/java/org/onap/ccsdk/apps/controllerblueprints/resource/dict/data/SourceInput.java b/ms/controllerblueprints/modules/resource-dict/src/main/java/org/onap/ccsdk/apps/controllerblueprints/resource/dict/data/SourceInput.java
new file mode 100644 (file)
index 0000000..82cb769
--- /dev/null
@@ -0,0 +1,37 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.resource.dict.data;\r
+/**\r
+ *\r
+ * SourceInput\r
+ * @author Brinda Santh\r
+ */\r
+public class SourceInput {\r
+\r
+    private String key;\r
+\r
+    public String getKey() {\r
+        return key;\r
+    }\r
+\r
+    public void setKey(String key) {\r
+        this.key = key;\r
+    }\r
+\r
+\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/resource-dict/src/main/java/org/onap/ccsdk/apps/controllerblueprints/resource/dict/data/SourceMdsal.java b/ms/controllerblueprints/modules/resource-dict/src/main/java/org/onap/ccsdk/apps/controllerblueprints/resource/dict/data/SourceMdsal.java
new file mode 100644 (file)
index 0000000..9eb233e
--- /dev/null
@@ -0,0 +1,97 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.resource.dict.data;\r
+/**\r
+ *\r
+ * SourceMdsal\r
+ * @author Brinda Santh\r
+ */\r
+import com.fasterxml.jackson.annotation.JsonProperty;\r
+\r
+import java.util.Map;\r
+\r
+public class SourceMdsal {\r
+\r
+    @JsonProperty(value = "base", required = true)\r
+    private String base;\r
+\r
+    @JsonProperty(value = "type", required = true)\r
+    private String type; // XML | JSON\r
+\r
+    @JsonProperty(value = "url-path", required = true)\r
+    private String urlPath;\r
+\r
+    @JsonProperty(value = "path", required = true)\r
+    private String path;\r
+\r
+    @JsonProperty("input-key-mapping")\r
+    private Map<String, String> inputKeyMapping;\r
+\r
+    @JsonProperty("output-key-mapping")\r
+    private Map<String, String> outputKeyMapping;\r
+\r
+    public String getBase() {\r
+        return base;\r
+    }\r
+\r
+    public void setBase(String base) {\r
+        this.base = base;\r
+    }\r
+\r
+    public String getType() {\r
+        return type;\r
+    }\r
+\r
+    public void setType(String type) {\r
+        this.type = type;\r
+    }\r
+\r
+    public String getUrlPath() {\r
+        return urlPath;\r
+    }\r
+\r
+    public void setUrlPath(String urlPath) {\r
+        this.urlPath = urlPath;\r
+    }\r
+\r
+    public String getPath() {\r
+        return path;\r
+    }\r
+\r
+    public void setPath(String path) {\r
+        this.path = path;\r
+    }\r
+\r
+    public Map<String, String> getInputKeyMapping() {\r
+        return inputKeyMapping;\r
+    }\r
+\r
+    public void setInputKeyMapping(Map<String, String> inputKeyMapping) {\r
+        this.inputKeyMapping = inputKeyMapping;\r
+    }\r
+\r
+    public Map<String, String> getOutputKeyMapping() {\r
+        return outputKeyMapping;\r
+    }\r
+\r
+    public void setOutputKeyMapping(Map<String, String> outputKeyMapping) {\r
+        this.outputKeyMapping = outputKeyMapping;\r
+    }\r
+\r
+\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/resource-dict/src/main/java/org/onap/ccsdk/apps/controllerblueprints/resource/dict/utils/ResourceDictionaryUtils.java b/ms/controllerblueprints/modules/resource-dict/src/main/java/org/onap/ccsdk/apps/controllerblueprints/resource/dict/utils/ResourceDictionaryUtils.java
new file mode 100644 (file)
index 0000000..9d51d82
--- /dev/null
@@ -0,0 +1,129 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.resource.dict.utils;\r
+\r
+import com.fasterxml.jackson.databind.JsonNode;\r
+import org.apache.commons.collections.MapUtils;\r
+import org.apache.commons.lang3.StringUtils;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.ConfigModelConstant;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.EntrySchema;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.PropertyDefinition;\r
+import org.onap.ccsdk.apps.controllerblueprints.resource.dict.ResourceAssignment;\r
+import org.onap.ccsdk.apps.controllerblueprints.resource.dict.data.DictionaryDefinition;\r
+import org.onap.ccsdk.apps.controllerblueprints.resource.dict.data.DictionaryDependency;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import java.util.Map;\r
+import java.util.Optional;\r
+import java.util.function.Supplier;\r
+\r
+/**\r
+ * ResourceDictionaryUtils.java Purpose to provide ResourceDictionaryUtils\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+public class ResourceDictionaryUtils {\r
+\r
+    private ResourceDictionaryUtils() {\r
+        // Do nothing\r
+    }\r
+\r
+    private static final Logger log = LoggerFactory.getLogger(ResourceDictionaryUtils.class);\r
+\r
+    /**\r
+     * This Method is to assign the source name to the Dictionary Definition Check to see if the source\r
+     * definition is not present then assign, if more than one source then assign only one first source.\r
+     *\r
+     * @param resourceAssignment\r
+     * @param dictionaryDefinition\r
+     */\r
+    @SuppressWarnings("squid:S3776")\r
+    public static void populateSourceMapping(ResourceAssignment resourceAssignment,\r
+                                             DictionaryDefinition dictionaryDefinition) {\r
+\r
+        if (resourceAssignment != null && dictionaryDefinition != null\r
+                && StringUtils.isBlank(resourceAssignment.getDictionarySource())) {\r
+\r
+            // Overwrite the Property Definitions from Dictionary\r
+            setProperty(resourceAssignment, dictionaryDefinition);\r
+\r
+            Map<String, JsonNode> dictionarySource = dictionaryDefinition.getSource();\r
+            Map<String, DictionaryDependency> dictionaryDependencyMap = dictionaryDefinition.getDependency();\r
+\r
+            if (MapUtils.isNotEmpty(dictionarySource)) {\r
+                String source = findFirstSource(dictionarySource);\r
+\r
+                // Populate and Assign First Source\r
+                if (StringUtils.isNotBlank(source)) {\r
+                    // Set Dictionary Source\r
+                    resourceAssignment.setDictionarySource(source);\r
+\r
+                    if (MapUtils.isNotEmpty(dictionaryDependencyMap)) {\r
+                        // Set Dependencies\r
+                        DictionaryDependency dictionaryDependency = dictionaryDependencyMap.get(source);\r
+                        if (dictionaryDependency != null) {\r
+                            resourceAssignment.setDependencies(dictionaryDependency.getNames());\r
+                        }\r
+                    }\r
+                } else {\r
+                    resourceAssignment.setDictionarySource(ConfigModelConstant.SOURCE_INPUT);\r
+                }\r
+                log.info("auto map resourceAssignment : {}", resourceAssignment);\r
+            }\r
+        }\r
+    }\r
+\r
+    public static <T> Optional<T> resolve(Supplier<T> resolver) {\r
+        try {\r
+            T result = resolver.get();\r
+            return Optional.ofNullable(result);\r
+        } catch (NullPointerException e) {\r
+            return Optional.empty();\r
+        }\r
+    }\r
+\r
+    private static String findFirstSource(Map<String, JsonNode> dictionarySource) {\r
+        String source = null;\r
+        if (MapUtils.isNotEmpty(dictionarySource)) {\r
+            source = dictionarySource.keySet().stream().findFirst().get();\r
+        }\r
+        return source;\r
+    }\r
+\r
+    /**\r
+     * Overriding ResourceAssignment Properties with properties defined in Dictionary\r
+     */\r
+    private static void setProperty(ResourceAssignment resourceAssignment, DictionaryDefinition dictionaryDefinition) {\r
+        if (StringUtils.isNotBlank(dictionaryDefinition.getDataType())) {\r
+            PropertyDefinition property = resourceAssignment.getProperty();\r
+            if (property == null) {\r
+                property = new PropertyDefinition();\r
+            }\r
+            property.setDefaultValue(dictionaryDefinition.getDefaultValue());\r
+            property.setType(dictionaryDefinition.getDataType());\r
+            if (StringUtils.isNotBlank(dictionaryDefinition.getEntrySchema())) {\r
+                EntrySchema entrySchema = new EntrySchema();\r
+                entrySchema.setType(dictionaryDefinition.getEntrySchema());\r
+                property.setEntrySchema(entrySchema);\r
+            }\r
+            resourceAssignment.setProperty(property);\r
+        }\r
+    }\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/resource-dict/src/main/java/org/onap/ccsdk/apps/controllerblueprints/resource/dict/validator/ResourceAssignmentValidator.java b/ms/controllerblueprints/modules/resource-dict/src/main/java/org/onap/ccsdk/apps/controllerblueprints/resource/dict/validator/ResourceAssignmentValidator.java
new file mode 100644 (file)
index 0000000..c980a0c
--- /dev/null
@@ -0,0 +1,164 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.resource.dict.validator;\r
+\r
+import org.apache.commons.lang3.StringUtils;\r
+import org.apache.commons.lang3.text.StrBuilder;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.ConfigModelConstant;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.CapabilityAssignment;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.NodeTemplate;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.TopologicalSortingUtils;\r
+import org.onap.ccsdk.apps.controllerblueprints.resource.dict.ResourceAssignment;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import java.util.*;\r
+/**\r
+ *\r
+ * ResourceAssignmentValidator.java Purpose:\r
+ * @author Brinda Santh\r
+ */\r
+public class ResourceAssignmentValidator {\r
+    private static final Logger log = LoggerFactory.getLogger(ResourceAssignmentValidator.class);\r
+    private List<ResourceAssignment> assignments;\r
+    private Map<String, ResourceAssignment> resourceAssignmentMap = new HashMap();\r
+    private StrBuilder validationMessage = new StrBuilder();\r
+\r
+    public ResourceAssignmentValidator(List<ResourceAssignment> assignments) {\r
+        this.assignments = assignments;\r
+    }\r
+\r
+    public ResourceAssignmentValidator(NodeTemplate nodeTemplate) throws BluePrintException {\r
+\r
+        if (nodeTemplate != null && nodeTemplate.getCapabilities() != null) {\r
+            CapabilityAssignment capabilityAssignment =\r
+                    nodeTemplate.getCapabilities().get(ConfigModelConstant.CAPABILITY_PROPERTY_MAPPING);\r
+            if (capabilityAssignment != null && capabilityAssignment.getProperties() != null) {\r
+                Object mappingObject =\r
+                        capabilityAssignment.getProperties().get(ConfigModelConstant.CAPABILITY_PROPERTY_MAPPING);\r
+                if (mappingObject != null) {\r
+                    String mappingContent = JacksonUtils.getJson(mappingObject);\r
+                    if (StringUtils.isNotBlank(mappingContent)) {\r
+                        this.assignments =\r
+                                JacksonUtils.getListFromJson(mappingContent, ResourceAssignment.class);\r
+                    } else {\r
+                        validationMessage\r
+                                .appendln(String.format("Failed to transform Mapping Content (%s) ", mappingContent));\r
+                        throw new BluePrintException(\r
+                                String.format("Failed to transform Mapping Content (%s) ", mappingContent));\r
+                    }\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * This is a validateResourceAssignment to validate the Topology Template\r
+     *\r
+     * @return boolean\r
+     * @throws BluePrintException\r
+     */\r
+    public boolean validateResourceAssignment() throws BluePrintException {\r
+        if (assignments != null && !assignments.isEmpty()) {\r
+            validateDuplicateDictionaryKeys();\r
+            validateCyclicDependency();\r
+            if (validationMessage.length() > 0) {\r
+                throw new BluePrintException("Resource Assignment Validation :" + validationMessage.toString());\r
+            }\r
+        }\r
+        return true;\r
+    }\r
+\r
+    @SuppressWarnings("squid:S3776")\r
+    private void validateDuplicateDictionaryKeys() {\r
+        this.assignments.forEach(resourceMapping -> {\r
+            if (resourceMapping != null) {\r
+                if (!resourceAssignmentMap.containsKey(resourceMapping.getName())) {\r
+                    resourceAssignmentMap.put(resourceMapping.getName(), resourceMapping);\r
+                } else {\r
+                    validationMessage.appendln(String.format("Duplicate Assignment Template Key (%s) is Present",\r
+                            resourceMapping.getName()));\r
+                }\r
+            }\r
+        });\r
+\r
+        if (!assignments.isEmpty()) {\r
+            Set<String> uniqueSet = new HashSet<>();\r
+            for (ResourceAssignment resourceAssignment : assignments) {\r
+                if (resourceAssignment != null) {\r
+                    boolean added = uniqueSet.add(resourceAssignment.getDictionaryName());\r
+                    if (!added) {\r
+                        validationMessage.appendln(\r
+                                String.format("Duplicate Assignment Dictionary Key (%s) present with Template Key (%s)",\r
+                                        resourceAssignment.getDictionaryName(), resourceAssignment.getName()));\r
+                    }\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    private void validateCyclicDependency() {\r
+        TopologicalSortingUtils<ResourceAssignment> topologySorting = new TopologicalSortingUtils<>();\r
+        this.resourceAssignmentMap.forEach((mappingKey, mapping) -> {\r
+            if (mapping != null) {\r
+                if (mapping.getDependencies() != null && !mapping.getDependencies().isEmpty()) {\r
+                    for (String dependency : mapping.getDependencies()) {\r
+                        topologySorting.add(resourceAssignmentMap.get(dependency), mapping);\r
+                    }\r
+                } else {\r
+                    topologySorting.add(null, mapping);\r
+                }\r
+            }\r
+        });\r
+\r
+        if (!topologySorting.isDag()) {\r
+            String graph = getTopologicalGraph(topologySorting);\r
+            validationMessage.appendln("Cyclic Dependency :" + graph);\r
+        }\r
+    }\r
+\r
+\r
+    public String getTopologicalGraph(TopologicalSortingUtils<ResourceAssignment> topologySorting) {\r
+        StringBuilder s = new StringBuilder();\r
+        if (topologySorting != null) {\r
+            Map<ResourceAssignment, List<ResourceAssignment>> neighbors = topologySorting.getNeighbors();\r
+\r
+            neighbors.forEach((v, vs) -> {\r
+                if (v == null) {\r
+                    s.append("\n    * -> [");\r
+                    List<ResourceAssignment> links = vs;\r
+                    for (ResourceAssignment resourceAssignment : links) {\r
+                        s.append("(" + resourceAssignment.getDictionaryName() + ":" + resourceAssignment.getName()\r
+                                + "),");\r
+                    }\r
+                    s.append("]");\r
+                } else {\r
+                    s.append("\n    (" + v.getDictionaryName() + ":" + v.getName() + ") -> [");\r
+                    List<ResourceAssignment> links = vs;\r
+                    for (ResourceAssignment resourceAssignment : links) {\r
+                        s.append("(" + resourceAssignment.getDictionaryName() + ":" + resourceAssignment.getName()\r
+                                + "),");\r
+                    }\r
+                    s.append("]");\r
+                }\r
+            });\r
+        }\r
+        return s.toString();\r
+    }\r
+}\r
diff --git a/ms/controllerblueprints/modules/resource-dict/src/test/java/org/onap/ccsdk/apps/controllerblueprints/resource/dict/util/ResourceDictionaryUtilsTest.java b/ms/controllerblueprints/modules/resource-dict/src/test/java/org/onap/ccsdk/apps/controllerblueprints/resource/dict/util/ResourceDictionaryUtilsTest.java
new file mode 100644 (file)
index 0000000..22b01c4
--- /dev/null
@@ -0,0 +1,165 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.resource.dict.util;\r
+\r
+\r
+import com.fasterxml.jackson.databind.JsonNode;\r
+import org.junit.Assert;\r
+import org.junit.Test;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.ConfigModelConstant;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils;\r
+import org.onap.ccsdk.apps.controllerblueprints.resource.dict.ResourceAssignment;\r
+import org.onap.ccsdk.apps.controllerblueprints.resource.dict.data.*;\r
+import org.onap.ccsdk.apps.controllerblueprints.resource.dict.utils.ResourceDictionaryUtils;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import java.util.Arrays;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+public class ResourceDictionaryUtilsTest {\r
+    private static final Logger log = LoggerFactory.getLogger(ResourceDictionaryUtilsTest.class);\r
+\r
+    @Test\r
+    public void validateSingleInputSource() {\r
+        try {\r
+            log.info(" **************** Validating validateSingleSource *****************");\r
+            ResourceAssignment resourceAssignment = new ResourceAssignment();\r
+            resourceAssignment.setName("test-input-key");\r
+            DictionaryDefinition dictionaryDefinition = new DictionaryDefinition();\r
+            dictionaryDefinition.setDataType(BluePrintConstants.DATA_TYPE_STRING);\r
+\r
+            Map<String, JsonNode> source = new HashMap<>();\r
+            SourceInput sourceInput = new SourceInput();\r
+            source.put(ConfigModelConstant.SOURCE_INPUT, JacksonUtils.jsonNodeFromObject(sourceInput));\r
+            dictionaryDefinition.setSource(source);\r
+\r
+            ResourceDictionaryUtils.populateSourceMapping(resourceAssignment, dictionaryDefinition);\r
+            Assert.assertNotNull("Resource assignment input source is missing ",\r
+                    resourceAssignment.getDictionarySource());\r
+            Assert.assertNotNull("Resource assignment input source property is missing ",\r
+                    resourceAssignment.getProperty());\r
+            Assert.assertNotNull("Resource assignment input source property type is missing ",\r
+                    resourceAssignment.getProperty().getType());\r
+\r
+        } catch (Exception e) {\r
+            e.printStackTrace();\r
+        }\r
+    }\r
+\r
+    @Test\r
+    public void validateSingleDbSource() {\r
+        try {\r
+            log.info(" **************** Validating validateSingleSource *****************");\r
+            ResourceAssignment resourceAssignment = new ResourceAssignment();\r
+            resourceAssignment.setName("test-db-key");\r
+            DictionaryDefinition dictionaryDefinition = new DictionaryDefinition();\r
+            dictionaryDefinition.setDataType(BluePrintConstants.DATA_TYPE_STRING);\r
+\r
+            Map<String, JsonNode> source = new HashMap<>();\r
+            SourceDb sourceDb = new SourceDb();\r
+            source.put(ConfigModelConstant.SOURCE_DB, JacksonUtils.jsonNodeFromObject(sourceDb));\r
+            dictionaryDefinition.setSource(source);\r
+\r
+            Map<String, DictionaryDependency> dependency = new HashMap<>();\r
+            DictionaryDependency dependencyDb = new DictionaryDependency();\r
+            dependencyDb.setNames(Arrays.asList("vnf-id", "vnf-name"));\r
+            dependency.put(ConfigModelConstant.SOURCE_DB, dependencyDb);\r
+            dictionaryDefinition.setDependency(dependency);\r
+\r
+            DecryptionRule decryptionRule = new DecryptionRule();\r
+            decryptionRule.setDecryptType("sample Type");\r
+            decryptionRule.setPath("$.");\r
+            decryptionRule.setRule("Sample Rule");\r
+            decryptionRule.setSources(Arrays.asList("vnf-id"));\r
+            dictionaryDefinition.setDecryptionRules(Arrays.asList(decryptionRule));\r
+\r
+            ResourceDictionaryUtils.populateSourceMapping(resourceAssignment, dictionaryDefinition);\r
+            Assert.assertNotNull("Resource assignment db source source is missing ",\r
+                    resourceAssignment.getDictionarySource());\r
+            Assert.assertNotNull("Resource assignment db source source property is missing ",\r
+                    resourceAssignment.getProperty());\r
+            Assert.assertNotNull("Resource assignment db source source property type is missing ",\r
+                    resourceAssignment.getProperty().getType());\r
+\r
+            Assert.assertNotNull("Resource assignment db dependecy is missing ", resourceAssignment.getDependencies());\r
+            Assert.assertEquals("Resource assignment db dependecy count mismatch ", 2,\r
+                    resourceAssignment.getDependencies().size());\r
+\r
+        } catch (Exception e) {\r
+            e.printStackTrace();\r
+        }\r
+    }\r
+\r
+    @Test\r
+    public void testSourceDefault() {\r
+        ResourceAssignment resourceAssignment = new ResourceAssignment();\r
+        resourceAssignment.setName("test-input-key");\r
+\r
+        DictionaryDefinition dictionaryDefinition = new DictionaryDefinition();\r
+        dictionaryDefinition.setDataType(BluePrintConstants.DATA_TYPE_STRING);\r
+\r
+        Map<String, JsonNode> source = new HashMap<>();\r
+        SourceDefault sourceDefault = new SourceDefault();\r
+        source.put(ConfigModelConstant.SOURCE_DEFAULT, JacksonUtils.jsonNodeFromObject(sourceDefault));\r
+        dictionaryDefinition.setSource(source);\r
+\r
+        Map<String, DictionaryDependency> dependency = new HashMap<>();\r
+        DictionaryDependency dependencyDefault = new DictionaryDependency();\r
+        dependencyDefault.setNames(Arrays.asList(new String[]{"vnf-id", "vnf-name"}));\r
+        dependency.put(ConfigModelConstant.SOURCE_DEFAULT, dependencyDefault);\r
+        dictionaryDefinition.setDependency(dependency);\r
+\r
+        ResourceDictionaryUtils.populateSourceMapping(resourceAssignment, dictionaryDefinition);\r
+\r
+        Assert.assertNotNull("Resource assignment default source is missing ",\r
+                resourceAssignment.getDictionarySource());\r
+        Assert.assertNotNull("Resource assignment default source property is missing ",\r
+                resourceAssignment.getProperty());\r
+        Assert.assertNotNull("Resource assignment default source property type is missing ",\r
+                resourceAssignment.getProperty().getType());\r
+    }\r
+\r
+    @Test\r
+    public void testSourceMdsal() {\r
+        ResourceAssignment resourceAssignment = new ResourceAssignment();\r
+        resourceAssignment.setName("test-input-key");\r
+        DictionaryDefinition dictionaryDefinition = new DictionaryDefinition();\r
+        dictionaryDefinition.setDataType(BluePrintConstants.DATA_TYPE_STRING);\r
+\r
+        Map<String, JsonNode> source = new HashMap<>();\r
+        SourceMdsal sourceMdsal = new SourceMdsal();\r
+        source.put(ConfigModelConstant.SOURCE_MDSAL, JacksonUtils.jsonNodeFromObject(sourceMdsal));\r
+        dictionaryDefinition.setSource(source);\r
+\r
+        Map<String, DictionaryDependency> dependency = new HashMap<>();\r
+        DictionaryDependency dependencyMdsal = new DictionaryDependency();\r
+        dependencyMdsal.setNames(Arrays.asList(new String[]{"vnf-id", "vnf-name"}));\r
+        dependency.put(ConfigModelConstant.SOURCE_MDSAL, dependencyMdsal);\r
+        dictionaryDefinition.setDependency(dependency);\r
+\r
+        ResourceDictionaryUtils.populateSourceMapping(resourceAssignment, dictionaryDefinition);\r
+\r
+        Assert.assertNotNull("Resource assignment mdsal source is missing ", resourceAssignment.getDictionarySource());\r
+        Assert.assertNotNull("Resource assignment mdsal source property is missing ", resourceAssignment.getProperty());\r
+        Assert.assertNotNull("Resource assignment mdsal source property type is missing ",\r
+                resourceAssignment.getProperty().getType());\r
+    }\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/load/blueprints/baseconfiguration/Definitions/activation-blueprint.json b/ms/controllerblueprints/modules/service/load/blueprints/baseconfiguration/Definitions/activation-blueprint.json
new file mode 100644 (file)
index 0000000..635e177
--- /dev/null
@@ -0,0 +1,411 @@
+{\r
+  "metadata": {\r
+    "template_author": "Brinda Santh Muthuramalingam",\r
+    "author-email": "brindasanth@gmail.com",\r
+    "user-groups" : "ADMIN, OPERATION",\r
+    "template_name": "baseconfiguration",\r
+    "template_version": "1.0.0",\r
+    "template_tags": "brinda, tosca"\r
+  },\r
+  "topology_template": {\r
+    "inputs": {\r
+      "request-id": {\r
+        "required": true,\r
+        "type": "string"\r
+      },\r
+      "action-name": {\r
+        "required": true,\r
+        "type": "string"\r
+      },\r
+      "scope-type": {\r
+        "required": true,\r
+        "type": "string"\r
+      },\r
+      "hostname": {\r
+        "required": true,\r
+        "type": "string"\r
+      }\r
+    },\r
+    "node_templates": {\r
+      "activate-process": {\r
+        "type": "bpmn-activate",\r
+        "properties": {\r
+          "process-name": { "get_input" : "action-name" },\r
+          "version" : { "get_property" : ["SELF", "process-name"] },\r
+          "content": { "get_artifact" : ["SELF", "activate-process"] }\r
+        },\r
+        "artifacts": {\r
+          "activate-process": {\r
+            "type": "artifact-bpmn-camunda",\r
+            "file": "Plans/ActivateProcess.bpmn"\r
+          }\r
+        }\r
+      },\r
+      "resource-assignment": {\r
+        "type": "component-resource-assignment",\r
+        "properties":{\r
+          "request-id": ["1234", "1234"]\r
+        },\r
+        "interfaces": {\r
+          "DefaultComponentNode": {\r
+            "operations": {\r
+              "process": {\r
+                "inputs": {\r
+                  "action-name": { "get_input" : "action-name" },\r
+                  "resource-type": "vnf-type",\r
+                  "request-id": { "get_input" : "request-id" },\r
+                  "resource-id": { "get_input" : "hostname" },\r
+                  "template-content": { "get_artifact" : ["SELF", "baseconfig-template"] },\r
+                  "mapping-content": { "get_artifact" : ["SELF", "baseconfig-mapping"] }\r
+                },\r
+                "outputs": {\r
+                  "resource-assignment-params": "",\r
+                  "status": ""\r
+                }\r
+              }\r
+            }\r
+          }\r
+        },\r
+        "artifacts": {\r
+          "baseconfig-template": {\r
+            "type": "artifact-template-velocity",\r
+            "file": "Templates/baseconfig-template.vtl"\r
+          },\r
+          "baseconfig-mapping": {\r
+            "type": "artifact-mapping-resource",\r
+            "file": "Mappings/baseconfig-mapping.json"\r
+          }\r
+        }\r
+      },\r
+      "resource-assignment-py": {\r
+        "type": "component-resource-assignment",\r
+        "properties":{\r
+          "request-id": ["1234", "1234"]\r
+        },\r
+        "interfaces": {\r
+          "DefaultComponentNode": {\r
+            "operations": {\r
+              "process": {\r
+                "implementation" :{\r
+                  "primary" : "component-script"\r
+                },\r
+                "inputs": {\r
+                  "action-name": { "get_input" : "action-name" }\r
+                },\r
+                "outputs": {\r
+                  "resource-assignment-params": "",\r
+                  "status": ""\r
+                }\r
+              }\r
+            }\r
+          }\r
+        },\r
+        "artifacts": {\r
+          "component-script": {\r
+            "type": "artifact-script-python",\r
+            "file": "Scripts/baseconfig-template.vtl"\r
+          }\r
+        }\r
+      }\r
+    },\r
+    "workflows":{\r
+      "activate-process":{\r
+        "steps" : {\r
+            "call-resource-assignment" : {\r
+              "description" : "Invoke Resource Assignment Component",\r
+              "target" : "resource-assignment",\r
+              "activities" : [\r
+                {\r
+                  "call_operation": "ResourceAssignmentNode.process"\r
+                }\r
+              ],\r
+              "on_success" : [\r
+                "download-baseconfig"\r
+              ]\r
+            },\r
+          "download-baseconfig" : {\r
+            "description" : "Call Download Base Config Component",\r
+            "target" : "activate-netconf",\r
+            "activities" : [\r
+              {\r
+                "call_operation": "NetconfTransactionNode.process"\r
+              }\r
+            ],\r
+            "on_success" : [\r
+              "download-licence"\r
+            ]\r
+          },\r
+          "download-licence" : {\r
+            "description" : "Call Download Licence Component",\r
+            "target" : "activate-netconf",\r
+            "activities" : [\r
+              {\r
+                "call_operation": "NetconfTransactionNode.process"\r
+              }\r
+            ]\r
+          }\r
+        }\r
+      }\r
+    }\r
+  },\r
+  "artifact_types": {\r
+    "artifact-template-velocity": {\r
+      "description": " Velocity Template used for Configuration",\r
+      "version": "1.0.0",\r
+      "file_ext": [\r
+        "vtl"\r
+      ],\r
+      "derived_from": "tosca.artifacts.Implementation"\r
+    },\r
+    "artifact-mapping-resource": {\r
+      "description": " Velocity Template Resource Mapping File used along with Configuration template",\r
+      "version": "1.0.0",\r
+      "file_ext": [\r
+        "json"\r
+      ],\r
+      "derived_from": "tosca.artifacts.Implementation"\r
+    },\r
+    "artifact-script-kotlin": {\r
+      "description": " Kotlin Script Template used for Configuration",\r
+      "version": "1.0.0",\r
+      "file_ext": [\r
+        "kt"\r
+      ],\r
+      "derived_from": "tosca.artifacts.Implementation"\r
+    },\r
+    "artifact-script-python": {\r
+      "description": " Kotlin Script Template used for Configuration",\r
+      "version": "1.0.0",\r
+      "file_ext": [\r
+        "py"\r
+      ],\r
+      "derived_from": "tosca.artifacts.Implementation"\r
+    },\r
+    "artifact-bpmn-camunda": {\r
+      "description": " Camunda BPM File",\r
+      "version": "1.0.0",\r
+      "file_ext": [\r
+        "bpmn"\r
+      ],\r
+      "derived_from": "tosca.artifacts.Implementation"\r
+    },\r
+    "artifact-component-jar": {\r
+      "description": "Component Jar",\r
+      "version": "1.0.0",\r
+      "file_ext": [\r
+        "jar"\r
+      ],\r
+      "derived_from": "tosca.artifacts.Implementation"\r
+    }\r
+  },\r
+  "node_types": {\r
+    "bpmn-activate": {\r
+      "description": "This is BPMN Activate node type",\r
+      "version": "1.0.0",\r
+      "properties": {\r
+        "content": {\r
+          "required": false,\r
+          "type": "string"\r
+        },\r
+        "process-name": {\r
+          "required": false,\r
+          "type": "string"\r
+        },\r
+        "version": {\r
+          "required": false,\r
+          "type": "string",\r
+          "default" : "LATEST"\r
+        }\r
+      },\r
+      "derived_from": "tosca.nodes.Component"\r
+    },\r
+    "tosca.nodes.Component": {\r
+      "description": "This is Resource Assignment Component API",\r
+      "version": "1.0.0",\r
+      "properties": {\r
+        "type": {\r
+          "description": "Request Id used to store the generated configuration, in the database along with the template-name",\r
+          "required": false,\r
+          "type": "string"\r
+        }\r
+      },\r
+      "interfaces": {\r
+        "DefaultOperation": {\r
+          "operations": {\r
+            "validate": {\r
+              "inputs": {\r
+                "action-name": {\r
+                  "description": "validate for action",\r
+                  "required": false,\r
+                  "type": "string"\r
+                }\r
+              }\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "artifacts" :{\r
+        "component-jar": {\r
+          "description": "Component Jar",\r
+          "type": "artifact-component-jar",\r
+          "file": "Component/basecomponent.jar"\r
+        }\r
+      },\r
+      "derived_from": "tosca.nodes.Root"\r
+    },\r
+    "tosca.nodes.component.Python": {\r
+      "description": "This is Resource Assignment Python Component API",\r
+      "version": "1.0.0",\r
+      "properties": {\r
+        "type": {\r
+          "description": "Request Id used to store the generated configuration, in the database along with the template-name",\r
+          "required": false,\r
+          "type": "string"\r
+        }\r
+      },\r
+      "interfaces": {\r
+        "DefaultOperation": {\r
+          "operations": {\r
+            "validate": {\r
+              "inputs": {\r
+                "action-name": {\r
+                  "description": "validate for action",\r
+                  "required": false,\r
+                  "type": "string"\r
+                }\r
+              }\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "artifacts" :{\r
+        "component-jar": {\r
+          "description": "Component Jar",\r
+          "type": "artifact-component-jar",\r
+          "file": "Component/basecomponent.jar"\r
+        }\r
+      },\r
+      "derived_from": "tosca.nodes.Root"\r
+    },\r
+    "component-resource-assignment": {\r
+      "description": "This is Resource Assignment Component API",\r
+      "version": "1.0.0",\r
+      "properties": {\r
+        "request-id": {\r
+          "description": "Request Id used to store the generated configuration, in the database along with the template-name",\r
+          "required": true,\r
+          "type": "string"\r
+        }\r
+      },\r
+      "interfaces": {\r
+        "DefaultComponentNode": {\r
+          "operations": {\r
+            "process": {\r
+              "inputs": {\r
+                "action-name": {\r
+                  "description": "Recipe Name to get from Database, Either (message & mask-info ) or ( resource-id & resource-type & action-name & template-name ) should be present. Message will be given higest priority",\r
+                  "required": false,\r
+                  "type": "string"\r
+                },\r
+                "resource-type": {\r
+                  "required": false,\r
+                  "type": "string"\r
+                },\r
+                "request-id": {\r
+                  "description": "Request Id used to store the generated configuration, in the database along with the template-name",\r
+                  "required": true,\r
+                  "type": "string"\r
+                },\r
+                "resource-id": {\r
+                  "description": "Id used to pull the data content from the data base. Either template-data or resource-id should be present",\r
+                  "required": true,\r
+                  "type": "string"\r
+                },\r
+                "template-content": {\r
+                  "description": "Id used to pull the data content from the data base. Either template-data or resource-id should be present",\r
+                  "required": true,\r
+                  "type": "string"\r
+                },\r
+                "mapping-content": {\r
+                  "description": "Id used to pull the data content from the data base. Either template-data or resource-id should be present",\r
+                  "required": true,\r
+                  "type": "string"\r
+                }\r
+              },\r
+              "outputs": {\r
+                "resource-assignment-params": {\r
+                  "required": true,\r
+                  "type": "string"\r
+                },\r
+                "status": {\r
+                  "required": true,\r
+                  "type": "string"\r
+                }\r
+              }\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "derived_from": "tosca.nodes.Component"\r
+    },\r
+    "component-resource-assignment-python": {\r
+      "description": "This is Resource Assignment Component API",\r
+      "version": "1.0.0",\r
+      "properties": {\r
+        "request-id": {\r
+          "description": "Request Id used to store the generated configuration, in the database along with the template-name",\r
+          "required": true,\r
+          "type": "string"\r
+        }\r
+      },\r
+      "interfaces": {\r
+        "DefaultComponentNode": {\r
+          "operations": {\r
+            "process": {\r
+              "inputs": {\r
+                "action-name": {\r
+                  "description": "Recipe Name to get from Database, Either (message & mask-info ) or ( resource-id & resource-type & action-name & template-name ) should be present. Message will be given higest priority",\r
+                  "required": false,\r
+                  "type": "string"\r
+                }\r
+              },\r
+              "outputs": {\r
+                "resource-assignment-params": {\r
+                  "required": true,\r
+                  "type": "string"\r
+                },\r
+                "status": {\r
+                  "required": true,\r
+                  "type": "string"\r
+                }\r
+              }\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "derived_from": "tosca.nodes.component.Python"\r
+    }\r
+  },\r
+  "data_types": {\r
+    "sample-property" : {\r
+      "description": "This is sample data type",\r
+      "version": "1.0.0",\r
+      "properties": {\r
+        "content": {\r
+          "required": false,\r
+          "type": "string"\r
+        },\r
+        "process-name": {\r
+          "required": false,\r
+          "type": "string"\r
+        },\r
+        "version": {\r
+          "required": false,\r
+          "type": "string",\r
+          "default" : "LATEST"\r
+        }\r
+      },\r
+      "derived_from" : "tosca.datatypes.Root"\r
+    }\r
+  }\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/load/blueprints/baseconfiguration/Mappings/baseconfig-mapping.json b/ms/controllerblueprints/modules/service/load/blueprints/baseconfiguration/Mappings/baseconfig-mapping.json
new file mode 100644 (file)
index 0000000..6abfb51
--- /dev/null
@@ -0,0 +1,3 @@
+{\r
+  "assignments": "Sample Assignments"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/load/blueprints/baseconfiguration/Plans/ActivateProcess.bpmn b/ms/controllerblueprints/modules/service/load/blueprints/baseconfiguration/Plans/ActivateProcess.bpmn
new file mode 100644 (file)
index 0000000..5e94c0f
--- /dev/null
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL"\r
+                  xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"\r
+                  xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"\r
+                  xmlns:camunda="http://camunda.org/schema/1.0/bpmn"\r
+                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1"\r
+                  targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="1.11.2">\r
+    <bpmn:process id="ActivateProcess" isExecutable="true">\r
+        <bpmn:startEvent id="StartEvent_1">\r
+            <bpmn:outgoing>SequenceFlow_0l0dq58</bpmn:outgoing>\r
+        </bpmn:startEvent>\r
+        <bpmn:endEvent id="EndEvent_1pr0kil">\r
+            <bpmn:incoming>SequenceFlow_1ay0k6p</bpmn:incoming>\r
+        </bpmn:endEvent>\r
+        <bpmn:sequenceFlow id="SequenceFlow_0l0dq58" sourceRef="StartEvent_1" targetRef="activate_device_task"/>\r
+        <bpmn:sequenceFlow id="SequenceFlow_1ay0k6p" sourceRef="activate_device_task" targetRef="EndEvent_1pr0kil"/>\r
+        <bpmn:serviceTask id="activate_device_task" name="Activate Device"\r
+                          camunda:delegateExpression="${componentDelegateService}">\r
+            <bpmn:extensionElements>\r
+                <camunda:inputOutput>\r
+                    <camunda:inputParameter name="selector"><![CDATA[resource-assignment\r
+]]></camunda:inputParameter>\r
+                </camunda:inputOutput>\r
+            </bpmn:extensionElements>\r
+            <bpmn:incoming>SequenceFlow_0l0dq58</bpmn:incoming>\r
+            <bpmn:outgoing>SequenceFlow_1ay0k6p</bpmn:outgoing>\r
+        </bpmn:serviceTask>\r
+    </bpmn:process>\r
+    <bpmndi:BPMNDiagram id="BPMNDiagram_1">\r
+        <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="ActivateProcess">\r
+            <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">\r
+                <dc:Bounds x="175" y="143" width="36" height="36"/>\r
+                <bpmndi:BPMNLabel>\r
+                    <dc:Bounds x="148" y="179" width="90" height="20"/>\r
+                </bpmndi:BPMNLabel>\r
+            </bpmndi:BPMNShape>\r
+            <bpmndi:BPMNShape id="EndEvent_1pr0kil_di" bpmnElement="EndEvent_1pr0kil">\r
+                <dc:Bounds x="575" y="114" width="36" height="36"/>\r
+                <bpmndi:BPMNLabel>\r
+                    <dc:Bounds x="593" y="154" width="0" height="12"/>\r
+                </bpmndi:BPMNLabel>\r
+            </bpmndi:BPMNShape>\r
+            <bpmndi:BPMNEdge id="SequenceFlow_0l0dq58_di" bpmnElement="SequenceFlow_0l0dq58">\r
+                <di:waypoint xsi:type="dc:Point" x="211" y="161"/>\r
+                <di:waypoint xsi:type="dc:Point" x="273" y="161"/>\r
+                <di:waypoint xsi:type="dc:Point" x="273" y="149"/>\r
+                <di:waypoint xsi:type="dc:Point" x="334" y="149"/>\r
+                <bpmndi:BPMNLabel>\r
+                    <dc:Bounds x="288" y="149" width="0" height="12"/>\r
+                </bpmndi:BPMNLabel>\r
+            </bpmndi:BPMNEdge>\r
+            <bpmndi:BPMNEdge id="SequenceFlow_1ay0k6p_di" bpmnElement="SequenceFlow_1ay0k6p">\r
+                <di:waypoint xsi:type="dc:Point" x="434" y="149"/>\r
+                <di:waypoint xsi:type="dc:Point" x="505" y="149"/>\r
+                <di:waypoint xsi:type="dc:Point" x="505" y="132"/>\r
+                <di:waypoint xsi:type="dc:Point" x="575" y="132"/>\r
+                <bpmndi:BPMNLabel>\r
+                    <dc:Bounds x="520" y="134.5" width="0" height="12"/>\r
+                </bpmndi:BPMNLabel>\r
+            </bpmndi:BPMNEdge>\r
+            <bpmndi:BPMNShape id="ServiceTask_0e8ek4f_di" bpmnElement="activate_device_task">\r
+                <dc:Bounds x="334" y="109" width="100" height="80"/>\r
+            </bpmndi:BPMNShape>\r
+        </bpmndi:BPMNPlane>\r
+    </bpmndi:BPMNDiagram>\r
+</bpmn:definitions>\r
diff --git a/ms/controllerblueprints/modules/service/load/blueprints/baseconfiguration/Scripts/SamplePythonComponentNode.py b/ms/controllerblueprints/modules/service/load/blueprints/baseconfiguration/Scripts/SamplePythonComponentNode.py
new file mode 100644 (file)
index 0000000..eb198c7
--- /dev/null
@@ -0,0 +1,8 @@
+from com.brvith.orchestrator.core.interfaces import ComponentNode\r
+\r
+class SamplePythonComponentNode(ComponentNode):\r
+    def prepare(self, context, componentContext):\r
+        return None\r
+\r
+    def prepare(self, context, componentContext):\r
+        return None
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/load/blueprints/baseconfiguration/Scripts/__init__.py b/ms/controllerblueprints/modules/service/load/blueprints/baseconfiguration/Scripts/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/ms/controllerblueprints/modules/service/load/blueprints/baseconfiguration/TOSCA-Metadata/TOSCA.meta b/ms/controllerblueprints/modules/service/load/blueprints/baseconfiguration/TOSCA-Metadata/TOSCA.meta
new file mode 100644 (file)
index 0000000..05c2c67
--- /dev/null
@@ -0,0 +1,8 @@
+TOSCA-Meta-File-Version: 1.0.0\r
+CSAR-Version: 1.0\r
+Created-By: Brinda Santh M\r
+Entry-Definitions: Definitions/activation-blueprint.json\r
+Template-Tags: vrr-test, Brinda Santh\r
+\r
+Name: Plans/ActivateProcess.bpmn\r
+Content-Type: application/vnd.oasis.bpmn\r
diff --git a/ms/controllerblueprints/modules/service/load/blueprints/baseconfiguration/Templates/baseconfig-template.vtl b/ms/controllerblueprints/modules/service/load/blueprints/baseconfiguration/Templates/baseconfig-template.vtl
new file mode 100644 (file)
index 0000000..026c591
--- /dev/null
@@ -0,0 +1 @@
+This is Sample Velocity Template
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/load/blueprints/baseconfiguration/__init__.py b/ms/controllerblueprints/modules/service/load/blueprints/baseconfiguration/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/ms/controllerblueprints/modules/service/load/blueprints/vrr-test/Definitions/vrr-test.json b/ms/controllerblueprints/modules/service/load/blueprints/vrr-test/Definitions/vrr-test.json
new file mode 100644 (file)
index 0000000..626329a
--- /dev/null
@@ -0,0 +1,742 @@
+{\r
+  "metadata": {\r
+    "template_author": "Brinda Santh ( bs2796@onap.com )",\r
+    "template_name": "vrr-test",\r
+    "template_version": "1.0.0",\r
+    "release": "201802",\r
+    "service-type": "AVPN",\r
+    "vnf-type": "VRR"\r
+  },\r
+  "topology_template": {\r
+    "inputs": {\r
+      "request-id": {\r
+        "required": true,\r
+        "type": "string"\r
+      },\r
+      "service-instance-id": {\r
+        "required": true,\r
+        "type": "string"\r
+      },\r
+      "action-name": {\r
+        "required": true,\r
+        "type": "string"\r
+      },\r
+      "scope-type": {\r
+        "required": true,\r
+        "type": "string"\r
+      },\r
+      "hostname": {\r
+        "required": true,\r
+        "type": "string"\r
+      },\r
+      "resource-assignment-request": {\r
+        "description": "This is Dynamic Data type for the receipe resource-assignment-action.",\r
+        "required": false,\r
+        "type": "dt-resource-assignment-request"\r
+      }\r
+    },\r
+    "node_templates": {\r
+      "base-config-template": {\r
+        "type": "artifact-config-template",\r
+        "properties": {\r
+          "action-names": [\r
+            "resource-assignment-action"\r
+          ]\r
+        },\r
+        "capabilities": {\r
+          "content": {\r
+            "properties": {\r
+              "content": "db://base-config-template"\r
+            }\r
+          },\r
+          "mapping": {\r
+            "properties": {\r
+              "mapping": [\r
+                {\r
+                  "name": "vnf-id",\r
+                  "input-param": true,\r
+                  "property": {\r
+                    "type": "string",\r
+                    "required": true\r
+                  },\r
+                  "dictionary-name": "vnf-id",\r
+                  "dictionary-source": "input"\r
+                },\r
+                {\r
+                  "name": "group-name",\r
+                  "input-param": true,\r
+                  "property": {\r
+                    "type": "string",\r
+                    "required": true\r
+                  },\r
+                  "dictionary-name": "group-name",\r
+                  "dictionary-source": "input"\r
+                }\r
+              ]\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "activate-action": {\r
+        "type": "dg-activate-netconf",\r
+        "interfaces": {\r
+          "CONFIG": {\r
+            "operations": {\r
+              "ActivateNetconf": {}\r
+            }\r
+          }\r
+        },\r
+        "capabilities": {\r
+          "dg-node": {}\r
+        },\r
+        "requirements": {\r
+          "component-dependency": {\r
+            "capability": "component-node",\r
+            "node": "transaction-netconf-baseconfig",\r
+            "relationship": "tosca.relationships.DependsOn"\r
+          }\r
+        }\r
+      },\r
+      "resource-assignment-action": {\r
+        "type": "dg-resource-assignment",\r
+        "interfaces": {\r
+          "CONFIG": {\r
+            "operations": {\r
+              "ResourceAssignment": {}\r
+            }\r
+          }\r
+        },\r
+        "capabilities": {\r
+          "dg-node": {}\r
+        },\r
+        "requirements": {\r
+          "component-dependency": {\r
+            "capability": "component-node",\r
+            "node": "resource-assignment",\r
+            "relationship": "tosca.relationships.DependsOn"\r
+          }\r
+        }\r
+      },\r
+      "licence-template": {\r
+        "type": "artifact-config-template",\r
+        "properties": {\r
+          "action-names": [\r
+            "resource-assignment-action"\r
+          ]\r
+        },\r
+        "capabilities": {\r
+          "content": {\r
+            "properties": {\r
+              "content": "db://licence-template"\r
+            }\r
+          },\r
+          "mapping": {\r
+            "properties": {\r
+              "mapping": [\r
+                {\r
+                  "name": "licence-key",\r
+                  "input-param": true,\r
+                  "property": {\r
+                    "type": "string",\r
+                    "required": true\r
+                  },\r
+                  "dictionary-name": "licence-key",\r
+                  "dictionary-source": "input"\r
+                }\r
+              ]\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "runningconfig-template": {\r
+        "type": "artifact-config-template",\r
+        "properties": {\r
+          "action-names": [\r
+            "resource-assignment-action"\r
+          ]\r
+        },\r
+        "capabilities": {\r
+          "content": {\r
+            "properties": {\r
+              "content": "db://runningconfig-template"\r
+            }\r
+          },\r
+          "mapping": {\r
+            "properties": {\r
+              "mapping": []\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "resource-assignment": {\r
+        "type": "component-resource-assignment",\r
+        "interfaces": {\r
+          "org-openecomp-sdnc-config-assignment-service-ConfigAssignmentNode": {\r
+            "operations": {\r
+              "process": {\r
+                "inputs": {\r
+                  "service-template-name": "{ \"get_attribute\" : \"template_name\" }",\r
+                  "service-template-version": "{ \"get_attribute\" : \"service-template-version\" }",\r
+                  "action-name": "{ \"get_input\" : \"action-name\" }",\r
+                  "resource-type": "vnf-type",\r
+                  "template-names": [\r
+                    "base-config-template",\r
+                    "licence-template"\r
+                  ],\r
+                  "request-id": "{ \"get_input\" : \"request-id\" }",\r
+                  "resource-id": "{ \"get_input\" : \"vnf-id\" }"\r
+                },\r
+                "outputs": {\r
+                  "resource-assignment-params": "",\r
+                  "status": ""\r
+                }\r
+              }\r
+            }\r
+          }\r
+        },\r
+        "capabilities": {\r
+          "component-node": {}\r
+        }\r
+      },\r
+      "vrr-netconf-device": {\r
+        "type": "vnf-netconf-device",\r
+        "capabilities": {\r
+          "netconf": {\r
+            "properties": {\r
+              "profile-name": "sample",\r
+              "oam-ipv4-address": "{ \"get_attribute\" : \"hostname\" }",\r
+              "port-number": "{ \"get_attribute\" : \"host-port\" }",\r
+              "connection-time-out": 30\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "transaction-netconf-baseconfig": {\r
+        "type": "component-netconf-executor",\r
+        "interfaces": {\r
+          "org-openecomp-sdnc-netconf-adaptor-service-NetconfExecutorNode": {\r
+            "operations": {\r
+              "process": {\r
+                "implementation" : {\r
+                  "primary" : "file://netconf-adaptor/DefaultGetConfig.py"\r
+                },\r
+                "inputs": {\r
+                  "action-name": "{ \"get_input\" : \"action-name\" }",\r
+                  "resource-type": "vnf-type",\r
+                  "request-id": "{ \"get_attribute\" : \"request-id\" }",\r
+                  "resource-id": "{ \"get_input\" : \"vnf-id\" }",\r
+                  "execution-script": "execution-script"\r
+                },\r
+                "outputs": {\r
+                  "response-data": "{ \"get_attribute\" : \"netconf-executor-baseconfig.response-data\" }",\r
+                  "status": "{ \"get_attribute\" : \"netconf-executor-baseconfig.status\" }"\r
+                }\r
+              }\r
+            }\r
+          }\r
+        },\r
+        "capabilities": {\r
+          "component-node": {\r
+          }\r
+        },\r
+        "requirements": {\r
+          "netconf-connection": {\r
+            "capability": "netconf",\r
+            "node": "vrr-netconf-device",\r
+            "relationship": "tosca.relationships.ConnectsTo"\r
+          }\r
+        }\r
+      }\r
+    }\r
+  },\r
+  "node_types": {\r
+    "dg-resource-assignment": {\r
+      "description": "This is Resource Assignment Directed Graph",\r
+      "version": "1.0.0",\r
+      "properties": {\r
+        "mode": {\r
+          "required": false,\r
+          "type": "string",\r
+          "default": "sync"\r
+        },\r
+        "version": {\r
+          "required": false,\r
+          "type": "string",\r
+          "default": "LATEST"\r
+        },\r
+        "is-start-flow": {\r
+          "required": false,\r
+          "type": "boolean",\r
+          "default": "false"\r
+        }\r
+      },\r
+      "capabilities": {\r
+        "dg-node": {\r
+          "type": "tosca.capabilities.Node"\r
+        },\r
+        "content": {\r
+          "type": "tosca.capability.Content",\r
+          "properties": {\r
+            "type": {\r
+              "required": false,\r
+              "type": "string",\r
+              "default": "json"\r
+            },\r
+            "content": {\r
+              "required": false,\r
+              "type": "string"\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "requirements": {\r
+        "component-dependency": {\r
+          "capability": "component-node",\r
+          "node": "component-resource-assignment",\r
+          "relationship": "tosca.relationships.DependsOn"\r
+        }\r
+      },\r
+      "interfaces": {\r
+        "CONFIG": {\r
+          "operations": {\r
+            "ResourceAssignment": {\r
+              "inputs": {\r
+                "params": {\r
+                  "required": false,\r
+                  "type": "list",\r
+                  "entry_schema": {\r
+                    "type": "datatype-property"\r
+                  }\r
+                }\r
+              }\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "derived_from": "tosca.nodes.DG"\r
+    },\r
+    "component-resource-assignment": {\r
+      "description": "This is Resource Assignment Component API",\r
+      "version": "1.0.0",\r
+      "capabilities": {\r
+        "component-node": {\r
+          "type": "tosca.capabilities.Node"\r
+        }\r
+      },\r
+      "interfaces": {\r
+        "org-openecomp-sdnc-config-assignment-service-ConfigAssignmentNode": {\r
+          "operations": {\r
+            "process": {\r
+              "inputs": {\r
+                "action-name": {\r
+                  "description": "Action Name of the process",\r
+                  "required": true,\r
+                  "type": "string"\r
+                },\r
+                "service-template-name": {\r
+                  "description": "Service Template Name.",\r
+                  "required": true,\r
+                  "type": "string"\r
+                },\r
+                "service-template-version": {\r
+                  "description": "Service Template Version.",\r
+                  "required": true,\r
+                  "type": "string"\r
+                },\r
+                "resource-type": {\r
+                  "description": "Request type.",\r
+                  "required": true,\r
+                  "type": "string"\r
+                },\r
+                "template-names": {\r
+                  "description": "Name of the artifact Node Templates, to get the template Content.",\r
+                  "required": true,\r
+                  "type": "list",\r
+                  "entry_schema": {\r
+                    "type": "string"\r
+                  }\r
+                },\r
+                "request-id": {\r
+                  "description": "Request Id, Unique Id for the request.",\r
+                  "required": true,\r
+                  "type": "string"\r
+                },\r
+                "resource-id": {\r
+                  "description": "Resource Id.",\r
+                  "required": true,\r
+                  "type": "string"\r
+                }\r
+              },\r
+              "outputs": {\r
+                "resource-assignment-params": {\r
+                  "required": true,\r
+                  "type": "string"\r
+                },\r
+                "status": {\r
+                  "required": true,\r
+                  "type": "string"\r
+                }\r
+              }\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "derived_from": "tosca.nodes.Component"\r
+    },\r
+    "artifact-config-template": {\r
+      "description": "This is Configuration Velocity Template",\r
+      "version": "1.0.0",\r
+      "properties": {\r
+        "action-names": {\r
+          "required": true,\r
+          "type": "list",\r
+          "entry_schema": {\r
+            "type": "string"\r
+          }\r
+        }\r
+      },\r
+      "capabilities": {\r
+        "content": {\r
+          "type": "tosca.capability.Content",\r
+          "properties": {\r
+            "content": {\r
+              "required": true,\r
+              "type": "string"\r
+            }\r
+          }\r
+        },\r
+        "mapping": {\r
+          "type": "tosca.capability.Mapping",\r
+          "properties": {\r
+            "mapping": {\r
+              "required": false,\r
+              "type": "list",\r
+              "entry_schema": {\r
+                "type": "datatype-resource-assignment"\r
+              }\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "derived_from": "tosca.nodes.Artifact"\r
+    },\r
+    "vnf-netconf-device": {\r
+      "description": "This is VNF Device with Netconf and SSH Capability",\r
+      "version": "1.0.0",\r
+      "capabilities": {\r
+        "netconf": {\r
+          "type": "tosca.capability.Netconf",\r
+          "properties": {\r
+            "profile-name": {\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "oam-ipv4-address": {\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "port-number": {\r
+              "required": true,\r
+              "type": "integer",\r
+              "default": 830\r
+            },\r
+            "connection-time-out": {\r
+              "required": false,\r
+              "type": "integer",\r
+              "default": 30\r
+            }\r
+          }\r
+        },\r
+        "ssh": {\r
+          "type": "tosca.capability.Ssh",\r
+          "properties": {\r
+            "profile-name": {\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "oam-ipv4-address": {\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "port-number": {\r
+              "required": true,\r
+              "type": "integer",\r
+              "default": 22\r
+            },\r
+            "message-time-out": {\r
+              "required": false,\r
+              "type": "integer",\r
+              "default": 3000\r
+            },\r
+            "connection-time-out": {\r
+              "required": false,\r
+              "type": "integer",\r
+              "default": 3000\r
+            }\r
+          }\r
+        },\r
+        "sftp": {\r
+          "type": "tosca.capability.Sftp",\r
+          "properties": {\r
+            "profile-name": {\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "oam-ipv4-address": {\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "port-number": {\r
+              "required": true,\r
+              "type": "integer",\r
+              "default": 22\r
+            },\r
+            "message-time-out": {\r
+              "required": false,\r
+              "type": "integer",\r
+              "default": 3000\r
+            },\r
+            "connection-time-out": {\r
+              "required": false,\r
+              "type": "integer",\r
+              "default": 3000\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "derived_from": "tosca.nodes.Vnf"\r
+    },\r
+    "dg-activate-netconf": {\r
+      "description": "This is Download Netconf Directed Graph",\r
+      "version": "1.0.0",\r
+      "properties": {\r
+        "mode": {\r
+          "required": false,\r
+          "type": "string",\r
+          "default": "sync"\r
+        },\r
+        "version": {\r
+          "required": false,\r
+          "type": "string",\r
+          "default": "LATEST"\r
+        },\r
+        "is-start-flow": {\r
+          "required": false,\r
+          "type": "boolean",\r
+          "default": "false"\r
+        }\r
+      },\r
+      "capabilities": {\r
+        "dg-node": {\r
+          "type": "tosca.capabilities.Node"\r
+        },\r
+        "content": {\r
+          "type": "tosca.capability.Content",\r
+          "properties": {\r
+            "type": {\r
+              "required": false,\r
+              "type": "string",\r
+              "default": "json"\r
+            },\r
+            "content": {\r
+              "required": true,\r
+              "type": "string"\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "requirements": {\r
+        "component-dependency": {\r
+          "capability": "component-node",\r
+          "node": "component-netconf-executor",\r
+          "relationship": "tosca.relationships.DependsOn"\r
+        }\r
+      },\r
+      "interfaces": {\r
+        "CONFIG": {\r
+          "operations": {\r
+            "ActivateNetconf": {\r
+              "inputs": {\r
+                "params": {\r
+                  "required": false,\r
+                  "type": "list",\r
+                  "entry_schema": {\r
+                    "type": "datatype-property"\r
+                  }\r
+                }\r
+              }\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "derived_from": "tosca.nodes.DG"\r
+    },\r
+    "component-netconf-executor": {\r
+      "description": "This is Netconf Transaction Configuration Component API",\r
+      "version": "1.0.0",\r
+      "capabilities": {\r
+        "component-node": {\r
+          "type": "tosca.capabilities.Node"\r
+        }\r
+      },\r
+      "requirements": {\r
+        "netconf-connection": {\r
+          "capability": "netconf",\r
+          "node": "vnf-netconf-device",\r
+          "relationship": "tosca.relationships.ConnectsTo"\r
+        }\r
+      },\r
+      "interfaces": {\r
+        "org-openecomp-sdnc-netconf-adaptor-service-NetconfExecutorNode": {\r
+          "operations": {\r
+            "process": {\r
+              "inputs": {\r
+                "request-id": {\r
+                  "description": "Request Id used to store the generated configuration, in the database along with the template-name",\r
+                  "required": true,\r
+                  "type": "string"\r
+                },\r
+                "service-template-name": {\r
+                  "description": "Service Template Name",\r
+                  "required": true,\r
+                  "type": "string"\r
+                },\r
+                "service-template-version": {\r
+                  "description": "Service Template Version",\r
+                  "required": true,\r
+                  "type": "string"\r
+                },\r
+                "action-name": {\r
+                  "description": "Action Name to get from Database, Either (message & mask-info ) or ( resource-id & resource-type & action-name & template-name ) should be present. Message will be given higest priority",\r
+                  "required": false,\r
+                  "type": "string"\r
+                },\r
+                "resource-type": {\r
+                  "description": "Resource Type to get from Database, Either (message & mask-info ) or( resource-id & resource-type & action-name & template-name ) should be present. Message will be given higest priority",\r
+                  "required": false,\r
+                  "type": "string"\r
+                },\r
+                "resource-id": {\r
+                  "description": "Resource Id to get from Database, Either (message & mask-info ) or ( resource-id & resource-type & action-name & template-name ) should be present. Message will be given higest priority",\r
+                  "required": false,\r
+                  "type": "string"\r
+                },\r
+                "execution-script": {\r
+                  "description": "Python Script to Execute for this Component action, It should refer any one of Prython Artifact Definition for this Node Template.",\r
+                  "required": true,\r
+                  "type": "string"\r
+                }\r
+              },\r
+              "outputs": {\r
+                "response-data": {\r
+                  "description": "Execution Response Data in JSON format.",\r
+                  "type": "string"\r
+                },\r
+                "status": {\r
+                  "description": "Status of the Component Execution ( success or failure )",\r
+                  "required": true,\r
+                  "type": "string"\r
+                }\r
+              }\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "derived_from": "tosca.nodes.Component"\r
+    }\r
+  },\r
+  "data_types": {\r
+    "datatype-resource-assignment": {\r
+      "version": "1.0.0",\r
+      "description": "This is Resource Assignment Data Type",\r
+      "properties": {\r
+        "property": {\r
+          "required": true,\r
+          "type": "datatype-property"\r
+        },\r
+        "input-param": {\r
+          "required": true,\r
+          "type": "boolean"\r
+        },\r
+        "dictionary-name": {\r
+          "required": false,\r
+          "type": "string"\r
+        },\r
+        "dictionary-source": {\r
+          "required": false,\r
+          "type": "string"\r
+        },\r
+        "dependencies": {\r
+          "required": true,\r
+          "type": "list",\r
+          "entry_schema": {\r
+            "type": "string"\r
+          }\r
+        },\r
+        "status": {\r
+          "required": false,\r
+          "type": "string"\r
+        },\r
+        "message": {\r
+          "required": false,\r
+          "type": "string"\r
+        },\r
+        "updated-date": {\r
+          "required": false,\r
+          "type": "string"\r
+        },\r
+        "updated-by": {\r
+          "required": false,\r
+          "type": "string"\r
+        }\r
+      },\r
+      "derived_from": "tosca.datatypes.Root"\r
+    },\r
+    "datatype-property": {\r
+      "version": "1.0.0",\r
+      "description": "This is Entry point Input Data Type, which is dynamic datatype, The parameter names will be populated during the Design time for each inputs",\r
+      "properties": {\r
+        "type": {\r
+          "required": true,\r
+          "type": "string"\r
+        },\r
+        "description": {\r
+          "required": false,\r
+          "type": "string"\r
+        },\r
+        "required": {\r
+          "required": false,\r
+          "type": "boolean"\r
+        },\r
+        "default": {\r
+          "required": false,\r
+          "type": "string"\r
+        },\r
+        "entry_schema": {\r
+          "required": false,\r
+          "type": "string"\r
+        }\r
+      },\r
+      "derived_from": "tosca.datatypes.Root"\r
+    },\r
+    "dt-resource-assignment-request": {\r
+      "version": "1.0.0",\r
+      "description": "This is Dynamic Data type definition generated from resource mapping for the config template name base-config-template.",\r
+      "properties": {\r
+        "vnf-id": {\r
+          "required": true,\r
+          "type": "string"\r
+        },\r
+        "group-name": {\r
+          "required": true,\r
+          "type": "string"\r
+        },\r
+        "licence-key": {\r
+          "required": true,\r
+          "type": "string"\r
+        }\r
+      },\r
+      "derived_from": "tosca.datatypes.Dynamic"\r
+    }\r
+  }\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/load/blueprints/vrr-test/TOSCA-Metadata/TOSCA.meta b/ms/controllerblueprints/modules/service/load/blueprints/vrr-test/TOSCA-Metadata/TOSCA.meta
new file mode 100644 (file)
index 0000000..a4e1df3
--- /dev/null
@@ -0,0 +1,5 @@
+TOSCA-Meta-File-Version: 1.0.0\r
+CSAR-Version: 1.0\r
+Created-By: Brinda Santh M\r
+Entry-Definitions: Definitions/vrr-test.json\r
+Template-Tags: vrr-test, Brinda Santh\r
diff --git a/ms/controllerblueprints/modules/service/load/blueprints/vrr-test/Templates/base-config-template.vtl b/ms/controllerblueprints/modules/service/load/blueprints/vrr-test/Templates/base-config-template.vtl
new file mode 100644 (file)
index 0000000..92dba10
--- /dev/null
@@ -0,0 +1,40 @@
+ <config>\r
+               <configuration>\r
+                       <groups>\r
+                               <name>${group-name}</name>\r
+                               <routing-instances>\r
+                                       <instance>\r
+                                               <name>&lt;*&gt;</name>\r
+                                               <protocols>\r
+                                                       <pim>\r
+                                                               <dense-groups>\r
+                                                                       <dynamic-reject />\r
+                                                                       <pim-dense-group-type>\r
+                                                                               <name>224.0.1.40/32</name>\r
+                                                                       </pim-dense-group-type>\r
+                                                                       <pim-dense-group-type>\r
+                                                                               <name>224.0.1.39/32</name>\r
+                                                                       </pim-dense-group-type>\r
+                                                                       <pim-dense-group-type>\r
+                                                                               <name>224.0.0.0/4</name>\r
+                                                                               <reject />\r
+                                                                       </pim-dense-group-type>\r
+                                                               </dense-groups>\r
+                                                               <rp>\r
+                                                                       <auto-rp>\r
+                                                                               <discovery />\r
+                                                                       </auto-rp>\r
+                                                               </rp>\r
+                                                               <interface>\r
+                                                                       <name>&lt;*&gt;</name>\r
+                                                                       <disable />\r
+                                                                       <priority>1000</priority>\r
+                                                               </interface>\r
+                                                               <reset-tracking-bit />\r
+                                                       </pim>\r
+                                               </protocols>\r
+                                       </instance>\r
+                               </routing-instances>\r
+                       </groups>\r
+               </configuration>\r
+       </config>
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/load/blueprints/vrr-test/Templates/licence-template.vtl b/ms/controllerblueprints/modules/service/load/blueprints/vrr-test/Templates/licence-template.vtl
new file mode 100644 (file)
index 0000000..626974f
--- /dev/null
@@ -0,0 +1,4 @@
+ <config>\r
+               <configuration>\r
+               </configuration>\r
+                </config>\r
diff --git a/ms/controllerblueprints/modules/service/load/blueprints/vrr-test/__init__.py b/ms/controllerblueprints/modules/service/load/blueprints/vrr-test/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/ms/controllerblueprints/modules/service/load/model_type/artifact_type/artifact-mapping-resource.json b/ms/controllerblueprints/modules/service/load/model_type/artifact_type/artifact-mapping-resource.json
new file mode 100644 (file)
index 0000000..0a3261b
--- /dev/null
@@ -0,0 +1,8 @@
+{\r
+  "description": " Velocity Template Resource Mapping File used along with Configuration template",\r
+  "version": "1.0.0",\r
+  "file_ext": [\r
+    "json"\r
+  ],\r
+  "derived_from": "tosca.artifacts.Implementation"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/load/model_type/artifact_type/artifact-script-python.json b/ms/controllerblueprints/modules/service/load/model_type/artifact_type/artifact-script-python.json
new file mode 100644 (file)
index 0000000..b48d2b6
--- /dev/null
@@ -0,0 +1,8 @@
+{\r
+  "description": " Kotlin Script Template used for Configuration",\r
+  "version": "1.0.0",\r
+  "file_ext": [\r
+    "py"\r
+  ],\r
+  "derived_from": "tosca.artifacts.Implementation"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/load/model_type/artifact_type/artifact-template-velocity.json b/ms/controllerblueprints/modules/service/load/model_type/artifact_type/artifact-template-velocity.json
new file mode 100644 (file)
index 0000000..9395d39
--- /dev/null
@@ -0,0 +1,8 @@
+{\r
+  "description": " Velocity Template used for Configuration",\r
+  "version": "1.0.0",\r
+  "file_ext": [\r
+    "vtl"\r
+  ],\r
+  "derived_from": "tosca.artifacts.Implementation"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/load/model_type/data_type/datatype-property.json b/ms/controllerblueprints/modules/service/load/model_type/data_type/datatype-property.json
new file mode 100644 (file)
index 0000000..5584b10
--- /dev/null
@@ -0,0 +1,27 @@
+{\r
+       "version": "1.0.0",\r
+       "description": "This is Entry point Input Data Type, which is dynamic datatype, The parameter names will be populated during the Design time for each inputs",\r
+       "properties": {\r
+               "type": {\r
+                       "required": true,\r
+                       "type": "string"\r
+               },\r
+               "description": {\r
+                       "required": false,\r
+                       "type": "string"\r
+               },\r
+               "required": {\r
+                       "required": false,\r
+                       "type": "boolean"\r
+               },\r
+               "default": {\r
+                       "required": false,\r
+                       "type": "string"\r
+               },\r
+               "entry_schema": {\r
+                       "required": false,\r
+                       "type": "string"\r
+               }\r
+       },\r
+       "derived_from": "tosca.datatypes.Root"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/load/model_type/data_type/datatype-resource-assignment.json b/ms/controllerblueprints/modules/service/load/model_type/data_type/datatype-resource-assignment.json
new file mode 100644 (file)
index 0000000..cc9816e
--- /dev/null
@@ -0,0 +1,46 @@
+{\r
+       "version": "1.0.0",\r
+       "description": "This is Resource Assignment Data Type",\r
+       "properties": {\r
+               "property": {\r
+                       "required": true,\r
+                       "type": "datatype-property"\r
+               },\r
+               "input-param": {\r
+                       "required": true,\r
+                       "type": "boolean"\r
+               },\r
+               "dictionary-name": {\r
+                       "required": false,\r
+                       "type": "string"\r
+               },\r
+               "dictionary-source": {\r
+                       "required": false,\r
+                       "type": "string"\r
+               },\r
+               "dependencies": {\r
+                       "required": true,\r
+                       "type": "list",\r
+                       "entry_schema": {\r
+                               "type": "string"\r
+                       }\r
+               },\r
+               "status": {\r
+                       "required": false,\r
+                       "type": "string"\r
+               },\r
+               "message": {\r
+                       "required": false,\r
+                       "type": "string"\r
+               },\r
+               "updated-date": {\r
+                       "required": false,\r
+                       "type": "string"\r
+               },\r
+               "updated-by": {\r
+                       "required": false,\r
+                       "type": "string"\r
+               }\r
+       },\r
+       "derived_from": "tosca.datatypes.Root"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/load/model_type/data_type/dt-license-key.json b/ms/controllerblueprints/modules/service/load/model_type/data_type/dt-license-key.json
new file mode 100644 (file)
index 0000000..e9c312b
--- /dev/null
@@ -0,0 +1,11 @@
+{\r
+       "version": "1.0.0",\r
+       "description": "This is dt-plicense-key Data Type",\r
+       "properties": {\r
+               "license-key": {\r
+                       "required": true,\r
+                       "type": "string"\r
+               }\r
+       },\r
+       "derived_from": "tosca.datatypes.Root"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/load/model_type/data_type/dt-v4-aggregate.json b/ms/controllerblueprints/modules/service/load/model_type/data_type/dt-v4-aggregate.json
new file mode 100644 (file)
index 0000000..842a7f8
--- /dev/null
@@ -0,0 +1,15 @@
+{\r
+       "version": "1.0.0",\r
+       "description": "This is dt-v4-aggregate Data Type",\r
+       "properties": {\r
+               "ipv4-address": {\r
+                       "required": true,\r
+                       "type": "string"\r
+               },\r
+               "ipv4-plen": {\r
+                       "required": false,\r
+                       "type": "integer"\r
+               }\r
+       },\r
+       "derived_from": "tosca.datatypes.Root"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/load/model_type/node_type/artifact-config-template.json b/ms/controllerblueprints/modules/service/load/model_type/node_type/artifact-config-template.json
new file mode 100644 (file)
index 0000000..be9bbfc
--- /dev/null
@@ -0,0 +1,37 @@
+{\r
+       "description": "This is Configuration Velocity Template",\r
+       "version": "1.0.0",\r
+       "properties": {\r
+               "action-names": {\r
+                       "required": true,\r
+                       "type": "list",\r
+                       "entry_schema": {\r
+                               "type": "string"\r
+                       }\r
+               }\r
+       },\r
+       "capabilities": {\r
+               "content": {\r
+                       "type": "tosca.capability.Content",\r
+                       "properties": {\r
+                               "content": {\r
+                                       "required": true,\r
+                                       "type": "string"\r
+                               }\r
+                       }\r
+               },\r
+               "mapping": {\r
+                       "type": "tosca.capability.Mapping",\r
+                       "properties": {\r
+                               "mapping": {\r
+                                       "required": false,\r
+                                       "type": "list",\r
+                                       "entry_schema": {\r
+                                               "type": "datatype-resource-assignment"\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       },\r
+       "derived_from": "tosca.nodes.Artifact"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/load/model_type/node_type/component-config-generator.json b/ms/controllerblueprints/modules/service/load/model_type/node_type/component-config-generator.json
new file mode 100644 (file)
index 0000000..764f9e8
--- /dev/null
@@ -0,0 +1,72 @@
+{\r
+       "description": "This is Generate Configuration Component API",\r
+       "version": "1.0.0",\r
+       "capabilities": {\r
+               "component-node": {\r
+                       "type": "tosca.capabilities.Node"\r
+               }\r
+       },\r
+       "interfaces": {\r
+               "org-openecomp-sdnc-config-generator-service-ConfigGeneratorNode": {\r
+                       "operations": {\r
+                               "process": {\r
+                                       "inputs": {\r
+                                               "template-data": {\r
+                                                       "description": "Conditional : JSON string which is used to mash with template. Either template-data or ( resource-id and resource-type ) should be present",\r
+                                                       "required": false,\r
+                                                       "type": "string"\r
+                                               },\r
+                                               "template-content": {\r
+                                                       "description": "Conditional : Dynamic Template used to generate Configuration.",\r
+                                                       "required": false,\r
+                                                       "type": "string"\r
+                                               },\r
+                                               "resource-type": {\r
+                                                       "description": "Conditional : resource-type used to pull the data content from the data base. Either template-data or ( resource-id and resource-type ) should be present",\r
+                                                       "required": false,\r
+                                                       "type": "string"\r
+                                               },\r
+                                               "request-id": {\r
+                                                       "description": "Request Id used to store the generated configuration, in the database along with the template-name",\r
+                                                       "required": true,\r
+                                                       "type": "string"\r
+                                               },\r
+                                               "resource-id": {\r
+                                                       "description": "Conditional : Id used to pull the data content from the data base. Either template-data or ( resource-id and resource-type ) should be present",\r
+                                                       "required": false,\r
+                                                       "type": "string"\r
+                                               },\r
+                                               "action-name": {\r
+                                                       "description": "Conditional : Action Name to get from Database, Either (message & mask-info ) or ( resource-id & resource-type & action-name & template-name ) should be present. Message will be given higest priority",\r
+                                                       "required": false,\r
+                                                       "type": "string"\r
+                                               },\r
+                                               "template-name": {\r
+                                                       "description": "Conditional : Name of the Artifact Node Template, to get the template Content. If template-content is present, then content wont be reterived from the Artifact Node Template.",\r
+                                                       "required": true,\r
+                                                       "type": "string"\r
+                                               }\r
+                                       },\r
+                                       "outputs": {\r
+                                               "generated-config": {\r
+                                                       "description": "Generated Configuration for the Template adn Resource Data",\r
+                                                       "required": true,\r
+                                                       "type": "string"\r
+                                               },\r
+                                               "mask-info": {\r
+                                                       "description": "If template contains mask encription keys, then this mask-info field will be generated, This JSON Content alligns to the bean org.onap.ccsdk.apps.controllerblueprints.core.data.custom.MaskInfo ",\r
+                                                       "required": false,\r
+                                                       "type": "string"\r
+                                               },\r
+                                               "status": {\r
+                                                       "description": "Status of the Component Execution ( success or failure )",\r
+                                                       "required": true,\r
+                                                       "type": "string"\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       },\r
+       "derived_from": "tosca.nodes.Component"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/load/model_type/node_type/component-netconf-edit.json b/ms/controllerblueprints/modules/service/load/model_type/node_type/component-netconf-edit.json
new file mode 100644 (file)
index 0000000..144e1dd
--- /dev/null
@@ -0,0 +1,95 @@
+{\r
+  "description": "This is Netconf Edit Configuration Component API",\r
+  "version": "1.0.0",\r
+  "capabilities": {\r
+    "component-node": {\r
+      "type": "tosca.capabilities.Node"\r
+    }\r
+  },\r
+  "interfaces": {\r
+    "org-openecomp-sdnc-netconf-adaptor-service-SimpleNetconfEditConfigNode": {\r
+      "operations": {\r
+        "process": {\r
+          "inputs": {\r
+            "template-name": {\r
+              "description": "Template name used by the Components during processing",\r
+              "required": false,\r
+              "type": "string"\r
+            },\r
+            "rpc-message": {\r
+              "description": "If the message is Neconf RPC message,It should be true or false.",\r
+              "required": false,\r
+              "type": "boolean",\r
+              "default": false\r
+            },\r
+            "wait": {\r
+              "description": "Delay time in sec before performing edit-config action.",\r
+              "required": false,\r
+              "type": "integer",\r
+              "default": 0\r
+            },\r
+            "unlock": {\r
+              "description": "If unLock command has to send before Edit Configuration.",\r
+              "required": false,\r
+              "type": "boolean",\r
+              "default": false\r
+            },\r
+            "config-target": {\r
+              "required": false,\r
+              "type": "string"\r
+            },\r
+            "commit": {\r
+              "description": "Issue commit command to the device after performing edit-config action.",\r
+              "required": false,\r
+              "type": "boolean",\r
+              "default": false\r
+            },\r
+            "edit-default-operation": {\r
+              "required": false,\r
+              "type": "string"\r
+            },\r
+            "content": {\r
+              "description": "Static messgae content, If this is not set, need to have Requirement relationship to Artifact contents.",\r
+              "required": false,\r
+              "type": "string"\r
+            },\r
+            "lock": {\r
+              "description": "Issue lock command to the device before performing edit-config action.",\r
+              "required": false,\r
+              "type": "boolean",\r
+              "default": false\r
+            },\r
+            "post-restart-wait": {\r
+              "description": "If Restart command should be issued before the Edit Operation, Provide the time to wait after restart. 0 meanno restart required or wait time in sec ex : 3000 for 5 ",\r
+              "required": false,\r
+              "type": "integer",\r
+              "default": 0\r
+            },\r
+            "pre-restart-wait": {\r
+              "description": "If Restart command should be issued after the Edit Operation, Provide the time to wait after restart. 0 meanno restart required or wait time in sec ex : 3000 for 5 ",\r
+              "required": false,\r
+              "type": "integer",\r
+              "default": 0\r
+            },\r
+            "message-time-out": {\r
+              "required": false,\r
+              "type": "integer",\r
+              "default": 30\r
+            }\r
+          },\r
+          "outputs": {\r
+            "rpc-response-message": {\r
+              "type": "string"\r
+            },\r
+            "status": {\r
+              "description": "Status of the Component Execution ( success or failure )",\r
+              "required": true,\r
+              "type": "string"\r
+            }\r
+          }\r
+        }\r
+      }\r
+    }\r
+  },\r
+  "derived_from": "tosca.nodes.Component"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/load/model_type/node_type/component-netconf-executor.json b/ms/controllerblueprints/modules/service/load/model_type/node_type/component-netconf-executor.json
new file mode 100644 (file)
index 0000000..aed667a
--- /dev/null
@@ -0,0 +1,79 @@
+{\r
+  "description": "This is Netconf Transaction Configuration Component API",\r
+  "version": "1.0.0",\r
+  "capabilities": {\r
+    "component-node": {\r
+      "type": "tosca.capabilities.Node"\r
+    }\r
+  },\r
+  "requirements": {\r
+    "netconf-connection": {\r
+      "capability": "netconf",\r
+      "node": "vnf-netconf-device",\r
+      "relationship": "tosca.relationships.ConnectsTo"\r
+    }\r
+  },\r
+  "interfaces": {\r
+    "org-openecomp-sdnc-netconf-adaptor-service-NetconfExecutorNode": {\r
+      "operations": {\r
+        "process": {\r
+          "inputs": {\r
+            "request-id": {\r
+              "description": "Request Id used to store the generated configuration, in the database along with the template-name",\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "service-template-name": {\r
+              "description": "Service Template Name",\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "service-template-version": {\r
+              "description": "Service Template Version",\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "action-name": {\r
+              "description": "Action Name to get from Database, Either (message & mask-info ) or ( resource-id & resource-type & action-name & template-name ) should be present. Message will be given higest priority",\r
+              "required": false,\r
+              "type": "string"\r
+            },\r
+            "resource-type": {\r
+              "description": "Resource Type to get from Database, Either (message & mask-info ) or( resource-id & resource-type & action-name & template-name ) should be present. Message will be given higest priority",\r
+              "required": false,\r
+              "type": "string"\r
+            },\r
+            "resource-id": {\r
+              "description": "Resource Id to get from Database, Either (message & mask-info ) or ( resource-id & resource-type & action-name & template-name ) should be present. Message will be given higest priority",\r
+              "required": false,\r
+              "type": "string"\r
+            },\r
+            "reservation-id": {\r
+                               "description": "Reservation Id used to send to NPM",\r
+                               "required": false,\r
+                               "type": "string"\r
+                       },\r
+            "execution-script": {\r
+              "description": "Python Script to Execute for this Component action, It should refer any one of Prython Artifact Definition for this Node Template.",\r
+              "required": true,\r
+              "type": "string"\r
+            }\r
+          },\r
+          "outputs": {\r
+            "response-data": {\r
+              "description": "Execution Response Data in JSON format.",\r
+              "required": false,\r
+              "type": "string"\r
+            },\r
+            "status": {\r
+              "description": "Status of the Component Execution ( success or failure )",\r
+              "required": true,\r
+              "type": "string"\r
+            }\r
+          }\r
+        }\r
+      }\r
+    }\r
+  },\r
+  "derived_from": "tosca.nodes.Component"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/load/model_type/node_type/component-netconf-get.json b/ms/controllerblueprints/modules/service/load/model_type/node_type/component-netconf-get.json
new file mode 100644 (file)
index 0000000..1659bf4
--- /dev/null
@@ -0,0 +1,61 @@
+{\r
+  "description": "This is Netconf Get Running Configuration Component API",\r
+  "version": "1.0.0",\r
+  "capabilities": {\r
+    "component-node": {\r
+      "type": "tosca.capabilities.Node"\r
+    }\r
+  },\r
+  "interfaces": {\r
+    "org-openecomp-sdnc-netconf-adaptor-service-SimpleNetconfGetConfigNode": {\r
+      "operations": {\r
+        "process": {\r
+          "inputs": {\r
+            "template-name": {\r
+              "description": "Template name used by the Components during processing",\r
+              "required": false,\r
+              "type": "string"\r
+            },\r
+            "rpc-message": {\r
+              "description": "It should be true, If the message is Neconf RPC message, It should be false If it is plain Config message.",\r
+              "required": false,\r
+              "type": "boolean",\r
+              "default": false\r
+            },\r
+            "wait": {\r
+              "required": false,\r
+              "type": "integer",\r
+              "default": 0\r
+            },\r
+            "lock": {\r
+              "required": false,\r
+              "type": "boolean",\r
+              "default": false\r
+            },\r
+            "content": {\r
+              "description": "Static messgae content, If this is not set, need to have Requirement relationship to Artifact contents.",\r
+              "required": false,\r
+              "type": "string"\r
+            },\r
+            "message-time-out": {\r
+              "required": false,\r
+              "type": "integer",\r
+              "default": 30\r
+            }\r
+          },\r
+          "outputs": {\r
+            "config-message": {\r
+              "type": "string"\r
+            },\r
+            "status": {\r
+              "description": "Status of the Component Execution ( success or failure )",\r
+              "required": true,\r
+              "type": "string"\r
+            }\r
+          }\r
+        }\r
+      }\r
+    }\r
+  },\r
+  "derived_from": "tosca.nodes.Component"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/load/model_type/node_type/component-resource-assignment.json b/ms/controllerblueprints/modules/service/load/model_type/node_type/component-resource-assignment.json
new file mode 100644 (file)
index 0000000..34c0284
--- /dev/null
@@ -0,0 +1,68 @@
+{\r
+  "description": "This is Resource Assignment Component API",\r
+  "version": "1.0.0",\r
+  "capabilities": {\r
+    "component-node": {\r
+      "type": "tosca.capabilities.Node"\r
+    }\r
+  },\r
+  "interfaces": {\r
+    "org-openecomp-sdnc-config-assignment-service-ConfigAssignmentNode": {\r
+      "operations": {\r
+        "process": {\r
+          "inputs": {\r
+            "service-template-name": {\r
+              "description": "Service Template Name.",\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "service-template-version": {\r
+              "description": "Service Template Version.",\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "resource-type": {\r
+              "description": "Request type.",\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "template-names": {\r
+              "description": "Name of the artifact Node Templates, to get the template Content.",\r
+              "required": true,\r
+              "type": "list",\r
+              "entry_schema": {\r
+                "type": "string"\r
+              }\r
+            },\r
+            "request-id": {\r
+              "description": "Request Id, Unique Id for the request.",\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "resource-id": {\r
+              "description": "Resource Id.",\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "action-name": {\r
+              "description": "Action Name of the process",\r
+              "required": true,\r
+              "type": "string"\r
+            }\r
+          },\r
+          "outputs": {\r
+            "resource-assignment-params": {\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "status": {\r
+              "required": true,\r
+              "type": "string"\r
+            }\r
+          }\r
+        }\r
+      }\r
+    }\r
+  },\r
+  "derived_from": "tosca.nodes.Component"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/load/model_type/node_type/component-transaction-netconf.json b/ms/controllerblueprints/modules/service/load/model_type/node_type/component-transaction-netconf.json
new file mode 100644 (file)
index 0000000..7c37458
--- /dev/null
@@ -0,0 +1,93 @@
+{\r
+  "description": "This is Netconf Transaction Configuration Component API",\r
+  "version": "1.0.0",\r
+  "capabilities": {\r
+    "component-node": {\r
+      "type": "tosca.capabilities.Node"\r
+    }\r
+  },\r
+  "requirements": {\r
+    "netconf-connection": {\r
+      "capability": "netconf",\r
+      "node": "vnf-netconf-device",\r
+      "relationship": "tosca.relationships.ConnectsTo"\r
+    }\r
+  },\r
+  "interfaces": {\r
+    "org-openecomp-sdnc-netconf-adaptor-service-NetconfTransactionNode": {\r
+      "operations": {\r
+        "process": {\r
+          "inputs": {\r
+            "rollback": {\r
+              "required": false,\r
+              "type": "boolean"\r
+            },\r
+            "assignment-action-name": {\r
+              "description": "Assignment Action Name to get from Database, Either (message & mask-info ) or ( resource-id & resource-type & action-name & template-name ) should be present. Message will be given higest priority",\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "transaction-components": {\r
+              "description": "Components used to used for the atomic transaction, Default Handlers are org.openecomp.sdnc.netconf.adaptor.service.SimpleNetconfEditConfigNode and org.openecomp.sdnc.netconf.adaptor.service.SimpleNetconfGetConfigNode",\r
+              "required": true,\r
+              "type": "list",\r
+              "entry_schema": {\r
+                "type": "string"\r
+              }\r
+            },\r
+            "resource-type": {\r
+              "description": "Resource Type to get from Database, Either (message & mask-info ) or( resource-id & resource-type & action-name & template-name ) should be present. Message will be given higest priority",\r
+              "required": false,\r
+              "type": "string"\r
+            },\r
+            "initialise-sftp": {\r
+              "required": false,\r
+              "type": "boolean"\r
+            },\r
+            "request-id": {\r
+              "description": "Request Id used to store the generated configuration, in the database along with the template-name",\r
+              "required": true,\r
+              "type": "string"\r
+            },\r
+            "initialise-ssh": {\r
+              "required": false,\r
+              "type": "boolean"\r
+            },\r
+            "lock": {\r
+              "required": false,\r
+              "type": "boolean",\r
+              "default": false\r
+            },\r
+            "unlock": {\r
+              "description": "If unLock command has to send before Edit Configuration.",\r
+              "required": false,\r
+              "type": "boolean",\r
+              "default": false\r
+            },\r
+            "resource-id": {\r
+              "description": "Resource Id to get from Database, Either (message & mask-info ) or ( resource-id & resource-type & action-name & template-name ) should be present. Message will be given higest priority",\r
+              "required": false,\r
+              "type": "string"\r
+            },\r
+            "action-name": {\r
+              "description": "Action Name to get from Database, Either (message & mask-info ) or ( resource-id & resource-type & action-name & template-name ) should be present. Message will be given higest priority",\r
+              "required": false,\r
+              "type": "string"\r
+            }\r
+          },\r
+          "outputs": {\r
+            "rpc-response-message": {\r
+              "type": "string"\r
+            },\r
+            "status": {\r
+              "description": "Status of the Component Execution ( success or failure )",\r
+              "required": true,\r
+              "type": "string"\r
+            }\r
+          }\r
+        }\r
+      }\r
+    }\r
+  },\r
+  "derived_from": "tosca.nodes.Component"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/load/model_type/node_type/dg-activate-netconf.json b/ms/controllerblueprints/modules/service/load/model_type/node_type/dg-activate-netconf.json
new file mode 100644 (file)
index 0000000..c638df0
--- /dev/null
@@ -0,0 +1,66 @@
+{
+       "description": "This is Download Netconf Directed Graph",
+       "version": "1.0.0",
+       "properties": {
+               "mode": {
+                       "required": false,
+                       "type": "string",
+                       "default": "sync"
+               },
+               "version": {
+                       "required": false,
+                       "type": "string",
+                       "default": "LATEST"
+               },
+               "is-start-flow": {
+                       "required": false,
+                       "type": "boolean",
+                       "default": "false"
+               }
+       },
+       "capabilities": {
+               "dg-node": {
+                       "type": "tosca.capabilities.Node"
+               },
+               "content": {
+                       "type": "tosca.capability.Content",
+                       "properties": {
+                               "type": {
+                                       "required": false,
+                                       "type": "string",
+                                       "default": "json"
+                               },
+                               "content": {
+                                       "required": true,
+                                       "type": "string"
+                               }
+                       }
+               }
+       },
+       "requirements": {
+               "component-dependency": {
+                       "capability": "component-node",
+                       "node": "component-netconf-executor",
+                       "relationship": "tosca.relationships.DependsOn"
+               }
+       },
+       "interfaces": {
+               "CONFIG": {
+                       "operations": {
+                               "ActivateNetconf": {
+                                       "inputs": {
+                                               "params": {
+                                                       "required": false,
+                                                       "type": "list",
+                                                       "entry_schema": {
+                                                               "type": "datatype-property"
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+       },
+       
+       "derived_from": "tosca.nodes.DG"
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/load/model_type/node_type/dg-config-generator.json b/ms/controllerblueprints/modules/service/load/model_type/node_type/dg-config-generator.json
new file mode 100644 (file)
index 0000000..28bace0
--- /dev/null
@@ -0,0 +1,65 @@
+{\r
+       "description": "This is Activate DG for Config Generator Directed Graph",\r
+       "version": "1.0.0",\r
+       "properties": {\r
+               "mode": {\r
+                       "required": false,\r
+                       "type": "string",\r
+                       "default": "sync"\r
+               },\r
+               "version": {\r
+                       "required": false,\r
+                       "type": "string",\r
+                       "default": "LATEST"\r
+               },\r
+               "is-start-flow": {\r
+                       "required": false,\r
+                       "type": "boolean",\r
+                       "default": "false"\r
+               }\r
+       },\r
+       "capabilities": {\r
+               "dg-node": {\r
+                       "type": "tosca.capabilities.Node"\r
+               },\r
+               "content": {\r
+                       "type": "tosca.capability.Content",\r
+                       "properties": {\r
+                               "type": {\r
+                                       "required": false,\r
+                                       "type": "string",\r
+                                       "default": "json"\r
+                               },\r
+                               "content": {\r
+                                       "required": true,\r
+                                       "type": "string"\r
+                               }\r
+                       }\r
+               }\r
+       },\r
+       "requirements": {\r
+               "component-dependency": {\r
+                       "capability": "component-node",\r
+                       "node": "component-config-generator",\r
+                       "relationship": "tosca.relationships.DependsOn"\r
+               }\r
+       },\r
+       "interfaces": {\r
+               "CONFIG": {\r
+                       "operations": {\r
+                               "GenerateConfiguration": {\r
+                                       "inputs": {\r
+                                               "params": {\r
+                                                       "required": false,\r
+                                                       "type": "list",\r
+                                                       "entry_schema": {\r
+                                                               "type": "datatype-property"\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       },\r
+       "derived_from": "tosca.nodes.DG"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/load/model_type/node_type/dg-resource-assign-activate.json b/ms/controllerblueprints/modules/service/load/model_type/node_type/dg-resource-assign-activate.json
new file mode 100644 (file)
index 0000000..e98fa5a
--- /dev/null
@@ -0,0 +1,70 @@
+{\r
+       "description": "This is Resource Assign and Activate Netconf Directed Graph",\r
+       "version": "1.0.0",\r
+       "properties": {\r
+               "mode": {\r
+                       "required": false,\r
+                       "type": "string",\r
+                       "default": "sync"\r
+               },\r
+               "version": {\r
+                       "required": false,\r
+                       "type": "string",\r
+                       "default": "LATEST"\r
+               },\r
+               "is-start-flow": {\r
+                       "required": false,\r
+                       "type": "boolean",\r
+                       "default": "false"\r
+               }\r
+       },\r
+       "capabilities": {\r
+               "dg-node": {\r
+                       "type": "tosca.capabilities.Node"\r
+               },\r
+               "content": {\r
+                       "type": "tosca.capability.Content",\r
+                       "properties": {\r
+                               "type": {\r
+                                       "required": false,\r
+                                       "type": "string",\r
+                                       "default": "json"\r
+                               },\r
+                               "content": {\r
+                                       "required": false,\r
+                                       "type": "string"\r
+                               }\r
+                       }\r
+               }\r
+       },\r
+       "requirements": {\r
+               "ra-component": {\r
+                       "capability": "component-node",\r
+                       "node": "component-resource-assignment",\r
+                       "relationship": "tosca.relationships.DependsOn"\r
+               },\r
+               "netconf-component": {\r
+                       "capability": "component-node",\r
+                       "node": "component-netconf-executor",\r
+                       "relationship": "tosca.relationships.DependsOn"\r
+               }\r
+       },\r
+       "interfaces": {\r
+               "CONFIG": {\r
+                       "operations": {\r
+                               "ResourceAssignAndActivate": {\r
+                                       "inputs": {\r
+                                               "params": {\r
+                                                       "required": false,\r
+                                                       "type": "list",\r
+                                                       "entry_schema": {\r
+                                                               "type": "datatype-property"\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       },\r
+       "derived_from": "tosca.nodes.DG"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/load/model_type/node_type/dg-resource-assignment.json b/ms/controllerblueprints/modules/service/load/model_type/node_type/dg-resource-assignment.json
new file mode 100644 (file)
index 0000000..36fbb68
--- /dev/null
@@ -0,0 +1,65 @@
+{\r
+       "description": "This is Resource Assignment Directed Graph",\r
+       "version": "1.0.0",\r
+       "properties": {\r
+               "mode": {\r
+                       "required": false,\r
+                       "type": "string",\r
+                       "default": "sync"\r
+               },\r
+               "version": {\r
+                       "required": false,\r
+                       "type": "string",\r
+                       "default": "LATEST"\r
+               },\r
+               "is-start-flow": {\r
+                       "required": false,\r
+                       "type": "boolean",\r
+                       "default": "false"\r
+               }\r
+       },\r
+       "capabilities": {\r
+               "dg-node": {\r
+                       "type": "tosca.capabilities.Node"\r
+               },\r
+               "content": {\r
+                       "type": "tosca.capability.Content",\r
+                       "properties": {\r
+                               "type": {\r
+                                       "required": false,\r
+                                       "type": "string",\r
+                                       "default": "json"\r
+                               },\r
+                               "content": {\r
+                                       "required": false,\r
+                                       "type": "string"\r
+                               }\r
+                       }\r
+               }\r
+       },\r
+       "requirements": {\r
+               "component-dependency": {\r
+                       "capability": "component-node",\r
+                       "node": "component-resource-assignment",\r
+                       "relationship": "tosca.relationships.DependsOn"\r
+               }\r
+       },\r
+       "interfaces": {\r
+               "CONFIG": {\r
+                       "operations": {\r
+                               "ResourceAssignment": {\r
+                                       "inputs": {\r
+                                               "params": {\r
+                                                       "required": false,\r
+                                                       "type": "list",\r
+                                                       "entry_schema": {\r
+                                                               "type": "datatype-property"\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       },\r
+       "derived_from": "tosca.nodes.DG"\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/load/model_type/node_type/vnf-netconf-device.json b/ms/controllerblueprints/modules/service/load/model_type/node_type/vnf-netconf-device.json
new file mode 100644 (file)
index 0000000..54573ba
--- /dev/null
@@ -0,0 +1,42 @@
+{\r
+       "description": "This is VNF Device with Netconf  Capability",\r
+       "version": "1.0.0",\r
+       "capabilities": {\r
+               "netconf": {\r
+                       "type": "tosca.capability.Netconf",\r
+                       "properties": {\r
+                               "login-key": {\r
+                                       "required": true,\r
+                                       "type": "string",\r
+                                       "default": "sdnc"\r
+                               },\r
+                               "login-account": {\r
+                                       "required": true,\r
+                                       "type": "string",\r
+                                       "default": "sdnc-tacacs"\r
+                               },\r
+                               "source": {\r
+                                       "required": true,\r
+                                       "type": "string",\r
+                                       "default": "npm"\r
+                               },\r
+                               "target-ip-address": {\r
+                                       "required": true,\r
+                                       "type": "string"\r
+                               },\r
+                               "port-number": {\r
+                                       "required": true,\r
+                                       "type": "integer",\r
+                                       "default": 830\r
+                               },\r
+                               "connection-time-out": {\r
+                                       "required": false,\r
+                                       "type": "integer",\r
+                                       "default": 30\r
+                               }\r
+                       }\r
+               }\r
+       },\r
+       "derived_from": "tosca.nodes.Vnf"\r
+       \r
+}\r
diff --git a/ms/controllerblueprints/modules/service/load/resource_dictionary/action-name.json b/ms/controllerblueprints/modules/service/load/resource_dictionary/action-name.json
new file mode 100644 (file)
index 0000000..92b64e6
--- /dev/null
@@ -0,0 +1,17 @@
+{\r
+       "name": "action-name",\r
+       "resource-path": "action-name",\r
+       "resource-type": "ONAP",\r
+       "description": "To be provided",\r
+       "valid-values": null,\r
+       "sample-value": null,\r
+       "updated-by": "ym9479@onap.com",\r
+       "tags": null,\r
+       "default": null,\r
+       "data-type": "string",\r
+       "source": {\r
+               "input": {\r
+                       "key": "action-name"\r
+               }\r
+       }\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/load/resource_dictionary/bundle-id.json b/ms/controllerblueprints/modules/service/load/resource_dictionary/bundle-id.json
new file mode 100644 (file)
index 0000000..f9678f5
--- /dev/null
@@ -0,0 +1,32 @@
+{\r
+  "name": "bundle-id",\r
+  "description": "name of the ",\r
+  "resource-type": "ONAP",\r
+  "resource-path": "vnf/bundle-id",\r
+  "updated-by": "ym9479@onap.com",\r
+  "data-type": "String",\r
+  "tags": "bundle-id, ym9479@onap.com",\r
+  "source": {\r
+    "db": {\r
+      "path": "$key-value",\r
+      "input-key-mapping": {\r
+        "key-value": "$resource-group-key"\r
+      },\r
+      "output-key-mapping": {\r
+        "bundle-id": "bundle-id"\r
+      }\r
+    },\r
+    "input": {\r
+    }\r
+  },\r
+  "decryption-rules": [\r
+    {\r
+      "sources": [\r
+        "input"\r
+      ],\r
+      "path": "/.",\r
+      "rule": "LOCAL-Decrypt",\r
+      "decrypt-type": "AES128"\r
+    }\r
+  ]\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/load/resource_dictionary/v4-ip-type.json b/ms/controllerblueprints/modules/service/load/resource_dictionary/v4-ip-type.json
new file mode 100644 (file)
index 0000000..03254b7
--- /dev/null
@@ -0,0 +1,14 @@
+{\r
+       "tags": "v4-ip-type, tosca.datatypes.Root, data_type, ym9479@onap.com",\r
+       "name": "v4-ip-type",\r
+       "description": "To be provided",\r
+       "updated-by": "ym9479@onap.com",\r
+       "resource-type": "ONAP",\r
+       "resource-path": "vnf/v4-ip-type",\r
+       "data-type": "string",\r
+       "source": {\r
+               "input": {\r
+                       \r
+               }\r
+       }\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/pom.xml b/ms/controllerblueprints/modules/service/pom.xml
new file mode 100644 (file)
index 0000000..17738bf
--- /dev/null
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+  ~ Copyright © 2017-2018 AT&T Intellectual Property.\r
+  ~\r
+  ~ Licensed under the Apache License, Version 2.0 (the "License");\r
+  ~ you may not use this file except in compliance with the License.\r
+  ~ You may obtain a copy of the License at\r
+  ~\r
+  ~     http://www.apache.org/licenses/LICENSE-2.0\r
+  ~\r
+  ~ Unless required by applicable law or agreed to in writing, software\r
+  ~ distributed under the License is distributed on an "AS IS" BASIS,\r
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+  ~ See the License for the specific language governing permissions and\r
+  ~ limitations under the License.\r
+  -->\r
+\r
+<project\r
+        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"\r
+        xmlns="http://maven.apache.org/POM/4.0.0"\r
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
+    <modelVersion>4.0.0</modelVersion>\r
+    <parent>\r
+        <groupId>org.onap.ccsdk.apps</groupId>\r
+        <artifactId>controllerblueprints-modules</artifactId>\r
+        <version>0.3.0-SNAPSHOT</version>\r
+    </parent>\r
+    <artifactId>controllerblueprints-service</artifactId>\r
+    <name>Controller Blueprints Service</name>\r
+\r
+    <properties>\r
+    </properties>\r
+\r
+    <dependencies>\r
+        <dependency>\r
+            <groupId>org.onap.ccsdk.apps</groupId>\r
+            <artifactId>controllerblueprints-resource-dict</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.apache.commons</groupId>\r
+            <artifactId>commons-lang3</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>commons-collections</groupId>\r
+            <artifactId>commons-collections</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>commons-io</groupId>\r
+            <artifactId>commons-io</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.apache.velocity</groupId>\r
+            <artifactId>velocity</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>io.swagger</groupId>\r
+            <artifactId>swagger-jersey2-jaxrs</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.json</groupId>\r
+            <artifactId>json</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.springframework.boot</groupId>\r
+            <artifactId>spring-boot-starter-web</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.springframework.boot</groupId>\r
+            <artifactId>spring-boot-starter-jersey</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>org.springframework.boot</groupId>\r
+            <artifactId>spring-boot-starter-data-jpa</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>mysql</groupId>\r
+            <artifactId>mysql-connector-java</artifactId>\r
+        </dependency>\r
+        <dependency>\r
+            <groupId>com.h2database</groupId>\r
+            <artifactId>h2</artifactId>\r
+            <scope>runtime</scope>\r
+        </dependency>\r
+        <!--<dependency>-->\r
+        <!--<groupId>org.mariadb.jdbc</groupId>-->\r
+        <!--<artifactId>mariadb-java-client</artifactId>-->\r
+        <!--</dependency>-->\r
+\r
+        <dependency>\r
+            <groupId>org.springframework.boot</groupId>\r
+            <artifactId>spring-boot-starter-test</artifactId>\r
+            <scope>test</scope>\r
+        </dependency>\r
+    </dependencies>\r
+</project>\r
+\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/AutoResourceMappingService.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/AutoResourceMappingService.java
new file mode 100644 (file)
index 0000000..6b09c81
--- /dev/null
@@ -0,0 +1,211 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service;\r
+\r
+import org.apache.commons.collections.CollectionUtils;\r
+import org.apache.commons.lang3.StringUtils;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.PropertyDefinition;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils;\r
+import org.onap.ccsdk.apps.controllerblueprints.resource.dict.ResourceAssignment;\r
+import org.onap.ccsdk.apps.controllerblueprints.resource.dict.data.DictionaryDefinition;\r
+import org.onap.ccsdk.apps.controllerblueprints.resource.dict.utils.ResourceDictionaryUtils;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ResourceDictionary;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.model.AutoMapResponse;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.repository.ResourceDictionaryRepository;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+import org.springframework.stereotype.Service;\r
+\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+/**\r
+ * AutoResourceMappingService.java Purpose: Provide Automapping of Resource Assignments AutoResourceMappingService\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+\r
+@Service\r
+public class AutoResourceMappingService {\r
+\r
+    private static Logger log = LoggerFactory.getLogger(AutoResourceMappingService.class);\r
+\r
+    private ResourceDictionaryRepository dataDictionaryRepository;\r
+\r
+    /**\r
+     * This is a AutoResourceMappingService constructor\r
+     * \r
+     * @param dataDictionaryRepository\r
+     * \r
+     */\r
+    public AutoResourceMappingService(ResourceDictionaryRepository dataDictionaryRepository) {\r
+        this.dataDictionaryRepository = dataDictionaryRepository;\r
+    }\r
+\r
+    /**\r
+     * This is a autoMap service to map the template keys automatically to Dictionary fields.\r
+     * \r
+     * @param resourceAssignments\r
+     * @return AutoMapResponse\r
+     */\r
+    public AutoMapResponse autoMap(List<ResourceAssignment> resourceAssignments) throws BluePrintException {\r
+        AutoMapResponse autoMapResponse = new AutoMapResponse();\r
+        try {\r
+            if (CollectionUtils.isNotEmpty(resourceAssignments)) {\r
+\r
+                // Create the Dictionary definitions for the ResourceAssignment Names\r
+                Map<String, ResourceDictionary> dictionaryMap = getDictionaryDefinitions(resourceAssignments);\r
+\r
+                for (ResourceAssignment resourceAssignment : resourceAssignments) {\r
+                    if (resourceAssignment != null && StringUtils.isNotBlank(resourceAssignment.getName())\r
+                            && StringUtils.isBlank(resourceAssignment.getDictionaryName())) {\r
+\r
+                        populateDictionaryMapping(dictionaryMap, resourceAssignment);\r
+\r
+                        log.info("Mapped Resource : {}", resourceAssignment);\r
+\r
+                    } else {\r
+                        // Do nothins\r
+                    }\r
+                }\r
+            }\r
+            List<ResourceDictionary> dictionaries = getDictionaryDefinitionsList(resourceAssignments);\r
+            List<ResourceAssignment> resourceAssignmentsFinal = getAllAutomapResourceAssignments(resourceAssignments);\r
+            autoMapResponse.setDataDictionaries(dictionaries);\r
+            autoMapResponse.setResourceAssignments(resourceAssignmentsFinal);\r
+        } catch (Exception e) {\r
+            log.error(String.format("Failed in auto process %s", e.getMessage()));\r
+            throw new BluePrintException(e.getMessage(), e);\r
+        }\r
+        return autoMapResponse;\r
+    }\r
+\r
+    private void populateDictionaryMapping(Map<String, ResourceDictionary> dictionaryMap, ResourceAssignment resourceAssignment) {\r
+        ResourceDictionary dbDataDictionary = dictionaryMap.get(resourceAssignment.getName());\r
+        if (dbDataDictionary != null && StringUtils.isNotBlank(dbDataDictionary.getDefinition())) {\r
+\r
+            DictionaryDefinition dictionaryDefinition = JacksonUtils.readValue(dbDataDictionary.getDefinition(), DictionaryDefinition.class);\r
+\r
+            if (dictionaryDefinition != null && StringUtils.isNotBlank(dictionaryDefinition.getName())\r
+                    && StringUtils.isBlank(resourceAssignment.getDictionaryName())) {\r
+\r
+                resourceAssignment.setDictionaryName(dbDataDictionary.getName());\r
+                ResourceDictionaryUtils.populateSourceMapping(resourceAssignment, dictionaryDefinition);\r
+            }\r
+        }\r
+    }\r
+\r
+    private Map<String, ResourceDictionary> getDictionaryDefinitions(List<ResourceAssignment> resourceAssignments) {\r
+        Map<String, ResourceDictionary> dictionaryMap = new HashMap<>();\r
+        List<String> names = new ArrayList<>();\r
+        for (ResourceAssignment resourceAssignment : resourceAssignments) {\r
+            if (resourceAssignment != null && StringUtils.isNotBlank(resourceAssignment.getName())) {\r
+                names.add(resourceAssignment.getName());\r
+            }\r
+        }\r
+        if (CollectionUtils.isNotEmpty(names)) {\r
+\r
+            List<ResourceDictionary> dictionaries = dataDictionaryRepository.findByNameIn(names);\r
+            if (CollectionUtils.isNotEmpty( dictionaries)) {\r
+                for (ResourceDictionary dataDictionary : dictionaries) {\r
+                    if (dataDictionary != null && StringUtils.isNotBlank(dataDictionary.getName())) {\r
+                        dictionaryMap.put(dataDictionary.getName(), dataDictionary);\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        return dictionaryMap;\r
+\r
+    }\r
+\r
+    private List<ResourceDictionary> getDictionaryDefinitionsList(List<ResourceAssignment> resourceAssignments) {\r
+        List<ResourceDictionary> dictionaries = null;\r
+        List<String> names = new ArrayList<>();\r
+        for (ResourceAssignment resourceAssignment : resourceAssignments) {\r
+            if (resourceAssignment != null && StringUtils.isNotBlank(resourceAssignment.getDictionaryName())) {\r
+\r
+                if (!names.contains(resourceAssignment.getDictionaryName())) {\r
+                    names.add(resourceAssignment.getDictionaryName());\r
+                }\r
+\r
+                if (resourceAssignment.getDependencies() != null && !resourceAssignment.getDependencies().isEmpty()) {\r
+                    List<String> dependencyNames = resourceAssignment.getDependencies();\r
+                    for (String dependencyName : dependencyNames) {\r
+                        if (StringUtils.isNotBlank(dependencyName) && !names.contains(dependencyName)) {\r
+                            names.add(dependencyName);\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        if (CollectionUtils.isNotEmpty(names)) {\r
+            dictionaries = dataDictionaryRepository.findByNameIn(names);\r
+        }\r
+        return dictionaries;\r
+\r
+    }\r
+\r
+    private List<ResourceAssignment> getAllAutomapResourceAssignments(List<ResourceAssignment> resourceAssignments) {\r
+        List<ResourceDictionary> dictionaries = null;\r
+        List<String> names = new ArrayList<>();\r
+        List<ResourceAssignment> resourceAssignmentsWithDepencies = resourceAssignments;\r
+        for (ResourceAssignment resourceAssignment : resourceAssignments) {\r
+            if (resourceAssignment != null && StringUtils.isNotBlank(resourceAssignment.getDictionaryName())) {\r
+                if (resourceAssignment.getDependencies() != null && !resourceAssignment.getDependencies().isEmpty()) {\r
+                    List<String> dependencieNames = resourceAssignment.getDependencies();\r
+                    for (String dependencieName : dependencieNames) {\r
+                        if (StringUtils.isNotBlank(dependencieName) && !names.contains(dependencieName)\r
+                                && !checkAssignmentsExists(resourceAssignmentsWithDepencies, dependencieName)) {\r
+                            names.add(dependencieName);\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+        }\r
+\r
+        if (!names.isEmpty()) {\r
+            dictionaries = dataDictionaryRepository.findByNameIn(names);\r
+        }\r
+        if (dictionaries != null) {\r
+            for (ResourceDictionary resourcedictionary : dictionaries) {\r
+                DictionaryDefinition dictionaryDefinition = JacksonUtils.readValue(resourcedictionary.getDefinition(), DictionaryDefinition.class);\r
+                PropertyDefinition property = new PropertyDefinition();\r
+                               property.setRequired(true);\r
+                               ResourceAssignment resourceAssignment = new ResourceAssignment();\r
+                               resourceAssignment.setName(resourcedictionary.getName());\r
+                               resourceAssignment.setDictionaryName(resourcedictionary\r
+                                               .getName());\r
+                               resourceAssignment.setVersion(0);\r
+                               resourceAssignment.setProperty(property);\r
+                ResourceDictionaryUtils.populateSourceMapping(resourceAssignment, dictionaryDefinition);\r
+                    resourceAssignmentsWithDepencies.add(resourceAssignment);\r
+            }\r
+        }\r
+        return resourceAssignmentsWithDepencies;\r
+\r
+    }\r
+\r
+\r
+    public boolean checkAssignmentsExists(List<ResourceAssignment> resourceAssignmentsWithDepencies, String resourceName) {\r
+        return resourceAssignmentsWithDepencies.stream().anyMatch(names -> names.getName().equalsIgnoreCase(resourceName));\r
+    }\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/BluePrintEnhancerRepoDBService.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/BluePrintEnhancerRepoDBService.java
new file mode 100644 (file)
index 0000000..a2e5b10
--- /dev/null
@@ -0,0 +1,100 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service;\r
+\r
+import com.google.common.base.Preconditions;\r
+import org.apache.commons.lang3.StringUtils;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.*;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.service.BluePrintEnhancerRepoService;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ModelType;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.repository.ModelTypeRepository;\r
+import org.springframework.stereotype.Service;\r
+\r
+import java.util.Optional;\r
+\r
+/**\r
+ * BluePrintEnhancerRepoDBService\r
+ *\r
+ * @author Brinda Santh\r
+ */\r
+@Service\r
+public class BluePrintEnhancerRepoDBService implements BluePrintEnhancerRepoService {\r
+\r
+    private ModelTypeRepository modelTypeRepository;\r
+\r
+    public BluePrintEnhancerRepoDBService(ModelTypeRepository modelTypeRepository) {\r
+        this.modelTypeRepository = modelTypeRepository;\r
+    }\r
+\r
+   \r
+    @Override\r
+    public NodeType getNodeType(String nodeTypeName) throws BluePrintException {\r
+        Preconditions.checkArgument(StringUtils.isNotBlank(nodeTypeName), "NodeType name is missing");\r
+        String content = getModelDefinitions(nodeTypeName);\r
+        Preconditions.checkArgument(StringUtils.isNotBlank(content), "NodeType content is missing");\r
+        return JacksonUtils.readValue(content, NodeType.class);\r
+    }\r
+\r
+   \r
+    @Override\r
+    public DataType getDataType(String dataTypeName) throws BluePrintException {\r
+        Preconditions.checkArgument(StringUtils.isNotBlank(dataTypeName), "DataType name is missing");\r
+        String content = getModelDefinitions(dataTypeName);\r
+        Preconditions.checkArgument(StringUtils.isNotBlank(content), "DataType content is missing");\r
+        return JacksonUtils.readValue(content, DataType.class);\r
+    }\r
+\r
+   \r
+    @Override\r
+    public ArtifactType getArtifactType(String artifactTypeName) throws BluePrintException {\r
+        Preconditions.checkArgument(StringUtils.isNotBlank(artifactTypeName), "ArtifactType name is missing");\r
+        String content = getModelDefinitions(artifactTypeName);\r
+        Preconditions.checkArgument(StringUtils.isNotBlank(content), "ArtifactType content is missing");\r
+        return JacksonUtils.readValue(content, ArtifactType.class);\r
+    }\r
+\r
+   \r
+    @Override\r
+    public RelationshipType getRelationshipType(String relationshipTypeName) throws BluePrintException {\r
+        Preconditions.checkArgument(StringUtils.isNotBlank(relationshipTypeName), "RelationshipType name is missing");\r
+        String content = getModelDefinitions(relationshipTypeName);\r
+        Preconditions.checkArgument(StringUtils.isNotBlank(content), "RelationshipType content is missing");\r
+        return JacksonUtils.readValue(content, RelationshipType.class);\r
+    }\r
+\r
+   \r
+    @Override\r
+    public CapabilityDefinition getCapabilityDefinition(String capabilityDefinitionName) throws BluePrintException {\r
+        Preconditions.checkArgument(StringUtils.isNotBlank(capabilityDefinitionName), "CapabilityDefinition name is missing");\r
+        String content = getModelDefinitions(capabilityDefinitionName);\r
+        Preconditions.checkArgument(StringUtils.isNotBlank(content), "CapabilityDefinition content is missing");\r
+        return JacksonUtils.readValue(content, CapabilityDefinition.class);\r
+    }\r
+\r
+    private String getModelDefinitions(String modelName) throws BluePrintException {\r
+        String modelDefinition = null;\r
+        Optional<ModelType> modelTypedb = modelTypeRepository.findByModelName(modelName);\r
+        if (modelTypedb.isPresent()) {\r
+            modelDefinition = modelTypedb.get().getDefinition();\r
+        } else {\r
+            throw new BluePrintException(String.format("failed to get model definition (%s) from repo", modelName));\r
+        }\r
+        return modelDefinition;\r
+    }\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/BluePrintEnhancerService.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/BluePrintEnhancerService.java
new file mode 100644 (file)
index 0000000..afd12f2
--- /dev/null
@@ -0,0 +1,207 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service;\r
+\r
+import com.fasterxml.jackson.databind.JsonNode;\r
+import com.google.common.base.Preconditions;\r
+import org.apache.commons.lang3.StringUtils;\r
+import org.jetbrains.annotations.NotNull;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.ConfigModelConstant;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.*;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.service.BluePrintEnhancerDefaultService;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.service.BluePrintEnhancerRepoService;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils;\r
+import org.onap.ccsdk.apps.controllerblueprints.resource.dict.ResourceAssignment;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+import org.springframework.stereotype.Service;\r
+\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+/**\r
+ * BluePrintEnhancerService\r
+ *\r
+ * @author Brinda Santh DATE : 8/8/2018\r
+ */\r
+\r
+@Service\r
+public class BluePrintEnhancerService extends BluePrintEnhancerDefaultService {\r
+\r
+    private static Logger log = LoggerFactory.getLogger(BluePrintEnhancerService.class);\r
+\r
+    private HashMap<String, DataType> recipeDataTypes = new HashMap<>();\r
+\r
+    public BluePrintEnhancerService(BluePrintEnhancerRepoService bluePrintEnhancerRepoDBService) {\r
+        super(bluePrintEnhancerRepoDBService);\r
+    }\r
+\r
+    @Override\r
+    public void enrichTopologyTemplate(@NotNull ServiceTemplate serviceTemplate) {\r
+        super.enrichTopologyTemplate(serviceTemplate);\r
+\r
+        // Update the Recipe Inputs and DataTypes\r
+        populateRecipeInputs(serviceTemplate);\r
+    }\r
+\r
+\r
+    @Override\r
+    public void enrichNodeTemplate(@NotNull String nodeTemplateName, @NotNull NodeTemplate nodeTemplate) throws BluePrintException {\r
+        super.enrichNodeTemplate(nodeTemplateName, nodeTemplate);\r
+\r
+        String nodeTypeName = nodeTemplate.getType();\r
+        log.info("*** Enriching NodeType: {}", nodeTypeName);\r
+        // Get NodeType from Repo and Update Service Template\r
+        NodeType nodeType = super.populateNodeType(nodeTypeName);\r
+\r
+        // Enrich NodeType\r
+        super.enrichNodeType(nodeTypeName, nodeType);\r
+\r
+        // Custom for Artifact Population\r
+        if (StringUtils.isNotBlank(nodeType.getDerivedFrom())\r
+                && ConfigModelConstant.MODEL_TYPE_NODE_ARTIFACT.equalsIgnoreCase(nodeType.getDerivedFrom())) {\r
+            populateArtifactTemplateMappingDataType(nodeTemplateName, nodeTemplate);\r
+        }\r
+\r
+        //Enrich Node Template Artifacts\r
+        super.enrichNodeTemplateArtifactDefinition(nodeTemplateName, nodeTemplate);\r
+\r
+    }\r
+\r
+\r
+    private void populateArtifactTemplateMappingDataType(@NotNull String nodeTemplateName, @NotNull NodeTemplate nodeTemplate)\r
+            throws BluePrintException {\r
+        log.info("****** Processing Artifact Node Template : {}", nodeTemplateName);\r
+\r
+        if (nodeTemplate.getProperties() != null) {\r
+\r
+            if (!nodeTemplate.getProperties().containsKey(ConfigModelConstant.PROPERTY_RECIPE_NAMES)) {\r
+                throw new BluePrintException("Node Template (" + nodeTemplateName + ") doesn't have "\r
+                        + ConfigModelConstant.PROPERTY_RECIPE_NAMES + " property.");\r
+            }\r
+\r
+            // Modified for ONAP converted Object to JsonNode\r
+            JsonNode recipeNames = nodeTemplate.getProperties().get(ConfigModelConstant.PROPERTY_RECIPE_NAMES);\r
+\r
+            log.info("Processing Receipe Names : {} ", recipeNames);\r
+\r
+            if (recipeNames != null && recipeNames.isArray() && recipeNames.size() > 0) {\r
+\r
+                Map<String, PropertyDefinition> mappingProperties =\r
+                        getCapabilityMappingProperties(nodeTemplateName, nodeTemplate);\r
+\r
+                for (JsonNode recipeNameNode : recipeNames) {\r
+                    String recipeName = recipeNameNode.textValue();\r
+                    processRecipe(nodeTemplateName, mappingProperties, recipeName);\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    private void processRecipe(@NotNull String nodeTemplateName, Map<String, PropertyDefinition> mappingProperties, String recipeName) {\r
+        if (StringUtils.isNotBlank(recipeName)) {\r
+            DataType recipeDataType = this.recipeDataTypes.get(recipeName);\r
+            if (recipeDataType == null) {\r
+                log.info("DataType not present for the recipe({})" , recipeName);\r
+                recipeDataType = new DataType();\r
+                recipeDataType.setVersion("1.0.0");\r
+                recipeDataType.setDescription(\r
+                        "This is Dynamic Data type definition generated from resource mapping for the config template name "\r
+                                + nodeTemplateName + ".");\r
+                recipeDataType.setDerivedFrom(ConfigModelConstant.MODEL_TYPE_DATA_TYPE_DYNAMIC);\r
+                Map<String, PropertyDefinition> dataTypeProperties = new HashMap<>();\r
+                recipeDataType.setProperties(dataTypeProperties);\r
+            } else {\r
+                log.info("DataType Already present for the recipe({})" , recipeName);\r
+            }\r
+\r
+            // Merge all the Recipe Properties\r
+            mergeDataTypeProperties(recipeDataType, mappingProperties);\r
+\r
+            // Overwrite Recipe DataType\r
+            this.recipeDataTypes.put(recipeName, recipeDataType);\r
+\r
+        }\r
+    }\r
+\r
+    private Map<String, PropertyDefinition> getCapabilityMappingProperties(String nodeTemplateName,\r
+                                                                           NodeTemplate nodeTemplate) {\r
+\r
+        Map<String, PropertyDefinition> dataTypeProperties = null;\r
+        if (nodeTemplate != null) {\r
+            CapabilityAssignment capability =\r
+                    nodeTemplate.getCapabilities().get(ConfigModelConstant.CAPABILITY_PROPERTY_MAPPING);\r
+\r
+            if (capability != null && capability.getProperties() != null) {\r
+\r
+                String resourceAssignmentContent = JacksonUtils\r
+                        .getJson(capability.getProperties().get(ConfigModelConstant.CAPABILITY_PROPERTY_MAPPING));\r
+\r
+                List<ResourceAssignment> resourceAssignments =\r
+                        JacksonUtils.getListFromJson(resourceAssignmentContent, ResourceAssignment.class);\r
+\r
+                Preconditions.checkNotNull(resourceAssignments, "Failed to Processing Resource Mapping " + resourceAssignmentContent);\r
+                dataTypeProperties = new HashMap<>();\r
+\r
+                for (ResourceAssignment resourceAssignment : resourceAssignments) {\r
+                    if (resourceAssignment != null\r
+                            // && Boolean.valueOf(resourceAssignment.getInputParameter())\r
+                            && resourceAssignment.getProperty() != null\r
+                            && StringUtils.isNotBlank(resourceAssignment.getName())) {\r
+\r
+                        // Enrich the Property Definition\r
+                        super.enrichPropertyDefinition(resourceAssignment.getName(), resourceAssignment.getProperty());\r
+\r
+                        dataTypeProperties.put(resourceAssignment.getName(), resourceAssignment.getProperty());\r
+\r
+                    }\r
+                }\r
+\r
+            }\r
+        }\r
+        return dataTypeProperties;\r
+    }\r
+\r
+    private void mergeDataTypeProperties(DataType dataType, Map<String, PropertyDefinition> mergeProperties) {\r
+        if (dataType != null && dataType.getProperties() != null && mergeProperties != null) {\r
+            // Add the Other Template Properties\r
+            mergeProperties.forEach((mappingKey, propertyDefinition) -> {\r
+                dataType.getProperties().put(mappingKey, propertyDefinition);\r
+            });\r
+        }\r
+    }\r
+\r
+    private void populateRecipeInputs(ServiceTemplate serviceTemplate) {\r
+        if (this.recipeDataTypes != null && !this.recipeDataTypes.isEmpty()) {\r
+            this.recipeDataTypes.forEach((recipeName, recipeDataType) -> {\r
+                String dataTypePrifix = recipeName.replace("-action", "") + "-request";\r
+                String dataTypeName = "dt-" + dataTypePrifix;\r
+\r
+                serviceTemplate.getDataTypes().put(dataTypeName, recipeDataType);\r
+\r
+                PropertyDefinition customInputProperty = new PropertyDefinition();\r
+                customInputProperty.setDescription("This is Dynamic Data type for the receipe " + recipeName + ".");\r
+                customInputProperty.setRequired(Boolean.FALSE);\r
+                customInputProperty.setType(dataTypeName);\r
+                serviceTemplate.getTopologyTemplate().getInputs().put(dataTypePrifix, customInputProperty);\r
+\r
+            });\r
+        }\r
+    }\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/ConfigModelCreateService.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/ConfigModelCreateService.java
new file mode 100644 (file)
index 0000000..7e96f2f
--- /dev/null
@@ -0,0 +1,339 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service;\r
+\r
+import com.google.common.base.Preconditions;\r
+import org.apache.commons.collections.CollectionUtils;\r
+import org.apache.commons.io.IOUtils;\r
+import org.apache.commons.lang3.StringUtils;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.ConfigModelConstant;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.ServiceTemplate;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.common.ApplicationConstants;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ConfigModel;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ConfigModelContent;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.repository.ConfigModelRepository;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+import org.springframework.stereotype.Service;\r
+\r
+import java.io.IOException;\r
+import java.nio.charset.Charset;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.Optional;\r
+\r
+/**\r
+ * ServiceTemplateCreateService.java Purpose: Provide Service Template Create Service processing\r
+ * ServiceTemplateCreateService\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+\r
+@Service\r
+public class ConfigModelCreateService {\r
+\r
+    private static Logger log = LoggerFactory.getLogger(ConfigModelCreateService.class);\r
+\r
+    private ConfigModelRepository configModelRepository;\r
+    private ConfigModelValidatorService configModelValidatorService;\r
+\r
+    /**\r
+     * This is a ConfigModelCreateService\r
+     *\r
+     * @param configModelRepository       ConfigModelRepository\r
+     * @param configModelValidatorService ConfigModelValidatorService\r
+     */\r
+    public ConfigModelCreateService(ConfigModelRepository configModelRepository,\r
+                                    ConfigModelValidatorService configModelValidatorService) {\r
+        this.configModelRepository = configModelRepository;\r
+        this.configModelValidatorService = configModelValidatorService;\r
+    }\r
+\r
+    /**\r
+     * This is a createInitialServiceTemplateContent method\r
+     *\r
+     * @param templateName templateName\r
+     * @return String\r
+     * @throws BluePrintException BluePrintException\r
+     */\r
+    public String createInitialServiceTemplateContent(String templateName) throws BluePrintException {\r
+        String serviceTemplateContent = null;\r
+        if (StringUtils.isNotBlank(templateName)) {\r
+            try {\r
+                serviceTemplateContent = IOUtils.toString(ConfigModelCreateService.class.getClassLoader()\r
+                        .getResourceAsStream("service_template/" + templateName + ".json"), Charset.defaultCharset());\r
+            } catch (IOException e) {\r
+                throw new BluePrintException(e.getMessage(), e);\r
+            }\r
+\r
+        }\r
+        return serviceTemplateContent;\r
+    }\r
+\r
+    /**\r
+     * This is a createInitialServiceTemplate method\r
+     *\r
+     * @param templateName templateName\r
+     * @return ServiceTemplate\r
+     * @throws BluePrintException BluePrintException\r
+     */\r
+    public ServiceTemplate createInitialServiceTemplate(String templateName) throws BluePrintException {\r
+        ServiceTemplate serviceTemplate = null;\r
+        if (StringUtils.isNotBlank(templateName)) {\r
+            try {\r
+                String serviceTemplateContent = IOUtils.toString(ConfigModelCreateService.class.getClassLoader()\r
+                        .getResourceAsStream("service_template/" + templateName + ".json"), Charset.defaultCharset());\r
+                if (StringUtils.isNotBlank(serviceTemplateContent)) {\r
+                    serviceTemplate = JacksonUtils.readValue(serviceTemplateContent, ServiceTemplate.class);\r
+                }\r
+            } catch (IOException e) {\r
+                throw new BluePrintException(e.getMessage(), e);\r
+            }\r
+\r
+        }\r
+        return serviceTemplate;\r
+    }\r
+\r
+    /**\r
+     * This is a saveConfigModel method\r
+     *\r
+     * @param configModel configModel\r
+     * @return ConfigModel\r
+     * @throws BluePrintException BluePrintException\r
+     */\r
+    public ConfigModel saveConfigModel(ConfigModel configModel) throws BluePrintException {\r
+\r
+        if (configModel != null) {\r
+            String artifactName = configModel.getArtifactName();\r
+            String artifactVersion = configModel.getArtifactVersion();\r
+            String author = configModel.getUpdatedBy();\r
+            // configModel.setTags(artifactName);\r
+\r
+            if (StringUtils.isBlank(author)) {\r
+                throw new BluePrintException("Artifact Author is missing in the Service Template");\r
+            }\r
+\r
+            if (StringUtils.isBlank(artifactName)) {\r
+                throw new BluePrintException("Artifact Name is missing in the Service Template");\r
+            }\r
+\r
+            if (StringUtils.isBlank(artifactVersion)) {\r
+                throw new BluePrintException("Artifact Version is missing in the Service Template");\r
+            }\r
+            ConfigModel updateConfigModel = null;\r
+\r
+            Optional<ConfigModel> dbConfigModelOptional = Optional.empty();\r
+\r
+            if (configModel.getId() != null) {\r
+                log.info("Searching for config model id : {}", configModel.getId());\r
+                dbConfigModelOptional = configModelRepository.findById(configModel.getId());\r
+            }\r
+\r
+            if (!dbConfigModelOptional.isPresent()) {\r
+                log.info("Searching for config model name :"\r
+                        + configModel.getArtifactName() + ", version " + configModel.getArtifactVersion());\r
+                dbConfigModelOptional = configModelRepository.findByArtifactNameAndArtifactVersion(\r
+                        configModel.getArtifactName(), configModel.getArtifactVersion());\r
+            }\r
+\r
+            if (dbConfigModelOptional.isPresent()) {\r
+                updateConfigModel = dbConfigModelOptional.get();\r
+                log.info("Processing for config model id : {} with config model content count : {}"\r
+                        , updateConfigModel.getId(), updateConfigModel.getConfigModelContents().size());\r
+            } else {\r
+                ConfigModel tempConfigModel = new ConfigModel();\r
+                tempConfigModel.setArtifactType(ApplicationConstants.ASDC_ARTIFACT_TYPE_SDNC_MODEL);\r
+                tempConfigModel.setArtifactName(artifactName);\r
+                tempConfigModel.setArtifactVersion(artifactVersion);\r
+                tempConfigModel.setUpdatedBy(author);\r
+                tempConfigModel.setPublished(ApplicationConstants.ACTIVE_N);\r
+                tempConfigModel.setTags(artifactName);\r
+                configModelRepository.saveAndFlush(tempConfigModel);\r
+                updateConfigModel = tempConfigModel;\r
+            }\r
+\r
+            Long dbConfigModelId = updateConfigModel.getId();\r
+\r
+            if (dbConfigModelId == null) {\r
+                throw new BluePrintException("failed to get the initial saved config model id.");\r
+            }\r
+\r
+            log.info("Processing for config model id : {}", dbConfigModelId);\r
+\r
+            deleteConfigModelContent(dbConfigModelId);\r
+\r
+            addConfigModelContent(dbConfigModelId, configModel);\r
+\r
+            // Populate Content model types\r
+            updateConfigModel = updateConfigModel(dbConfigModelId, artifactName, artifactVersion, author);\r
+\r
+\r
+            return updateConfigModel;\r
+        } else {\r
+            throw new BluePrintException("Config model information is missing");\r
+        }\r
+\r
+    }\r
+\r
+    private void deleteConfigModelContent(Long dbConfigModelId) {\r
+        if (dbConfigModelId != null) {\r
+            ConfigModel dbConfigModel = configModelRepository.getOne(dbConfigModelId);\r
+            if (dbConfigModel != null && CollectionUtils.isNotEmpty(dbConfigModel.getConfigModelContents())) {\r
+                dbConfigModel.getConfigModelContents().clear();\r
+                log.debug("Configuration Model content deleting : {}", dbConfigModel.getConfigModelContents());\r
+                configModelRepository.saveAndFlush(dbConfigModel);\r
+            }\r
+\r
+        }\r
+    }\r
+\r
+    private void addConfigModelContent(Long dbConfigModelId, ConfigModel configModel) {\r
+        if (dbConfigModelId != null && configModel != null\r
+                && CollectionUtils.isNotEmpty(configModel.getConfigModelContents())) {\r
+            ConfigModel dbConfigModel = configModelRepository.getOne(dbConfigModelId);\r
+            if (dbConfigModel != null) {\r
+                for (ConfigModelContent configModelContent : configModel.getConfigModelContents()) {\r
+                    if (configModelContent != null) {\r
+                        configModelContent.setId(null);\r
+                        configModelContent.setConfigModel(dbConfigModel);\r
+                        dbConfigModel.getConfigModelContents().add(configModelContent);\r
+                        log.debug("Configuration Model content adding : {}", configModelContent);\r
+                    }\r
+                }\r
+                configModelRepository.saveAndFlush(dbConfigModel);\r
+            }\r
+\r
+        }\r
+    }\r
+\r
+    private ConfigModel updateConfigModel(Long dbConfigModelId, String artifactName, String artifactVersion,\r
+                                          String author) throws BluePrintException {\r
+\r
+        ConfigModel dbConfigModel = configModelRepository.getOne(dbConfigModelId);\r
+        if (dbConfigModel != null) {\r
+            // Populate tags from metadata\r
+            String tags = getConfigModelTags(dbConfigModel);\r
+            if (StringUtils.isBlank(tags)) {\r
+                throw new BluePrintException("Failed to populate tags for the config model name " + artifactName);\r
+            }\r
+            dbConfigModel.setArtifactType(ApplicationConstants.ASDC_ARTIFACT_TYPE_SDNC_MODEL);\r
+            dbConfigModel.setArtifactName(artifactName);\r
+            dbConfigModel.setArtifactVersion(artifactVersion);\r
+            dbConfigModel.setUpdatedBy(author);\r
+            dbConfigModel.setPublished(ApplicationConstants.ACTIVE_N);\r
+            dbConfigModel.setTags(tags);\r
+            configModelRepository.saveAndFlush(dbConfigModel);\r
+\r
+            log.info("Config model ({}) saved successfully.", dbConfigModel.getId());\r
+        }\r
+        return dbConfigModel;\r
+    }\r
+\r
+    private List<String> getValidContentTypes() {\r
+        List<String> valids = new ArrayList<>();\r
+        valids.add(ConfigModelConstant.MODEL_CONTENT_TYPE_TOSCA_JSON);\r
+        valids.add(ConfigModelConstant.MODEL_CONTENT_TYPE_TEMPLATE);\r
+        return valids;\r
+\r
+    }\r
+\r
+    private String getConfigModelTags(ConfigModel configModel) throws BluePrintException {\r
+        String tags = null;\r
+        if (CollectionUtils.isNotEmpty(configModel.getConfigModelContents())) {\r
+\r
+            for (ConfigModelContent configModelContent : configModel.getConfigModelContents()) {\r
+                if (configModelContent != null && StringUtils.isNotBlank(configModelContent.getContentType())) {\r
+\r
+                    if (!getValidContentTypes().contains(configModelContent.getContentType())) {\r
+                        throw new BluePrintException(configModelContent.getContentType()\r
+                                + " is not a valid content type, It should be any one of this "\r
+                                + getValidContentTypes());\r
+                    }\r
+\r
+                    if (configModelContent.getContentType().equals(ConfigModelConstant.MODEL_CONTENT_TYPE_TOSCA_JSON)) {\r
+                        ServiceTemplate serviceTemplate =\r
+                                JacksonUtils.readValue(configModelContent.getContent(), ServiceTemplate.class);\r
+                        Preconditions.checkNotNull(serviceTemplate, "failed to transform service template content");\r
+                        if (serviceTemplate.getMetadata() != null) {\r
+                            serviceTemplate.getMetadata().put(BluePrintConstants.METADATA_TEMPLATE_AUTHOR,\r
+                                    configModel.getUpdatedBy());\r
+                            serviceTemplate.getMetadata().put(BluePrintConstants.METADATA_TEMPLATE_VERSION,\r
+                                    configModel.getArtifactVersion());\r
+                            serviceTemplate.getMetadata().put(BluePrintConstants.METADATA_TEMPLATE_NAME,\r
+                                    configModel.getArtifactName());\r
+                        }\r
+                        tags = String.valueOf(serviceTemplate.getMetadata());\r
+                    } else {\r
+                        // Do Nothing\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        return tags;\r
+    }\r
+\r
+    /**\r
+     * This is a publishConfigModel method\r
+     *\r
+     * @param id id\r
+     * @return ConfigModel\r
+     * @throws BluePrintException BluePrintException\r
+     */\r
+    public ConfigModel publishConfigModel(Long id) throws BluePrintException {\r
+        ConfigModel dbConfigModel = null;\r
+        if (id != null) {\r
+            Optional<ConfigModel> dbConfigModelOptional = configModelRepository.findById(id);\r
+            if (dbConfigModelOptional.isPresent()) {\r
+                dbConfigModel = dbConfigModelOptional.get();\r
+                List<ConfigModelContent> configModelContents = dbConfigModel.getConfigModelContents();\r
+                if (configModelContents != null && !configModelContents.isEmpty()) {\r
+                    for (ConfigModelContent configModelContent : configModelContents) {\r
+                        if (configModelContent.getContentType()\r
+                                .equals(ConfigModelConstant.MODEL_CONTENT_TYPE_TOSCA_JSON)) {\r
+                            ServiceTemplate serviceTemplate = JacksonUtils\r
+                                    .readValue(configModelContent.getContent(), ServiceTemplate.class);\r
+                            if (serviceTemplate != null) {\r
+                                validateServiceTemplate(serviceTemplate);\r
+                            }\r
+                        }\r
+                    }\r
+                }\r
+                dbConfigModel.setPublished(ApplicationConstants.ACTIVE_Y);\r
+                configModelRepository.save(dbConfigModel);\r
+                log.info("Config model ({}) published successfully.", id);\r
+\r
+            }\r
+\r
+        }\r
+        return dbConfigModel;\r
+    }\r
+\r
+    /**\r
+     * This is a validateServiceTemplate method\r
+     *\r
+     * @param serviceTemplate Service Template\r
+     * @return ServiceTemplate\r
+     * @throws BluePrintException BluePrintException\r
+     */\r
+    public ServiceTemplate validateServiceTemplate(ServiceTemplate serviceTemplate) throws BluePrintException {\r
+        return this.configModelValidatorService.validateServiceTemplate(serviceTemplate);\r
+    }\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/ConfigModelService.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/ConfigModelService.java
new file mode 100644 (file)
index 0000000..feee3a3
--- /dev/null
@@ -0,0 +1,247 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service;\r
+\r
+import org.apache.commons.collections.CollectionUtils;\r
+import org.apache.commons.lang3.StringUtils;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.ConfigModelConstant;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.ServiceTemplate;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.common.ApplicationConstants;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ConfigModel;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ConfigModelContent;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.repository.ConfigModelContentRepository;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.repository.ConfigModelRepository;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+import org.springframework.stereotype.Service;\r
+import org.springframework.transaction.annotation.Transactional;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Date;\r
+import java.util.List;\r
+import java.util.Optional;\r
+\r
+/**\r
+ * ConfigModelService.java Purpose: Provide Service Template Service processing ConfigModelService\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+\r
+@Service\r
+public class ConfigModelService {\r
+\r
+    private static Logger log = LoggerFactory.getLogger(ConfigModelService.class);\r
+\r
+    private ConfigModelRepository configModelRepository;\r
+    private ConfigModelContentRepository configModelContentRepository;\r
+    private ConfigModelCreateService configModelCreateService;\r
+\r
+    /**\r
+     * This is a ConfigModelService constructor.\r
+     * \r
+     * @param configModelRepository\r
+     * @param configModelContentRepository\r
+     * @param configModelCreateService\r
+     */\r
+    public ConfigModelService(ConfigModelRepository configModelRepository,\r
+            ConfigModelContentRepository configModelContentRepository,\r
+            ConfigModelCreateService configModelCreateService) {\r
+        this.configModelRepository = configModelRepository;\r
+        this.configModelContentRepository = configModelContentRepository;\r
+        this.configModelCreateService = configModelCreateService;\r
+    }\r
+\r
+    /**\r
+     * This is a getInitialConfigModel method\r
+     * \r
+     * @param templateName\r
+     * @return ConfigModel\r
+     * @throws BluePrintException\r
+     */\r
+    public ConfigModel getInitialConfigModel(String templateName) throws BluePrintException {\r
+        ConfigModel configModel = null;\r
+        if (StringUtils.isNotBlank(templateName)) {\r
+            configModel = new ConfigModel();\r
+            configModel.setArtifactName(templateName);\r
+            configModel.setArtifactType(ApplicationConstants.ASDC_ARTIFACT_TYPE_SDNC_MODEL);\r
+            configModel.setUpdatedBy("xxxxx@xxx.com");\r
+            ConfigModelContent configModelContent = new ConfigModelContent();\r
+            configModelContent.setContentType(ConfigModelConstant.MODEL_CONTENT_TYPE_TOSCA_JSON);\r
+            configModelContent.setName(templateName);\r
+            String content = this.configModelCreateService.createInitialServiceTemplateContent(templateName);\r
+            configModelContent.setContent(content);\r
+\r
+            List<ConfigModelContent> configModelContents = new ArrayList<>();\r
+            configModelContents.add(configModelContent);\r
+\r
+            configModel.setConfigModelContents(configModelContents);\r
+        }\r
+        return configModel;\r
+    }\r
+\r
+    /**\r
+     * This is a saveConfigModel method\r
+     * \r
+     * @param configModel\r
+     * @return ConfigModel\r
+     * @throws BluePrintException\r
+     */\r
+    public ConfigModel saveConfigModel(ConfigModel configModel) throws BluePrintException {\r
+        return this.configModelCreateService.saveConfigModel(configModel);\r
+    }\r
+\r
+    /**\r
+     * This is a publishConfigModel method\r
+     * \r
+     * @param id\r
+     * @return ConfigModel\r
+     * @throws BluePrintException\r
+     */\r
+    public ConfigModel publishConfigModel(Long id) throws BluePrintException {\r
+        return this.configModelCreateService.publishConfigModel(id);\r
+    }\r
+\r
+    /**\r
+     * This is a searchConfigModels method\r
+     * \r
+     * @param tags\r
+     * @return ConfigModel\r
+     */\r
+    public List<ConfigModel> searchConfigModels(String tags) {\r
+        List<ConfigModel> models = configModelRepository.findByTagsContainingIgnoreCase(tags);\r
+        if (models != null) {\r
+            for (ConfigModel configModel : models) {\r
+                configModel.setConfigModelContents(null);\r
+            }\r
+        }\r
+        return models;\r
+    }\r
+\r
+    /**\r
+     * This is a getConfigModelByNameAndVersion method\r
+     * \r
+     * @param name\r
+     * @param version\r
+     * @return ConfigModel\r
+     */\r
+    public ConfigModel getConfigModelByNameAndVersion(String name, String version) {\r
+        ConfigModel configModel = null;\r
+        Optional<ConfigModel> dbConfigModel = null;\r
+        if (StringUtils.isNotBlank(version)) {\r
+            dbConfigModel = configModelRepository.findByArtifactNameAndArtifactVersion(name, version);\r
+        } else {\r
+            dbConfigModel = configModelRepository.findTopByArtifactNameOrderByArtifactVersionDesc(name);\r
+        }\r
+        if (dbConfigModel.isPresent()) {\r
+            configModel = dbConfigModel.get();\r
+        }\r
+        return configModel;\r
+    }\r
+\r
+    /**\r
+     * This is a getConfigModel method\r
+     * \r
+     * @param id\r
+     * @return ConfigModel\r
+     */\r
+    public ConfigModel getConfigModel(Long id) {\r
+        ConfigModel configModel = null;\r
+        if (id != null) {\r
+            Optional<ConfigModel> dbConfigModel = configModelRepository.findById(id);\r
+            if (dbConfigModel.isPresent()) {\r
+                configModel = dbConfigModel.get();\r
+            }\r
+        }\r
+        return configModel;\r
+    }\r
+\r
+    /**\r
+     * This method returns clone of the given model id, by masking the other unrelated fields\r
+     * \r
+     * @param id\r
+     * @return\r
+     */\r
+\r
+    public ConfigModel getCloneConfigModel(Long id) {\r
+\r
+        ConfigModel configModel = null;\r
+        ConfigModel cloneConfigModel = null;\r
+        if (id != null) {\r
+            Optional<ConfigModel> dbConfigModel = configModelRepository.findById(id);\r
+            if (dbConfigModel.isPresent()) {\r
+                configModel = dbConfigModel.get();\r
+                cloneConfigModel = configModel;\r
+                cloneConfigModel.setUpdatedBy("xxxxx@xxx.com");\r
+                cloneConfigModel.setArtifactName("XXXX");\r
+                cloneConfigModel.setPublished("XXXX");\r
+                cloneConfigModel.setPublished("XXXX");\r
+                cloneConfigModel.setUpdatedBy("XXXX");\r
+                cloneConfigModel.setId(null);\r
+                cloneConfigModel.setTags(null);\r
+                cloneConfigModel.setCreatedDate(new Date());\r
+                List<ConfigModelContent> configModelContents = cloneConfigModel.getConfigModelContents();\r
+\r
+                if (CollectionUtils.isNotEmpty(configModelContents)) {\r
+                    for (ConfigModelContent configModelContent : configModelContents) {\r
+                        if (configModelContent != null && StringUtils.isNotBlank(configModelContent.getContentType())) {\r
+                            configModelContent.setId(null);\r
+                            configModelContent.setCreationDate(new Date());\r
+\r
+                            if (ConfigModelConstant.MODEL_CONTENT_TYPE_TOSCA_JSON\r
+                                    .equalsIgnoreCase(configModelContent.getContentType())) {\r
+                                ServiceTemplate serviceTemplate = JacksonUtils\r
+                                        .readValue(configModelContent.getContent(), ServiceTemplate.class);\r
+                                if (serviceTemplate != null && serviceTemplate.getMetadata() != null) {\r
+                                    serviceTemplate.getMetadata()\r
+                                            .put(BluePrintConstants.METADATA_TEMPLATE_AUTHOR, "XXXX");\r
+                                    serviceTemplate.getMetadata()\r
+                                            .put(BluePrintConstants.METADATA_TEMPLATE_VERSION, "1.0.0");\r
+                                    serviceTemplate.getMetadata()\r
+                                            .put(BluePrintConstants.METADATA_TEMPLATE_NAME, "XXXXXX");\r
+\r
+                                    configModelContent.setContent(JacksonUtils.getJson(serviceTemplate));\r
+                                }\r
+                            }\r
+                        }\r
+\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        return cloneConfigModel;\r
+    }\r
+\r
+    /**\r
+     * This is a deleteConfigModel method\r
+     * \r
+     * @param id\r
+     */\r
+\r
+    @Transactional\r
+    public void deleteConfigModel(Long id) {\r
+        Optional<ConfigModel> dbConfigModel = configModelRepository.findById(id);\r
+        if (dbConfigModel.isPresent()) {\r
+            configModelContentRepository.deleteByConfigModel(dbConfigModel.get());\r
+            configModelRepository.delete(dbConfigModel.get());\r
+        }\r
+    }\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/ConfigModelValidatorService.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/ConfigModelValidatorService.java
new file mode 100644 (file)
index 0000000..21b00f8
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service;\r
+\r
+import com.google.common.base.Preconditions;\r
+import org.apache.commons.lang3.StringUtils;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.ServiceTemplate;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.validator.ServiceTemplateValidator;\r
+import org.springframework.stereotype.Service;\r
+\r
+/**\r
+ * ServiceTemplateValidatorService.java Purpose: Provide Service to Validate Service Model Template\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+\r
+@Service\r
+public class ConfigModelValidatorService {\r
+\r
+    /**\r
+     * This is a validateServiceTemplate\r
+     *\r
+     * @param serviceTemplateContent\r
+     * @return ServiceTemplate\r
+     * @throws BluePrintException\r
+     */\r
+    public ServiceTemplate validateServiceTemplate(String serviceTemplateContent) throws BluePrintException {\r
+        Preconditions.checkArgument(StringUtils.isNotBlank(serviceTemplateContent), "Service Template Content is  (" + serviceTemplateContent + ") not Defined.");\r
+        ServiceTemplate serviceTemplate =\r
+                JacksonUtils.readValue(serviceTemplateContent, ServiceTemplate.class);\r
+        return validateServiceTemplate(serviceTemplate);\r
+    }\r
+\r
+    /**\r
+     * This is a enhanceServiceTemplate\r
+     *\r
+     * @param serviceTemplate\r
+     * @return ServiceTemplate\r
+     * @throws BluePrintException\r
+     */\r
+    @SuppressWarnings("squid:S00112")\r
+    public ServiceTemplate validateServiceTemplate(ServiceTemplate serviceTemplate) throws BluePrintException {\r
+        Preconditions.checkNotNull(serviceTemplate, "Service Template is not defined.");\r
+        ServiceTemplateValidator validator = new ServiceTemplateValidator();\r
+        validator.validateServiceTemplate(serviceTemplate);\r
+        return serviceTemplate;\r
+    }\r
+\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/DataBaseInitService.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/DataBaseInitService.java
new file mode 100644 (file)
index 0000000..9ab319c
--- /dev/null
@@ -0,0 +1,325 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service;\r
+\r
+import org.apache.commons.collections.CollectionUtils;\r
+import org.apache.commons.io.IOUtils;\r
+import org.apache.commons.lang3.StringUtils;\r
+import org.apache.commons.lang3.text.StrBuilder;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.ArtifactType;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.DataType;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.NodeType;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils;\r
+import org.onap.ccsdk.apps.controllerblueprints.resource.dict.data.DictionaryDefinition;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ConfigModel;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ModelType;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ResourceDictionary;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.utils.ConfigModelUtils;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+import org.springframework.beans.factory.annotation.Autowired;\r
+import org.springframework.beans.factory.annotation.Value;\r
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;\r
+import org.springframework.core.io.Resource;\r
+import org.springframework.core.io.support.ResourcePatternResolver;\r
+import org.springframework.stereotype.Component;\r
+\r
+import javax.annotation.PostConstruct;\r
+import java.io.IOException;\r
+import java.nio.charset.Charset;\r
+import java.util.List;\r
+\r
+/**\r
+ * DataBaseInitService.java Purpose: Provide DataBaseInitService Service\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+\r
+@Component\r
+@ConditionalOnProperty(name = "blueprints.load.initial-data", havingValue = "true", matchIfMissing = false)\r
+public class DataBaseInitService {\r
+\r
+    private static Logger log = LoggerFactory.getLogger(DataBaseInitService.class);\r
+    @Value("${blueprints.load.path}")\r
+    private String modelLoadPath;\r
+    private ModelTypeService modelTypeService;\r
+    private ResourceDictionaryService resourceDictionaryService;\r
+    private ConfigModelService configModelService;\r
+\r
+    private String dataTypePath;\r
+    private String nodeTypePath;\r
+    private String artifactTypePath;\r
+    private String resourceDictionaryPath;\r
+    private String bluePrintsPath;\r
+\r
+    @Autowired\r
+    private ResourcePatternResolver resourceLoader;\r
+\r
+    /**\r
+     * This is a DataBaseInitService, used to load the initial data\r
+     *\r
+     * @param modelTypeService\r
+     * @param resourceDictionaryService\r
+     * @param configModelService\r
+     */\r
+    public DataBaseInitService(ModelTypeService modelTypeService, ResourceDictionaryService resourceDictionaryService,\r
+                               ConfigModelService configModelService) {\r
+        this.modelTypeService = modelTypeService;\r
+        this.resourceDictionaryService = resourceDictionaryService;\r
+        this.configModelService = configModelService;\r
+        log.info("DataBaseInitService started...");\r
+\r
+    }\r
+\r
+    @PostConstruct\r
+    private void initDatabase() {\r
+        log.info("loading Blueprints from DIR : {}", modelLoadPath);\r
+        dataTypePath = modelLoadPath + "/model_type/data_type";\r
+        nodeTypePath = modelLoadPath + "/model_type/node_type";\r
+        artifactTypePath = modelLoadPath + "/model_type/artifact_type";\r
+        resourceDictionaryPath = modelLoadPath + "/resource_dictionary";\r
+        bluePrintsPath = modelLoadPath + "/blueprints";\r
+\r
+        log.info("loading dataTypePath from DIR : {}", dataTypePath);\r
+        log.info("loading nodeTypePath from DIR : {}", nodeTypePath);\r
+        log.info("loading artifactTypePath from DIR : {}", artifactTypePath);\r
+        log.info("loading resourceDictionaryPath from DIR : {}", resourceDictionaryPath);\r
+        log.info("loading bluePrintsPath from DIR : {}", bluePrintsPath);\r
+\r
+        loadModelType();\r
+        loadResourceDictionary();\r
+        loadBlueprints();\r
+    }\r
+\r
+    private void loadModelType() {\r
+        log.info(" *************************** loadModelType **********************");\r
+        try {\r
+            Resource[] dataTypefiles = getPathResources(dataTypePath, ".json");\r
+            StrBuilder errorBuilder = new StrBuilder();\r
+            if (dataTypefiles != null) {\r
+                for (Resource file : dataTypefiles) {\r
+                    if (file != null) {\r
+                        loadDataType(file, errorBuilder);\r
+                    }\r
+                }\r
+            }\r
+\r
+            Resource[] nodeTypefiles = getPathResources(nodeTypePath, ".json");\r
+            if (nodeTypefiles != null) {\r
+                for (Resource file : nodeTypefiles) {\r
+                    if (file != null) {\r
+                        loadNodeType(file, errorBuilder);\r
+                    }\r
+                }\r
+            }\r
+\r
+            Resource[] artifactTypefiles = getPathResources(artifactTypePath, ".json");\r
+            if (artifactTypefiles != null) {\r
+                for (Resource file : artifactTypefiles) {\r
+                    if (file != null) {\r
+                        loadArtifactType(file, errorBuilder);\r
+                    }\r
+                }\r
+            }\r
+\r
+            if (!errorBuilder.isEmpty()) {\r
+                log.error(errorBuilder.toString());\r
+            }\r
+        } catch (Exception e) {\r
+            log.error("Failed in Data type loading", e);\r
+        }\r
+    }\r
+\r
+    private void loadResourceDictionary() {\r
+        log.info(\r
+                " *************************** loadResourceDictionary **********************");\r
+        try {\r
+            Resource[] dataTypefiles = getPathResources(resourceDictionaryPath, ".json");\r
+            if (dataTypefiles != null) {\r
+                StrBuilder errorBuilder = new StrBuilder();\r
+                String fileName = null;\r
+                for (Resource file : dataTypefiles) {\r
+                    try {\r
+                        fileName = file.getFilename();\r
+                        log.trace("Loading : {}", fileName);\r
+                        String definitionContent = getResourceContent(file);\r
+                        DictionaryDefinition dictionaryDefinition =\r
+                                JacksonUtils.readValue(definitionContent, DictionaryDefinition.class);\r
+                        if (dictionaryDefinition != null) {\r
+                            ResourceDictionary resourceDictionary = new ResourceDictionary();\r
+                            resourceDictionary.setResourcePath(dictionaryDefinition.getResourcePath());\r
+                            resourceDictionary.setName(dictionaryDefinition.getName());\r
+                            resourceDictionary.setDefinition(definitionContent);\r
+\r
+                            if (dictionaryDefinition.getValidValues() != null)\r
+                                resourceDictionary\r
+                                        .setValidValues(String.valueOf(dictionaryDefinition.getValidValues()));\r
+\r
+                            if (dictionaryDefinition.getSampleValue() != null)\r
+                                resourceDictionary\r
+                                        .setValidValues(String.valueOf(dictionaryDefinition.getSampleValue()));\r
+\r
+                            resourceDictionary.setResourceType(dictionaryDefinition.getResourceType());\r
+                            resourceDictionary.setDataType(dictionaryDefinition.getDataType());\r
+                            resourceDictionary.setEntrySchema(dictionaryDefinition.getEntrySchema());\r
+                            resourceDictionary.setDescription(dictionaryDefinition.getDescription());\r
+                            resourceDictionary.setUpdatedBy(dictionaryDefinition.getUpdatedBy());\r
+                            if (StringUtils.isBlank(dictionaryDefinition.getTags())) {\r
+                                resourceDictionary.setTags(\r
+                                        dictionaryDefinition.getName() + ", " + dictionaryDefinition.getUpdatedBy()\r
+                                                + ", " + dictionaryDefinition.getResourceType() + ", "\r
+                                                + dictionaryDefinition.getUpdatedBy());\r
+\r
+                            } else {\r
+                                resourceDictionary.setTags(dictionaryDefinition.getTags());\r
+                            }\r
+                            resourceDictionaryService.saveResourceDictionary(resourceDictionary);\r
+\r
+                            log.trace(" Loaded successfully : {}", file.getFilename());\r
+                        } else {\r
+                            throw new BluePrintException("couldn't get dictionary from content information");\r
+                        }\r
+                    } catch (Exception e) {\r
+                        errorBuilder.appendln("Dictionary loading Errors : " + file.getFilename() + ":" + e.getMessage());\r
+                    }\r
+                }\r
+                if (!errorBuilder.isEmpty()) {\r
+                    log.error(errorBuilder.toString());\r
+                }\r
+\r
+            }\r
+        } catch (Exception e) {\r
+            log.error(\r
+                    "Failed in Resource dictionary loading", e);\r
+        }\r
+    }\r
+\r
+    private void loadBlueprints() {\r
+        log.info("*************************** loadServiceTemplate **********************");\r
+        try {\r
+            List<String> serviceTemplateDirs = ConfigModelUtils.getBlueprintNames(bluePrintsPath);\r
+            if (CollectionUtils.isNotEmpty(serviceTemplateDirs)) {\r
+                StrBuilder errorBuilder = new StrBuilder();\r
+                for (String fileName : serviceTemplateDirs) {\r
+                    try {\r
+                        String bluePrintPath = this.bluePrintsPath.concat("/").concat(fileName);\r
+                        log.debug("***** Loading service template :  {}", bluePrintPath);\r
+                        ConfigModel configModel = ConfigModelUtils.getConfigModel(bluePrintPath);\r
+\r
+                        configModel = this.configModelService.saveConfigModel(configModel);\r
+\r
+                        log.info("Publishing : {}", configModel.getId());\r
+\r
+                        this.configModelService.publishConfigModel(configModel.getId());\r
+\r
+                        log.info("Loaded service template successfully: {}", fileName);\r
+\r
+                    } catch (Exception e) {\r
+                        errorBuilder.appendln("load config model " + fileName + " error : " + e.getMessage());\r
+                    }\r
+                }\r
+\r
+                if (!errorBuilder.isEmpty()) {\r
+                    log.error(errorBuilder.toString());\r
+                }\r
+            }\r
+        } catch (Exception e) {\r
+            log.error("Failed in Service Template loading", e);\r
+        }\r
+    }\r
+\r
+    private void loadNodeType(Resource file, StrBuilder errorBuilder) {\r
+        try {\r
+            log.trace("Loading Node Type : {}", file.getFilename());\r
+            String nodeKey = file.getFilename().replace(".json", "");\r
+            String definitionContent = getResourceContent(file);\r
+            NodeType nodeType = JacksonUtils.readValue(definitionContent, NodeType.class);\r
+            ModelType modelType = new ModelType();\r
+            modelType.setDefinitionType(BluePrintConstants.MODEL_DEFINITION_TYPE_NODE_TYPE);\r
+            modelType.setDerivedFrom(nodeType.getDerivedFrom());\r
+            modelType.setDescription(nodeType.getDescription());\r
+            modelType.setDefinition(definitionContent);\r
+            modelType.setModelName(nodeKey);\r
+            modelType.setVersion(nodeType.getVersion());\r
+            modelType.setUpdatedBy("System");\r
+            modelType.setTags(nodeKey + "," + BluePrintConstants.MODEL_DEFINITION_TYPE_NODE_TYPE + ","\r
+                    + nodeType.getDerivedFrom());\r
+            modelTypeService.saveModel(modelType);\r
+            log.trace("Loaded Node Type successfully : {}", file.getFilename());\r
+        } catch (Exception e) {\r
+            errorBuilder.appendln("Node type loading error : " + file.getFilename() + ":" + e.getMessage());\r
+        }\r
+    }\r
+\r
+    private void loadDataType(Resource file, StrBuilder errorBuilder) {\r
+        try {\r
+            log.trace("Loading Data Type: {}", file.getFilename());\r
+            String dataKey = file.getFilename().replace(".json", "");\r
+            String definitionContent = getResourceContent(file);\r
+            DataType dataType = JacksonUtils.readValue(definitionContent, DataType.class);\r
+            ModelType modelType = new ModelType();\r
+            modelType.setDefinitionType(BluePrintConstants.MODEL_DEFINITION_TYPE_DATA_TYPE);\r
+            modelType.setDerivedFrom(dataType.getDerivedFrom());\r
+            modelType.setDescription(dataType.getDescription());\r
+            modelType.setDefinition(definitionContent);\r
+            modelType.setModelName(dataKey);\r
+            modelType.setVersion(dataType.getVersion());\r
+            modelType.setUpdatedBy("System");\r
+            modelType.setTags(dataKey + "," + dataType.getDerivedFrom() + ","\r
+                    + BluePrintConstants.MODEL_DEFINITION_TYPE_DATA_TYPE);\r
+            modelTypeService.saveModel(modelType);\r
+            log.trace(" Loaded Data Type successfully : {}", file.getFilename());\r
+        } catch (Exception e) {\r
+            errorBuilder.appendln("Data type loading error : " + file.getFilename() + ":" + e.getMessage());\r
+        }\r
+    }\r
+\r
+    private void loadArtifactType(Resource file, StrBuilder errorBuilder) {\r
+        try {\r
+            log.trace("Loading Artifact Type: {}", file.getFilename());\r
+            String dataKey = file.getFilename().replace(".json", "");\r
+            String definitionContent = getResourceContent(file);\r
+            ArtifactType artifactType = JacksonUtils.readValue(definitionContent, ArtifactType.class);\r
+            ModelType modelType = new ModelType();\r
+            modelType.setDefinitionType(BluePrintConstants.MODEL_DEFINITION_TYPE_ARTIFACT_TYPE);\r
+            modelType.setDerivedFrom(artifactType.getDerivedFrom());\r
+            modelType.setDescription(artifactType.getDescription());\r
+            modelType.setDefinition(definitionContent);\r
+            modelType.setModelName(dataKey);\r
+            modelType.setVersion(artifactType.getVersion());\r
+            modelType.setUpdatedBy("System");\r
+            modelType.setTags(dataKey + "," + artifactType.getDerivedFrom() + ","\r
+                    + BluePrintConstants.MODEL_DEFINITION_TYPE_ARTIFACT_TYPE);\r
+            modelTypeService.saveModel(modelType);\r
+            log.trace("Loaded Artifact Type successfully : {}", file.getFilename());\r
+        } catch (Exception e) {\r
+            errorBuilder.appendln("Artifact type loading error : " + file.getFilename() + ":" + e.getMessage());\r
+        }\r
+    }\r
+\r
+    private Resource[] getPathResources(String path, String extension) throws IOException {\r
+        return resourceLoader.getResources("file:" + path + "/*" + extension);\r
+    }\r
+\r
+    private String getResourceContent(Resource resource) throws IOException {\r
+        return IOUtils.toString(resource.getInputStream(), Charset.defaultCharset());\r
+    }\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/ModelTypeService.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/ModelTypeService.java
new file mode 100644 (file)
index 0000000..2bc2963
--- /dev/null
@@ -0,0 +1,178 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service;\r
+\r
+import org.apache.commons.lang3.StringUtils;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ModelType;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.repository.ModelTypeRepository;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.validator.ModelTypeValidator;\r
+import org.springframework.stereotype.Service;\r
+import org.springframework.transaction.annotation.Transactional;\r
+\r
+import java.util.List;\r
+import java.util.Optional;\r
+\r
+/**\r
+ * ModelTypeService.java Purpose: Provide ModelTypeService Service ModelTypeService\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+\r
+@Service\r
+@Transactional\r
+public class ModelTypeService {\r
+\r
+    private ModelTypeRepository modelTypeRepository;\r
+\r
+    /**\r
+     * This is a ModelTypeService, used to save and get the model types stored in database\r
+     *\r
+     * @param modelTypeRepository\r
+     */\r
+    public ModelTypeService(ModelTypeRepository modelTypeRepository) {\r
+        this.modelTypeRepository = modelTypeRepository;\r
+    }\r
+\r
+\r
+    /**\r
+     * This is a getModelTypeByName service\r
+     *\r
+     * @param modelTypeName\r
+     * @return ModelType\r
+     * @throws BluePrintException\r
+     */\r
+    public ModelType getModelTypeByName(String modelTypeName) throws BluePrintException {\r
+        ModelType modelType = null;\r
+        if (StringUtils.isNotBlank(modelTypeName)) {\r
+            Optional<ModelType> modelTypeOption = modelTypeRepository.findByModelName(modelTypeName);\r
+            if (modelTypeOption.isPresent()) {\r
+                modelType = modelTypeOption.get();\r
+            }\r
+        } else {\r
+            throw new BluePrintException("Model Name Information is missing.");\r
+        }\r
+        return modelType;\r
+    }\r
+\r
+\r
+    /**\r
+     * This is a searchModelTypes service\r
+     *\r
+     * @param tags\r
+     * @return List<ModelType>\r
+     * @throws BluePrintException\r
+     */\r
+    public List<ModelType> searchModelTypes(String tags) throws BluePrintException {\r
+        if (tags != null) {\r
+            return modelTypeRepository.findByTagsContainingIgnoreCase(tags);\r
+        } else {\r
+            throw new BluePrintException("No Search Information provide");\r
+        }\r
+    }\r
+\r
+    /**\r
+     * This is a saveModel service\r
+     *\r
+     * @param modelType\r
+     * @return ModelType\r
+     * @throws BluePrintException\r
+     */\r
+    public ModelType saveModel(ModelType modelType) throws BluePrintException {\r
+\r
+        ModelTypeValidator.validateModelType(modelType);\r
+\r
+        Optional<ModelType> dbModelType = modelTypeRepository.findByModelName(modelType.getModelName());\r
+        if (dbModelType.isPresent()) {\r
+            ModelType dbModel = dbModelType.get();\r
+            dbModel.setDescription(modelType.getDescription());\r
+            dbModel.setDefinition(modelType.getDefinition());\r
+            dbModel.setDefinitionType(modelType.getDefinitionType());\r
+            dbModel.setDerivedFrom(modelType.getDerivedFrom());\r
+            dbModel.setTags(modelType.getTags());\r
+            dbModel.setVersion(modelType.getVersion());\r
+            dbModel.setUpdatedBy(modelType.getUpdatedBy());\r
+            modelType = modelTypeRepository.save(dbModel);\r
+        } else {\r
+            modelType = modelTypeRepository.save(modelType);\r
+        }\r
+        return modelType;\r
+    }\r
+\r
+\r
+    /**\r
+     * This is a deleteByModelName service\r
+     *\r
+     * @param modelName\r
+     * @throws BluePrintException\r
+     */\r
+    public void deleteByModelName(String modelName) throws BluePrintException {\r
+        if (modelName != null) {\r
+            modelTypeRepository.deleteByModelName(modelName);\r
+        } else {\r
+            throw new BluePrintException("Model Name Information is missing.");\r
+        }\r
+    }\r
+\r
+    /**\r
+     * This is a getModelTypeByTags service\r
+     *\r
+     * @param tags\r
+     * @return List<ModelType>\r
+     * @throws BluePrintException\r
+     */\r
+    public List<ModelType> getModelTypeByTags(String tags) throws BluePrintException {\r
+        if (StringUtils.isNotBlank(tags)) {\r
+            return modelTypeRepository.findByTagsContainingIgnoreCase(tags);\r
+        } else {\r
+            throw new BluePrintException("Model Tag Information is missing.");\r
+        }\r
+    }\r
+\r
+    /**\r
+     * This is a getModelTypeByDefinitionType service\r
+     *\r
+     * @param definitionType\r
+     * @return List<ModelType>\r
+     * @throws BluePrintException\r
+     */\r
+    public List<ModelType> getModelTypeByDefinitionType(String definitionType) throws BluePrintException {\r
+        if (StringUtils.isNotBlank(definitionType)) {\r
+            return modelTypeRepository.findByDefinitionType(definitionType);\r
+        } else {\r
+            throw new BluePrintException("Model definitionType Information is missing.");\r
+        }\r
+    }\r
+\r
+    /**\r
+     * This is a getModelTypeByDerivedFrom service\r
+     *\r
+     * @param derivedFrom\r
+     * @return List<ModelType>\r
+     * @throws BluePrintException\r
+     */\r
+    public List<ModelType> getModelTypeByDerivedFrom(String derivedFrom) throws BluePrintException {\r
+        if (StringUtils.isNotBlank(derivedFrom)) {\r
+            return modelTypeRepository.findByDerivedFrom(derivedFrom);\r
+        } else {\r
+            throw new BluePrintException("Model derivedFrom Information is missing.");\r
+        }\r
+    }\r
+\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/ResourceDictionaryService.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/ResourceDictionaryService.java
new file mode 100644 (file)
index 0000000..b9567db
--- /dev/null
@@ -0,0 +1,169 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service;\r
+\r
+import org.apache.commons.lang3.StringUtils;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils;\r
+import org.onap.ccsdk.apps.controllerblueprints.resource.dict.data.DictionaryDefinition;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ResourceDictionary;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.repository.ResourceDictionaryRepository;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.validator.ResourceDictionaryValidator;\r
+import org.springframework.stereotype.Service;\r
+\r
+import java.util.List;\r
+import java.util.Optional;\r
+\r
+/**\r
+ * ResourceDictionaryService.java Purpose: Provide DataDictionaryService Service\r
+ * DataDictionaryService\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+@Service\r
+public class ResourceDictionaryService {\r
+\r
+    private ResourceDictionaryRepository resourceDictionaryRepository;\r
+\r
+    /**\r
+     * This is a DataDictionaryService, used to save and get the Resource Mapping stored in database\r
+     * \r
+     * @param dataDictionaryRepository\r
+     * \r
+     */\r
+    public ResourceDictionaryService(ResourceDictionaryRepository dataDictionaryRepository) {\r
+        this.resourceDictionaryRepository = dataDictionaryRepository;\r
+    }\r
+\r
+    /**\r
+     * This is a getDataDictionaryByName service\r
+     * \r
+     * @param name\r
+     * @return DataDictionary\r
+     * @throws BluePrintException\r
+     */\r
+    public ResourceDictionary getResourceDictionaryByName(String name) throws BluePrintException {\r
+        if (StringUtils.isNotBlank(name)) {\r
+            return resourceDictionaryRepository.findByName(name).get();\r
+        } else {\r
+            throw new BluePrintException("Resource Mapping Name Information is missing.");\r
+        }\r
+    }\r
+\r
+    /**\r
+     * This is a searchResourceDictionaryByNames service\r
+     * \r
+     * @param names\r
+     * @return List<ResourceDictionary>\r
+     * @throws BluePrintException\r
+     */\r
+    public List<ResourceDictionary> searchResourceDictionaryByNames(List<String> names)\r
+            throws BluePrintException {\r
+        if (names != null && !names.isEmpty()) {\r
+            return resourceDictionaryRepository.findByNameIn(names);\r
+        } else {\r
+            throw new BluePrintException("No Search Information provide");\r
+        }\r
+    }\r
+\r
+    /**\r
+     * This is a searchResourceDictionaryByTags service\r
+     * \r
+     * @param tags\r
+     * @return List<ResourceDictionary>\r
+     * @throws BluePrintException\r
+     */\r
+    public List<ResourceDictionary> searchResourceDictionaryByTags(String tags) throws BluePrintException {\r
+        if (StringUtils.isNotBlank(tags)) {\r
+            return resourceDictionaryRepository.findByTagsContainingIgnoreCase(tags);\r
+        } else {\r
+            throw new BluePrintException("No Search Information provide");\r
+        }\r
+    }\r
+\r
+    /**\r
+     * This is a saveDataDictionary service\r
+     * \r
+     * @param resourceDictionary\r
+     * @return DataDictionary\r
+     * @throws BluePrintException\r
+     */\r
+    public ResourceDictionary saveResourceDictionary(ResourceDictionary resourceDictionary)\r
+            throws BluePrintException {\r
+        if (resourceDictionary != null) {\r
+            ResourceDictionaryValidator.validateResourceDictionary(resourceDictionary);\r
+\r
+            DictionaryDefinition dictionaryDefinition =\r
+                    JacksonUtils.readValue(resourceDictionary.getDefinition(), DictionaryDefinition.class);\r
+\r
+            if (dictionaryDefinition == null) {\r
+                throw new BluePrintException(\r
+                        "Resource dictionary definition is not valid content " + resourceDictionary.getDefinition());\r
+            }\r
+\r
+            dictionaryDefinition.setName(resourceDictionary.getName());\r
+            dictionaryDefinition.setResourcePath(resourceDictionary.getResourcePath());\r
+            dictionaryDefinition.setResourceType(resourceDictionary.getResourceType());\r
+            dictionaryDefinition.setDataType(resourceDictionary.getDataType());\r
+            dictionaryDefinition.setEntrySchema(resourceDictionary.getEntrySchema());\r
+            dictionaryDefinition.setTags(resourceDictionary.getTags());\r
+            dictionaryDefinition.setDescription(resourceDictionary.getDescription());\r
+            dictionaryDefinition.setUpdatedBy(resourceDictionary.getUpdatedBy());\r
+\r
+            String definitionContent = JacksonUtils.getJson(dictionaryDefinition, true);\r
+            resourceDictionary.setDefinition(definitionContent);\r
+\r
+            Optional<ResourceDictionary> dbResourceDictionaryData =\r
+                    resourceDictionaryRepository.findByName(resourceDictionary.getName());\r
+            if (dbResourceDictionaryData.isPresent()) {\r
+                ResourceDictionary dbResourceDictionary = dbResourceDictionaryData.get();\r
+\r
+                dbResourceDictionary.setName(resourceDictionary.getName());\r
+                dbResourceDictionary.setDefinition(resourceDictionary.getDefinition());\r
+                dbResourceDictionary.setDescription(resourceDictionary.getDescription());\r
+                dbResourceDictionary.setResourceType(resourceDictionary.getResourceType());\r
+                dbResourceDictionary.setResourcePath(resourceDictionary.getResourcePath());\r
+                dbResourceDictionary.setDataType(resourceDictionary.getDataType());\r
+                dbResourceDictionary.setEntrySchema(resourceDictionary.getEntrySchema());\r
+                dbResourceDictionary.setTags(resourceDictionary.getTags());\r
+                dbResourceDictionary.setValidValues(resourceDictionary.getValidValues());\r
+                resourceDictionary = resourceDictionaryRepository.save(dbResourceDictionary);\r
+            } else {\r
+                resourceDictionary = resourceDictionaryRepository.save(resourceDictionary);\r
+            }\r
+        } else {\r
+            throw new BluePrintException("Resource Dictionary information is missing");\r
+        }\r
+        return resourceDictionary;\r
+    }\r
+\r
+    /**\r
+     * This is a deleteResourceDictionary service\r
+     * \r
+     * @param name\r
+     * @throws BluePrintException\r
+     */\r
+    public void deleteResourceDictionary(String name) throws BluePrintException {\r
+        if (name != null) {\r
+            resourceDictionaryRepository.deleteByName(name);\r
+        } else {\r
+            throw new BluePrintException("Resource Mapping Id Information is missing.");\r
+        }\r
+\r
+    }\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/SchemaGeneratorService.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/SchemaGeneratorService.java
new file mode 100644 (file)
index 0000000..a75651f
--- /dev/null
@@ -0,0 +1,116 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service;\r
+\r
+import com.google.common.base.Preconditions;\r
+import org.apache.commons.collections.MapUtils;\r
+import org.apache.commons.lang3.StringUtils;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.DataType;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.ServiceTemplate;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.common.SwaggerGenerator;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+/**\r
+ * SchemaGeneratorService.java Purpose: Provide Service to generate service template input schema definition and Sample\r
+ * Json generation.\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+\r
+public class SchemaGeneratorService {\r
+    private static Logger log = LoggerFactory.getLogger(SchemaGeneratorService.class);\r
+\r
+    private Map<String, DataType> dataTypes;\r
+\r
+    /**\r
+     * This is a SchemaGeneratorService constructor\r
+     */\r
+    public SchemaGeneratorService() {\r
+        dataTypes = new HashMap<>();\r
+    }\r
+\r
+    /**\r
+     * This is a generateSchema\r
+     *\r
+     * @param serviceTemplateContent service template content\r
+     * @return String\r
+     * @throws BluePrintException Blueprint Exception\r
+     */\r
+    public String generateSchema(String serviceTemplateContent) throws BluePrintException {\r
+        if (StringUtils.isNotBlank(serviceTemplateContent)) {\r
+            ServiceTemplate serviceTemplate = JacksonUtils.readValue(serviceTemplateContent,\r
+                    ServiceTemplate.class);\r
+            return generateSchema(serviceTemplate);\r
+        } else {\r
+            throw new BluePrintException(\r
+                    "Service Template Content is  (" + serviceTemplateContent + ") not Defined.");\r
+        }\r
+    }\r
+\r
+    /**\r
+     * This is a generateSchema\r
+     *\r
+     * @param serviceTemplate service template content\r
+     * @return String\r
+     * @throws BluePrintException Blueprint Exception\r
+     */\r
+    public String generateSchema(ServiceTemplate serviceTemplate) throws BluePrintException {\r
+        String schemaContent = null;\r
+        Preconditions.checkNotNull(serviceTemplate, "Service Template is not defined.");\r
+        try {\r
+            if (serviceTemplate.getTopologyTemplate() != null\r
+                    && serviceTemplate.getTopologyTemplate().getInputs() != null) {\r
+                SwaggerGenerator swaggerGenerator = new SwaggerGenerator(serviceTemplate);\r
+                schemaContent = swaggerGenerator.generateSwagger();\r
+            }\r
+        } catch (Exception e) {\r
+            throw new BluePrintException(e.getMessage(), e);\r
+        }\r
+\r
+        return schemaContent;\r
+    }\r
+\r
+    private void manageServiceTemplateActions(ServiceTemplate serviceTemplate, String actionName) {\r
+        if (serviceTemplate != null && serviceTemplate.getTopologyTemplate() != null\r
+                && StringUtils.isNotBlank(actionName)) {\r
+\r
+            if (MapUtils.isNotEmpty(serviceTemplate.getTopologyTemplate().getInputs())) {\r
+\r
+                serviceTemplate.getTopologyTemplate().getInputs().entrySet().removeIf(entity -> {\r
+                    String keyName = entity.getKey();\r
+                    String replacedAction = actionName.replace("-action", "-request");\r
+                    log.debug("Key name : " + keyName + ", actionName "\r
+                            + actionName + ", replacedAction :" + replacedAction);\r
+                    if (keyName.endsWith("-request") && !keyName.equals(replacedAction)) {\r
+                        log.info("deleting input property {} ", keyName);\r
+                        return true;\r
+                    }\r
+                    return false;\r
+                });\r
+            }\r
+\r
+        }\r
+    }\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/ServiceTemplateService.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/ServiceTemplateService.java
new file mode 100644 (file)
index 0000000..70b7917
--- /dev/null
@@ -0,0 +1,140 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service;\r
+\r
+import org.apache.commons.lang3.StringUtils;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.ServiceTemplate;\r
+import org.onap.ccsdk.apps.controllerblueprints.resource.dict.ResourceAssignment;\r
+import org.onap.ccsdk.apps.controllerblueprints.resource.dict.validator.ResourceAssignmentValidator;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ConfigModelContent;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.model.AutoMapResponse;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.repository.ResourceDictionaryRepository;\r
+import org.springframework.stereotype.Service;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.regex.Matcher;\r
+import java.util.regex.Pattern;\r
+\r
+/**\r
+ * ServiceTemplateService.java Purpose: Provide Service Template Create Service processing ServiceTemplateService\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+\r
+@Service\r
+public class ServiceTemplateService {\r
+\r
+    private ResourceDictionaryRepository dataDictionaryRepository;\r
+\r
+    private ConfigModelCreateService configModelCreateService;\r
+    private BluePrintEnhancerService bluePrintEnhancerService;\r
+\r
+    /**\r
+     * This is a SchemaGeneratorService constructor\r
+     *\r
+     * @param dataDictionaryRepository\r
+     * @param configModelCreateService\r
+     * @param bluePrintEnhancerService\r
+     */\r
+    public ServiceTemplateService(ResourceDictionaryRepository dataDictionaryRepository,\r
+                                  ConfigModelCreateService configModelCreateService,\r
+                                  BluePrintEnhancerService bluePrintEnhancerService) {\r
+        this.dataDictionaryRepository = dataDictionaryRepository;\r
+        this.configModelCreateService = configModelCreateService;\r
+        this.bluePrintEnhancerService = bluePrintEnhancerService;\r
+\r
+    }\r
+\r
+    /**\r
+     * This is a validateServiceTemplate method\r
+     *\r
+     * @param serviceTemplate\r
+     * @return ServiceTemplate\r
+     * @throws BluePrintException\r
+     */\r
+    public ServiceTemplate validateServiceTemplate(ServiceTemplate serviceTemplate) throws BluePrintException {\r
+        return this.configModelCreateService.validateServiceTemplate(serviceTemplate);\r
+    }\r
+\r
+    /**\r
+     * This is a enrichServiceTemplate method\r
+     *\r
+     * @param serviceTemplate\r
+     * @return ServiceTemplate\r
+     * @throws BluePrintException\r
+     */\r
+    public ServiceTemplate enrichServiceTemplate(ServiceTemplate serviceTemplate) throws BluePrintException {\r
+        this.bluePrintEnhancerService.enhance(serviceTemplate);\r
+        return serviceTemplate;\r
+    }\r
+\r
+    /**\r
+     * This is a autoMap method to map the template keys\r
+     *\r
+     * @param resourceAssignments\r
+     * @return AutoMapResponse\r
+     * @throws BluePrintException\r
+     */\r
+    public AutoMapResponse autoMap(List<ResourceAssignment> resourceAssignments) throws BluePrintException {\r
+        AutoResourceMappingService autoMappingService = new AutoResourceMappingService(dataDictionaryRepository);\r
+        AutoMapResponse autoMapResponse = autoMappingService.autoMap(resourceAssignments);\r
+        return autoMapResponse;\r
+    }\r
+\r
+    /**\r
+     * This is a validateResourceAssignments method\r
+     *\r
+     * @param resourceAssignments\r
+     * @return List<ResourceAssignment>\r
+     * @throws BluePrintException\r
+     */\r
+    public List<ResourceAssignment> validateResourceAssignments(List<ResourceAssignment> resourceAssignments)\r
+            throws BluePrintException {\r
+        try {\r
+            ResourceAssignmentValidator resourceAssignmentValidator =\r
+                    new ResourceAssignmentValidator(resourceAssignments);\r
+            resourceAssignmentValidator.validateResourceAssignment();\r
+        } catch (BluePrintException e) {\r
+            throw new BluePrintException(e.getMessage(), e);\r
+        }\r
+        return resourceAssignments;\r
+    }\r
+\r
+    /**\r
+     * This is a generateResourceAssignments method\r
+     *\r
+     * @param templateContent\r
+     * @return List<ResourceAssignment>\r
+     */\r
+    public List<ResourceAssignment> generateResourceAssignments(ConfigModelContent templateContent) {\r
+        List<ResourceAssignment> resourceAssignments = new ArrayList<>();\r
+        if (templateContent != null && StringUtils.isNotBlank(templateContent.getContent())) {\r
+            Pattern p = Pattern.compile("(?<=\\$\\{)([^\\}]+)(?=\\})");\r
+            Matcher m = p.matcher(templateContent.getContent());\r
+            while (m.find()) {\r
+                ResourceAssignment resourceAssignment = new ResourceAssignment();\r
+                resourceAssignment.setName(m.group());\r
+                resourceAssignments.add(resourceAssignment);\r
+            }\r
+        }\r
+        return resourceAssignments;\r
+    }\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/common/ApplicationConstants.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/common/ApplicationConstants.java
new file mode 100644 (file)
index 0000000..8dd7484
--- /dev/null
@@ -0,0 +1,33 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.common;\r
+\r
+/**\r
+ * ApplicationConstants.java Purpose: Provide ControllerBluprintsApplication Constant Information\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+public final class ApplicationConstants {\r
+    private ApplicationConstants() {\r
+\r
+    }\r
+    public static final String ACTIVE_Y = "Y";\r
+    public static final String ACTIVE_N = "N";\r
+    public static final String ASDC_ARTIFACT_TYPE_SDNC_MODEL = "SDNC_MODEL";\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/common/ErrorMessage.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/common/ErrorMessage.java
new file mode 100644 (file)
index 0000000..f7a802e
--- /dev/null
@@ -0,0 +1,63 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.common;\r
+\r
+import com.fasterxml.jackson.annotation.JsonInclude;\r
+import com.fasterxml.jackson.annotation.JsonInclude.Include;\r
+\r
+import java.io.Serializable;\r
+\r
+@JsonInclude(Include.NON_NULL)\r
+public class ErrorMessage implements Serializable {\r
+    private Integer httpStatus;\r
+    private String message;\r
+    private Integer code;\r
+    private String developerMessage;\r
+\r
+    public Integer getHttpStatus() {\r
+        return httpStatus;\r
+    }\r
+\r
+    public void setHttpStatus(Integer httpStatus) {\r
+        this.httpStatus = httpStatus;\r
+    }\r
+\r
+    public String getMessage() {\r
+        return message;\r
+    }\r
+\r
+    public void setMessage(String message) {\r
+        this.message = message;\r
+    }\r
+\r
+    public Integer getCode() {\r
+        return code;\r
+    }\r
+\r
+    public void setCode(Integer code) {\r
+        this.code = code;\r
+    }\r
+\r
+    public String getDeveloperMessage() {\r
+        return developerMessage;\r
+    }\r
+\r
+    public void setDeveloperMessage(String developerMessage) {\r
+        this.developerMessage = developerMessage;\r
+    }\r
+\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/common/ServiceExceptionMapper.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/common/ServiceExceptionMapper.java
new file mode 100644 (file)
index 0000000..f223dcc
--- /dev/null
@@ -0,0 +1,42 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.common;\r
+\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException;\r
+\r
+import javax.ws.rs.core.MediaType;\r
+import javax.ws.rs.core.Response;\r
+import javax.ws.rs.ext.ExceptionMapper;\r
+import javax.ws.rs.ext.Provider;\r
+import java.io.PrintWriter;\r
+import java.io.StringWriter;\r
+\r
+@Provider\r
+public class ServiceExceptionMapper implements ExceptionMapper<BluePrintException> {\r
+\r
+    @Override\r
+    public Response toResponse(BluePrintException ex) {\r
+        ErrorMessage errorMessage = new ErrorMessage();\r
+        errorMessage.setCode(ex.getCode());\r
+        errorMessage.setMessage(ex.getMessage());\r
+        StringWriter errorStackTrace = new StringWriter();\r
+        ex.printStackTrace(new PrintWriter(errorStackTrace));\r
+        errorMessage.setDeveloperMessage(ex.toString());\r
+        return Response.status(500).entity(errorMessage).type(MediaType.APPLICATION_JSON).build();\r
+    }\r
+\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/common/SwaggerGenerator.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/common/SwaggerGenerator.java
new file mode 100644 (file)
index 0000000..e908076
--- /dev/null
@@ -0,0 +1,187 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.common;\r
+\r
+import io.swagger.models.*;\r
+import io.swagger.models.parameters.BodyParameter;\r
+import io.swagger.models.parameters.Parameter;\r
+import io.swagger.models.properties.*;\r
+import io.swagger.util.Json;\r
+import org.apache.commons.collections.MapUtils;\r
+import org.apache.commons.lang3.BooleanUtils;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintTypes;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.PropertyDefinition;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.ServiceTemplate;\r
+\r
+import java.util.*;\r
+\r
+/**\r
+ * SwaggerGenerator.java Purpose: Provide Service to generate service template input schema definition and Sample Json\r
+ * generation.\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+@Deprecated\r
+public class SwaggerGenerator {\r
+\r
+    private ServiceTemplate serviceTemplate;\r
+\r
+    /**\r
+     * This is a SwaggerGenerator constructor\r
+     */\r
+    public SwaggerGenerator(ServiceTemplate serviceTemplate) {\r
+        this.serviceTemplate = serviceTemplate;\r
+    }\r
+\r
+    /**\r
+     * This is a generateSwagger\r
+     *\r
+     * @return String\r
+     */\r
+    public String generateSwagger() {\r
+        String swaggerContent = null;\r
+\r
+        Swagger swagger = new Swagger().info(getInfo());\r
+\r
+        swagger.setPaths(getPaths());\r
+        swagger.setDefinitions(getDefinition());\r
+\r
+\r
+        swaggerContent = Json.pretty(swagger);\r
+        return swaggerContent;\r
+    }\r
+\r
+    private Info getInfo() {\r
+        Info info = new Info();\r
+        Contact contact = new Contact();\r
+        contact.setName(serviceTemplate.getMetadata().get(BluePrintConstants.METADATA_TEMPLATE_AUTHOR));\r
+        info.setContact(contact);\r
+        info.setTitle(serviceTemplate.getMetadata().get(BluePrintConstants.METADATA_TEMPLATE_NAME));\r
+        info.setDescription(serviceTemplate.getDescription());\r
+        info.setVersion(serviceTemplate.getMetadata().get(BluePrintConstants.METADATA_TEMPLATE_VERSION));\r
+        return info;\r
+    }\r
+\r
+    private Map<String, Path> getPaths() {\r
+        Map<String, Path> paths = new HashMap<>();\r
+        Path path = new Path();\r
+        Operation post = new Operation();\r
+        post.setOperationId("configure");\r
+        post.setConsumes(Arrays.asList("application/json", "application/xml"));\r
+        post.setProduces(Arrays.asList("application/json", "application/xml"));\r
+        List<Parameter> parameters = new ArrayList<>();\r
+        Parameter in = new BodyParameter().schema(new RefModel("#/definitions/inputs"));\r
+        in.setRequired(true);\r
+        in.setName("inputs");\r
+        parameters.add(in);\r
+        post.setParameters(parameters);\r
+\r
+        Map<String, Response> responses = new HashMap<>();\r
+        Response response = new Response().description("Success");\r
+        responses.put("200", response);\r
+\r
+        Response failureResponse = new Response().description("Failure");\r
+        responses.put("400", failureResponse);\r
+        post.setResponses(responses);\r
+\r
+        path.setPost(post);\r
+        paths.put("/operations/config-selfservice-api:configure", path);\r
+        return paths;\r
+    }\r
+\r
+    private Map<String, Model> getDefinition() {\r
+        Map<String, Model> models = new HashMap<>();\r
+\r
+        ModelImpl inputmodel = new ModelImpl();\r
+        inputmodel.setTitle("inputs");\r
+        serviceTemplate.getTopologyTemplate().getInputs().forEach((propertyName, property) -> {\r
+            Property defProperty = getPropery(propertyName, property);\r
+            inputmodel.property(propertyName, defProperty);\r
+        });\r
+        models.put("inputs", inputmodel);\r
+\r
+        if (MapUtils.isNotEmpty(serviceTemplate.getDataTypes())) {\r
+            serviceTemplate.getDataTypes().forEach((name, dataType) -> {\r
+                ModelImpl model = new ModelImpl();\r
+                model.setDescription(dataType.getDescription());\r
+                // model.setType("object");\r
+                if (dataType != null && MapUtils.isNotEmpty(dataType.getProperties())) {\r
+\r
+                    dataType.getProperties().forEach((propertyName, property) -> {\r
+                        Property defProperty = getPropery(propertyName, property);\r
+                        model.addProperty(propertyName, defProperty);\r
+                    });\r
+                }\r
+                models.put(name, model);\r
+            });\r
+        }\r
+        return models;\r
+\r
+    }\r
+\r
+    private Property getPropery(String name, PropertyDefinition propertyDefinition) {\r
+        Property defProperty = null;\r
+\r
+        if (BluePrintTypes.validPrimitiveTypes().contains(propertyDefinition.getType())) {\r
+            if (BluePrintConstants.DATA_TYPE_BOOLEAN.equals(propertyDefinition.getType())) {\r
+                defProperty = new BooleanProperty();\r
+            } else if (BluePrintConstants.DATA_TYPE_INTEGER.equals(propertyDefinition.getType())) {\r
+                StringProperty stringProperty = new StringProperty();\r
+                stringProperty.setType("integer");\r
+                defProperty = stringProperty;\r
+            } else if (BluePrintConstants.DATA_TYPE_FLOAT.equals(propertyDefinition.getType())) {\r
+                StringProperty stringProperty = new StringProperty();\r
+                stringProperty.setFormat("float");\r
+                defProperty = stringProperty;\r
+            } else if (BluePrintConstants.DATA_TYPE_TIMESTAMP.equals(propertyDefinition.getType())) {\r
+                DateTimeProperty dateTimeProperty = new DateTimeProperty();\r
+                dateTimeProperty.setFormat("date-time");\r
+                defProperty = dateTimeProperty;\r
+            } else {\r
+                defProperty = new StringProperty();\r
+            }\r
+        } else if (BluePrintTypes.validCollectionTypes().contains(propertyDefinition.getType())) {\r
+            ArrayProperty arrayProperty = new ArrayProperty();\r
+            if (propertyDefinition.getEntrySchema() != null) {\r
+                String entrySchema = propertyDefinition.getEntrySchema().getType();\r
+                if (!BluePrintTypes.validPrimitiveTypes().contains(entrySchema)) {\r
+                    Property innerType = new RefProperty("#/definitions/" + entrySchema);\r
+                    arrayProperty.setItems(innerType);\r
+                } else {\r
+                    Property innerType = new StringProperty();\r
+                    arrayProperty.setItems(innerType);\r
+                }\r
+                defProperty = arrayProperty;\r
+            }\r
+\r
+        } else {\r
+            defProperty = new RefProperty("#/definitions/" + propertyDefinition.getType());\r
+        }\r
+        defProperty.setName(name);\r
+        if (propertyDefinition.getDefaultValue() != null) {\r
+            defProperty.setDefault(String.valueOf(propertyDefinition.getDefaultValue()));\r
+        }\r
+\r
+        defProperty.setRequired(BooleanUtils.isTrue(propertyDefinition.getRequired()));\r
+        defProperty.setDescription(propertyDefinition.getDescription());\r
+        return defProperty;\r
+    }\r
+\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/domain/ConfigModel.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/domain/ConfigModel.java
new file mode 100644 (file)
index 0000000..224960f
--- /dev/null
@@ -0,0 +1,291 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.domain;\r
+\r
+import com.fasterxml.jackson.annotation.JsonFormat;\r
+import com.fasterxml.jackson.annotation.JsonManagedReference;\r
+import org.hibernate.annotations.Proxy;\r
+import org.springframework.data.annotation.LastModifiedDate;\r
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;\r
+\r
+import javax.persistence.*;\r
+import javax.validation.constraints.NotNull;\r
+import java.io.Serializable;\r
+import java.util.ArrayList;\r
+import java.util.Date;\r
+import java.util.List;\r
+\r
+/**\r
+ * ConfigModel.java Purpose: Provide Configuration Generator ConfigModel Entity\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+\r
+@EntityListeners({AuditingEntityListener.class})\r
+@Entity\r
+@Table(name = "CONFIG_MODEL")\r
+@Proxy(lazy=false)\r
+public class ConfigModel implements Serializable {\r
+    private static final long serialVersionUID = 1L;\r
+    @Id\r
+    @GeneratedValue(strategy = GenerationType.IDENTITY)\r
+    @Column(name = "config_model_id")\r
+    private Long id;\r
+\r
+    @Column(name = "service_uuid")\r
+    private String serviceUUID;\r
+\r
+    @Column(name = "distribution_id")\r
+    private String distributionId;\r
+\r
+    @Column(name = "service_name")\r
+    private String serviceName;\r
+\r
+    @Column(name = "service_description")\r
+    private String serviceDescription;\r
+\r
+    @Column(name = "resource_uuid")\r
+    private String resourceUUID;\r
+\r
+    @Column(name = "resource_instance_name")\r
+    private String resourceInstanceName;\r
+\r
+    @Column(name = "resource_name")\r
+    private String resourceName;\r
+\r
+    @Column(name = "resource_version")\r
+    private String resourceVersion;\r
+\r
+    @Column(name = "resource_type")\r
+    private String resourceType;\r
+\r
+    @Column(name = "artifact_uuid")\r
+    private String artifactUUId;\r
+\r
+    @Column(name = "artifact_type")\r
+    private String artifactType;\r
+\r
+    @NotNull\r
+    @Column(name = "artifact_version")\r
+    private String artifactVersion;\r
+\r
+    @Lob\r
+    @Column(name = "artifact_description")\r
+    private String artifactDescription;\r
+\r
+    @Column(name = "internal_version")\r
+    private Integer internalVersion;\r
+\r
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "MM/dd/yyyy KK:mm:ss a Z")\r
+    @LastModifiedDate\r
+    @Temporal(TemporalType.TIMESTAMP)\r
+    @Column(name = "creation_date")\r
+    private Date createdDate = new Date();\r
+\r
+    @NotNull\r
+    @Column(name = "artifact_name")\r
+    private String artifactName;\r
+\r
+    @NotNull\r
+    @Column(name = "published")\r
+    private String published;\r
+\r
+    @NotNull\r
+    @Column(name = "updated_by")\r
+    private String updatedBy;\r
+\r
+    @NotNull\r
+    @Lob\r
+    @Column(name = "tags")\r
+    private String tags;\r
+\r
+\r
+    @OneToMany(mappedBy = "configModel", fetch = FetchType.EAGER, orphanRemoval = true, cascade = CascadeType.ALL)\r
+    @Column(nullable = true)\r
+    @JsonManagedReference\r
+    private List<ConfigModelContent> configModelContents = new ArrayList<>();\r
+\r
+    public Long getId() {\r
+        return id;\r
+    }\r
+\r
+    public void setId(Long id) {\r
+        this.id = id;\r
+    }\r
+\r
+    public String getServiceUUID() {\r
+        return serviceUUID;\r
+    }\r
+\r
+    public void setServiceUUID(String serviceUUID) {\r
+        this.serviceUUID = serviceUUID;\r
+    }\r
+\r
+    public String getDistributionId() {\r
+        return distributionId;\r
+    }\r
+\r
+    public void setDistributionId(String distributionId) {\r
+        this.distributionId = distributionId;\r
+    }\r
+\r
+    public String getServiceName() {\r
+        return serviceName;\r
+    }\r
+\r
+    public void setServiceName(String serviceName) {\r
+        this.serviceName = serviceName;\r
+    }\r
+\r
+    public String getServiceDescription() {\r
+        return serviceDescription;\r
+    }\r
+\r
+    public void setServiceDescription(String serviceDescription) {\r
+        this.serviceDescription = serviceDescription;\r
+    }\r
+\r
+    public String getResourceUUID() {\r
+        return resourceUUID;\r
+    }\r
+\r
+    public void setResourceUUID(String resourceUUID) {\r
+        this.resourceUUID = resourceUUID;\r
+    }\r
+\r
+    public String getResourceInstanceName() {\r
+        return resourceInstanceName;\r
+    }\r
+\r
+    public void setResourceInstanceName(String resourceInstanceName) {\r
+        this.resourceInstanceName = resourceInstanceName;\r
+    }\r
+\r
+    public String getResourceName() {\r
+        return resourceName;\r
+    }\r
+\r
+    public void setResourceName(String resourceName) {\r
+        this.resourceName = resourceName;\r
+    }\r
+\r
+    public String getResourceVersion() {\r
+        return resourceVersion;\r
+    }\r
+\r
+    public void setResourceVersion(String resourceVersion) {\r
+        this.resourceVersion = resourceVersion;\r
+    }\r
+\r
+    public String getResourceType() {\r
+        return resourceType;\r
+    }\r
+\r
+    public void setResourceType(String resourceType) {\r
+        this.resourceType = resourceType;\r
+    }\r
+\r
+    public String getArtifactUUId() {\r
+        return artifactUUId;\r
+    }\r
+\r
+    public void setArtifactUUId(String artifactUUId) {\r
+        this.artifactUUId = artifactUUId;\r
+    }\r
+\r
+    public String getArtifactType() {\r
+        return artifactType;\r
+    }\r
+\r
+    public void setArtifactType(String artifactType) {\r
+        this.artifactType = artifactType;\r
+    }\r
+\r
+    public String getArtifactVersion() {\r
+        return artifactVersion;\r
+    }\r
+\r
+    public void setArtifactVersion(String artifactVersion) {\r
+        this.artifactVersion = artifactVersion;\r
+    }\r
+\r
+    public String getArtifactDescription() {\r
+        return artifactDescription;\r
+    }\r
+\r
+    public void setArtifactDescription(String artifactDescription) {\r
+        this.artifactDescription = artifactDescription;\r
+    }\r
+\r
+    public Integer getInternalVersion() {\r
+        return internalVersion;\r
+    }\r
+\r
+    public void setInternalVersion(Integer internalVersion) {\r
+        this.internalVersion = internalVersion;\r
+    }\r
+\r
+    public Date getCreatedDate() {\r
+        return createdDate;\r
+    }\r
+\r
+    public void setCreatedDate(Date createdDate) {\r
+        this.createdDate = createdDate;\r
+    }\r
+\r
+    public String getArtifactName() {\r
+        return artifactName;\r
+    }\r
+\r
+    public void setArtifactName(String artifactName) {\r
+        this.artifactName = artifactName;\r
+    }\r
+\r
+    public String getPublished() {\r
+        return published;\r
+    }\r
+\r
+    public void setPublished(String published) {\r
+        this.published = published;\r
+    }\r
+\r
+    public String getUpdatedBy() {\r
+        return updatedBy;\r
+    }\r
+\r
+    public void setUpdatedBy(String updatedBy) {\r
+        this.updatedBy = updatedBy;\r
+    }\r
+\r
+    public String getTags() {\r
+        return tags;\r
+    }\r
+\r
+    public void setTags(String tags) {\r
+        this.tags = tags;\r
+    }\r
+\r
+    public List<ConfigModelContent> getConfigModelContents() {\r
+        return configModelContents;\r
+    }\r
+\r
+    public void setConfigModelContents(List<ConfigModelContent> configModelContents) {\r
+        this.configModelContents = configModelContents;\r
+    }\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/domain/ConfigModelContent.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/domain/ConfigModelContent.java
new file mode 100644 (file)
index 0000000..f7bd554
--- /dev/null
@@ -0,0 +1,175 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.domain;\r
+\r
+import com.fasterxml.jackson.annotation.JsonBackReference;\r
+import com.fasterxml.jackson.annotation.JsonFormat;\r
+import org.springframework.data.annotation.LastModifiedDate;\r
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;\r
+\r
+import javax.persistence.*;\r
+import javax.validation.constraints.NotNull;\r
+import java.util.Date;\r
+import java.util.Objects;\r
+\r
+/**\r
+ * DataDictionary.java Purpose: Provide Configuration Generator DataDictionary Entity\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+@EntityListeners({AuditingEntityListener.class})\r
+@Entity\r
+@Table(name = "CONFIG_MODEL_CONTENT")\r
+public class ConfigModelContent {\r
+\r
+    private static final long serialVersionUID = 1L;\r
+\r
+    @Id\r
+    @GeneratedValue(strategy = GenerationType.IDENTITY)\r
+    @Column(name = "config_model_content_id")\r
+    private Long id;\r
+\r
+    @NotNull\r
+    @Column(name = "name")\r
+    private String name;\r
+\r
+    @NotNull\r
+    @Column(name = "content_type")\r
+    private String contentType;\r
+\r
+\r
+    @ManyToOne\r
+    @JoinColumn(name = "config_model_id")\r
+    @JsonBackReference\r
+    private ConfigModel configModel;\r
+\r
+    @Lob\r
+    @Column(name = "description")\r
+    private String description;\r
+\r
+    @NotNull\r
+    @Lob\r
+    @Column(name = "content")\r
+    private String content;\r
+\r
+\r
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "MM/dd/yyyy KK:mm:ss a Z")\r
+    @LastModifiedDate\r
+    @Temporal(TemporalType.TIMESTAMP)\r
+    @Column(name = "updated_date")\r
+    private Date creationDate;\r
+\r
+    @Override\r
+    public String toString() {\r
+        StringBuilder builder = new StringBuilder("[");\r
+        builder.append("id = " + id);\r
+        builder.append(", name = " + name);\r
+        builder.append(", contentType = " + contentType);\r
+        builder.append("]");\r
+        return builder.toString();\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(Object o) {\r
+\r
+        if (o == this) {\r
+            return true;\r
+        }\r
+        if (!(o instanceof ConfigModelContent)) {\r
+            return false;\r
+        }\r
+        ConfigModelContent configModelContent = (ConfigModelContent) o;\r
+        return Objects.equals(id, configModelContent.id) && Objects.equals(name, configModelContent.name)\r
+                && Objects.equals(contentType, configModelContent.contentType);\r
+    }\r
+\r
+    @Override\r
+    public int hashCode() {\r
+        return Objects.hash(id, name, contentType);\r
+    }\r
+\r
+    public Long getId() {\r
+        return id;\r
+    }\r
+\r
+\r
+    public void setId(Long id) {\r
+        this.id = id;\r
+    }\r
+\r
+\r
+    public String getName() {\r
+        return name;\r
+    }\r
+\r
+\r
+    public void setName(String name) {\r
+        this.name = name;\r
+    }\r
+\r
+\r
+    public String getContentType() {\r
+        return contentType;\r
+    }\r
+\r
+\r
+    public void setContentType(String contentType) {\r
+        this.contentType = contentType;\r
+    }\r
+\r
+\r
+    public ConfigModel getConfigModel() {\r
+        return configModel;\r
+    }\r
+\r
+\r
+    public void setConfigModel(ConfigModel configModel) {\r
+        this.configModel = configModel;\r
+    }\r
+\r
+\r
+    public String getDescription() {\r
+        return description;\r
+    }\r
+\r
+\r
+    public void setDescription(String description) {\r
+        this.description = description;\r
+    }\r
+\r
+\r
+    public String getContent() {\r
+        return content;\r
+    }\r
+\r
+\r
+    public void setContent(String content) {\r
+        this.content = content;\r
+    }\r
+\r
+\r
+    public Date getCreationDate() {\r
+        return creationDate;\r
+    }\r
+\r
+\r
+    public void setCreationDate(Date creationDate) {\r
+        this.creationDate = creationDate;\r
+    }\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/domain/ConfigModelSearch.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/domain/ConfigModelSearch.java
new file mode 100644 (file)
index 0000000..2e90188
--- /dev/null
@@ -0,0 +1,171 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.domain;\r
+\r
+import com.fasterxml.jackson.annotation.JsonFormat;\r
+import org.springframework.data.annotation.LastModifiedDate;\r
+\r
+import javax.persistence.*;\r
+import javax.validation.constraints.NotNull;\r
+import java.io.Serializable;\r
+import java.util.Date;\r
+\r
+@Entity\r
+@Table(name = "CONFIG_MODEL")\r
+public class ConfigModelSearch implements Serializable {\r
+    private static final long serialVersionUID = 1L;\r
+\r
+    @Id\r
+    @GeneratedValue(strategy = GenerationType.IDENTITY)\r
+    @Column(name = "config_model_id")\r
+    private Long id;\r
+\r
+    @Column(name = "artifact_uuid")\r
+    private String artifactUUId;\r
+\r
+    @Column(name = "artifact_type")\r
+    private String artifactType;\r
+\r
+    @NotNull\r
+    @Column(name = "artifact_version")\r
+    private String artifactVersion;\r
+\r
+    @Lob\r
+    @Column(name = "artifact_description")\r
+    private String artifactDescription;\r
+\r
+    @Column(name = "internal_version")\r
+    private Integer internalVersion;\r
+\r
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "MM/dd/yyyy KK:mm:ss a Z")\r
+    @LastModifiedDate\r
+    @Temporal(TemporalType.TIMESTAMP)\r
+    @Column(name = "creation_date")\r
+    private Date createdDate = new Date();\r
+\r
+    @NotNull\r
+    @Column(name = "artifact_name")\r
+    private String artifactName;\r
+\r
+    @NotNull\r
+    @Column(name = "published")\r
+    private String published;\r
+\r
+    @NotNull\r
+    @Column(name = "updated_by")\r
+    private String updatedBy;\r
+\r
+    @NotNull\r
+    @Lob\r
+    @Column(name = "tags")\r
+    private String tags;\r
+\r
+    public Long getId() {\r
+        return id;\r
+    }\r
+\r
+    public void setId(Long id) {\r
+        this.id = id;\r
+    }\r
+\r
+    public String getArtifactUUId() {\r
+        return artifactUUId;\r
+    }\r
+\r
+    public void setArtifactUUId(String artifactUUId) {\r
+        this.artifactUUId = artifactUUId;\r
+    }\r
+\r
+    public String getArtifactType() {\r
+        return artifactType;\r
+    }\r
+\r
+    public void setArtifactType(String artifactType) {\r
+        this.artifactType = artifactType;\r
+    }\r
+\r
+    public String getArtifactVersion() {\r
+        return artifactVersion;\r
+    }\r
+\r
+    public void setArtifactVersion(String artifactVersion) {\r
+        this.artifactVersion = artifactVersion;\r
+    }\r
+\r
+    public String getArtifactDescription() {\r
+        return artifactDescription;\r
+    }\r
+\r
+    public void setArtifactDescription(String artifactDescription) {\r
+        this.artifactDescription = artifactDescription;\r
+    }\r
+\r
+    public Integer getInternalVersion() {\r
+        return internalVersion;\r
+    }\r
+\r
+    public void setInternalVersion(Integer internalVersion) {\r
+        this.internalVersion = internalVersion;\r
+    }\r
+\r
+    public Date getCreatedDate() {\r
+        return createdDate;\r
+    }\r
+\r
+    public void setCreatedDate(Date createdDate) {\r
+        this.createdDate = createdDate;\r
+    }\r
+\r
+    public String getArtifactName() {\r
+        return artifactName;\r
+    }\r
+\r
+    public void setArtifactName(String artifactName) {\r
+        this.artifactName = artifactName;\r
+    }\r
+\r
+    public String getPublished() {\r
+        return published;\r
+    }\r
+\r
+    public void setPublished(String published) {\r
+        this.published = published;\r
+    }\r
+\r
+    public String getUpdatedBy() {\r
+        return updatedBy;\r
+    }\r
+\r
+    public void setUpdatedBy(String updatedBy) {\r
+        this.updatedBy = updatedBy;\r
+    }\r
+\r
+    public String getTags() {\r
+        return tags;\r
+    }\r
+\r
+    public void setTags(String tags) {\r
+        this.tags = tags;\r
+    }\r
+\r
+    public static long getSerialversionuid() {\r
+        return serialVersionUID;\r
+    }\r
+\r
+\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/domain/ModelType.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/domain/ModelType.java
new file mode 100644 (file)
index 0000000..ed6340a
--- /dev/null
@@ -0,0 +1,170 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.domain;\r
+\r
+import org.springframework.data.annotation.LastModifiedDate;\r
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;\r
+\r
+import javax.persistence.*;\r
+import javax.validation.constraints.NotNull;\r
+import java.io.Serializable;\r
+import java.util.Date;\r
+\r
+\r
+/**\r
+ * AsdcReference.java Purpose: Provide Configuration Generator AsdcReference Entity\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+@EntityListeners({AuditingEntityListener.class})\r
+@Entity\r
+@Table(name = "MODEL_TYPE")\r
+public class ModelType implements Serializable {\r
+    private static final long serialVersionUID = 1L;\r
+\r
+    @Id\r
+    @NotNull\r
+    @Column(name = "model_name", nullable = false)\r
+    private String modelName;\r
+\r
+    @NotNull\r
+    @Column(name = "derived_from")\r
+    private String derivedFrom;\r
+\r
+    @NotNull\r
+    @Column(name = "definition_type")\r
+    private String definitionType;\r
+\r
+    @NotNull\r
+    @Lob\r
+    @Column(name = "definition")\r
+    private String definition;\r
+\r
+    @NotNull\r
+    @Lob\r
+    @Column(name = "description")\r
+    private String description;\r
+\r
+    @NotNull\r
+    @Column(name = "version")\r
+    private String version;\r
+\r
+    @NotNull\r
+    @Lob\r
+    @Column(name = "tags")\r
+    private String tags;\r
+\r
+    // @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "MM/dd/yyyy KK:mm:ss a Z")\r
+    @LastModifiedDate\r
+    @Temporal(TemporalType.TIMESTAMP)\r
+    @Column(name = "creation_date")\r
+    private Date creationDate;\r
+\r
+    @NotNull\r
+    @Column(name = "updated_by")\r
+    private String updatedBy;\r
+\r
+    @Override\r
+    public String toString() {\r
+        StringBuilder buffer = new StringBuilder("[");\r
+        buffer.append(", modelName = " + modelName);\r
+        buffer.append(", derivedFrom = " + derivedFrom);\r
+        buffer.append(", definitionType = " + definitionType);\r
+        buffer.append(", description = " + description);\r
+        buffer.append(", creationDate = " + creationDate);\r
+        buffer.append(", version = " + version);\r
+        buffer.append(", updatedBy = " + updatedBy);\r
+        buffer.append(", tags = " + tags);\r
+        buffer.append("]");\r
+        return buffer.toString();\r
+    }\r
+\r
+    public String getModelName() {\r
+        return modelName;\r
+    }\r
+\r
+    public void setModelName(String modelName) {\r
+        this.modelName = modelName;\r
+    }\r
+\r
+    public String getDerivedFrom() {\r
+        return derivedFrom;\r
+    }\r
+\r
+    public void setDerivedFrom(String derivedFrom) {\r
+        this.derivedFrom = derivedFrom;\r
+    }\r
+\r
+    public String getDefinitionType() {\r
+        return definitionType;\r
+    }\r
+\r
+    public void setDefinitionType(String definitionType) {\r
+        this.definitionType = definitionType;\r
+    }\r
+\r
+    public String getDefinition() {\r
+        return definition;\r
+    }\r
+\r
+    public void setDefinition(String definition) {\r
+        this.definition = definition;\r
+    }\r
+\r
+    public String getDescription() {\r
+        return description;\r
+    }\r
+\r
+    public void setDescription(String description) {\r
+        this.description = description;\r
+    }\r
+\r
+    public String getVersion() {\r
+        return version;\r
+    }\r
+\r
+    public void setVersion(String version) {\r
+        this.version = version;\r
+    }\r
+\r
+    public String getTags() {\r
+        return tags;\r
+    }\r
+\r
+    public void setTags(String tags) {\r
+        this.tags = tags;\r
+    }\r
+\r
+    public Date getCreationDate() {\r
+        return creationDate;\r
+    }\r
+\r
+    public void setCreationDate(Date creationDate) {\r
+        this.creationDate = creationDate;\r
+    }\r
+\r
+    public String getUpdatedBy() {\r
+        return updatedBy;\r
+    }\r
+\r
+    public void setUpdatedBy(String updatedBy) {\r
+        this.updatedBy = updatedBy;\r
+    }\r
+\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/domain/ResourceDictionary.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/domain/ResourceDictionary.java
new file mode 100644 (file)
index 0000000..adb0188
--- /dev/null
@@ -0,0 +1,207 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.domain;\r
+\r
+import org.springframework.data.annotation.LastModifiedDate;\r
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;\r
+\r
+import javax.persistence.*;\r
+import javax.validation.constraints.NotNull;\r
+import java.io.Serializable;\r
+import java.util.Date;\r
+\r
+/**\r
+ * DataDictionary.java Purpose: Provide Configuration Generator DataDictionary Entity\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+@EntityListeners({AuditingEntityListener.class})\r
+@Entity\r
+@Table(name = "RESOURCE_DICTIONARY")\r
+public class ResourceDictionary implements Serializable {\r
+    private static final long serialVersionUID = 1L;\r
+\r
+    @Id\r
+    @NotNull\r
+    @Column(name = "name")\r
+    private String name;\r
+\r
+    @NotNull\r
+    @Column(name = "resource_path")\r
+    private String resourcePath;\r
+\r
+    @NotNull\r
+    @Column(name = "resource_type")\r
+    private String resourceType;\r
+\r
+    @NotNull\r
+    @Column(name = "data_type")\r
+    private String dataType;\r
+\r
+    @Column(name = "entry_schema")\r
+    private String entrySchema;\r
+\r
+    @Lob\r
+    @Column(name = "valid_values")\r
+    private String validValues;\r
+\r
+    @Lob\r
+    @Column(name = "sample_value")\r
+    private String sampleValue;\r
+\r
+    @NotNull\r
+    @Lob\r
+    @Column(name = "definition")\r
+    private String definition;\r
+\r
+    @NotNull\r
+    @Lob\r
+    @Column(name = "description")\r
+    private String description;\r
+\r
+    @NotNull\r
+    @Lob\r
+    @Column(name = "tags")\r
+    private String tags;\r
+\r
+    @LastModifiedDate\r
+    @Temporal(TemporalType.TIMESTAMP)\r
+    @Column(name = "creation_date")\r
+    private Date creationDate;\r
+\r
+    @NotNull\r
+    @Column(name = "updated_by")\r
+    private String updatedBy;\r
+\r
+    @Override\r
+    public String toString() {\r
+        StringBuilder buffer = new StringBuilder("[");\r
+        buffer.append(", name = " + name);\r
+        buffer.append(", resourcePath = " + resourcePath);\r
+        buffer.append(", resourceType = " + resourceType);\r
+        buffer.append(", dataType = " + dataType);\r
+        buffer.append(", entrySchema = " + entrySchema);\r
+        buffer.append(", validValues = " + validValues);\r
+        buffer.append(", definition =" + definition);\r
+        buffer.append(", description = " + description);\r
+        buffer.append(", updatedBy = " + updatedBy);\r
+        buffer.append(", tags = " + tags);\r
+        buffer.append(", creationDate = " + creationDate);\r
+        buffer.append("]");\r
+        return buffer.toString();\r
+    }\r
+\r
+    public String getResourcePath() {\r
+        return resourcePath;\r
+    }\r
+\r
+    public void setResourcePath(String resourcePath) {\r
+        this.resourcePath = resourcePath;\r
+    }\r
+\r
+    public String getName() {\r
+        return name;\r
+    }\r
+\r
+    public void setName(String name) {\r
+        this.name = name;\r
+    }\r
+\r
+    public String getResourceType() {\r
+        return resourceType;\r
+    }\r
+\r
+    public void setResourceType(String resourceType) {\r
+        this.resourceType = resourceType;\r
+    }\r
+\r
+    public String getDataType() {\r
+        return dataType;\r
+    }\r
+\r
+    public void setDataType(String dataType) {\r
+        this.dataType = dataType;\r
+    }\r
+\r
+    public String getEntrySchema() {\r
+        return entrySchema;\r
+    }\r
+\r
+    public void setEntrySchema(String entrySchema) {\r
+        this.entrySchema = entrySchema;\r
+    }\r
+\r
+    public String getValidValues() {\r
+        return validValues;\r
+    }\r
+\r
+    public void setValidValues(String validValues) {\r
+        this.validValues = validValues;\r
+    }\r
+\r
+    public String getSampleValue() {\r
+        return sampleValue;\r
+    }\r
+\r
+    public void setSampleValue(String sampleValue) {\r
+        this.sampleValue = sampleValue;\r
+    }\r
+\r
+    public String getDefinition() {\r
+        return definition;\r
+    }\r
+\r
+    public void setDefinition(String definition) {\r
+        this.definition = definition;\r
+    }\r
+\r
+    public String getDescription() {\r
+        return description;\r
+    }\r
+\r
+    public void setDescription(String description) {\r
+        this.description = description;\r
+    }\r
+\r
+    public String getTags() {\r
+        return tags;\r
+    }\r
+\r
+    public void setTags(String tags) {\r
+        this.tags = tags;\r
+    }\r
+\r
+    public Date getCreationDate() {\r
+        return creationDate;\r
+    }\r
+\r
+    public void setCreationDate(Date creationDate) {\r
+        this.creationDate = creationDate;\r
+    }\r
+\r
+    public String getUpdatedBy() {\r
+        return updatedBy;\r
+    }\r
+\r
+    public void setUpdatedBy(String updatedBy) {\r
+        this.updatedBy = updatedBy;\r
+    }\r
+\r
+\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/model/AutoMapResponse.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/model/AutoMapResponse.java
new file mode 100644 (file)
index 0000000..2250828
--- /dev/null
@@ -0,0 +1,53 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.model;\r
+\r
+import org.onap.ccsdk.apps.controllerblueprints.resource.dict.ResourceAssignment;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ResourceDictionary;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * ArtifactRequest.java Purpose: Provide Configuration Generator ArtifactRequest Model\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+public class AutoMapResponse {\r
+\r
+    private List<ResourceAssignment> resourceAssignments;\r
+    private List<ResourceDictionary> dataDictionaries;\r
+\r
+    public List<ResourceAssignment> getResourceAssignments() {\r
+        return resourceAssignments;\r
+    }\r
+\r
+    public void setResourceAssignments(List<ResourceAssignment> resourceAssignments) {\r
+        this.resourceAssignments = resourceAssignments;\r
+    }\r
+\r
+    public List<ResourceDictionary> getDataDictionaries() {\r
+        return dataDictionaries;\r
+    }\r
+\r
+    public void setDataDictionaries(List<ResourceDictionary> dataDictionaries) {\r
+        this.dataDictionaries = dataDictionaries;\r
+    }\r
+\r
+\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/repository/ConfigModelContentRepository.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/repository/ConfigModelContentRepository.java
new file mode 100644 (file)
index 0000000..ad2584a
--- /dev/null
@@ -0,0 +1,95 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.repository;\r
+\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ConfigModel;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ConfigModelContent;\r
+import org.springframework.data.jpa.repository.JpaRepository;\r
+import org.springframework.stereotype.Repository;\r
+\r
+import java.util.List;\r
+import java.util.Optional;\r
+\r
+/**\r
+ * ConfigModelContentRepository.java Purpose: Provide ConfigModelContentRepository of Repository\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+@Repository\r
+public interface ConfigModelContentRepository extends JpaRepository<ConfigModelContent, Long> {\r
+\r
+    /**\r
+     * This is a findById method\r
+     * \r
+     * @param id\r
+     * @return Optional<AsdcArtifacts>\r
+     */\r
+    Optional<ConfigModelContent> findById(Long id);\r
+\r
+    /**\r
+     * This is a findTopByConfigModelAndContentType method\r
+     * \r
+     * @param configModel\r
+     * @param contentType\r
+     * @return Optional<ConfigModelContent>\r
+     */\r
+    Optional<ConfigModelContent> findTopByConfigModelAndContentType(ConfigModel configModel, String contentType);\r
+\r
+    /**\r
+     * This is a findByConfigModelAndContentType method\r
+     * \r
+     * @param configModel\r
+     * @param contentType\r
+     * @return Optional<ConfigModelContent>\r
+     */\r
+    List<ConfigModelContent> findByConfigModelAndContentType(ConfigModel configModel, String contentType);\r
+\r
+    /**\r
+     * This is a findByConfigModel method\r
+     * \r
+     * @param configModel\r
+     * @return Optional<ConfigModelContent>\r
+     */\r
+    List<ConfigModelContent> findByConfigModel(ConfigModel configModel);\r
+\r
+    /**\r
+     * This is a findByConfigModelAndContentTypeAndName method\r
+     * \r
+     * @param configModel\r
+     * @param contentType\r
+     * @param name\r
+     * @return Optional<ConfigModelContent>\r
+     */\r
+    Optional<ConfigModelContent> findByConfigModelAndContentTypeAndName(ConfigModel configModel,\r
+                                                                        String contentType, String name);\r
+\r
+    /**\r
+     * This is a deleteByMdeleteByConfigModelodelName method\r
+     * \r
+     * @param configModel\r
+     */\r
+    void deleteByConfigModel(ConfigModel configModel);\r
+\r
+    /**\r
+     * This is a deleteById method\r
+     * \r
+     * @param id\r
+     */\r
+    void deleteById(Long id);\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/repository/ConfigModelRepository.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/repository/ConfigModelRepository.java
new file mode 100644 (file)
index 0000000..4822ee9
--- /dev/null
@@ -0,0 +1,90 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.repository;\r
+\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ConfigModel;\r
+import org.springframework.data.jpa.repository.JpaRepository;\r
+import org.springframework.stereotype.Repository;\r
+\r
+import java.util.List;\r
+import java.util.Optional;\r
+\r
+/**\r
+ * AsdcArtifactsRepository.java Purpose: Provide Configuration Generator AsdcArtifactsRepository\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+@Repository\r
+public interface ConfigModelRepository extends JpaRepository<ConfigModel, Long> {\r
+    /**\r
+     * This is a findById method\r
+     * \r
+     * @param id\r
+     * @return Optional<AsdcArtifacts>\r
+     */\r
+    Optional<ConfigModel> findById(Long id);\r
+\r
+    /**\r
+     * This is a findByArtifactNameAndArtifactVersion method\r
+     * \r
+     * @param artifactName\r
+     * @param artifactVersion\r
+     * @return Optional<AsdcArtifacts>\r
+     */\r
+    Optional<ConfigModel> findByArtifactNameAndArtifactVersion(String artifactName, String artifactVersion);\r
+\r
+    /**\r
+     * This is a findTopByArtifactNameOrderByArtifactIdDesc method\r
+     * \r
+     * @param artifactName\r
+     * @return Optional<AsdcArtifacts>\r
+     */\r
+    Optional<ConfigModel> findTopByArtifactNameOrderByArtifactVersionDesc(String artifactName);\r
+\r
+    /**\r
+     * This is a findTopByArtifactName method\r
+     * \r
+     * @param artifactName\r
+     * @return Optional<AsdcArtifacts>\r
+     */\r
+    List<ConfigModel> findTopByArtifactName(String artifactName);\r
+\r
+    /**\r
+     * This is a findByTagsContainingIgnoreCase method\r
+     * \r
+     * @param tags\r
+     * @return Optional<ModelType>\r
+     */\r
+    List<ConfigModel> findByTagsContainingIgnoreCase(String tags);\r
+\r
+    /**\r
+     * This is a deleteByArtifactNameAndArtifactVersion method\r
+     * \r
+     * @param artifactName\r
+     * @param artifactVersion\r
+     */\r
+    void deleteByArtifactNameAndArtifactVersion(String artifactName, String artifactVersion);\r
+\r
+    /**\r
+     * This is a deleteById method\r
+     * \r
+     * @param id\r
+     */\r
+    void deleteById(Long id);\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/repository/ConfigModelSearchRepository.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/repository/ConfigModelSearchRepository.java
new file mode 100644 (file)
index 0000000..bafc3aa
--- /dev/null
@@ -0,0 +1,43 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.repository;\r
+\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ConfigModel;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ConfigModelSearch;\r
+import org.springframework.data.jpa.repository.JpaRepository;\r
+import org.springframework.stereotype.Repository;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * ConfigModelSearchRepository.java Purpose: Provide Configuration Generator AsdcArtifactsRepository\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+@Repository\r
+public interface ConfigModelSearchRepository extends JpaRepository<ConfigModelSearch, Long> {\r
+\r
+\r
+    /**\r
+     * This is a findByTagsContainingIgnoreCase method\r
+     * \r
+     * @param tags\r
+     * @return Optional<ModelType>\r
+     */\r
+    List<ConfigModel> findByTagsContainingIgnoreCase(String tags);\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/repository/ModelTypeRepository.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/repository/ModelTypeRepository.java
new file mode 100644 (file)
index 0000000..51ae752
--- /dev/null
@@ -0,0 +1,98 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.repository;\r
+\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ModelType;\r
+import org.springframework.data.jpa.repository.JpaRepository;\r
+import org.springframework.stereotype.Repository;\r
+\r
+import java.util.List;\r
+import java.util.Optional;\r
+\r
+\r
+/**\r
+ * ModelTypeRepository.java Purpose: Provide Configuration Generator ModelTypeRepository\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+@Repository\r
+public interface ModelTypeRepository extends JpaRepository<ModelType, String> {\r
+\r
+\r
+    /**\r
+     * This is a findByModelName method\r
+     * \r
+     * @param modelName\r
+     * @return Optional<ModelType>\r
+     */\r
+    Optional<ModelType> findByModelName(String modelName);\r
+\r
+    /**\r
+     * This is a findByDerivedFrom method\r
+     * \r
+     * @param derivedFrom\r
+     * @return List<ModelType>\r
+     */\r
+    List<ModelType> findByDerivedFrom(String derivedFrom);\r
+\r
+\r
+    /**\r
+     * This is a findByDerivedFromIn method\r
+     * \r
+     * @param derivedFroms\r
+     * @return List<ModelType>\r
+     */\r
+    List<ModelType> findByDerivedFromIn(List<String> derivedFroms);\r
+\r
+    /**\r
+     * This is a findByDefinitionType method\r
+     * \r
+     * @param definitionType\r
+     * @return List<ModelType>\r
+     */\r
+    List<ModelType> findByDefinitionType(String definitionType);\r
+\r
+    /**\r
+     * This is a findByDefinitionTypeIn method\r
+     * \r
+     * @param definitionTypes\r
+     * @return List<ModelType>\r
+     */\r
+    List<ModelType> findByDefinitionTypeIn(List<String> definitionTypes);\r
+\r
+\r
+    /**\r
+     * This is a findByTagsContainingIgnoreCase method\r
+     * \r
+     * @param tags\r
+     * @return Optional<ModelType>\r
+     */\r
+    List<ModelType> findByTagsContainingIgnoreCase(String tags);\r
+\r
+\r
+    /**\r
+     * This is a deleteByModelName method\r
+     * \r
+     * @param modelName\r
+     * @return Optional<ModelType>\r
+     */\r
+    void deleteByModelName(String modelName);\r
+\r
+\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/repository/ResourceDictionaryRepository.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/repository/ResourceDictionaryRepository.java
new file mode 100644 (file)
index 0000000..279dcd1
--- /dev/null
@@ -0,0 +1,68 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.repository;\r
+\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ResourceDictionary;\r
+import org.springframework.data.jpa.repository.JpaRepository;\r
+import org.springframework.stereotype.Repository;\r
+\r
+import java.util.List;\r
+import java.util.Optional;\r
+\r
+/**\r
+ * ResourceMappingRepository.java Purpose: Provide Configuration Generator ResourceMappingRepository\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+@Repository\r
+public interface ResourceDictionaryRepository extends JpaRepository<ResourceDictionary, String> {\r
+\r
+\r
+    /**\r
+     * This is a findByName method\r
+     * \r
+     * @param name\r
+     * @return Optional<ResourceMapping>\r
+     */\r
+    Optional<ResourceDictionary> findByName(String name);\r
+\r
+    /**\r
+     * This is a findByNameIn method\r
+     * \r
+     * @param names\r
+     * @return Optional<ResourceMapping>\r
+     */\r
+    List<ResourceDictionary> findByNameIn(List<String> names);\r
+\r
+    /**\r
+     * This is a findByTagsContainingIgnoreCase method\r
+     * \r
+     * @param tags\r
+     * @return Optional<ModelType>\r
+     */\r
+    List<ResourceDictionary> findByTagsContainingIgnoreCase(String tags);\r
+\r
+    /**\r
+     * This is a deleteByName method\r
+     * \r
+     * @param name\r
+     */\r
+    void deleteByName(String name);\r
+\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ConfigModelRest.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ConfigModelRest.java
new file mode 100644 (file)
index 0000000..86c89bf
--- /dev/null
@@ -0,0 +1,179 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.rs;\r
+\r
+import io.swagger.annotations.*;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.ServiceTemplate;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ConfigModel;\r
+import org.springframework.web.bind.annotation.RequestMapping;\r
+import org.springframework.web.bind.annotation.RequestMethod;\r
+import org.springframework.web.bind.annotation.ResponseBody;\r
+\r
+import javax.ws.rs.*;\r
+import javax.ws.rs.core.MediaType;\r
+import java.util.List;\r
+\r
+/**\r
+ * ConfigModelRest.java Purpose: Rest service controller for ConfigModelRest Management\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+@Api\r
+@Path("/service")\r
+@Produces({MediaType.APPLICATION_JSON})\r
+public interface ConfigModelRest {\r
+\r
+    /**\r
+     * This is a getConfigModel rest service\r
+     * \r
+     * @param id\r
+     * @return ConfigModel\r
+     * @throws BluePrintException\r
+     */\r
+    @GET\r
+    @Path("/configmodel/{id}")\r
+    @Consumes({MediaType.APPLICATION_JSON})\r
+    @Produces({MediaType.APPLICATION_JSON})\r
+    @ApiOperation(value = "Provides Rest service to Search Service Template", response = ConfigModel.class)\r
+    @ApiResponses(value = {@ApiResponse(code = 404, message = "Service not available"),\r
+            @ApiResponse(code = 500, message = "Unexpected Runtime error")})\r
+    @RequestMapping(value = "/configmodel/{id}", method = RequestMethod.GET)\r
+    @ResponseBody ConfigModel getConfigModel(@ApiParam(required = true) @PathParam("id") Long id)\r
+            throws BluePrintException;\r
+    \r
+\r
+    /**\r
+     * This is a saveConfigModel rest service\r
+     * \r
+     * @param configModel\r
+     * @return ConfigModel\r
+     * @throws BluePrintException\r
+     */\r
+    @POST\r
+    @Path("/configmodel")\r
+    @Consumes({MediaType.APPLICATION_JSON})\r
+    @Produces({MediaType.APPLICATION_JSON})\r
+    @ApiOperation(value = "Provides Rest service to get Model Type by Tags", response = ServiceTemplate.class)\r
+    @ApiResponses(value = {@ApiResponse(code = 404, message = "Service not available"),\r
+            @ApiResponse(code = 500, message = "Unexpected Runtime error")})\r
+    ConfigModel saveConfigModel(@ApiParam(required = true) ConfigModel configModel)\r
+            throws BluePrintException;\r
+\r
+    /**\r
+     * This is a deleteConfigModel rest service\r
+     * \r
+     * @param id\r
+     * @throws BluePrintException\r
+     */\r
+    @DELETE\r
+    @Path("/configmodel/{id}")\r
+    @Consumes({MediaType.APPLICATION_JSON})\r
+    @Produces({MediaType.APPLICATION_JSON})\r
+    @ApiOperation(value = "Provides Rest service to delete ConfigModel.")\r
+    @ApiResponses(value = {@ApiResponse(code = 404, message = "Service not available"),\r
+            @ApiResponse(code = 500, message = "Unexpected Runtime error")})\r
+    void deleteConfigModel(@ApiParam(required = true) @PathParam("id") Long id) throws BluePrintException;\r
+\r
+    /**\r
+     * This is a getInitialConfigModel rest service\r
+     * \r
+     * @param name\r
+     * @return ConfigModel\r
+     * @throws BluePrintException\r
+     */\r
+    @GET\r
+    @Path("/configmodelinitial/{name}")\r
+    @Consumes({MediaType.APPLICATION_JSON})\r
+    @Produces({MediaType.APPLICATION_JSON})\r
+    @ApiOperation(value = "Provides Rest service to create default Service Template", response = ConfigModel.class)\r
+    @ApiResponses(value = {@ApiResponse(code = 404, message = "Service not available"),\r
+            @ApiResponse(code = 500, message = "Unexpected Runtime error")})\r
+    ConfigModel getInitialConfigModel(@ApiParam(required = true) @PathParam("name") String name)\r
+            throws BluePrintException;\r
+\r
+    /**\r
+     * This is a getCloneConfigModel rest service\r
+     * \r
+     * @param id\r
+     * @return ConfigModel\r
+     * @throws BluePrintException\r
+     */\r
+    @GET\r
+    @Path("/configmodelclone/{id}")\r
+    @Consumes({MediaType.APPLICATION_JSON})\r
+    @Produces({MediaType.APPLICATION_JSON})\r
+    @ApiOperation(value = "Provides Rest service to create default Service Template", response = ConfigModel.class)\r
+    @ApiResponses(value = {@ApiResponse(code = 404, message = "Service not available"),\r
+            @ApiResponse(code = 500, message = "Unexpected Runtime error")})\r
+    ConfigModel getCloneConfigModel(@ApiParam(required = true) @PathParam("id") Long id)\r
+            throws BluePrintException;\r
+\r
+    /**\r
+     * This is a publishConfigModel rest service\r
+     * \r
+     * @param id\r
+     * @return ServiceTemplate\r
+     * @throws BluePrintException\r
+     */\r
+    @GET\r
+    @Path("/configmodelpublish/{id}")\r
+    @Consumes({MediaType.APPLICATION_JSON})\r
+    @Produces({MediaType.APPLICATION_JSON})\r
+    @ApiOperation(value = "Provides Rest service to get Model Type by Tags", response = ConfigModel.class)\r
+    @ApiResponses(value = {@ApiResponse(code = 404, message = "Service not available"),\r
+            @ApiResponse(code = 500, message = "Unexpected Runtime error")})\r
+    ConfigModel publishConfigModel(@ApiParam(required = true) @PathParam("id") Long id)\r
+            throws BluePrintException;\r
+\r
+    /**\r
+     * This is a getConfigModelByNameAndVersion rest service\r
+     * \r
+     * @param name\r
+     * @param version\r
+     * @return ConfigModel\r
+     * @throws BluePrintException\r
+     */\r
+    @GET\r
+    @Path("/configmodelbyname/{name}/version/{version}")\r
+    @Consumes({MediaType.APPLICATION_JSON})\r
+    @Produces({MediaType.APPLICATION_JSON})\r
+    @ApiOperation(value = "Provides Rest service to Search Service Template", response = ConfigModel.class)\r
+    @ApiResponses(value = {@ApiResponse(code = 404, message = "Service not available"),\r
+            @ApiResponse(code = 500, message = "Unexpected Runtime error")})\r
+    ConfigModel getConfigModelByNameAndVersion(@ApiParam(required = true) @PathParam("name") String name,\r
+                                               @ApiParam(required = true) @PathParam("version") String version) throws BluePrintException;\r
+\r
+    /**\r
+     * This is a searchServiceModels rest service\r
+     * \r
+     * @param tags\r
+     * @return List<ConfigModel>\r
+     * @throws BluePrintException\r
+     */\r
+    @GET\r
+    @Path("/configmodelsearch/{tags}")\r
+    @Consumes({MediaType.APPLICATION_JSON})\r
+    @Produces({MediaType.APPLICATION_JSON})\r
+    @ApiOperation(value = "Provides Rest service to Search Service Template", response = ConfigModel.class)\r
+    @ApiResponses(value = {@ApiResponse(code = 404, message = "Service not available"),\r
+            @ApiResponse(code = 500, message = "Unexpected Runtime error")})\r
+    List<ConfigModel> searchConfigModels(@ApiParam(required = true) @PathParam("tags") String tags)\r
+            throws BluePrintException;\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ConfigModelRestImpl.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ConfigModelRestImpl.java
new file mode 100644 (file)
index 0000000..a9abcd5
--- /dev/null
@@ -0,0 +1,116 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.rs;\r
+\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.ConfigModelService;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ConfigModel;\r
+import org.springframework.stereotype.Service;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * {@inheritDoc}\r
+ */\r
+@Service\r
+public class ConfigModelRestImpl implements ConfigModelRest {\r
+\r
+    private ConfigModelService configModelService;\r
+\r
+    /**\r
+     * This is a ConfigModelRestImpl constructor.\r
+     *\r
+     * @param configModelService Config Model Service\r
+     */\r
+    public ConfigModelRestImpl(ConfigModelService configModelService) {\r
+        this.configModelService = configModelService;\r
+\r
+    }\r
+\r
+    @Override\r
+    public ConfigModel getInitialConfigModel(String name) throws BluePrintException {\r
+        try {\r
+            return this.configModelService.getInitialConfigModel(name);\r
+        } catch (Exception e) {\r
+            throw new BluePrintException(2000, e.getMessage(), e);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public ConfigModel saveConfigModel(ConfigModel configModel) throws BluePrintException {\r
+        try {\r
+            return this.configModelService.saveConfigModel(configModel);\r
+        } catch (Exception e) {\r
+            throw new BluePrintException(2200, e.getMessage(), e);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void deleteConfigModel(Long id) throws BluePrintException {\r
+        try {\r
+            this.configModelService.deleteConfigModel(id);\r
+        } catch (Exception e) {\r
+            throw new BluePrintException(4000, e.getMessage(), e);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public ConfigModel publishConfigModel(Long id) throws BluePrintException {\r
+        try {\r
+            return this.configModelService.publishConfigModel(id);\r
+        } catch (Exception e) {\r
+            throw new BluePrintException(2500, e.getMessage(), e);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public ConfigModel getConfigModel(Long id) throws BluePrintException {\r
+        try {\r
+            return this.configModelService.getConfigModel(id);\r
+        } catch (Exception e) {\r
+            throw new BluePrintException(2001, e.getMessage(), e);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public ConfigModel getConfigModelByNameAndVersion(String name, String version) throws BluePrintException {\r
+        try {\r
+            return this.configModelService.getConfigModelByNameAndVersion(name, version);\r
+        } catch (Exception e) {\r
+            throw new BluePrintException(2002, e.getMessage(), e);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public List<ConfigModel> searchConfigModels(String tags) throws BluePrintException {\r
+        try {\r
+            return this.configModelService.searchConfigModels(tags);\r
+        } catch (Exception e) {\r
+            throw new BluePrintException(2003, e.getMessage(), e);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public ConfigModel getCloneConfigModel(Long id) throws BluePrintException {\r
+        try {\r
+            return this.configModelService.getCloneConfigModel(id);\r
+        } catch (Exception e) {\r
+            throw new BluePrintException(2004, e.getMessage(), e);\r
+        }\r
+    }\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ModelTypeRest.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ModelTypeRest.java
new file mode 100644 (file)
index 0000000..59b7303
--- /dev/null
@@ -0,0 +1,125 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.rs;\r
+\r
+import io.swagger.annotations.*;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ModelType;\r
+\r
+import javax.ws.rs.*;\r
+import javax.ws.rs.core.MediaType;\r
+import java.util.List;\r
+\r
+/**\r
+ * ModelTypeRest.java Purpose: Rest service controller for Artifact Handling\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+@Api\r
+@Path("/service")\r
+@Produces({MediaType.APPLICATION_JSON})\r
+public interface ModelTypeRest {\r
+\r
+    /**\r
+     * This is a getModelTypeByName rest service\r
+     * \r
+     * @param name\r
+     * @return ModelType\r
+     * @throws BluePrintException\r
+     */\r
+    @GET\r
+    @Path("/modeltype/{name}")\r
+    @Consumes({MediaType.APPLICATION_JSON})\r
+    @Produces({MediaType.APPLICATION_JSON})\r
+    @ApiOperation(value = "Provides Rest service to get Model Type by id", response = ModelType.class)\r
+    @ApiResponses(value = {@ApiResponse(code = 404, message = "Service not available"),\r
+            @ApiResponse(code = 500, message = "Unexpected Runtime error")})\r
+    ModelType getModelTypeByName(@ApiParam(required = true) @PathParam("name") String name)\r
+            throws BluePrintException;\r
+\r
+    /**\r
+     * This is a saveModelType rest service\r
+     * \r
+     * @param modelType\r
+     * @return ModelType\r
+     * @throws BluePrintException\r
+     */\r
+\r
+    @POST\r
+    @Path("/modeltype")\r
+    @Consumes({MediaType.APPLICATION_JSON})\r
+    @Produces({MediaType.APPLICATION_JSON})\r
+    @ApiOperation(value = "Provides Rest service to Save Model Type", response = ModelType.class)\r
+    @ApiResponses(value = {@ApiResponse(code = 404, message = "Service not available"),\r
+            @ApiResponse(code = 500, message = "Unexpected Runtime error")})\r
+    ModelType saveModelType(@ApiParam(required = true) ModelType modelType) throws BluePrintException;\r
+\r
+    /**\r
+     * This is a deleteModelType rest service\r
+     * \r
+     * @param name\r
+     * @throws BluePrintException\r
+     */\r
+    @DELETE\r
+    @Path("/modeltype/{name}")\r
+    @Consumes({MediaType.APPLICATION_JSON})\r
+    @Produces({MediaType.APPLICATION_JSON})\r
+    @ApiOperation(value = "Provides Rest service to delete Model Type")\r
+    @ApiResponses(value = {@ApiResponse(code = 404, message = "Service not available"),\r
+            @ApiResponse(code = 500, message = "Unexpected Runtime error")})\r
+    void deleteModelTypeByName(@ApiParam(required = true) @PathParam("name") String name)\r
+            throws BluePrintException;\r
+\r
+    /**\r
+     * This is a searchModelType rest service\r
+     * \r
+     * @param tags\r
+     * @return List<ModelType>\r
+     * @throws BluePrintException\r
+     */\r
+    @GET\r
+    @Path("/modeltypesearch/{tags}")\r
+    @Consumes({MediaType.APPLICATION_JSON})\r
+    @Produces({MediaType.APPLICATION_JSON})\r
+    @ApiOperation(value = "Provides Rest service to get Model Type by tags", response = ModelType.class,\r
+            responseContainer = "List")\r
+    @ApiResponses(value = {@ApiResponse(code = 404, message = "Service not available"),\r
+            @ApiResponse(code = 500, message = "Unexpected Runtime error")})\r
+    List<ModelType> searchModelTypes(@ApiParam(required = true) @PathParam("tags") String tags)\r
+            throws BluePrintException;\r
+\r
+    /**\r
+     * This is a getModelTypeByDefinitionType rest service\r
+     * \r
+     * @param definitionType\r
+     * @return List<ModelType>\r
+     * @throws BluePrintException\r
+     */\r
+    @GET\r
+    @Path("/modeltypebydefinition/{definitionType}")\r
+    @Consumes({MediaType.APPLICATION_JSON})\r
+    @Produces({MediaType.APPLICATION_JSON})\r
+    @ApiOperation(value = "Provides Rest service to get Model Type by tags", response = ModelType.class,\r
+            responseContainer = "List")\r
+    @ApiResponses(value = {@ApiResponse(code = 404, message = "Service not available"),\r
+            @ApiResponse(code = 500, message = "Unexpected Runtime error")})\r
+    List<ModelType> getModelTypeByDefinitionType(\r
+            @ApiParam(required = true) @PathParam("definitionType") String definitionType)\r
+            throws BluePrintException;\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ModelTypeRestImpl.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ModelTypeRestImpl.java
new file mode 100644 (file)
index 0000000..6fbc696
--- /dev/null
@@ -0,0 +1,87 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.rs;\r
+\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.ModelTypeService;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ModelType;\r
+import org.springframework.stereotype.Service;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * {@inheritDoc}\r
+ */\r
+@Service\r
+public class ModelTypeRestImpl implements ModelTypeRest {\r
+\r
+    private ModelTypeService modelTypeService;\r
+\r
+    /**\r
+     * This is a ModelTypeResourceImpl, used to save and get the model types stored in database\r
+     *\r
+     * @param modelTypeService Model Type Service\r
+     */\r
+    public ModelTypeRestImpl(ModelTypeService modelTypeService) {\r
+        this.modelTypeService = modelTypeService;\r
+    }\r
+\r
+    @Override\r
+    public ModelType getModelTypeByName(String modelName) throws BluePrintException {\r
+        try {\r
+            return modelTypeService.getModelTypeByName(modelName);\r
+        } catch (Exception e) {\r
+            throw new BluePrintException(1000, e.getMessage(), e);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public List<ModelType> searchModelTypes(String tags) throws BluePrintException {\r
+        try {\r
+            return modelTypeService.searchModelTypes(tags);\r
+        } catch (Exception e) {\r
+            throw new BluePrintException(1001, e.getMessage(), e);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public List<ModelType> getModelTypeByDefinitionType(String definitionType) throws BluePrintException {\r
+        try {\r
+            return modelTypeService.getModelTypeByDefinitionType(definitionType);\r
+        } catch (Exception e) {\r
+            throw new BluePrintException(1002, e.getMessage(), e);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public ModelType saveModelType(ModelType modelType) throws BluePrintException {\r
+        try {\r
+            return modelTypeService.saveModel(modelType);\r
+        } catch (Exception e) {\r
+            throw new BluePrintException(1100, e.getMessage(), e);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void deleteModelTypeByName(String name) throws BluePrintException {\r
+        try {\r
+            modelTypeService.deleteByModelName(name);\r
+        } catch (Exception e) {\r
+            throw new BluePrintException(1400, e.getMessage(), e);\r
+        }\r
+    }\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ResourceDictionaryRest.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ResourceDictionaryRest.java
new file mode 100644 (file)
index 0000000..5bc9833
--- /dev/null
@@ -0,0 +1,126 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.rs;\r
+\r
+import io.swagger.annotations.*;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ResourceDictionary;\r
+\r
+import javax.ws.rs.*;\r
+import javax.ws.rs.core.MediaType;\r
+import java.util.List;\r
+\r
+/**\r
+ * ResourceDictionaryRest.java Purpose: Rest service controller for Artifact Handling\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+@Api\r
+@Path("/service")\r
+@Produces({MediaType.APPLICATION_JSON})\r
+\r
+public interface ResourceDictionaryRest {\r
+\r
+    /**\r
+     * This is a getDataDictionaryByPath rest service\r
+     * \r
+     * @param name\r
+     * @return ResourceDictionary\r
+     * @throws BluePrintException\r
+     */\r
+    @GET\r
+    @Path("/dictionary/{name}")\r
+    @Consumes({MediaType.APPLICATION_JSON})\r
+    @Produces({MediaType.APPLICATION_JSON})\r
+    @ApiOperation(value = "Provides Rest service to get Resource dictionary", response = ResourceDictionary.class)\r
+    @ApiResponses(value = {@ApiResponse(code = 404, message = "Service not available"),\r
+            @ApiResponse(code = 500, message = "Unexpected Runtime error")})\r
+    ResourceDictionary getResourceDictionaryByName(@ApiParam(required = true) @PathParam("name") String name)\r
+            throws BluePrintException;\r
+\r
+    /**\r
+     * This is a saveDataDictionary rest service\r
+     * \r
+     * @param resourceMapping\r
+     * @return ResourceDictionary\r
+     * @throws BluePrintException\r
+     */\r
+\r
+    @POST\r
+    @Path("/dictionary")\r
+    @Consumes({MediaType.APPLICATION_JSON})\r
+    @Produces({MediaType.APPLICATION_JSON})\r
+    @ApiOperation(value = "Provides Rest service to Save Resource dictionary Type", response = ResourceDictionary.class)\r
+    @ApiResponses(value = {@ApiResponse(code = 404, message = "Service not available"),\r
+            @ApiResponse(code = 500, message = "Unexpected Runtime error")})\r
+    ResourceDictionary saveResourceDictionary(@ApiParam(required = true) ResourceDictionary resourceMapping)\r
+            throws BluePrintException;\r
+\r
+    /**\r
+     * This is a deleteDataDictionaryByName rest service\r
+     * \r
+     * @param name\r
+     * @throws BluePrintException\r
+     */\r
+    @DELETE\r
+    @Path("/dictionary/{name}")\r
+    @Consumes({MediaType.APPLICATION_JSON})\r
+    @Produces({MediaType.APPLICATION_JSON})\r
+    @ApiOperation(value = "Provides Rest service to delete ResourceDictionary Type")\r
+    @ApiResponses(value = {@ApiResponse(code = 404, message = "Service not available"),\r
+            @ApiResponse(code = 500, message = "Unexpected Runtime error")})\r
+    void deleteResourceDictionaryByName(@ApiParam(required = true) @PathParam("name") String name)\r
+            throws BluePrintException;\r
+\r
+    /**\r
+     * This is a searchResourceDictionaryByTags rest service\r
+     * \r
+     * @param tags\r
+     * @return ResourceDictionary\r
+     * @throws BluePrintException\r
+     */\r
+    @GET\r
+    @Path("/dictionarysearch/{tags}")\r
+    @Consumes({MediaType.APPLICATION_JSON})\r
+    @Produces({MediaType.APPLICATION_JSON})\r
+    @ApiOperation(value = "Provides Rest service to search Resource dictionary by tags",\r
+            response = ResourceDictionary.class, responseContainer = "List")\r
+    @ApiResponses(value = {@ApiResponse(code = 404, message = "Service not available"),\r
+            @ApiResponse(code = 500, message = "Unexpected Runtime error")})\r
+    List<ResourceDictionary> searchResourceDictionaryByTags(\r
+            @ApiParam(required = true) @PathParam("tags") String tags) throws BluePrintException;\r
+\r
+    /**\r
+     * This is a searchResourceDictionaryByNames rest service\r
+     * \r
+     * @param names\r
+     * @return List<ResourceDictionary>\r
+     * @throws BluePrintException\r
+     */\r
+    @POST\r
+    @Path("/dictionarybynames")\r
+    @Consumes({MediaType.APPLICATION_JSON})\r
+    @Produces({MediaType.APPLICATION_JSON})\r
+    @ApiOperation(value = "Provides Rest service to get ResourceDictionary Type by names",\r
+            response = ResourceDictionary.class, responseContainer = "List")\r
+    @ApiResponses(value = {@ApiResponse(code = 404, message = "Service not available"),\r
+            @ApiResponse(code = 500, message = "Unexpected Runtime error")})\r
+    List<ResourceDictionary> searchResourceDictionaryByNames(@ApiParam(required = true) List<String> names)\r
+            throws BluePrintException;\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ResourceDictionaryRestImpl.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ResourceDictionaryRestImpl.java
new file mode 100644 (file)
index 0000000..e344842
--- /dev/null
@@ -0,0 +1,91 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.rs;\r
+\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.ResourceDictionaryService;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ResourceDictionary;\r
+import org.springframework.stereotype.Service;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * {@inheritDoc}\r
+ */\r
+@Service\r
+public class ResourceDictionaryRestImpl implements ResourceDictionaryRest {\r
+\r
+\r
+    private ResourceDictionaryService resourceDictionaryService;\r
+\r
+    /**\r
+     * This is a DataDictionaryRestImpl, used to save and get the Resource Mapping stored in database\r
+     *\r
+     * @param dataDictionaryService Data Dictionary Service\r
+     */\r
+    public ResourceDictionaryRestImpl(ResourceDictionaryService dataDictionaryService) {\r
+        this.resourceDictionaryService = dataDictionaryService;\r
+    }\r
+\r
+    @Override\r
+    public ResourceDictionary saveResourceDictionary(ResourceDictionary dataDictionary)\r
+            throws BluePrintException {\r
+        try {\r
+            return resourceDictionaryService.saveResourceDictionary(dataDictionary);\r
+        } catch (Exception e) {\r
+            throw new BluePrintException(4100, e.getMessage(), e);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void deleteResourceDictionaryByName(String name) throws BluePrintException {\r
+        try {\r
+            resourceDictionaryService.deleteResourceDictionary(name);\r
+        } catch (Exception e) {\r
+            throw new BluePrintException(4400, e.getMessage(), e);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public ResourceDictionary getResourceDictionaryByName(String resourcePath) throws BluePrintException {\r
+        try {\r
+            return resourceDictionaryService.getResourceDictionaryByName(resourcePath);\r
+        } catch (Exception e) {\r
+            throw new BluePrintException(4001, e.getMessage(), e);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public List<ResourceDictionary> searchResourceDictionaryByNames(List<String> names)\r
+            throws BluePrintException {\r
+        try {\r
+            return resourceDictionaryService.searchResourceDictionaryByNames(names);\r
+        } catch (Exception e) {\r
+            throw new BluePrintException(4002, e.getMessage(), e);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public List<ResourceDictionary> searchResourceDictionaryByTags(String tags) throws BluePrintException {\r
+        try {\r
+            return resourceDictionaryService.searchResourceDictionaryByTags(tags);\r
+        } catch (Exception e) {\r
+            throw new BluePrintException(4003, e.getMessage(), e);\r
+        }\r
+    }\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ServiceTemplateRest.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ServiceTemplateRest.java
new file mode 100644 (file)
index 0000000..fcb8f31
--- /dev/null
@@ -0,0 +1,134 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.rs;\r
+\r
+import io.swagger.annotations.*;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.ServiceTemplate;\r
+import org.onap.ccsdk.apps.controllerblueprints.resource.dict.ResourceAssignment;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ConfigModelContent;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.model.AutoMapResponse;\r
+\r
+import javax.ws.rs.Consumes;\r
+import javax.ws.rs.POST;\r
+import javax.ws.rs.Path;\r
+import javax.ws.rs.Produces;\r
+import javax.ws.rs.core.MediaType;\r
+import java.util.List;\r
+\r
+\r
+/**\r
+ * ServiceTemplateRest.java Purpose: ServiceTemplateRest interface\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+\r
+@Api\r
+@Path("/service")\r
+@Produces({MediaType.APPLICATION_JSON})\r
+public interface ServiceTemplateRest {\r
+\r
+    /**\r
+     * This is a enrichServiceTemplate rest service\r
+     * \r
+     * @param serviceTemplate\r
+     * @return ServiceTemplate\r
+     * @throws BluePrintException\r
+     */\r
+    @POST\r
+    @Path("/servicetemplate/enrich")\r
+    @Consumes({MediaType.APPLICATION_JSON})\r
+    @Produces({MediaType.APPLICATION_JSON})\r
+    @ApiOperation(value = "Provides Rest service to enrich service template", response = ServiceTemplate.class)\r
+    @ApiResponses(value = {@ApiResponse(code = 404, message = "Service not available"),\r
+            @ApiResponse(code = 500, message = "Unexpected Runtime error")})\r
+    ServiceTemplate enrichServiceTemplate(@ApiParam(required = true) ServiceTemplate serviceTemplate)\r
+            throws BluePrintException;\r
+\r
+    /**\r
+     * This is a validateServiceTemplate rest service\r
+     * \r
+     * @param serviceTemplate\r
+     * @return ServiceTemplate\r
+     * @throws BluePrintException\r
+     */\r
+    @POST\r
+    @Path("/servicetemplate/validate")\r
+    @Consumes({MediaType.APPLICATION_JSON})\r
+    @Produces({MediaType.APPLICATION_JSON})\r
+    @ApiOperation(value = "Provides Rest service to validate service template", response = ServiceTemplate.class)\r
+    @ApiResponses(value = {@ApiResponse(code = 404, message = "Service not available"),\r
+            @ApiResponse(code = 500, message = "Unexpected Runtime error")})\r
+    ServiceTemplate validateServiceTemplate(@ApiParam(required = true) ServiceTemplate serviceTemplate)\r
+            throws BluePrintException;\r
+\r
+    /**\r
+     * This is a generateResourceAssignments rest service\r
+     * \r
+     * @param templateContent\r
+     * @return List<ResourceAssignment>\r
+     * @throws BluePrintException\r
+     */\r
+    @POST\r
+    @Path("/resourceassignment/generate")\r
+    @Consumes({MediaType.APPLICATION_JSON})\r
+    @Produces({MediaType.APPLICATION_JSON})\r
+    @ApiOperation(value = "Provides Rest service to auto map for the Resource Mapping",\r
+            response = ResourceAssignment.class, responseContainer = "List")\r
+    @ApiResponses(value = {@ApiResponse(code = 404, message = "Service not available"),\r
+            @ApiResponse(code = 500, message = "Unexpected Runtime error")})\r
+    List<ResourceAssignment> generateResourceAssignments(\r
+            @ApiParam(required = true) ConfigModelContent templateContent) throws BluePrintException;\r
+\r
+    /**\r
+     * This is a autoMap rest service\r
+     * \r
+     * @param resourceAssignments\r
+     * @return AutoMapResponse\r
+     * @throws BluePrintException\r
+     */\r
+    @POST\r
+    @Path("/resourceassignment/automap")\r
+    @Consumes({MediaType.APPLICATION_JSON})\r
+    @Produces({MediaType.APPLICATION_JSON})\r
+    @ApiOperation(value = "Provides Rest service to auto map for the Resource assignments",\r
+            response = AutoMapResponse.class)\r
+    @ApiResponses(value = {@ApiResponse(code = 404, message = "Service not available"),\r
+            @ApiResponse(code = 500, message = "Unexpected Runtime error")})\r
+    AutoMapResponse autoMap(@ApiParam(required = true) List<ResourceAssignment> resourceAssignments)\r
+            throws BluePrintException;\r
+\r
+    /**\r
+     * This is a validateResourceAssignments rest service\r
+     * \r
+     * @param resourceAssignments\r
+     * @return List<ResourceAssignment>\r
+     * @throws BluePrintException\r
+     */\r
+    @POST\r
+    @Path("/resourceassignment/validate")\r
+    @Consumes({MediaType.APPLICATION_JSON})\r
+    @Produces({MediaType.APPLICATION_JSON})\r
+    @ApiOperation(value = "Provides Rest service to validate Resource assignments", response = ResourceAssignment.class,\r
+            responseContainer = "List")\r
+    @ApiResponses(value = {@ApiResponse(code = 404, message = "Service not available"),\r
+            @ApiResponse(code = 500, message = "Unexpected Runtime error")})\r
+    List<ResourceAssignment> validateResourceAssignments(\r
+            @ApiParam(required = true) List<ResourceAssignment> resourceAssignments) throws BluePrintException;\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ServiceTemplateRestImpl.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ServiceTemplateRestImpl.java
new file mode 100644 (file)
index 0000000..6c49d5c
--- /dev/null
@@ -0,0 +1,94 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.rs;\r
+\r
+\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.ServiceTemplate;\r
+import org.onap.ccsdk.apps.controllerblueprints.resource.dict.ResourceAssignment;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.ServiceTemplateService;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ConfigModelContent;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.model.AutoMapResponse;\r
+import org.springframework.stereotype.Service;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * {@inheritDoc}\r
+ */\r
+@Service\r
+public class ServiceTemplateRestImpl implements ServiceTemplateRest {\r
+\r
+    private ServiceTemplateService serviceTemplateService;\r
+\r
+    /**\r
+     * This is a ServiceTemplateRestImpl constructor\r
+     *\r
+     * @param serviceTemplateService Service Template Service\r
+     */\r
+    public ServiceTemplateRestImpl(ServiceTemplateService serviceTemplateService) {\r
+        this.serviceTemplateService = serviceTemplateService;\r
+    }\r
+\r
+    @Override\r
+    public ServiceTemplate enrichServiceTemplate(ServiceTemplate serviceTemplate) throws BluePrintException {\r
+        try {\r
+            return serviceTemplateService.enrichServiceTemplate(serviceTemplate);\r
+        } catch (Exception e) {\r
+            throw new BluePrintException(3500, e.getMessage(), e);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public ServiceTemplate validateServiceTemplate(ServiceTemplate serviceTemplate) throws BluePrintException {\r
+        try {\r
+            return serviceTemplateService.validateServiceTemplate(serviceTemplate);\r
+        } catch (Exception e) {\r
+            throw new BluePrintException(3501, e.getMessage(), e);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public AutoMapResponse autoMap(List<ResourceAssignment> resourceAssignments) throws BluePrintException {\r
+        try {\r
+            return serviceTemplateService.autoMap(resourceAssignments);\r
+        } catch (Exception e) {\r
+            throw new BluePrintException(3502, e.getMessage(), e);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public List<ResourceAssignment> validateResourceAssignments(List<ResourceAssignment> resourceAssignments)\r
+            throws BluePrintException {\r
+        try {\r
+            return serviceTemplateService.validateResourceAssignments(resourceAssignments);\r
+        } catch (Exception e) {\r
+            throw new BluePrintException(3503, e.getMessage(), e);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public List<ResourceAssignment> generateResourceAssignments(ConfigModelContent templateContent)\r
+            throws BluePrintException {\r
+        try {\r
+            return serviceTemplateService.generateResourceAssignments(templateContent);\r
+        } catch (Exception e) {\r
+            throw new BluePrintException(3504, e.getMessage(), e);\r
+        }\r
+    }\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/utils/ConfigModelUtils.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/utils/ConfigModelUtils.java
new file mode 100644 (file)
index 0000000..e31b04d
--- /dev/null
@@ -0,0 +1,124 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.utils;\r
+\r
+import com.google.common.base.Preconditions;\r
+import org.apache.commons.collections.CollectionUtils;\r
+import org.apache.commons.io.FileUtils;\r
+import org.apache.commons.io.FilenameUtils;\r
+import org.apache.commons.io.filefilter.DirectoryFileFilter;\r
+import org.apache.commons.lang3.StringUtils;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.ConfigModelConstant;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.ToscaMetaData;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.BluePrintMetadataUtils;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ConfigModel;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ConfigModelContent;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\r
+import java.nio.charset.Charset;\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.List;\r
+\r
+public class ConfigModelUtils {\r
+\r
+    private ConfigModelUtils(){\r
+\r
+    }\r
+    private static Logger log = LoggerFactory.getLogger(ConfigModelUtils.class);\r
+\r
+    public static ConfigModel getConfigModel(String blueprintPath) throws Exception {\r
+        Preconditions.checkArgument(StringUtils.isNotBlank(blueprintPath), "Blueprint Path is missing");\r
+        ToscaMetaData toscaMetaData = BluePrintMetadataUtils.toscaMetaData(blueprintPath);\r
+\r
+        Preconditions.checkNotNull(toscaMetaData, "failed to get Blueprint Metadata information");\r
+        Preconditions.checkArgument(StringUtils.isNotBlank(toscaMetaData.getEntityDefinitions()), "failed to get Blueprint Definition file");\r
+        Preconditions.checkArgument(StringUtils.isNotBlank(toscaMetaData.getCreatedBy()), "failed to get Blueprint created by");\r
+        Preconditions.checkArgument(StringUtils.isNotBlank(toscaMetaData.getToscaMetaFileVersion()), "failed to get Blueprint package version");\r
+\r
+        String bluePrintName = FilenameUtils.getBaseName(toscaMetaData.getEntityDefinitions());\r
+        Preconditions.checkArgument(StringUtils.isNotBlank(bluePrintName), "failed to get Blueprint Definition Name");\r
+\r
+        // TODO - Update Rest of the Model\r
+        ConfigModel configModel = new ConfigModel();\r
+        configModel.setUpdatedBy(toscaMetaData.getCreatedBy());\r
+        configModel.setArtifactName(bluePrintName);\r
+        configModel.setArtifactVersion(toscaMetaData.getToscaMetaFileVersion());\r
+        configModel.setTags(toscaMetaData.getTemplateTags());\r
+        configModel.setArtifactType("SDNC_MODEL");\r
+\r
+        String blueprintContent =\r
+                getPathContent(blueprintPath + "/" + toscaMetaData.getEntityDefinitions());\r
+\r
+        Preconditions.checkArgument(StringUtils.isNotBlank(blueprintPath), "failed to get Blueprint content");\r
+\r
+        List<ConfigModelContent> configModelContents = new ArrayList<>();\r
+        ConfigModelContent stConfigModelContent = new ConfigModelContent();\r
+        stConfigModelContent.setName(configModel.getArtifactName());\r
+        stConfigModelContent.setContentType(ConfigModelConstant.MODEL_CONTENT_TYPE_TOSCA_JSON);\r
+        stConfigModelContent.setContent(blueprintContent);\r
+        configModelContents.add(stConfigModelContent);\r
+\r
+        String velocityDir = blueprintPath + "/Templates";\r
+        List<File> velocityTemplateFiles = getFileOfExtension(velocityDir, new String[]{"vtl"});\r
+\r
+        if (CollectionUtils.isNotEmpty(velocityTemplateFiles)) {\r
+            for (File velocityTemplateFile : velocityTemplateFiles) {\r
+                if (velocityTemplateFile != null) {\r
+                    String contentName = velocityTemplateFile.getName().replace(".vtl", "");\r
+                    ConfigModelContent velocityConfigModelContent = new ConfigModelContent();\r
+                    String velocityConfigContent = getPathContent(velocityTemplateFile);\r
+                    velocityConfigModelContent.setName(contentName);\r
+                    velocityConfigModelContent\r
+                            .setContentType(ConfigModelConstant.MODEL_CONTENT_TYPE_TEMPLATE);\r
+                    velocityConfigModelContent.setContent(velocityConfigContent);\r
+                    configModelContents.add(velocityConfigModelContent);\r
+                    log.info("Loaded blueprint template successfully: {}", velocityTemplateFile.getName());\r
+                }\r
+            }\r
+        }\r
+        configModel.setConfigModelContents(configModelContents);\r
+\r
+        return configModel;\r
+\r
+    }\r
+\r
+    public static String getPathContent(String path) throws IOException {\r
+        Preconditions.checkArgument(StringUtils.isNotBlank(path), "Path is missing");\r
+        return FileUtils.readFileToString(new File(path), Charset.defaultCharset());\r
+    }\r
+\r
+    public static String getPathContent(File file) throws IOException {\r
+        Preconditions.checkNotNull(file, "File is missing");\r
+        return FileUtils.readFileToString(file, Charset.defaultCharset());\r
+    }\r
+\r
+    public static List<File> getFileOfExtension(String basePath, String[] extensions) {\r
+        Preconditions.checkArgument(StringUtils.isNotBlank(basePath), "Path is missing");\r
+        Preconditions.checkNotNull(extensions, "Extensions is missing");\r
+        return (List<File>) FileUtils.listFiles(new File(basePath), extensions, true);\r
+    }\r
+\r
+    public static List<String> getBlueprintNames(String pathName) {\r
+        File blueprintDir = new File(pathName);\r
+        Preconditions.checkNotNull(blueprintDir, "failed to find the blueprint pathName file");\r
+        return  Arrays.asList(blueprintDir.list(DirectoryFileFilter.INSTANCE));\r
+    }\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/validator/ModelTypeValidator.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/validator/ModelTypeValidator.java
new file mode 100644 (file)
index 0000000..85f256e
--- /dev/null
@@ -0,0 +1,200 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.validator;\r
+\r
+import org.apache.commons.lang3.StringUtils;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.ConfigModelConstant;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.ArtifactType;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.CapabilityDefinition;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.DataType;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.NodeType;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ModelType;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+/**\r
+ * ModelTypeValidation.java Purpose: Provide Validation Service for Model Type ModelTypeValidation\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+\r
+public class ModelTypeValidator {\r
+\r
+    private ModelTypeValidator() {\r
+\r
+    }\r
+\r
+    private static List<String> getValidModelDefinitionType() {\r
+        List<String> validTypes = new ArrayList<>();\r
+        validTypes.add(BluePrintConstants.MODEL_DEFINITION_TYPE_DATA_TYPE);\r
+        validTypes.add(BluePrintConstants.MODEL_DEFINITION_TYPE_NODE_TYPE);\r
+        validTypes.add(BluePrintConstants.MODEL_DEFINITION_TYPE_ARTIFACT_TYPE);\r
+        validTypes.add(BluePrintConstants.MODEL_DEFINITION_TYPE_CAPABILITY_TYPE);\r
+        validTypes.add(BluePrintConstants.MODEL_DEFINITION_TYPE_RELATIONSHIP_TYPE);\r
+        return validTypes;\r
+    }\r
+\r
+    @Deprecated\r
+    private static List<String> getValidModelDerivedFrom(String definitionType) {\r
+        List<String> validTypes = new ArrayList<>();\r
+        if (StringUtils.isNotBlank(definitionType)) {\r
+            if (BluePrintConstants.MODEL_DEFINITION_TYPE_NODE_TYPE.equalsIgnoreCase(definitionType)) {\r
+                validTypes.add(ConfigModelConstant.MODEL_TYPE_NODE_DG);\r
+                validTypes.add(ConfigModelConstant.MODEL_TYPE_NODE_COMPONENT);\r
+                validTypes.add(ConfigModelConstant.MODEL_TYPE_NODE_VNF);\r
+                validTypes.add(ConfigModelConstant.MODEL_TYPE_NODE_ARTIFACT);\r
+            } else if (BluePrintConstants.MODEL_DEFINITION_TYPE_CAPABILITY_TYPE.equalsIgnoreCase(definitionType)) {\r
+                validTypes.add(ConfigModelConstant.MODEL_TYPE_CAPABILITY_NETCONF);\r
+                validTypes.add(ConfigModelConstant.MODEL_TYPE_CAPABILITY_SSH);\r
+                validTypes.add(ConfigModelConstant.MODEL_TYPE_CAPABILITY_SFTP);\r
+                validTypes.add(ConfigModelConstant.MODEL_TYPE_CAPABILITY_CHEF);\r
+                validTypes.add(ConfigModelConstant.MODEL_TYPE_CAPABILITY_ANSIBLEF);\r
+            } else if (BluePrintConstants.MODEL_DEFINITION_TYPE_RELATIONSHIP_TYPE.equalsIgnoreCase(definitionType)) {\r
+                validTypes.add(BluePrintConstants.MODEL_TYPE_RELATIONSHIPS_DEPENDS_ON);\r
+                validTypes.add(BluePrintConstants.MODEL_TYPE_RELATIONSHIPS_HOSTED_ON);\r
+                validTypes.add(BluePrintConstants.MODEL_TYPE_RELATIONSHIPS_CONNECTS_TO);\r
+                validTypes.add(BluePrintConstants.MODEL_TYPE_RELATIONSHIPS_ATTACH_TO);\r
+                validTypes.add(BluePrintConstants.MODEL_TYPE_RELATIONSHIPS_ROUTES_TO);\r
+            }\r
+\r
+        }\r
+        return validTypes;\r
+    }\r
+\r
+    /**\r
+     * This is a validateNodeType\r
+     * \r
+     * @param definitionType\r
+     * @param derivedFrom\r
+     * @return boolean\r
+     * @throws BluePrintException\r
+     */\r
+    public static boolean validateNodeType(String definitionType, String derivedFrom) throws BluePrintException {\r
+        boolean valid = true;\r
+        if (!BluePrintConstants.MODEL_DEFINITION_TYPE_DATA_TYPE.equalsIgnoreCase(definitionType)\r
+                && !BluePrintConstants.MODEL_DEFINITION_TYPE_ARTIFACT_TYPE.equalsIgnoreCase(definitionType)) {\r
+            List<String> validTypes = getValidModelDerivedFrom(definitionType);\r
+            if (!validTypes.contains(derivedFrom)) {\r
+                throw new BluePrintException(\r
+                        "Not Valid Model Type (" + derivedFrom + "), It sould be " + validTypes);\r
+            }\r
+        }\r
+        return valid;\r
+    }\r
+\r
+    /**\r
+     * This is a validateModelTypeDefinition\r
+     * \r
+     * @param definitionType\r
+     * @param definitionContent\r
+     * @return boolean\r
+     * @throws BluePrintException\r
+     */\r
+    public static boolean validateModelTypeDefinition(String definitionType, String definitionContent)\r
+            throws BluePrintException {\r
+        boolean valid = true;\r
+        if (StringUtils.isNotBlank(definitionContent)) {\r
+            if (BluePrintConstants.MODEL_DEFINITION_TYPE_DATA_TYPE.equalsIgnoreCase(definitionType)) {\r
+                DataType dataType = JacksonUtils.readValue(definitionContent, DataType.class);\r
+                if (dataType == null) {\r
+                    throw new BluePrintException(\r
+                            "Model type definition is not DataType valid content " + definitionContent);\r
+                }\r
+            } else if (BluePrintConstants.MODEL_DEFINITION_TYPE_NODE_TYPE.equalsIgnoreCase(definitionType)) {\r
+                NodeType nodeType = JacksonUtils.readValue(definitionContent, NodeType.class);\r
+                if (nodeType == null) {\r
+                    throw new BluePrintException(\r
+                            "Model type definition is not NodeType valid content " + definitionContent);\r
+                }\r
+            } else if (BluePrintConstants.MODEL_DEFINITION_TYPE_ARTIFACT_TYPE.equalsIgnoreCase(definitionType)) {\r
+                ArtifactType artifactType = JacksonUtils.readValue(definitionContent, ArtifactType.class);\r
+                if (artifactType == null) {\r
+                    throw new BluePrintException(\r
+                            "Model type definition is not ArtifactType valid content " + definitionContent);\r
+                }\r
+            }else if (BluePrintConstants.MODEL_DEFINITION_TYPE_CAPABILITY_TYPE.equalsIgnoreCase(definitionType)) {\r
+                CapabilityDefinition capabilityDefinition =\r
+                        JacksonUtils.readValue(definitionContent, CapabilityDefinition.class);\r
+                if (capabilityDefinition == null) {\r
+                    throw new BluePrintException(\r
+                            "Model type definition is not CapabilityDefinition valid content " + definitionContent);\r
+                }\r
+            }\r
+\r
+        }\r
+        return valid;\r
+    }\r
+\r
+    /**\r
+     * This is a validateModelType method\r
+     * \r
+     * @param modelType\r
+     * @return boolean\r
+     */\r
+    public static boolean validateModelType(ModelType modelType) throws BluePrintException {\r
+        if (modelType != null) {\r
+\r
+            if (StringUtils.isBlank(modelType.getModelName())) {\r
+                throw new BluePrintException("Model Name Information is missing.");\r
+            }\r
+\r
+            if (StringUtils.isBlank(modelType.getDefinitionType())) {\r
+                throw new BluePrintException("Model Root Type Information is missing.");\r
+            }\r
+            if (StringUtils.isBlank(modelType.getDerivedFrom())) {\r
+                throw new BluePrintException("Model Type Information is missing.");\r
+            }\r
+\r
+            if (StringUtils.isBlank(modelType.getDefinition())) {\r
+                throw new BluePrintException("Model Definition Information is missing.");\r
+            }\r
+            if (StringUtils.isBlank(modelType.getDescription())) {\r
+                throw new BluePrintException("Model Description Information is missing.");\r
+            }\r
+\r
+            if (StringUtils.isBlank(modelType.getVersion())) {\r
+                throw new BluePrintException("Model Version Information is missing.");\r
+            }\r
+\r
+            if (StringUtils.isBlank(modelType.getUpdatedBy())) {\r
+                throw new BluePrintException("Model Updated By Information is missing.");\r
+            }\r
+\r
+            List<String> validRootTypes = getValidModelDefinitionType();\r
+            if (!validRootTypes.contains(modelType.getDefinitionType())) {\r
+                throw new BluePrintException("Not Valid Model Root Type(" + modelType.getDefinitionType()\r
+                        + "), It sould be " + validRootTypes);\r
+            }\r
+\r
+            validateModelTypeDefinition(modelType.getDefinitionType(), modelType.getDefinition());\r
+\r
+            validateNodeType(modelType.getDefinitionType(), modelType.getDerivedFrom());\r
+\r
+        } else {\r
+            throw new BluePrintException("Model Type Information is missing.");\r
+        }\r
+\r
+        return true;\r
+\r
+    }\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/validator/ResourceDictionaryValidator.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/validator/ResourceDictionaryValidator.java
new file mode 100644 (file)
index 0000000..eb2448e
--- /dev/null
@@ -0,0 +1,88 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.validator;\r
+\r
+import com.google.common.base.Preconditions;\r
+import org.apache.commons.lang3.StringUtils;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils;\r
+import org.onap.ccsdk.apps.controllerblueprints.resource.dict.data.DictionaryDefinition;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ResourceDictionary;\r
+\r
+/**\r
+ * ResourceDictionaryValidator.java Purpose: Provide Validation Service for Model Type Resource\r
+ * Dictionary Validator\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+public class ResourceDictionaryValidator {\r
+\r
+    private ResourceDictionaryValidator() {}\r
+\r
+    /**\r
+     * This is a validateResourceDictionaryDefinition\r
+     * \r
+     * @param definitionContent\r
+     * @return boolean\r
+     * @throws BluePrintException\r
+     */\r
+    public static boolean validateResourceDictionaryDefinition(String definitionContent)\r
+            throws BluePrintException {\r
+        boolean valid = true;\r
+        if (StringUtils.isNotBlank(definitionContent)) {\r
+            DictionaryDefinition dictionaryDefinition =\r
+                    JacksonUtils.readValue(definitionContent, DictionaryDefinition.class);\r
+            if (dictionaryDefinition == null) {\r
+                throw new BluePrintException(\r
+                        "Resource dictionary definition is not valid content " + definitionContent);\r
+            }\r
+\r
+        }\r
+        return valid;\r
+    }\r
+\r
+    /**\r
+     * This is a validateResourceDictionary method\r
+     * \r
+     * @param resourceDictionary\r
+     * @return boolean\r
+     *\r
+     */\r
+    public static boolean validateResourceDictionary(ResourceDictionary resourceDictionary) {\r
+\r
+        Preconditions.checkNotNull(resourceDictionary,"ResourceDictionary Information is missing." );\r
+\r
+        Preconditions.checkArgument( StringUtils.isNotBlank(resourceDictionary.getName()),\r
+                "DataDictionary Alias Name Information is missing.");\r
+        Preconditions.checkArgument( StringUtils.isNotBlank(resourceDictionary.getResourcePath()),\r
+                "DataDictionary Resource Name Information is missing.");\r
+        Preconditions.checkArgument( StringUtils.isNotBlank(resourceDictionary.getResourceType()),\r
+                "DataDictionary Resource Type Information is missing.");\r
+        Preconditions.checkArgument( StringUtils.isNotBlank(resourceDictionary.getDefinition()),\r
+                "DataDictionary Definition Information is missing.");\r
+        Preconditions.checkArgument( StringUtils.isNotBlank(resourceDictionary.getDescription()),\r
+                "DataDictionary Description Information is missing.");\r
+        Preconditions.checkArgument( StringUtils.isNotBlank(resourceDictionary.getTags()),\r
+                "DataDictionary Tags Information is missing.");\r
+        Preconditions.checkArgument( StringUtils.isNotBlank(resourceDictionary.getUpdatedBy()),\r
+                "DataDictionary Updated By Information is missing.");\r
+        return true;\r
+\r
+    }\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/validator/ServiceTemplateValidator.java b/ms/controllerblueprints/modules/service/src/main/java/org/onap/ccsdk/apps/controllerblueprints/service/validator/ServiceTemplateValidator.java
new file mode 100644 (file)
index 0000000..ea46f3a
--- /dev/null
@@ -0,0 +1,123 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.validator;\r
+\r
+import com.google.common.base.Preconditions;\r
+import org.apache.commons.lang3.StringUtils;\r
+import org.jetbrains.annotations.NotNull;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintException;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.NodeTemplate;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.ServiceTemplate;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.service.BluePrintValidatorDefaultService;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils;\r
+import org.onap.ccsdk.apps.controllerblueprints.resource.dict.validator.ResourceAssignmentValidator;\r
+\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+/**\r
+ * ServiceTemplateValidator.java Purpose: Provide Configuration Generator ServiceTemplateValidator\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+\r
+public class ServiceTemplateValidator extends BluePrintValidatorDefaultService {\r
+\r
+    StringBuilder message = new StringBuilder();\r
+    private Map<String, String> metaData = new HashMap();\r
+\r
+    /**\r
+     * This is a validateServiceTemplate\r
+     *\r
+     * @param serviceTemplateContent\r
+     * @return boolean\r
+     * @throws BluePrintException\r
+     */\r
+    public boolean validateServiceTemplate(String serviceTemplateContent) throws BluePrintException {\r
+        if (StringUtils.isNotBlank(serviceTemplateContent)) {\r
+            ServiceTemplate serviceTemplate =\r
+                    JacksonUtils.readValue(serviceTemplateContent, ServiceTemplate.class);\r
+            return validateServiceTemplate(serviceTemplate);\r
+        } else {\r
+            throw new BluePrintException(\r
+                    "Service Template Content is  (" + serviceTemplateContent + ") not Defined.");\r
+        }\r
+    }\r
+\r
+    /**\r
+     * This is a validateServiceTemplate\r
+     *\r
+     * @param serviceTemplate\r
+     * @return boolean\r
+     * @throws BluePrintException\r
+     */\r
+    @SuppressWarnings("squid:S00112")\r
+    public boolean validateServiceTemplate(ServiceTemplate serviceTemplate) throws BluePrintException {\r
+        Map<String, Object> properties = new HashMap<>();\r
+        super.validateBlueprint(serviceTemplate, properties);\r
+        return true;\r
+    }\r
+\r
+    /**\r
+     * This is a getMetaData to get the key information during the\r
+     *\r
+     * @return Map<String                                                                                                                                                                                                                                                               ,\r
+                       *       String>\r
+     */\r
+    public Map<String, String> getMetaData() {\r
+        return metaData;\r
+    }\r
+\r
+    @Override\r
+    public void validateMetadata(@NotNull Map<String, String> metaDataMap) throws BluePrintException {\r
+\r
+        Preconditions.checkNotNull(serviceTemplate.getMetadata(), "Service Template Metadata Information is missing.");\r
+\r
+        this.metaData.putAll(serviceTemplate.getMetadata());\r
+\r
+        String author = serviceTemplate.getMetadata().get(BluePrintConstants.METADATA_TEMPLATE_AUTHOR);\r
+        String serviceTemplateName =\r
+                serviceTemplate.getMetadata().get(BluePrintConstants.METADATA_TEMPLATE_NAME);\r
+        String serviceTemplateVersion =\r
+                serviceTemplate.getMetadata().get(BluePrintConstants.METADATA_TEMPLATE_VERSION);\r
+\r
+        Preconditions.checkArgument(StringUtils.isNotBlank(author), "Template Metadata (author) Information is missing.");\r
+        Preconditions.checkArgument(StringUtils.isNotBlank(serviceTemplateName), "Template Metadata (service-template-name) Information is missing.");\r
+        Preconditions.checkArgument(StringUtils.isNotBlank(serviceTemplateVersion), "Template Metadata (service-template-version) Information is missing.");\r
+    }\r
+\r
+\r
+    @Override\r
+    public void validateNodeTemplate(@NotNull String nodeTemplateName, @NotNull NodeTemplate nodeTemplate)\r
+            throws BluePrintException {\r
+        super.validateNodeTemplate(nodeTemplateName, nodeTemplate);\r
+        validateNodeTemplateCustom(nodeTemplateName, nodeTemplate);\r
+\r
+    }\r
+\r
+    @Deprecated()\r
+    private void validateNodeTemplateCustom(@NotNull String nodeTemplateName, @NotNull NodeTemplate nodeTemplate)\r
+            throws BluePrintException {\r
+        String derivedFrom = getBluePrintContext().nodeTemplateNodeType(nodeTemplateName).getDerivedFrom();\r
+        if ("tosca.nodes.Artifact".equals(derivedFrom)) {\r
+            ResourceAssignmentValidator resourceAssignmentValidator = new ResourceAssignmentValidator(nodeTemplate);\r
+            resourceAssignmentValidator.validateResourceAssignment();\r
+        }\r
+    }\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/main/resources/service_template/default_netconf.json b/ms/controllerblueprints/modules/service/src/main/resources/service_template/default_netconf.json
new file mode 100644 (file)
index 0000000..95c829c
--- /dev/null
@@ -0,0 +1,890 @@
+{\r
+       "version": "1.0.0",\r
+       "metadata": {\r
+               "template_author": "xxxx@onap.com",\r
+               "template_name": "default_netconf",\r
+               "template_version": "1.0.0",\r
+               "service-type": "XXXXXXXXXXX",\r
+               "vnf-type": "XXXXXXXXX"\r
+       },\r
+       "topology_template": {\r
+               "inputs": {\r
+                       "request-id": {\r
+                               "required": true,\r
+                               "type": "string"\r
+                       },\r
+                       "service-template-name": {\r
+                               "required": true,\r
+                               "type": "string"\r
+                       },\r
+                       "service-template-version": {\r
+                               "required": true,\r
+                               "type": "string"\r
+                       },\r
+                       "action-name": {\r
+                               "required": true,\r
+                               "type": "string"\r
+                       },\r
+                       "service-instance-id": {\r
+                               "required": true,\r
+                               "type": "string"\r
+                       },\r
+                       "resource-type": {\r
+                               "required": true,\r
+                               "type": "string"\r
+                       }\r
+               },\r
+               "node_templates": {\r
+                       "base-config-template": {\r
+                               "type": "artifact-config-template",\r
+                               "properties": {\r
+                                       "action-names": [\r
+                                               "resource-assignment-action"\r
+                                       ]\r
+                               },\r
+                               "capabilities": {\r
+                                       "content": {\r
+                                               "properties": {\r
+                                                       "content": ""\r
+                                               }\r
+                                       },\r
+                                       "mapping": {\r
+                                               "properties": {\r
+                                                       "mapping": []\r
+                                               }\r
+                                       }\r
+                               }\r
+                       },\r
+                       "licence-template": {\r
+                               "type": "artifact-config-template",\r
+                               "properties": {\r
+                                       "action-names": [\r
+                                               "activate-netconf-action"\r
+                                       ]\r
+                               },\r
+                               "capabilities": {\r
+                                       "content": {\r
+                                               "properties": {\r
+                                                       "content": ""\r
+                                               }\r
+                                       },\r
+                                       "mapping": {\r
+                                               "properties": {\r
+                                                       "mapping": []\r
+                                               }\r
+                                       }\r
+                               }\r
+                       },\r
+                       "runningconfig-template": {\r
+                               "type": "artifact-config-template",\r
+                               "properties": {\r
+                                       "action-names": [\r
+                                               "activate-netconf-action"\r
+                                       ]\r
+                               },\r
+                               "capabilities": {\r
+                                       "content": {\r
+                                               "properties": {\r
+                                                       "content": "<get-config><source><running/></source></get-config>"\r
+                                               }\r
+                                       },\r
+                                       "mapping": {\r
+                                               "properties": {\r
+                                                       "mapping": []\r
+                                               }\r
+                                       }\r
+                               }\r
+                       },\r
+                       "resource-assignment-action": {\r
+                               "type": "dg-resource-assignment",\r
+                               "interfaces": {\r
+                                       "CONFIG": {\r
+                                               "operations": {\r
+                                                       "ResourceAssignment": {\r
+                                                               \r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               },\r
+                               "capabilities": {\r
+                                       "dg-node": {\r
+                                               \r
+                                       }\r
+                               },\r
+                               "requirements": {\r
+                                       "component-dependency": {\r
+                                               "capability": "component-node",\r
+                                               "node": "get-resource-assignment",\r
+                                               "relationship": "tosca.relationships.DependsOn"\r
+                                       }\r
+                               }\r
+                       },\r
+                       "activate-netconf-action": {\r
+                               "type": "dg-activate-netconf",\r
+                               "interfaces": {\r
+                                       "CONFIG": {\r
+                                               "operations": {\r
+                                                       "ActivateNetconf": {\r
+                                                               \r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               },\r
+                               "capabilities": {\r
+                                       "dg-node": {\r
+                                               \r
+                                       }\r
+                               },\r
+                               "requirements": {\r
+                                       "component-dependency": {\r
+                                               "capability": "component-node",\r
+                                               "node": "transaction-netconf-baseconfig",\r
+                                               "relationship": "tosca.relationships.DependsOn"\r
+                                       }\r
+                               }\r
+                       },\r
+                       "resource-assignment": {\r
+                               "type": "component-resource-assignment",\r
+                               "interfaces": {\r
+                                       "org-openecomp-sdnc-config-assignment-service-ConfigAssignmentNode": {\r
+                                               "operations": {\r
+                                                       "process": {\r
+                                                               "inputs": {\r
+                                                                       "resource-type": "vnf-type",\r
+                                                                       "template-names": [\r
+                                                                               "base-config-template",\r
+                                                                               "licence-template"\r
+                                                                       ],\r
+                                                                       "request-id": "{ \"get_attribute\" : \"request-id\" }",\r
+                                                                       "resource-id": "{ \"get_input\" : \"vnf-id\" }"\r
+                                                               },\r
+                                                               "outputs": {\r
+                                                                       "resource-assignment-params": "",\r
+                                                                       "status": ""\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               },\r
+                               "capabilities": {\r
+                                       "component-node": {\r
+                                               \r
+                                       }\r
+                               }\r
+                       },\r
+                       "edit-netconf-config": {\r
+                               "type": "component-netconf-edit",\r
+                               "interfaces": {\r
+                                       "org-openecomp-sdnc-netconf-adaptor-service-SimpleNetconfEditConfigNode": {\r
+                                               "operations": {\r
+                                                       "process": {\r
+                                                               "inputs": {\r
+                                                                       "rpc-message": false,\r
+                                                                       "wait": 0,\r
+                                                                       "unlock": false,\r
+                                                                       "config-target": "RUNNING",\r
+                                                                       "commit": true,\r
+                                                                       "edit-default-operation": "repalce",\r
+                                                                       "lock": false,\r
+                                                                       "post-restart-wait": false,\r
+                                                                       "pre-restart-wait": false\r
+                                                               },\r
+                                                               "outputs": {\r
+                                                                       "rpc-response-message": "",\r
+                                                                       "status": ""\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               },\r
+                               "capabilities": {\r
+                                       "component-node": {\r
+                                               \r
+                                       }\r
+                               }\r
+                       },\r
+                       "transaction-netconf-baseconfig": {\r
+                               "type": "component-transaction-netconf",\r
+                               "interfaces": {\r
+                                       "org-openecomp-sdnc-netconf-adaptor-service-NetconfTransactionNode": {\r
+                                               "operations": {\r
+                                                       "process": {\r
+                                                               "inputs": {\r
+                                                                       "rollback": false,\r
+                                                                       "transaction-templates": [\r
+                                                                               "runningconfig-template"\r
+                                                                       ],\r
+                                                                       "assignment-action-name": "resource-assignment-action",\r
+                                                                       "transaction-components": [\r
+                                                                               "get-netconf-config"\r
+                                                                       ],\r
+                                                                       "resource-type": "vnf-type",\r
+                                                                       "initialise-sftp": false,\r
+                                                                       "request-id": "{ \"get_input\" : \"request-id\" }",\r
+                                                                       "initialise-ssh": false,\r
+                                                                       "resource-id": "{ \"get_input\" : \"vnf-id\" }",\r
+                                                                       "action-name": "{ \"get_input\" : \"action-name\" }"\r
+                                                               },\r
+                                                               "outputs": {\r
+                                                                       "rpc-response-message": "",\r
+                                                                       "status": ""\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               },\r
+                               "capabilities": {\r
+                                       "component-node": {\r
+                                               \r
+                                       }\r
+                               },\r
+                               "requirements": {\r
+                                       "netconf-connection": {\r
+                                               "capability": "netconf",\r
+                                               "node": "vdbe-netconf-device",\r
+                                               "relationship": "tosca.relationships.ConnectsTo"\r
+                                       }\r
+                               }\r
+                       },\r
+                       "get-netconf-config": {\r
+                               "type": "component-netconf-get",\r
+                               "interfaces": {\r
+                                       "org-openecomp-sdnc-netconf-adaptor-service-SimpleNetconfGetConfigNode": {\r
+                                               "operations": {\r
+                                                       "process": {\r
+                                                               "inputs": {\r
+                                                                       "rpc-message": true,\r
+                                                                       "wait": 1,\r
+                                                                       "message-time-out": 10\r
+                                                               },\r
+                                                               "outputs": {\r
+                                                                       "rpc-response-message": "",\r
+                                                                       "status": ""\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               },\r
+                               "capabilities": {\r
+                                       "component-node": {\r
+                                               \r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       },\r
+       "node_types": {\r
+               "vnf-netconf-device": {\r
+                       "description": "This is VNF Device with Netconf and SSH Capability",\r
+                       "version": "1.0.0",\r
+                       "capabilities": {\r
+                               "netconf": {\r
+                                       "type": "tosca.capability.Netconf",\r
+                                       "properties": {\r
+                                               "password": {\r
+                                                       "required": false,\r
+                                                       "type": "string"\r
+                                               },\r
+                                               "user-id": {\r
+                                                       "required": true,\r
+                                                       "type": "string"\r
+                                               },\r
+                                               "host-ip-address": {\r
+                                                       "required": true,\r
+                                                       "type": "string"\r
+                                               },\r
+                                               "port-number": {\r
+                                                       "required": true,\r
+                                                       "type": "integer",\r
+                                                       "default": 830\r
+                                               },\r
+                                               "message-time-out": {\r
+                                                       "required": false,\r
+                                                       "type": "integer",\r
+                                                       "default": 3000\r
+                                               },\r
+                                               "connection-time-out": {\r
+                                                       "required": false,\r
+                                                       "type": "integer",\r
+                                                       "default": 30\r
+                                               }\r
+                                       }\r
+                               },\r
+                               "ssh": {\r
+                                       "type": "tosca.capability.Ssh",\r
+                                       "properties": {\r
+                                               "password": {\r
+                                                       "required": false,\r
+                                                       "type": "string"\r
+                                               },\r
+                                               "user-id": {\r
+                                                       "required": true,\r
+                                                       "type": "string"\r
+                                               },\r
+                                               "host-ip-address": {\r
+                                                       "required": true,\r
+                                                       "type": "string"\r
+                                               },\r
+                                               "port-number": {\r
+                                                       "required": true,\r
+                                                       "type": "integer",\r
+                                                       "default": 22\r
+                                               },\r
+                                               "message-time-out": {\r
+                                                       "required": false,\r
+                                                       "type": "integer",\r
+                                                       "default": 180\r
+                                               },\r
+                                               "connection-time-out": {\r
+                                                       "required": false,\r
+                                                       "type": "integer",\r
+                                                       "default": 30\r
+                                               }\r
+                                       }\r
+                               },\r
+                               "sftp": {\r
+                                       "type": "tosca.capability.Sftp",\r
+                                       "properties": {\r
+                                               "password": {\r
+                                                       "required": false,\r
+                                                       "type": "string"\r
+                                               },\r
+                                               "user-id": {\r
+                                                       "required": true,\r
+                                                       "type": "string"\r
+                                               },\r
+                                               "host-ip-address": {\r
+                                                       "required": true,\r
+                                                       "type": "string"\r
+                                               },\r
+                                               "port-number": {\r
+                                                       "required": true,\r
+                                                       "type": "integer",\r
+                                                       "default": 22\r
+                                               },\r
+                                               "message-time-out": {\r
+                                                       "required": false,\r
+                                                       "type": "integer",\r
+                                                       "default": 180\r
+                                               },\r
+                                               "connection-time-out": {\r
+                                                       "required": false,\r
+                                                       "type": "integer",\r
+                                                       "default": 30\r
+                                               }\r
+                                       }\r
+                               }\r
+                       },\r
+                       "derived_from": "tosca.nodes.Vnf"\r
+               },\r
+               "dg-resource-assignment": {\r
+                       "description": "This is Resource Assignment Directed Graph",\r
+                       "version": "1.0.0",\r
+                       "properties": {\r
+                               "mode": {\r
+                                       "required": false,\r
+                                       "type": "string",\r
+                                       "default": "sync"\r
+                               },\r
+                               "version": {\r
+                                       "required": false,\r
+                                       "type": "string",\r
+                                       "default": "LATEST"\r
+                               },\r
+                               "is-start-flow": {\r
+                                       "required": false,\r
+                                       "type": "boolean",\r
+                                       "default": "false"\r
+                               }\r
+                       },\r
+                       "capabilities": {\r
+                               "dg-node": {\r
+                                       "type": "tosca.capabilities.Node"\r
+                               },\r
+                               "content": {\r
+                                       "type": "tosca.capability.Content",\r
+                                       "properties": {\r
+                                               "type": {\r
+                                                       "required": false,\r
+                                                       "type": "string",\r
+                                                       "default": "json"\r
+                                               },\r
+                                               "content": {\r
+                                                       "required": true,\r
+                                                       "type": "string"\r
+                                               }\r
+                                       }\r
+                               }\r
+                       },\r
+                       "requirements": {\r
+                               "component-dependency": {\r
+                                       "capability": "component-node",\r
+                                       "node": "component-resource-assignment",\r
+                                       "relationship": "tosca.relationships.DependsOn"\r
+                               }\r
+                       },\r
+                       "interfaces": {\r
+                               "CONFIG": {\r
+                                       "operations": {\r
+                                               "ResourceAssignment": {\r
+                                                       "inputs": {\r
+                                                               "params": {\r
+                                                                       "required": false,\r
+                                                                       "type": "list",\r
+                                                                       "entry_schema": {\r
+                                                                               "type": "datatype-property"\r
+                                                                       }\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+                       },\r
+                       "derived_from": "tosca.nodes.DG"\r
+               },\r
+               "dg-activate-netconf": {\r
+                       "description": "This is Download Netconf Directed Graph",\r
+                       "version": "1.0.0",\r
+                       "properties": {\r
+                               "mode": {\r
+                                       "required": false,\r
+                                       "type": "string",\r
+                                       "default": "sync"\r
+                               },\r
+                               "version": {\r
+                                       "required": false,\r
+                                       "type": "string",\r
+                                       "default": "LATEST"\r
+                               },\r
+                               "is-start-flow": {\r
+                                       "required": false,\r
+                                       "type": "boolean",\r
+                                       "default": "false"\r
+                               }\r
+                       },\r
+                       "capabilities": {\r
+                               "dg-node": {\r
+                                       "type": "tosca.capabilities.Node"\r
+                               },\r
+                               "content": {\r
+                                       "type": "tosca.capability.Content",\r
+                                       "properties": {\r
+                                               "type": {\r
+                                                       "required": false,\r
+                                                       "type": "string",\r
+                                                       "default": "json"\r
+                                               },\r
+                                               "content": {\r
+                                                       "required": true,\r
+                                                       "type": "string"\r
+                                               }\r
+                                       }\r
+                               }\r
+                       },\r
+                       "requirements": {\r
+                               "component-dependency": {\r
+                                       "capability": "component-node",\r
+                                       "node": "component-transaction-netconf",\r
+                                       "relationship": "tosca.relationships.DependsOn"\r
+                               }\r
+                       },\r
+                       "interfaces": {\r
+                               "CONFIG": {\r
+                                       "operations": {\r
+                                               "ActivateNetconf": {\r
+                                                       "inputs": {\r
+                                                               "params": {\r
+                                                                       "required": false,\r
+                                                                       "type": "list",\r
+                                                                       "entry_schema": {\r
+                                                                               "type": "datatype-property"\r
+                                                                       }\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+                       },\r
+                       "derived_from": "tosca.nodes.DG"\r
+               },\r
+               "artifact-config-template": {\r
+                       "description": "This is Configuration Velocity Template",\r
+                       "version": "1.0.0",\r
+                       "properties": {\r
+                               "action-names": {\r
+                                       "required": true,\r
+                                       "type": "list",\r
+                                       "entry_schema": {\r
+                                               "type": "string"\r
+                                       }\r
+                               }\r
+                       },\r
+                       "capabilities": {\r
+                               "content": {\r
+                                       "type": "tosca.capability.Content",\r
+                                       "properties": {\r
+                                               "content": {\r
+                                                       "required": true,\r
+                                                       "type": "string"\r
+                                               }\r
+                                       }\r
+                               },\r
+                               "mapping": {\r
+                                       "type": "tosca.capability.Mapping",\r
+                                       "properties": {\r
+                                               "mapping": {\r
+                                                       "required": false,\r
+                                                       "type": "list",\r
+                                                       "entry_schema": {\r
+                                                               "type": "datatype-resource-assignment"\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+                       },\r
+                       "derived_from": "tosca.nodes.Artifact"\r
+               },\r
+               "component-resource-assignment": {\r
+                       "description": "This is Resource Assignment Component API",\r
+                       "version": "1.0.0",\r
+                       "capabilities": {\r
+                               "component-node": {\r
+                                       "type": "tosca.capabilities.Node"\r
+                               }\r
+                       },\r
+                       "interfaces": {\r
+                               "org-openecomp-sdnc-config-assignment-service-ConfigAssignmentNode": {\r
+                                       "operations": {\r
+                                               "process": {\r
+                                                       "inputs": {\r
+                                                               "handler-name": {\r
+                                                                       "description": "Name of the Artifact Node Template, to get the template Content. If template-content is present, then content wont be reterived from the Artifact Node Template.",\r
+                                                                       "required": true,\r
+                                                                       "type": "string"\r
+                                                               },\r
+                                                               "resource-type": {\r
+                                                                       "required": false,\r
+                                                                       "type": "string"\r
+                                                               },\r
+                                                               "template-names": {\r
+                                                                       "description": "Name of the Artifact Node Templates, to get the template Content.",\r
+                                                                       "required": true,\r
+                                                                       "type": "list",\r
+                                                                       "entry_schema": {\r
+                                                                               "type": "string"\r
+                                                                       }\r
+                                                               },\r
+                                                               "request-id": {\r
+                                                                       "description": "Request Id used to store the generated configuration, in the database along with the template-name",\r
+                                                                       "required": true,\r
+                                                                       "type": "string"\r
+                                                               },\r
+                                                               "resource-id": {\r
+                                                                       "description": "Id used to pull the data content from the data base. Either template-data or resource-id should be present",\r
+                                                                       "required": true,\r
+                                                                       "type": "string"\r
+                                                               },\r
+                                                               "action-name": {\r
+                                                                       "description": "Action Name to get from Database, Either (message & mask-info ) or ( resource-id & resource-type & action-name & template-name ) should be present. Message will be given higest priority",\r
+                                                                       "required": false,\r
+                                                                       "type": "string"\r
+                                                               }\r
+                                                       },\r
+                                                       "outputs": {\r
+                                                               "resource-assignment-params": {\r
+                                                                       "required": true,\r
+                                                                       "type": "string"\r
+                                                               },\r
+                                                               "status": {\r
+                                                                       "required": true,\r
+                                                                       "type": "string"\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+                       },\r
+                       "derived_from": "tosca.nodes.Component"\r
+               },\r
+               "component-netconf-get": {\r
+                       "description": "This is Netconf Get Running Configuration Component API",\r
+                       "version": "1.0.0",\r
+                       "capabilities": {\r
+                               "component-node": {\r
+                                       "type": "tosca.capabilities.Node"\r
+                               }\r
+                       },\r
+                       "interfaces": {\r
+                               "org-openecomp-sdnc-netconf-adaptor-service-SimpleNetconfGetConfigNode": {\r
+                                       "operations": {\r
+                                               "process": {\r
+                                                       "inputs": {\r
+                                                               "rpc-message": {\r
+                                                                       "description": "It should be true, If the message is Neconf RPC message, It should be false If it is plain Config message.",\r
+                                                                       "required": false,\r
+                                                                       "type": "boolean",\r
+                                                                       "default": false\r
+                                                               },\r
+                                                               "wait": {\r
+                                                                       "required": false,\r
+                                                                       "type": "integer",\r
+                                                                       "default": 0\r
+                                                               },\r
+                                                               "message-time-out": {\r
+                                                                       "required": false,\r
+                                                                       "type": "integer",\r
+                                                                       "default": 30\r
+                                                               }\r
+                                                       },\r
+                                                       "outputs": {\r
+                                                               "config-message": {\r
+                                                                       "type": "string"\r
+                                                               },\r
+                                                               "status": {\r
+                                                                       "description": "Status of the Component Execution ( success or failure )",\r
+                                                                       "required": true,\r
+                                                                       "type": "string"\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+                       },\r
+                       "derived_from": "tosca.nodes.Component"\r
+               },\r
+               "component-netconf-edit": {\r
+                       "description": "This is Netconf Edit Configuration Component API",\r
+                       "version": "1.0.0",\r
+                       "capabilities": {\r
+                               "component-node": {\r
+                                       "type": "tosca.capabilities.Node"\r
+                               }\r
+                       },\r
+                       "interfaces": {\r
+                               "org-openecomp-sdnc-netconf-adaptor-service-SimpleNetconfEditConfigNode": {\r
+                                       "operations": {\r
+                                               "process": {\r
+                                                       "inputs": {\r
+                                                               "rpc-message": {\r
+                                                                       "description": "If the message is Neconf RPC message,It should be true or false.",\r
+                                                                       "required": false,\r
+                                                                       "type": "boolean",\r
+                                                                       "default": false\r
+                                                               },\r
+                                                               "wait": {\r
+                                                                       "description": "Delay time in sec before performing edit-config action.",\r
+                                                                       "required": false,\r
+                                                                       "type": "integer",\r
+                                                                       "default": 0\r
+                                                               },\r
+                                                               "unlock": {\r
+                                                                       "description": "If unLock command has to send before Edit Configuration.",\r
+                                                                       "required": false,\r
+                                                                       "type": "boolean",\r
+                                                                       "default": false\r
+                                                               },\r
+                                                               "config-target": {\r
+                                                                       "required": false,\r
+                                                                       "type": "string"\r
+                                                               },\r
+                                                               "commit": {\r
+                                                                       "description": "Issue commit command to the device after performing edit-config action.",\r
+                                                                       "required": false,\r
+                                                                       "type": "boolean",\r
+                                                                       "default": false\r
+                                                               },\r
+                                                               "edit-default-operation": {\r
+                                                                       "required": false,\r
+                                                                       "type": "string"\r
+                                                               },\r
+                                                               "lock": {\r
+                                                                       "description": "Issue lock command to the device before performing edit-config action.",\r
+                                                                       "required": false,\r
+                                                                       "type": "boolean",\r
+                                                                       "default": false\r
+                                                               },\r
+                                                               "post-restart-wait": {\r
+                                                                       "description": "If Restart command should be issued before the Edit Operation, Provide the time to wait after restart. 0 meanno restart required or wait time in sec ex : 3000 for 5 ",\r
+                                                                       "required": false,\r
+                                                                       "type": "integer",\r
+                                                                       "default": 0\r
+                                                               },\r
+                                                               "pre-restart-wait": {\r
+                                                                       "description": "If Restart command should be issued after the Edit Operation, Provide the time to wait after restart. 0 meanno restart required or wait time in sec ex : 3000 for 5 ",\r
+                                                                       "required": false,\r
+                                                                       "type": "integer",\r
+                                                                       "default": 0\r
+                                                               },\r
+                                                               "message-time-out": {\r
+                                                                       "required": false,\r
+                                                                       "type": "integer",\r
+                                                                       "default": 30\r
+                                                               }\r
+                                                       },\r
+                                                       "outputs": {\r
+                                                               "rpc-response-message": {\r
+                                                                       "type": "string"\r
+                                                               },\r
+                                                               "status": {\r
+                                                                       "description": "Status of the Component Execution ( success or failure )",\r
+                                                                       "required": true,\r
+                                                                       "type": "string"\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+                       },\r
+                       "derived_from": "tosca.nodes.Component"\r
+               },\r
+               "component-transaction-netconf": {\r
+                       "description": "This is Netconf Transaction Configuration Component API",\r
+                       "version": "1.0.0",\r
+                       "capabilities": {\r
+                               "component-node": {\r
+                                       "type": "tosca.capabilities.Node"\r
+                               }\r
+                       },\r
+                       "requirements": {\r
+                               "netconf-connection": {\r
+                                       "capability": "netconf",\r
+                                       "node": "vnf-netconf-device",\r
+                                       "relationship": "tosca.relationships.ConnectsTo"\r
+                               }\r
+                       },\r
+                       "interfaces": {\r
+                               "org-openecomp-sdnc-netconf-adaptor-service-NetconfTransactionNode": {\r
+                                       "operations": {\r
+                                               "process": {\r
+                                                       "inputs": {\r
+                                                               "rollback": {\r
+                                                                       "required": false,\r
+                                                                       "type": "boolean"\r
+                                                               },\r
+                                                               "transaction-templates": {\r
+                                                                       "description": "Templates used by the Transaction Components during processing",\r
+                                                                       "required": true,\r
+                                                                       "type": "list",\r
+                                                                       "entry_schema": {\r
+                                                                               "type": "string"\r
+                                                                       }\r
+                                                               },\r
+                                                               "assignment-action-name": {\r
+                                                                       "description": "Assignment Action Name to get from Database, Either (message & mask-info ) or ( resource-id & resource-type & action-name & template-name ) should be present. Message will be given higest priority",\r
+                                                                       "required": true,\r
+                                                                       "type": "string"\r
+                                                               },\r
+                                                               "transaction-components": {\r
+                                                                       "description": "Components used to used for the atomic transaction, Default Handlers are org.openecomp.sdnc.netconf.adaptor.service.SimpleNetconfEditConfigNode and org.openecomp.sdnc.netconf.adaptor.service.SimpleNetconfGetConfigNode",\r
+                                                                       "required": true,\r
+                                                                       "type": "list",\r
+                                                                       "entry_schema": {\r
+                                                                               "type": "string"\r
+                                                                       }\r
+                                                               },\r
+                                                               "resource-type": {\r
+                                                                       "description": "Resource Type to get from Database, Either (message & mask-info ) or( resource-id & resource-type & action-name & template-name ) should be present. Message will be given higest priority",\r
+                                                                       "required": false,\r
+                                                                       "type": "string"\r
+                                                               },\r
+                                                               "initialise-sftp": {\r
+                                                                       "required": false,\r
+                                                                       "type": "boolean"\r
+                                                               },\r
+                                                               "request-id": {\r
+                                                                       "description": "Request Id used to store the generated configuration, in the database along with the template-name",\r
+                                                                       "required": true,\r
+                                                                       "type": "string"\r
+                                                               },\r
+                                                               "initialise-ssh": {\r
+                                                                       "required": false,\r
+                                                                       "type": "boolean"\r
+                                                               },\r
+                                                               "resource-id": {\r
+                                                                       "description": "Resource Id to get from Database, Either (message & mask-info ) or ( resource-id & resource-type & action-name & template-name ) should be present. Message will be given higest priority",\r
+                                                                       "required": false,\r
+                                                                       "type": "string"\r
+                                                               },\r
+                                                               "action-name": {\r
+                                                                       "description": "Action Name to get from Database, Either (message & mask-info ) or ( resource-id & resource-type & action-name & template-name ) should be present. Message will be given higest priority",\r
+                                                                       "required": false,\r
+                                                                       "type": "string"\r
+                                                               }\r
+                                                       },\r
+                                                       "outputs": {\r
+                                                               "rpc-response-message": {\r
+                                                                       "type": "string"\r
+                                                               },\r
+                                                               "status": {\r
+                                                                       "description": "Status of the Component Execution ( success or failure )",\r
+                                                                       "required": true,\r
+                                                                       "type": "string"\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+                       },\r
+                       "derived_from": "tosca.nodes.Component"\r
+               }\r
+       },\r
+       "data_types": {\r
+               "datatype-resource-assignment": {\r
+                       "version": "1.0.0",\r
+                       "description": "This is Resource Assignment Data Type",\r
+                       "properties": {\r
+                               "property": {\r
+                                       "required": true,\r
+                                       "type": "datatype-property"\r
+                               },\r
+                               "input-param": {\r
+                                       "required": true,\r
+                                       "type": "boolean"\r
+                               },\r
+                               "dictionary-name": {\r
+                                       "required": false,\r
+                                       "type": "string"\r
+                               },\r
+                               "dictionary-source": {\r
+                                       "required": false,\r
+                                       "type": "string"\r
+                               },\r
+                               "dependencies": {\r
+                                       "required": true,\r
+                                       "type": "list",\r
+                                       "entry_schema": {\r
+                                               "type": "string"\r
+                                       }\r
+                               }\r
+                       },\r
+                       "derived_from": "tosca.datatypes.Root"\r
+               },\r
+               "datatype-property": {\r
+                       "version": "1.0.0",\r
+                       "description": "This is Entry point Input Data Type, which is dynamic datatype, The parameter names will be populated during the Design time for each inputs",\r
+                       "properties": {\r
+                               "type": {\r
+                                       "required": true,\r
+                                       "type": "string"\r
+                               },\r
+                               "description": {\r
+                                       "required": false,\r
+                                       "type": "string"\r
+                               },\r
+                               "required": {\r
+                                       "required": false,\r
+                                       "type": "boolean"\r
+                               },\r
+                               "default": {\r
+                                       "required": false,\r
+                                       "type": "string"\r
+                               },\r
+                               "entry_schema": {\r
+                                       "required": false,\r
+                                       "type": "string"\r
+                               }\r
+                       },\r
+                       "derived_from": "tosca.datatypes.Root"\r
+               }\r
+       }\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/src/main/resources/sql/data.sql b/ms/controllerblueprints/modules/service/src/main/resources/sql/data.sql
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/ms/controllerblueprints/modules/service/src/main/resources/sql/schema-local.sql b/ms/controllerblueprints/modules/service/src/main/resources/sql/schema-local.sql
new file mode 100644 (file)
index 0000000..1ba9c36
--- /dev/null
@@ -0,0 +1,87 @@
+-- drop table sdnctl.MODEL_TYPE;\r
+-- drop table sdnctl.RESOURCE_DICTIONARY;\r
+-- drop table sdnctl.CONFIG_MODEL_CONTENT;\r
+-- drop table sdnctl.CONFIG_MODEL;\r
+\r
+-- -----------------------------------------------------\r
+-- table CONFIG_MODEL\r
+-- -----------------------------------------------------\r
+CREATE TABLE IF NOT EXISTS sdnctl.CONFIG_MODEL (\r
+  config_model_id              INT(11) NOT NULL AUTO_INCREMENT,\r
+  service_uuid                         VARCHAR(50) NULL DEFAULT NULL,\r
+  distribution_id              VARCHAR(50) NULL DEFAULT NULL,\r
+  service_name                         VARCHAR(255) NULL DEFAULT NULL,\r
+  service_description          VARCHAR(255) NULL DEFAULT NULL,\r
+  resource_uuid                VARCHAR(255) NULL DEFAULT NULL,\r
+  resource_instance_name       VARCHAR(255) NULL DEFAULT NULL,\r
+  resource_name                varchar(255) null default null,\r
+  resource_version             varchar(50) null default null,\r
+  resource_type                varchar(50) null default null,\r
+  artifact_uuid                varchar(50) null default null,\r
+  artifact_type                varchar(50) not null,\r
+  artifact_version             varchar(25) not null,\r
+  artifact_description                 longtext null default null,\r
+  internal_version             int(11) null default null,\r
+  creation_date                datetime not null default current_timestamp,\r
+  artifact_name                varchar(100) not null,\r
+  published                    varchar(1) not null,\r
+  updated_by                   varchar(100) not null,\r
+  tags                                 longtext null default null,\r
+  primary key PK_CONFIG_MODEL (config_model_id),\r
+  UNIQUE KEY UK_CONFIG_MODEL (artifact_name , artifact_version)\r
+) ENGINE=InnoDB;\r
+\r
+\r
+-- -----------------------------------------------------\r
+-- table CONFIG_MODEL_CONTENT\r
+-- -----------------------------------------------------\r
+CREATE TABLE IF NOT EXISTS sdnctl.CONFIG_MODEL_CONTENT (\r
+  config_model_content_id      INT(11) NOT NULL AUTO_INCREMENT, \r
+  config_model_id              INT NOT NULL,\r
+  name                                 VARCHAR(100) NOT NULL,\r
+  content_type                         VARCHAR(50) NOT NULL,\r
+  description                  LONGTEXT NULL DEFAULT NULL,\r
+  updated_date                         DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,\r
+  content                      LONGTEXT NULL DEFAULT NULL,\r
+  PRIMARY KEY PK_CONFIG_MODEL_CONTENT (config_model_content_id),\r
+  UNIQUE KEY UK_CONFIG_MODEL_CONTENT (config_model_id, name, content_type),\r
+  FOREIGN KEY FK_CONFIG_MODEL_CONTENT (config_model_id) REFERENCES sdnctl.CONFIG_MODEL(config_model_id) ON DELETE CASCADE\r
+) ENGINE=InnoDB;\r
+\r
+-- -----------------------------------------------------\r
+-- table MODEL_TYPE\r
+-- -----------------------------------------------------\r
+CREATE TABLE IF NOT EXISTS sdnctl.MODEL_TYPE (\r
+  model_name           VARCHAR(100) NOT NULL,\r
+  derived_from                 VARCHAR(100) NOT NULL,\r
+  definition_type      VARCHAR(100) NOT NULL,\r
+  definition           LONGTEXT NOT NULL,\r
+  version              VARCHAR(10) NOT NULL,\r
+  description          LONGTEXT NOT NULL,\r
+  tags                         LONGTEXT NULL DEFAULT NULL,  \r
+  creation_date        DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,\r
+  updated_by           VARCHAR(100) NOT NULL,\r
+  PRIMARY KEY PK_MODEL_TYPE (model_name),\r
+  INDEX IX_MODEL_TYPE (model_name)\r
+) ENGINE=InnoDB;\r
+\r
+\r
+-- -----------------------------------------------------\r
+-- table RESOURCE_DICTIONARY\r
+-- -----------------------------------------------------\r
+CREATE TABLE IF NOT EXISTS sdnctl.RESOURCE_DICTIONARY (\r
+  name                         VARCHAR(100) NOT NULL,\r
+  resource_path        VARCHAR(500) NOT NULL,  \r
+  resource_type        VARCHAR(100) NOT NULL,\r
+  data_type            VARCHAR(100) NOT NULL,\r
+  entry_schema                 VARCHAR(100) NULL DEFAULT NULL,\r
+  valid_values                 LONGTEXT NULL DEFAULT NULL,\r
+  sample_value                 LONGTEXT NULL DEFAULT NULL,\r
+  definition           LONGTEXT NOT NULL,\r
+  description          LONGTEXT NOT NULL,\r
+  tags                         LONGTEXT NOT NULL,  \r
+  creation_date        DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,\r
+  updated_by           VARCHAR(100) NOT NULL,\r
+  primary key PK_RESOURCE_DICTIONARY (name),\r
+  INDEX IX_RESOURCE_DICTIONARY (name)\r
+) ENGINE=InnoDB;
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/src/main/resources/sql/schema.sql b/ms/controllerblueprints/modules/service/src/main/resources/sql/schema.sql
new file mode 100644 (file)
index 0000000..b884cf3
--- /dev/null
@@ -0,0 +1,82 @@
+-- -----------------------------------------------------\r
+-- table CONFIG_MODEL\r
+-- -----------------------------------------------------\r
+CREATE TABLE IF NOT EXISTS configurator.CONFIG_MODEL (\r
+  config_model_id              INT(11) NOT NULL AUTO_INCREMENT,\r
+  service_uuid                         VARCHAR(50) NULL DEFAULT NULL,\r
+  distribution_id              VARCHAR(50) NULL DEFAULT NULL,\r
+  service_name                         VARCHAR(255) NULL DEFAULT NULL,\r
+  service_description          VARCHAR(255) NULL DEFAULT NULL,\r
+  resource_uuid                VARCHAR(255) NULL DEFAULT NULL,\r
+  resource_instance_name       VARCHAR(255) NULL DEFAULT NULL,\r
+  resource_name                varchar(255) null default null,\r
+  resource_version             varchar(50) null default null,\r
+  resource_type                varchar(50) null default null,\r
+  artifact_uuid                varchar(50) null default null,\r
+  artifact_type                varchar(50) not null,\r
+  artifact_version             varchar(25) not null,\r
+  artifact_description                 longtext null default null,\r
+  internal_version             int(11) null default null,\r
+  creation_date                datetime not null default current_timestamp,\r
+  artifact_name                varchar(100) not null,\r
+  published                    varchar(1) not null,\r
+  updated_by                   varchar(100) not null,\r
+  tags                                 longtext null default null,\r
+  primary key PK_CONFIG_MODEL (config_model_id),\r
+  UNIQUE KEY UK_CONFIG_MODEL (artifact_name , artifact_version)\r
+) ENGINE=InnoDB;\r
+\r
+\r
+-- -----------------------------------------------------\r
+-- table CONFIG_MODEL_CONTENT\r
+-- -----------------------------------------------------\r
+CREATE TABLE IF NOT EXISTS configurator.CONFIG_MODEL_CONTENT (\r
+  config_model_content_id      INT(11) NOT NULL AUTO_INCREMENT, \r
+  config_model_id              INT NOT NULL,\r
+  name                                 VARCHAR(100) NOT NULL,\r
+  content_type                         VARCHAR(50) NOT NULL,\r
+  description                  LONGTEXT NULL DEFAULT NULL,\r
+  updated_date                         DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,\r
+  content                      LONGTEXT NULL DEFAULT NULL,\r
+  PRIMARY KEY PK_CONFIG_MODEL_CONTENT (config_model_content_id),\r
+  UNIQUE KEY UK_CONFIG_MODEL_CONTENT (config_model_id, name, content_type),\r
+  FOREIGN KEY FK_CONFIG_MODEL_CONTENT (config_model_id) REFERENCES configurator.CONFIG_MODEL(config_model_id) ON DELETE CASCADE\r
+) ENGINE=InnoDB;\r
+\r
+-- -----------------------------------------------------\r
+-- table MODEL_TYPE\r
+-- -----------------------------------------------------\r
+CREATE TABLE IF NOT EXISTS configurator.MODEL_TYPE (\r
+  model_name           VARCHAR(100) NOT NULL,\r
+  derived_from                 VARCHAR(100) NOT NULL,\r
+  definition_type      VARCHAR(100) NOT NULL,\r
+  definition           LONGTEXT NOT NULL,\r
+  version              VARCHAR(10) NOT NULL,\r
+  description          LONGTEXT NOT NULL,\r
+  tags                         LONGTEXT NULL DEFAULT NULL,  \r
+  creation_date        DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,\r
+  updated_by           VARCHAR(100) NOT NULL,\r
+  PRIMARY KEY PK_MODEL_TYPE (model_name),\r
+  INDEX IX_MODEL_TYPE (model_name)\r
+) ENGINE=InnoDB;\r
+\r
+\r
+-- -----------------------------------------------------\r
+-- table RESOURCE_DICTIONARY\r
+-- -----------------------------------------------------\r
+CREATE TABLE IF NOT EXISTS configurator.RESOURCE_DICTIONARY (\r
+  name                         VARCHAR(100) NOT NULL,\r
+  resource_path        VARCHAR(500) NOT NULL,  \r
+  resource_type        VARCHAR(100) NOT NULL,\r
+  data_type            VARCHAR(100) NOT NULL,\r
+  entry_schema                 VARCHAR(100) NULL DEFAULT NULL,\r
+  valid_values                 LONGTEXT NULL DEFAULT NULL,\r
+  sample_value                 LONGTEXT NULL DEFAULT NULL,\r
+  definition           LONGTEXT NOT NULL,\r
+  description          LONGTEXT NOT NULL,\r
+  tags                         LONGTEXT NOT NULL,  \r
+  creation_date        DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,\r
+  updated_by           VARCHAR(100) NOT NULL,\r
+  primary key PK_RESOURCE_DICTIONARY (name),\r
+  INDEX IX_RESOURCE_DICTIONARY (name)\r
+) ENGINE=InnoDB;\r
diff --git a/ms/controllerblueprints/modules/service/src/test/java/org/onap/ccsdk/apps/controllerblueprints/DatabaseConfig.java b/ms/controllerblueprints/modules/service/src/test/java/org/onap/ccsdk/apps/controllerblueprints/DatabaseConfig.java
new file mode 100644 (file)
index 0000000..db35fe6
--- /dev/null
@@ -0,0 +1,61 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints;\r
+\r
+import org.springframework.boot.autoconfigure.domain.EntityScan;\r
+import org.springframework.context.annotation.Bean;\r
+import org.springframework.context.annotation.Configuration;\r
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;\r
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;\r
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;\r
+import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;\r
+import org.springframework.transaction.annotation.EnableTransactionManagement;\r
+\r
+import javax.sql.DataSource;\r
+\r
+/**\r
+ * DatabaseConfig.java Purpose: Provide Configuration Generator DatabaseConfig Information\r
+ *\r
+ * @author Brinda Santh\r
+ * @version 1.0\r
+ */\r
+@Configuration\r
+@EntityScan("org.onap.ccsdk.apps.controllerblueprints.service.domain")\r
+@EnableTransactionManagement\r
+@EnableJpaRepositories("org.onap.ccsdk.apps.controllerblueprints.service.repository")\r
+@EnableJpaAuditing\r
+public class DatabaseConfig {\r
+    /**\r
+     * This is a entityManagerFactory method\r
+     * \r
+     * @param dataSource\r
+     * @return LocalContainerEntityManagerFactoryBean\r
+     */\r
+\r
+    @Bean\r
+    public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {\r
+        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();\r
+        vendorAdapter.setGenerateDdl(true);\r
+        vendorAdapter.setShowSql(false);\r
+        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();\r
+        factory.setJpaVendorAdapter(vendorAdapter);\r
+        factory.setPackagesToScan("org.onap.ccsdk.apps.controllerblueprints.service.domain");\r
+        factory.setDataSource(dataSource);\r
+        return factory;\r
+    }\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/test/java/org/onap/ccsdk/apps/controllerblueprints/JerseyConfiguration.java b/ms/controllerblueprints/modules/service/src/test/java/org/onap/ccsdk/apps/controllerblueprints/JerseyConfiguration.java
new file mode 100644 (file)
index 0000000..f5535eb
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright © 2017-2018 AT&T Intellectual Property.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onap.ccsdk.apps.controllerblueprints;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.MapperFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.servlet.ServletProperties;
+import org.onap.ccsdk.apps.controllerblueprints.service.common.ServiceExceptionMapper;
+import org.onap.ccsdk.apps.controllerblueprints.service.rs.ConfigModelRestImpl;
+import org.onap.ccsdk.apps.controllerblueprints.service.rs.ModelTypeRestImpl;
+import org.onap.ccsdk.apps.controllerblueprints.service.rs.ResourceDictionaryRestImpl;
+import org.onap.ccsdk.apps.controllerblueprints.service.rs.ServiceTemplateRestImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Primary;
+import org.springframework.stereotype.Component;
+
+import java.util.logging.Logger;
+
+
+@Component
+public class JerseyConfiguration extends ResourceConfig {
+    private static final Logger log = Logger.getLogger(JerseyConfiguration.class.getName());
+
+    @Bean
+    @Primary
+    public ObjectMapper objectMapper() {
+        ObjectMapper objectMapper = new ObjectMapper();
+        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
+        objectMapper.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES);
+        objectMapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);
+        objectMapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
+        return objectMapper;
+    }
+
+    @Autowired
+    public JerseyConfiguration() {
+        register(ConfigModelRestImpl.class);
+        register(ModelTypeRestImpl.class);
+        register(ResourceDictionaryRestImpl.class);
+        register(ServiceTemplateRestImpl.class);
+        // Exception Mapping
+        register(ServiceExceptionMapper.class);
+        property(ServletProperties.FILTER_FORWARD_ON_404, true);
+        register(new LoggingFeature(log));
+    }
+
+
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/src/test/java/org/onap/ccsdk/apps/controllerblueprints/TestApplication.java b/ms/controllerblueprints/modules/service/src/test/java/org/onap/ccsdk/apps/controllerblueprints/TestApplication.java
new file mode 100644 (file)
index 0000000..537429f
--- /dev/null
@@ -0,0 +1,34 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints;\r
+\r
+import org.springframework.boot.SpringApplication;\r
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;\r
+import org.springframework.boot.autoconfigure.SpringBootApplication;\r
+import org.springframework.context.annotation.ComponentScan;\r
+\r
+\r
+@SpringBootApplication\r
+@ComponentScan(basePackages = {"org.onap.ccsdk.apps.controllerblueprints"})\r
+@EnableAutoConfiguration\r
+public class TestApplication {\r
+\r
+    public static void main(String[] args) {\r
+        SpringApplication.run(TestApplication.class, args);\r
+    }\r
+\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/src/test/java/org/onap/ccsdk/apps/controllerblueprints/TestConfiguration.java b/ms/controllerblueprints/modules/service/src/test/java/org/onap/ccsdk/apps/controllerblueprints/TestConfiguration.java
new file mode 100644 (file)
index 0000000..ea259c9
--- /dev/null
@@ -0,0 +1,36 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints;\r
+\r
+import org.springframework.context.annotation.Bean;\r
+\r
+import java.util.ArrayList;\r
+\r
+//@Configuration\r
+public class TestConfiguration {\r
+\r
+    @Bean("jaxrsProviders")\r
+    public ArrayList<Object> provider() {\r
+        return new ArrayList<Object>();\r
+    }\r
+\r
+    @Bean("jaxrsServices")\r
+    public ArrayList<Object> service() {\r
+        return new ArrayList<Object>();\r
+    }\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/test/java/org/onap/ccsdk/apps/controllerblueprints/service/common/SchemaGeneratorServiceTest.java b/ms/controllerblueprints/modules/service/src/test/java/org/onap/ccsdk/apps/controllerblueprints/service/common/SchemaGeneratorServiceTest.java
new file mode 100644 (file)
index 0000000..50e94df
--- /dev/null
@@ -0,0 +1,50 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.common;\r
+\r
+import org.apache.commons.io.FileUtils;\r
+import org.junit.Assert;\r
+import org.junit.FixMethodOrder;\r
+import org.junit.Test;\r
+import org.junit.runners.MethodSorters;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.SchemaGeneratorService;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import java.io.File;\r
+import java.nio.charset.Charset;\r
+\r
+\r
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)\r
+public class SchemaGeneratorServiceTest {\r
+\r
+    private static Logger log = LoggerFactory.getLogger(ServiceTemplateValidationTest.class);\r
+\r
+    @Test\r
+    public void test01GenerateSwaggerData() throws Exception {\r
+        log.info("******************* test01GenerateSwaggerData  ******************************");\r
+\r
+        String file = "src/test/resources/enhance/enhanced-template.json";\r
+        String serviceTemplateContent = FileUtils.readFileToString(new File(file), Charset.defaultCharset());\r
+        SchemaGeneratorService schemaGeneratorService = new SchemaGeneratorService();\r
+        String schema = schemaGeneratorService.generateSchema(serviceTemplateContent);\r
+        log.trace("Generated Schema " + schema);\r
+        Assert.assertNotNull("failed to generate Sample Data", schema);\r
+\r
+    }\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/test/java/org/onap/ccsdk/apps/controllerblueprints/service/common/ServiceTemplateValidationTest.java b/ms/controllerblueprints/modules/service/src/test/java/org/onap/ccsdk/apps/controllerblueprints/service/common/ServiceTemplateValidationTest.java
new file mode 100644 (file)
index 0000000..af309e2
--- /dev/null
@@ -0,0 +1,56 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.common;\r
+\r
+\r
+import org.apache.commons.io.IOUtils;\r
+import org.junit.Assert;\r
+import org.junit.Test;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.utils.ConfigModelUtils;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.validator.ServiceTemplateValidator;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import java.nio.charset.Charset;\r
+import java.util.List;\r
+\r
+public class ServiceTemplateValidationTest {\r
+    private static Logger log = LoggerFactory.getLogger(ServiceTemplateValidationTest.class);\r
+\r
+    @Test\r
+    public void testBluePrintDirs(){\r
+        List<String> dirs = ConfigModelUtils.getBlueprintNames("load/blueprints");\r
+        Assert.assertNotNull("Failed to get blueprint directories", dirs );\r
+        Assert.assertEquals("Failed to get actual directories",2, dirs.size() );\r
+    }\r
+\r
+    // @Test\r
+    public void validateServiceTemplate() {\r
+        try {\r
+            String file = "load/service_template/vrr-201806-test/service-template.json";\r
+            String serviceTemplateContent =\r
+                    IOUtils.toString(ServiceTemplateValidationTest.class.getClassLoader().getResourceAsStream(file),\r
+                            Charset.defaultCharset());\r
+            ServiceTemplateValidator serviceTemplateValidator = new ServiceTemplateValidator();\r
+            serviceTemplateValidator.validateServiceTemplate(serviceTemplateContent);\r
+            log.info("Validated Service Template " + serviceTemplateValidator.getMetaData());\r
+\r
+        } catch (Exception e) {\r
+            e.printStackTrace();\r
+        }\r
+    }\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/test/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ConfigModelRestTest.java b/ms/controllerblueprints/modules/service/src/test/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ConfigModelRestTest.java
new file mode 100644 (file)
index 0000000..5b10a7e
--- /dev/null
@@ -0,0 +1,172 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.rs;\r
+\r
+import org.junit.*;\r
+import org.junit.runner.RunWith;\r
+import org.junit.runners.MethodSorters;\r
+import org.onap.ccsdk.apps.controllerblueprints.TestApplication;\r
+import org.onap.ccsdk.apps.controllerblueprints.TestConfiguration;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ConfigModel;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.utils.ConfigModelUtils;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+import org.springframework.beans.factory.annotation.Autowired;\r
+import org.springframework.boot.test.context.SpringBootTest;\r
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;\r
+import org.springframework.test.context.ContextConfiguration;\r
+import org.springframework.test.context.junit4.SpringRunner;\r
+\r
+import java.util.List;\r
+\r
+@RunWith(SpringRunner.class)\r
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)\r
+@ContextConfiguration(classes = {TestApplication.class, TestConfiguration.class})\r
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)\r
+public class ConfigModelRestTest {\r
+\r
+    private static Logger log = LoggerFactory.getLogger(ConfigModelRestTest.class);\r
+\r
+    @Autowired\r
+    ConfigModelRest configModelRest;\r
+\r
+    ConfigModel configModel;\r
+\r
+    String name = "vrr-test";\r
+    String version = "1.0.0";\r
+\r
+    @Before\r
+    public void setUp() {\r
+\r
+    }\r
+\r
+\r
+    @After\r
+    public void tearDown() {\r
+    }\r
+\r
+\r
+    @Test\r
+    public void test01getInitialConfigModel() throws Exception {\r
+        log.info("** test01getInitialConfigModel  *****************");\r
+\r
+        String name = "default_netconf";\r
+        ConfigModel configModel = configModelRest.getInitialConfigModel(name);\r
+        Assert.assertNotNull("Failed to get Initial Config Model , Return object is Null", configModel);\r
+        Assert.assertNotNull("Failed to get Service Template Content ", configModel.getConfigModelContents());\r
+\r
+    }\r
+\r
+\r
+    @Test\r
+    public void test02SaveServiceTemplate() throws Exception {\r
+        log.info("************************ test02SaveServiceTemplate  ******************");\r
+\r
+\r
+        configModel = ConfigModelUtils.getConfigModel("load/blueprints/vrr-test");\r
+\r
+        configModel = configModelRest.saveConfigModel(configModel);\r
+        Assert.assertNotNull("Failed to ConfigModel, Return object is Null", configModel);\r
+        Assert.assertNotNull("Failed to ConfigModel Id , Return ID object is Null", configModel.getId());\r
+        Assert.assertNotNull("Failed to ConfigModel Content, Return object is Null",\r
+                configModel.getConfigModelContents());\r
+        Assert.assertEquals("Failed in validation of ConfigModel Content count,", 3,\r
+                configModel.getConfigModelContents().size());\r
+\r
+        ConfigModel dbconfigModel = configModelRest.getConfigModel(configModel.getId());\r
+\r
+        log.info("************************ test02SaveServiceTemplate-2  ******************");\r
+\r
+        dbconfigModel.getConfigModelContents().remove(2);\r
+        dbconfigModel = configModelRest.saveConfigModel(dbconfigModel);\r
+        log.info("Saved Config Model " + configModel.getId());\r
+        Assert.assertNotNull("Failed to ConfigModel, Return object is Null", dbconfigModel);\r
+        Assert.assertNotNull("Failed to ConfigModel Id ", dbconfigModel.getId());\r
+        Assert.assertNotNull("Failed to ConfigModel Content",\r
+                dbconfigModel.getConfigModelContents());\r
+        Assert.assertEquals("Failed to Remove the ConfigModel Content,", 2,\r
+                dbconfigModel.getConfigModelContents().size());\r
+\r
+\r
+    }\r
+\r
+\r
+    @Test\r
+    public void test03PublishServiceTemplate() throws Exception {\r
+        log.info("** test03PublishServiceTemplate  *****************");\r
+\r
+        ConfigModel configModel = configModelRest.getConfigModelByNameAndVersion(name, version);\r
+        log.info("Publishing Config Model " + configModel.getId());\r
+        configModel = configModelRest.publishConfigModel(configModel.getId());\r
+        Assert.assertNotNull("Failed to ConfigModel, Return object is Null", configModel);\r
+        Assert.assertNotNull("Failed to ConfigModel Id ", configModel.getId());\r
+        Assert.assertNotNull("Failed to ConfigModel Content", configModel.getConfigModelContents());\r
+        Assert.assertEquals("Failed to update the publish indicator", "Y", configModel.getPublished());\r
+    }\r
+\r
+\r
+    @Test\r
+    public void test04GetConfigModel() throws Exception {\r
+        log.info("** test04GetConfigModel  *****************");\r
+\r
+        ConfigModel configModel = configModelRest.getConfigModelByNameAndVersion(name, version);\r
+        Assert.assertNotNull("Failed to get ConfigModel for the Name (" + configModel.getArtifactName() + ") and ("\r
+                + configModel.getArtifactVersion() + ")", configModel);\r
+        Assert.assertNotNull("Failed to get ConfigModel Id", configModel.getId());\r
+\r
+        configModel = configModelRest.getConfigModel(configModel.getId());\r
+        Assert.assertNotNull("Failed to get ConfigModel for the Id (" + configModel.getId() + ") ", configModel);\r
+\r
+    }\r
+\r
+    @Test\r
+    public void test05GetCloneConfigModel() throws Exception {\r
+        log.info("** test05GetCloneConfigModel  *****************");\r
+\r
+        ConfigModel configModel = configModelRest.getConfigModelByNameAndVersion(name, version);\r
+\r
+        Assert.assertNotNull("Failed to get ConfigModel for the Name (" + configModel.getArtifactName() + ") and ("\r
+                + configModel.getArtifactVersion() + ")", configModel);\r
+        Assert.assertNotNull("Failed to get ConfigModel Id", configModel.getId());\r
+\r
+        configModel = configModelRest.getCloneConfigModel(configModel.getId());\r
+        Assert.assertNotNull("Failed to get ConfigModel for the Id (" + configModel.getId() + ") ", configModel);\r
+    }\r
+\r
+\r
+    @Test\r
+    public void test07SearchConfigModels() throws Exception {\r
+        log.info("** test07SearchConfigModels  *****************");\r
+\r
+        List<ConfigModel> configModels = configModelRest.searchConfigModels("vrr-test");\r
+        Assert.assertNotNull("Failed to search ConfigModel", configModels);\r
+        Assert.assertTrue("Failed to search ConfigModel with count", configModels.size() > 0);\r
+        // update the ServiceModelContent\r
+    }\r
+\r
+\r
+    @Test\r
+    public void test08DeleteConfigModels() throws Exception {\r
+        log.info("** test08DeleteConfigModels  *****************");\r
+\r
+        ConfigModel configModel = configModelRest.getConfigModelByNameAndVersion(name, version);\r
+        configModelRest.deleteConfigModel(configModel.getId());\r
+\r
+    }\r
+\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/test/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ModelTypeRestTest.java b/ms/controllerblueprints/modules/service/src/test/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ModelTypeRestTest.java
new file mode 100644 (file)
index 0000000..d33349c
--- /dev/null
@@ -0,0 +1,130 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.rs;\r
+\r
+import org.apache.commons.io.FileUtils;\r
+import org.junit.*;\r
+import org.junit.runner.RunWith;\r
+import org.junit.runners.MethodSorters;\r
+import org.onap.ccsdk.apps.controllerblueprints.TestApplication;\r
+import org.onap.ccsdk.apps.controllerblueprints.TestConfiguration;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.BluePrintConstants;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ModelType;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+import org.springframework.beans.factory.annotation.Autowired;\r
+import org.springframework.boot.test.context.SpringBootTest;\r
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;\r
+import org.springframework.test.context.ContextConfiguration;\r
+import org.springframework.test.context.junit4.SpringRunner;\r
+\r
+import java.io.File;\r
+import java.nio.charset.Charset;\r
+import java.util.List;\r
+\r
+@RunWith(SpringRunner.class)\r
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)\r
+@ContextConfiguration(classes = {TestApplication.class, TestConfiguration.class})\r
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)\r
+public class ModelTypeRestTest {\r
+    private static Logger log = LoggerFactory.getLogger(ModelTypeRestTest.class);\r
+    @Autowired\r
+    ModelTypeRest modelTypeRest;\r
+\r
+    String modelName = "test-datatype";\r
+\r
+    @Before\r
+    public void setUp() {\r
+\r
+    }\r
+\r
+\r
+    @After\r
+    public void tearDown() {}\r
+\r
+    @Test\r
+    public void test01SaveModelType() throws Exception {\r
+        log.info( "**************** test01SaveModelType  ********************");\r
+\r
+        String content = FileUtils.readFileToString(new File("load/model_type/data_type/datatype-property.json"), Charset.defaultCharset());\r
+        ModelType modelType = new ModelType();\r
+        modelType.setDefinitionType(BluePrintConstants.MODEL_DEFINITION_TYPE_DATA_TYPE);\r
+        modelType.setDerivedFrom(BluePrintConstants.MODEL_TYPE_DATATYPES_ROOT);\r
+        modelType.setDescription("Definition for Sample Datatype ");\r
+        modelType.setDefinition(content);\r
+        modelType.setModelName(modelName);\r
+        modelType.setVersion("1.0.0");\r
+        modelType.setTags("test-datatype ," + BluePrintConstants.MODEL_TYPE_DATATYPES_ROOT + ","\r
+                + BluePrintConstants.MODEL_DEFINITION_TYPE_DATA_TYPE);\r
+        modelType.setUpdatedBy("xxxxxx@xxx.com");\r
+        modelType = modelTypeRest.saveModelType(modelType);\r
+        log.info( "Saved Mode {}", modelType.toString());\r
+        Assert.assertNotNull("Failed to get Saved ModelType", modelType);\r
+        Assert.assertNotNull("Failed to get Saved ModelType, Id", modelType.getModelName());\r
+\r
+        ModelType dbModelType = modelTypeRest.getModelTypeByName(modelType.getModelName());\r
+        Assert.assertNotNull("Failed to query ResourceMapping for ID (" + dbModelType.getModelName() + ")",\r
+                dbModelType);\r
+\r
+        // Model Update\r
+        modelType.setUpdatedBy("bs2796@xxx.com");\r
+        modelType = modelTypeRest.saveModelType(modelType);\r
+        Assert.assertNotNull("Failed to get Saved ModelType", modelType);\r
+        Assert.assertEquals("Failed to get Saved getUpdatedBy ", "bs2796@xxx.com", modelType.getUpdatedBy());\r
+\r
+    }\r
+\r
+    @Test\r
+    public void test02SearchModelTypes() throws Exception {\r
+        log.info( "*********************** test02SearchModelTypes  ***************************");\r
+\r
+        String tags = "test-datatype";\r
+\r
+        List<ModelType> dbModelTypes = modelTypeRest.searchModelTypes(tags);\r
+        Assert.assertNotNull("Failed to search ResourceMapping by tags", dbModelTypes);\r
+        Assert.assertEquals("Failed to search ResourceMapping by tags count", true, dbModelTypes.size() > 0);\r
+\r
+    }\r
+\r
+    @Test\r
+    public void test03GetModelType() throws Exception {\r
+        log.info( "************************* test03GetModelType  *********************************");\r
+        ModelType dbModelType = modelTypeRest.getModelTypeByName(modelName);\r
+        Assert.assertNotNull("Failed to get response for api call getModelByName ", dbModelType);\r
+        Assert.assertNotNull("Failed to get Id for api call  getModelByName ", dbModelType.getModelName());\r
+\r
+        List<ModelType> dbDatatypeModelTypes =\r
+                modelTypeRest.getModelTypeByDefinitionType(BluePrintConstants.MODEL_DEFINITION_TYPE_DATA_TYPE);\r
+        Assert.assertNotNull("Failed to find getModelTypeByDefinitionType by tags", dbDatatypeModelTypes);\r
+        Assert.assertEquals("Failed to find getModelTypeByDefinitionType by count", true,\r
+                dbDatatypeModelTypes.size() > 0);\r
+    }\r
+\r
+    @Test\r
+    public void test04DeleteModelType() throws Exception {\r
+        log.info(\r
+                "************************ test03DeleteModelType  ***********************");\r
+        ModelType dbResourceMapping = modelTypeRest.getModelTypeByName(modelName);\r
+        Assert.assertNotNull("Failed to get response for api call getModelByName ", dbResourceMapping);\r
+        Assert.assertNotNull("Failed to get Id for api call  getModelByName ", dbResourceMapping.getModelName());\r
+\r
+        modelTypeRest.deleteModelTypeByName(dbResourceMapping.getModelName());\r
+    }\r
+\r
+\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/test/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ResourceDictionaryRestTest.java b/ms/controllerblueprints/modules/service/src/test/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ResourceDictionaryRestTest.java
new file mode 100644 (file)
index 0000000..71dff33
--- /dev/null
@@ -0,0 +1,113 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.rs;\r
+\r
+import org.apache.commons.io.IOUtils;\r
+import org.junit.Assert;\r
+import org.junit.Before;\r
+import org.junit.FixMethodOrder;\r
+import org.junit.Test;\r
+import org.junit.runner.RunWith;\r
+import org.junit.runners.MethodSorters;\r
+import org.onap.ccsdk.apps.controllerblueprints.TestApplication;\r
+import org.onap.ccsdk.apps.controllerblueprints.TestConfiguration;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ResourceDictionary;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+import org.springframework.beans.factory.annotation.Autowired;\r
+import org.springframework.boot.test.context.SpringBootTest;\r
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;\r
+import org.springframework.test.context.ContextConfiguration;\r
+import org.springframework.test.context.junit4.SpringRunner;\r
+\r
+import java.nio.charset.Charset;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+\r
+@RunWith(SpringRunner.class)\r
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)\r
+@ContextConfiguration(classes = {TestApplication.class, TestConfiguration.class})\r
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)\r
+public class ResourceDictionaryRestTest {\r
+\r
+    private static Logger log = LoggerFactory.getLogger(ResourceDictionaryRestTest.class);\r
+\r
+    @Autowired\r
+    protected ResourceDictionaryRest resourceDictionaryRest;\r
+\r
+    @Before\r
+    public void setUp() {\r
+\r
+    }\r
+\r
+    @Test\r
+    public void test01SaveDataDictionary() throws Exception {\r
+        String definition = IOUtils.toString(\r
+                getClass().getClassLoader().getResourceAsStream("resourcedictionary/default_definition.json"),\r
+                Charset.defaultCharset());\r
+\r
+        ResourceDictionary dataDictionary = new ResourceDictionary();\r
+        dataDictionary.setResourcePath("test/vnf/ipaddress");\r
+        dataDictionary.setName("test-name");\r
+        dataDictionary.setDefinition(definition);\r
+        dataDictionary.setValidValues("127.0.0.1");\r
+        dataDictionary.setResourceType("ONAP");\r
+        dataDictionary.setDataType("string");\r
+        dataDictionary.setDescription("Sample Resource Mapping");\r
+        dataDictionary.setTags("test, ipaddress");\r
+        dataDictionary.setUpdatedBy("xxxxxx@xxx.com");\r
+\r
+        dataDictionary = resourceDictionaryRest.saveResourceDictionary(dataDictionary);\r
+\r
+        Assert.assertNotNull("Failed to get Saved Resource Dictionary", dataDictionary);\r
+        Assert.assertNotNull("Failed to get Saved Resource Dictionary, Id", dataDictionary.getName());\r
+\r
+        ResourceDictionary dbDataDictionary =\r
+                resourceDictionaryRest.getResourceDictionaryByName(dataDictionary.getName());\r
+        Assert.assertNotNull("Failed to query Resource Dictionary for ID (" + dataDictionary.getName() + ")",\r
+                dbDataDictionary);\r
+        Assert.assertNotNull("Failed to query Resource Dictionary definition for ID (" + dataDictionary.getName() + ")",\r
+                dbDataDictionary.getDefinition());\r
+\r
+        log.trace("Saved Dictionary " + dbDataDictionary.getDefinition());\r
+\r
+    }\r
+\r
+    @Test\r
+    public void test02GetDataDictionary() throws Exception {\r
+\r
+        ResourceDictionary dbResourceDictionary = resourceDictionaryRest.getResourceDictionaryByName("test-name");\r
+        Assert.assertNotNull("Failed to query Resource Dictionary by Name", dbResourceDictionary);\r
+\r
+        String tags = "ipaddress";\r
+\r
+        List<ResourceDictionary> dbResourceDictionaries = resourceDictionaryRest.searchResourceDictionaryByTags(tags);\r
+        Assert.assertNotNull("Failed to search ResourceDictionary by tags", dbResourceDictionaries);\r
+        Assert.assertTrue("Failed to search searchResourceDictionaryByTags by tags by count",\r
+                dbResourceDictionaries.size() > 0);\r
+\r
+        List<String> names = new ArrayList<>();\r
+        names.add("test-name");\r
+        dbResourceDictionaries = resourceDictionaryRest.searchResourceDictionaryByNames(names);\r
+        Assert.assertNotNull("Failed to search ResourceDictionary by Names", dbResourceDictionaries);\r
+        Assert.assertTrue("Failed to search searchResourceDictionaryByNames by tags by count",\r
+                dbResourceDictionaries.size() > 0);\r
+\r
+    }\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/test/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ServiceTemplateRestTest.java b/ms/controllerblueprints/modules/service/src/test/java/org/onap/ccsdk/apps/controllerblueprints/service/rs/ServiceTemplateRestTest.java
new file mode 100644 (file)
index 0000000..f81dd41
--- /dev/null
@@ -0,0 +1,155 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.rs;\r
+\r
+import org.apache.commons.collections.CollectionUtils;\r
+import org.apache.commons.io.FileUtils;\r
+import org.junit.Assert;\r
+import org.junit.FixMethodOrder;\r
+import org.junit.Test;\r
+import org.junit.runner.RunWith;\r
+import org.junit.runners.MethodSorters;\r
+import org.onap.ccsdk.apps.controllerblueprints.TestApplication;\r
+import org.onap.ccsdk.apps.controllerblueprints.TestConfiguration;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.ConfigModelConstant;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.data.ServiceTemplate;\r
+import org.onap.ccsdk.apps.controllerblueprints.core.utils.JacksonUtils;\r
+import org.onap.ccsdk.apps.controllerblueprints.resource.dict.ResourceAssignment;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ConfigModelContent;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.model.AutoMapResponse;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+import org.springframework.beans.factory.annotation.Autowired;\r
+import org.springframework.boot.test.context.SpringBootTest;\r
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;\r
+import org.springframework.test.context.ContextConfiguration;\r
+import org.springframework.test.context.junit4.SpringRunner;\r
+\r
+import java.io.File;\r
+import java.nio.charset.Charset;\r
+import java.util.List;\r
+\r
+\r
+@RunWith(SpringRunner.class)\r
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)\r
+@ContextConfiguration(classes = {TestApplication.class, TestConfiguration.class})\r
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)\r
+public class ServiceTemplateRestTest {\r
+\r
+    private static Logger log = LoggerFactory.getLogger(ServiceTemplateRestTest.class);\r
+    @Autowired\r
+    ModelTypeRest modelTypeRest;\r
+\r
+    @Autowired\r
+    private ServiceTemplateRest serviceTemplateRest;\r
+\r
+    @Test\r
+    public void test02EnrichServiceTemplate() throws Exception {\r
+        log.info("*********** test02EnrichServiceTemplate  ***********************");\r
+        String file = "src/test/resources/enhance/enhance-template.json";\r
+\r
+        String serviceTemplateContent = FileUtils.readFileToString(new File(file), Charset.defaultCharset());\r
+\r
+        ServiceTemplate serviceTemplate = JacksonUtils.readValue(serviceTemplateContent, ServiceTemplate.class);\r
+\r
+        serviceTemplate = serviceTemplateRest.enrichServiceTemplate(serviceTemplate);\r
+\r
+        String enhancedFile = "src/test/resources/enhance/enhanced-template.json";\r
+\r
+        FileUtils.write(new File(enhancedFile),\r
+                JacksonUtils.getJson(serviceTemplate, true), Charset.defaultCharset());\r
+\r
+        Assert.assertNotNull("Failed to get Enriched Blueprints, Return object is Null", serviceTemplate);\r
+        Assert.assertNotNull("Failed to get Enriched Blueprints Data Type, Return object is Null",\r
+                serviceTemplate.getDataTypes());\r
+        Assert.assertNotNull("Failed to get Enriched Blueprints Node Type, Return object is Null",\r
+                serviceTemplate.getNodeTypes());\r
+        log.trace("Enriched Service Template :\n" + JacksonUtils.getJson(serviceTemplate, true));\r
+    }\r
+\r
+    @Test\r
+    public void test03ValidateServiceTemplate() throws Exception {\r
+        log.info("*********** test03ValidateServiceTemplate  *******************************************");\r
+        String enhancedFile = "src/test/resources/enhance/enhanced-template.json";\r
+        String serviceTemplateContent = FileUtils.readFileToString(new File(enhancedFile), Charset.defaultCharset());\r
+\r
+        ServiceTemplate serviceTemplate =\r
+                JacksonUtils.readValue(serviceTemplateContent, ServiceTemplate.class);\r
+\r
+        serviceTemplate = serviceTemplateRest.validateServiceTemplate(serviceTemplate);\r
+\r
+        Assert.assertNotNull("Failed to validate Service Template, Return object is Null", serviceTemplate);\r
+        Assert.assertNotNull("Failed to get Service Template Data Type, Return object is Null",\r
+                serviceTemplate.getDataTypes());\r
+        Assert.assertNotNull("Failed to get Service Template Node Type, Return object is Null",\r
+                serviceTemplate.getNodeTypes());\r
+\r
+        log.trace("Validated Service Template :\n" + JacksonUtils.getJson(serviceTemplate, true));\r
+\r
+    }\r
+\r
+\r
+    @Test\r
+    public void test04GenerateResourceAssignments() throws Exception {\r
+        log.info("*********** test04GenerateResourceAssignments  *******************************************");\r
+        ConfigModelContent baseConfigConfigModelContent = new ConfigModelContent();\r
+        String baseConfigContent = FileUtils.readFileToString(new File("load/blueprints/vrr-test/Templates/base-config-template.vtl")\r
+                , Charset.defaultCharset());\r
+        baseConfigConfigModelContent.setName("base-config-template");\r
+        baseConfigConfigModelContent.setContentType(ConfigModelConstant.MODEL_CONTENT_TYPE_TEMPLATE);\r
+        baseConfigConfigModelContent.setContent(baseConfigContent);\r
+\r
+        List<ResourceAssignment> resourceAssignments =\r
+                serviceTemplateRest.generateResourceAssignments(baseConfigConfigModelContent);\r
+\r
+        Assert.assertNotNull("Failed to get ResourceAssignments, Return object is Null", resourceAssignments);\r
+        Assert.assertTrue("Failed to get ResourceAssignments count", resourceAssignments.size() > 0);\r
+\r
+        log.trace("Validated Service Template :\n" + JacksonUtils.getJson(resourceAssignments, true));\r
+\r
+\r
+    }\r
+\r
+    @Test\r
+    public void test05AutoMap() throws Exception {\r
+        log.info("*********** test05AutoMap  *******************************************");\r
+\r
+        String resourceassignmentContent = FileUtils.readFileToString(\r
+                new File("src/test/resources/resourcedictionary/automap.json"), Charset.defaultCharset());\r
+        List<ResourceAssignment> batchResourceAssignment =\r
+                JacksonUtils.getListFromJson(resourceassignmentContent, ResourceAssignment.class);\r
+        AutoMapResponse autoMapResponse = serviceTemplateRest.autoMap(batchResourceAssignment);\r
+\r
+        Assert.assertNotNull("Failed to get ResourceAssignments, Return object is Null",\r
+                autoMapResponse.getResourceAssignments());\r
+        Assert.assertNotNull("Failed to get Data Dictionary from ResourceAssignments",\r
+                autoMapResponse.getDataDictionaries());\r
+        Assert.assertTrue("Failed to get ResourceAssignments count",\r
+                CollectionUtils.isNotEmpty(autoMapResponse.getDataDictionaries()));\r
+\r
+        List<ResourceAssignment> autoMappedResourceAssignment = autoMapResponse.getResourceAssignments();\r
+        autoMappedResourceAssignment.forEach(resourceAssignment -> {\r
+            if ("bundle-id".equals(resourceAssignment.getName())) {\r
+                Assert.assertEquals("Failed to assign default first source", "db",\r
+                        resourceAssignment.getDictionarySource());\r
+            }\r
+        });\r
+\r
+    }\r
+\r
+\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/test/java/org/onap/ccsdk/apps/controllerblueprints/service/utils/ConfigModelUtilsTest.java b/ms/controllerblueprints/modules/service/src/test/java/org/onap/ccsdk/apps/controllerblueprints/service/utils/ConfigModelUtilsTest.java
new file mode 100644 (file)
index 0000000..b38dd6d
--- /dev/null
@@ -0,0 +1,33 @@
+/*\r
+ * Copyright © 2017-2018 AT&T Intellectual Property.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.ccsdk.apps.controllerblueprints.service.utils;\r
+\r
+import org.apache.commons.collections.CollectionUtils;\r
+import org.junit.Assert;\r
+import org.junit.Test;\r
+import org.onap.ccsdk.apps.controllerblueprints.service.domain.ConfigModel;\r
+\r
+public class ConfigModelUtilsTest {\r
+\r
+    @Test\r
+    public void testConfigModel() throws Exception {\r
+\r
+        ConfigModel configModel = ConfigModelUtils.getConfigModel("load/blueprints/vrr-test");\r
+        Assert.assertNotNull("Failed to prepare config model", configModel);\r
+        Assert.assertTrue("Failed to prepare config model contents", CollectionUtils.isNotEmpty(configModel.getConfigModelContents()));\r
+    }\r
+}\r
diff --git a/ms/controllerblueprints/modules/service/src/test/resources/application.properties b/ms/controllerblueprints/modules/service/src/test/resources/application.properties
new file mode 100644 (file)
index 0000000..a13e168
--- /dev/null
@@ -0,0 +1,67 @@
+#
+# Copyright © 2017-2018 AT&T Intellectual Property.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+info.build.artifact=@project.artifactId@
+info.build.name=@project.name@
+info.build.description=@project.description@
+info.build.version=@project.version@
+info.build.groupId=@project.groupId@
+logging.level.root=info
+
+server.contextPath=/
+server.servlet-path=/
+spring.jersey.application-path=/api/controller-blueprints/v1
+server.routingPath=/api
+
+
+mots.application.acronym=MOTS_ID
+platform.identifier=AJSC7_JERSEY
+#spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
+
+#logging.pattern.console=%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr($ threadId: {PID:- }){magenta} %clr(---){faint} %clr([ hostname: %X{hostname} serviceName: %X{serviceName} version: %X{version} transactionId: %X{transactionId} requestTimeStamp: %X{requestTimestamp}  responseTimeStamp: %X{responseTimestamp} duration: %X{duration}]){yellow} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wex
+
+
+#The max number of active threads in this pool
+server.tomcat.max-threads=200
+#The minimum number of threads always kept alive
+server.tomcat.min-Spare-Threads=25
+#The number of milliseconds before an idle thread shutsdown, unless the number of active threads are less or equal to minSpareThreads
+server.tomcat.max-idle-time=60000
+
+#for changing the tomcat port...
+#server.port=8081
+
+
+
+#Servlet context parameters
+server.context_parameters.p-name=value #context parameter with p-name as key and value as value.
+
+# make this true for AAF authentication and place cadi.properties into etc folder
+aaf.enabled=true
+
+# set to true to enable version proxy
+#ivp.enabled=false
+
+spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS = false
+
+
+logging.level.org.springframework.web=INFO
+logging.level.org.hibernate.SQL=warn
+logging.level.org.hibernate.type.descriptor.sql=debug
+
+
+blueprints.load.initial-data=true
+blueprints.load.path=load
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/src/test/resources/enhance/enhance-template.json b/ms/controllerblueprints/modules/service/src/test/resources/enhance/enhance-template.json
new file mode 100644 (file)
index 0000000..8b4fd9d
--- /dev/null
@@ -0,0 +1,345 @@
+{\r
+  "metadata": {\r
+    "template_author": "Brinda Santh",\r
+    "template_name": "enhance-template",\r
+    "template_version": "1.0.0",\r
+    "service-type": "Sample Service",\r
+    "release": "1806",\r
+    "vnf-type": "VPE"\r
+  },\r
+  "topology_template": {\r
+    "inputs": {\r
+      "request-id": {\r
+        "required": true,\r
+        "type": "string"\r
+      },\r
+      "service-instance-id": {\r
+        "required": true,\r
+        "type": "string"\r
+      },\r
+      "scope-type": {\r
+        "required": true,\r
+        "type": "string"\r
+      },\r
+      "action-name": {\r
+        "required": true,\r
+        "type": "string"\r
+      },\r
+      "hostname": {\r
+        "required": true,\r
+        "type": "string"\r
+      }\r
+    },\r
+    "node_templates": {\r
+      "vpe-netconf-device": {\r
+        "capabilities": {\r
+          "netconf": {\r
+            "properties": {\r
+              "login-key": "sdnc",\r
+              "login-account": "sndc-local",\r
+              "source": "local",\r
+              "target-ip-address": "{\"get_attribute\":\"lo0-local-ipv4-address\"}",\r
+              "port-number": 22,\r
+              "connection-time-out": 30\r
+            }\r
+          }\r
+        },\r
+        "type": "vnf-netconf-device"\r
+      },\r
+      "activate-netconf-component": {\r
+        "capabilities": {\r
+          "component-node": {}\r
+        },\r
+        "requirements": {\r
+          "netconf-connection": {\r
+            "capability": "netconf",\r
+            "node": "vpe-netconf-device",\r
+            "relationship": "tosca.relationships.ConnectsTo"\r
+          }\r
+        },\r
+        "interfaces": {\r
+          "org-openecomp-sdnc-netconf-adaptor-service-NetconfExecutorNode": {\r
+            "operations": {\r
+              "process": {\r
+                "inputs": {\r
+                  "action-name": "{ \"get_input\" : \"action-name\" }",\r
+                  "template_name": "{ \"get_attribute\" : \"template_name\" }",\r
+                  "service-template-version": "{ \"get_attribute\" : \"service-template-version\" }",\r
+                  "resource-type": "vnf-type",\r
+                  "request-id": "{ \"get_input\" : \"request-id\" }",\r
+                  "resource-id": "{ \"get_input\" : \"hostname\" }",\r
+                  "execution-script": "execution-script"\r
+                },\r
+                "outputs": {\r
+                  "response-data": "{ \"get_attribute\" : \"netconf-executor-baseconfig.response-data\" }",\r
+                  "status": "{ \"get_attribute\" : \"netconf-executor-baseconfig.status\" }"\r
+                },\r
+                "implementation" : {\r
+                  "primary" : "file://netconf_adaptor/DefaultBaseLicenceConfig.py"\r
+                }\r
+              }\r
+            }\r
+          }\r
+        },\r
+        "type": "component-netconf-executor"\r
+      },\r
+      "resource-assignment-ra-component": {\r
+        "capabilities": {\r
+          "component-node": {}\r
+        },\r
+        "interfaces": {\r
+          "org-openecomp-sdnc-config-assignment-service-ConfigAssignmentNode": {\r
+            "operations": {\r
+              "process": {\r
+                "inputs": {\r
+                  "template-names": [\r
+                    "base-config-template",\r
+                    "licence-template"\r
+                  ],\r
+                  "action-name": "{ \"get_input\" : \"action-name\" }",\r
+                  "service-template-name": "{ \"get_attribute\" : \"template_name\" }",\r
+                  "service-template-version": "{ \"get_attribute\" : \"service-template-version\" }",\r
+                  "resource-type": "vnf-type",\r
+                  "request-id": "{ \"get_input\" : \"request-id\" }",\r
+                  "resource-id": "{ \"get_input\" : \"hostname\" }"\r
+                },\r
+                "outputs": {\r
+                  "resource-assignment-params": "success",\r
+                  "status": "status"\r
+                }\r
+              }\r
+            }\r
+          }\r
+        },\r
+        "type": "component-resource-assignment"\r
+      },\r
+      "resource-assignment-action": {\r
+        "properties": {\r
+          "mode": "sync",\r
+          "version": "LATEST",\r
+          "is-start-flow": "false"\r
+        },\r
+        "requirements": {\r
+          "component-dependency": {\r
+            "capability": "component-node",\r
+            "node": "resource-assignment-ra-component",\r
+            "relationship": "tosca.relationships.DependsOn"\r
+          }\r
+        },\r
+        "capabilities": {\r
+          "dg-node": {},\r
+          "content": {\r
+            "properties": {\r
+              "type": "json"\r
+            }\r
+          }\r
+        },\r
+        "interfaces": {\r
+          "CONFIG": {\r
+            "operations": {\r
+              "ResourceAssignment": {\r
+                "inputs": {\r
+                  "params": []\r
+                }\r
+              }\r
+            }\r
+          }\r
+        },\r
+        "type": "dg-resource-assignment"\r
+      },\r
+      "activate-action": {\r
+        "properties": {\r
+          "mode": "sync",\r
+          "version": "LATEST",\r
+          "is-start-flow": "false"\r
+        },\r
+        "requirements": {\r
+          "component-dependency": {\r
+            "capability": "component-node",\r
+            "node": "activate-netconf-component",\r
+            "relationship": "tosca.relationships.DependsOn"\r
+          }\r
+        },\r
+        "capabilities": {\r
+          "dg-node": {},\r
+          "content": {\r
+            "properties": {\r
+              "type": "json"\r
+            }\r
+          }\r
+        },\r
+        "interfaces": {\r
+          "CONFIG": {\r
+            "operations": {\r
+              "ActivateNetconf": {\r
+                "inputs": {\r
+                  "params": []\r
+                }\r
+              }\r
+            }\r
+          }\r
+        },\r
+        "type": "dg-activate-netconf"\r
+      },\r
+      "base-config-template": {\r
+        "capabilities": {\r
+          "content": {\r
+            "properties": {\r
+              "content": "db://base-config-template"\r
+            }\r
+          },\r
+          "mapping": {\r
+            "properties": {\r
+              "mapping": [\r
+                {\r
+                  "name": "bundle-mac",\r
+                  "property": {\r
+                    "description": "",\r
+                    "required": true,\r
+                    "type": "string",\r
+                    "status": "",\r
+                    "constraints": [\r
+                      {}\r
+                    ],\r
+                    "entry_schema": {\r
+                      "type": ""\r
+                    }\r
+                  },\r
+                  "input-param": false,\r
+                  "dictionary-name": "bundle-mac",\r
+                  "dictionary-source": "db",\r
+                  "dependencies": [\r
+                    "hostname"\r
+                  ],\r
+                  "version": 0\r
+                },\r
+                {\r
+                  "name": "wan-aggregate-ipv4-addresses",\r
+                  "property": {\r
+                    "description": "",\r
+                    "required": true,\r
+                    "type": "list",\r
+                    "status": "",\r
+                    "constraints": [\r
+                      {}\r
+                    ],\r
+                    "entry_schema": {\r
+                      "type": "dt-v4-aggregate"\r
+                    }\r
+                  },\r
+                  "input-param": false,\r
+                  "dictionary-name": "wan-aggregate-ipv4-addresses",\r
+                  "dictionary-source": "mdsal",\r
+                  "dependencies": [\r
+                    "service-instance-id",\r
+                    "oam-network-role",\r
+                    "oam-v4-ip-type ",\r
+                    "oam-vm-type"\r
+                  ],\r
+                  "version": 0\r
+                },\r
+                {\r
+                  "name": "hostname",\r
+                  "property": {\r
+                    "required": true,\r
+                    "type": "string"\r
+                  },\r
+                  "dictionary-name": "hostname",\r
+                  "dictionary-source": "input",\r
+                  "version": 0,\r
+                  "input-param": false\r
+                },\r
+                {\r
+                  "name": "service",\r
+                  "property": {\r
+                    "required": true,\r
+                    "type": "string"\r
+                  },\r
+                  "dictionary-name": "service",\r
+                  "dictionary-source": "input",\r
+                  "version": 0,\r
+                  "input-param": false\r
+                },\r
+                {\r
+                  "name": "service-instance-id",\r
+                  "property": {\r
+                    "required": true,\r
+                    "type": "string"\r
+                  },\r
+                  "dictionary-name": "service-instance-id",\r
+                  "dictionary-source": "input",\r
+                  "version": 0,\r
+                  "input-param": false\r
+                }\r
+              ]\r
+            }\r
+          }\r
+        },\r
+        "properties": {\r
+          "action-names": [\r
+            "resource-assignment-action"\r
+          ]\r
+        },\r
+        "type": "artifact-config-template"\r
+      },\r
+      "licence-template": {\r
+        "capabilities": {\r
+          "content": {\r
+            "properties": {\r
+              "content": "db://licence-template"\r
+            }\r
+          },\r
+          "mapping": {\r
+            "properties": {\r
+              "mapping": [\r
+                {\r
+                  "name": "licenses",\r
+                  "property": {\r
+                    "description": "",\r
+                    "required": true,\r
+                    "type": "list",\r
+                    "status": "",\r
+                    "constraints": [\r
+                      {}\r
+                    ],\r
+                    "entry_schema": {\r
+                      "type": "dt-license-key"\r
+                    }\r
+                  },\r
+                  "input-param": false,\r
+                  "dictionary-name": "licenses",\r
+                  "dictionary-source": "mdsal",\r
+                  "dependencies": [\r
+                    "service-instance-id"\r
+                  ],\r
+                  "version": 0\r
+                },\r
+                {\r
+                  "name": "service-instance-id",\r
+                  "property": {\r
+                    "required": true,\r
+                    "type": "string"\r
+                  },\r
+                  "dictionary-name": "service-instance-id",\r
+                  "dictionary-source": "input",\r
+                  "version": 0,\r
+                  "input-param": false\r
+                }\r
+              ]\r
+            }\r
+          }\r
+        },\r
+        "properties": {\r
+          "action-names": [\r
+            "resource-assignment-action"\r
+          ]\r
+        },\r
+        "type": "artifact-config-template"\r
+      }\r
+    }\r
+  },\r
+  "node_types": {\r
+  },\r
+  "data_types": {\r
+  }\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/src/test/resources/enhance/enhanced-template.json b/ms/controllerblueprints/modules/service/src/test/resources/enhance/enhanced-template.json
new file mode 100644 (file)
index 0000000..18f4992
--- /dev/null
@@ -0,0 +1,824 @@
+{\r
+  "metadata" : {\r
+    "template_author" : "Brinda Santh",\r
+    "template_name" : "enhance-template",\r
+    "template_version" : "1.0.0",\r
+    "service-type" : "Sample Service",\r
+    "release" : "1806",\r
+    "vnf-type" : "VPE"\r
+  },\r
+  "tosca_definitions_version" : "controller_blueprint_1_0_0",\r
+  "artifact_types" : { },\r
+  "data_types" : {\r
+    "dt-v4-aggregate" : {\r
+      "description" : "This is dt-v4-aggregate Data Type",\r
+      "version" : "1.0.0",\r
+      "properties" : {\r
+        "ipv4-address" : {\r
+          "required" : true,\r
+          "type" : "string"\r
+        },\r
+        "ipv4-plen" : {\r
+          "required" : false,\r
+          "type" : "integer"\r
+        }\r
+      },\r
+      "derived_from" : "tosca.datatypes.Root"\r
+    },\r
+    "dt-license-key" : {\r
+      "description" : "This is dt-plicense-key Data Type",\r
+      "version" : "1.0.0",\r
+      "properties" : {\r
+        "license-key" : {\r
+          "required" : true,\r
+          "type" : "string"\r
+        }\r
+      },\r
+      "derived_from" : "tosca.datatypes.Root"\r
+    },\r
+    "datatype-resource-assignment" : {\r
+      "description" : "This is Resource Assignment Data Type",\r
+      "version" : "1.0.0",\r
+      "properties" : {\r
+        "property" : {\r
+          "required" : true,\r
+          "type" : "datatype-property"\r
+        },\r
+        "input-param" : {\r
+          "required" : true,\r
+          "type" : "boolean"\r
+        },\r
+        "dictionary-name" : {\r
+          "required" : false,\r
+          "type" : "string"\r
+        },\r
+        "dictionary-source" : {\r
+          "required" : false,\r
+          "type" : "string"\r
+        },\r
+        "dependencies" : {\r
+          "required" : true,\r
+          "type" : "list",\r
+          "entry_schema" : {\r
+            "type" : "string"\r
+          }\r
+        },\r
+        "status" : {\r
+          "required" : false,\r
+          "type" : "string"\r
+        },\r
+        "message" : {\r
+          "required" : false,\r
+          "type" : "string"\r
+        },\r
+        "updated-date" : {\r
+          "required" : false,\r
+          "type" : "string"\r
+        },\r
+        "updated-by" : {\r
+          "required" : false,\r
+          "type" : "string"\r
+        }\r
+      },\r
+      "derived_from" : "tosca.datatypes.Root"\r
+    },\r
+    "datatype-property" : {\r
+      "description" : "This is Entry point Input Data Type, which is dynamic datatype, The parameter names will be populated during the Design time for each inputs",\r
+      "version" : "1.0.0",\r
+      "properties" : {\r
+        "type" : {\r
+          "required" : true,\r
+          "type" : "string"\r
+        },\r
+        "description" : {\r
+          "required" : false,\r
+          "type" : "string"\r
+        },\r
+        "required" : {\r
+          "required" : false,\r
+          "type" : "boolean"\r
+        },\r
+        "default" : {\r
+          "required" : false,\r
+          "type" : "string"\r
+        },\r
+        "entry_schema" : {\r
+          "required" : false,\r
+          "type" : "string"\r
+        }\r
+      },\r
+      "derived_from" : "tosca.datatypes.Root"\r
+    },\r
+    "dt-resource-assignment-request" : {\r
+      "description" : "This is Dynamic Data type definition generated from resource mapping for the config template name base-config-template.",\r
+      "version" : "1.0.0",\r
+      "properties" : {\r
+        "bundle-mac" : {\r
+          "description" : "",\r
+          "required" : true,\r
+          "type" : "string",\r
+          "status" : "",\r
+          "constraints" : [ { } ],\r
+          "entry_schema" : {\r
+            "type" : ""\r
+          }\r
+        },\r
+        "hostname" : {\r
+          "required" : true,\r
+          "type" : "string"\r
+        },\r
+        "licenses" : {\r
+          "description" : "",\r
+          "required" : true,\r
+          "type" : "list",\r
+          "status" : "",\r
+          "constraints" : [ { } ],\r
+          "entry_schema" : {\r
+            "type" : "dt-license-key"\r
+          }\r
+        },\r
+        "wan-aggregate-ipv4-addresses" : {\r
+          "description" : "",\r
+          "required" : true,\r
+          "type" : "list",\r
+          "status" : "",\r
+          "constraints" : [ { } ],\r
+          "entry_schema" : {\r
+            "type" : "dt-v4-aggregate"\r
+          }\r
+        },\r
+        "service" : {\r
+          "required" : true,\r
+          "type" : "string"\r
+        },\r
+        "service-instance-id" : {\r
+          "required" : true,\r
+          "type" : "string"\r
+        }\r
+      },\r
+      "derived_from" : "tosca.datatypes.Dynamic"\r
+    }\r
+  },\r
+  "node_types" : {\r
+    "dg-resource-assignment" : {\r
+      "description" : "This is Resource Assignment Directed Graph",\r
+      "version" : "1.0.0",\r
+      "properties" : {\r
+        "mode" : {\r
+          "required" : false,\r
+          "type" : "string",\r
+          "default" : "sync"\r
+        },\r
+        "version" : {\r
+          "required" : false,\r
+          "type" : "string",\r
+          "default" : "LATEST"\r
+        },\r
+        "is-start-flow" : {\r
+          "required" : false,\r
+          "type" : "boolean",\r
+          "default" : "false"\r
+        }\r
+      },\r
+      "capabilities" : {\r
+        "dg-node" : {\r
+          "type" : "tosca.capabilities.Node"\r
+        },\r
+        "content" : {\r
+          "type" : "tosca.capability.Content",\r
+          "properties" : {\r
+            "type" : {\r
+              "required" : false,\r
+              "type" : "string",\r
+              "default" : "json"\r
+            },\r
+            "content" : {\r
+              "required" : false,\r
+              "type" : "string"\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "requirements" : {\r
+        "component-dependency" : {\r
+          "capability" : "component-node",\r
+          "node" : "component-resource-assignment",\r
+          "relationship" : "tosca.relationships.DependsOn"\r
+        }\r
+      },\r
+      "interfaces" : {\r
+        "CONFIG" : {\r
+          "operations" : {\r
+            "ResourceAssignment" : {\r
+              "inputs" : {\r
+                "params" : {\r
+                  "required" : false,\r
+                  "type" : "list",\r
+                  "entry_schema" : {\r
+                    "type" : "datatype-property"\r
+                  }\r
+                }\r
+              }\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "derived_from" : "tosca.nodes.DG"\r
+    },\r
+    "component-resource-assignment" : {\r
+      "description" : "This is Resource Assignment Component API",\r
+      "version" : "1.0.0",\r
+      "capabilities" : {\r
+        "component-node" : {\r
+          "type" : "tosca.capabilities.Node"\r
+        }\r
+      },\r
+      "interfaces" : {\r
+        "org-openecomp-sdnc-config-assignment-service-ConfigAssignmentNode" : {\r
+          "operations" : {\r
+            "process" : {\r
+              "inputs" : {\r
+                "service-template-name" : {\r
+                  "description" : "Service Template Name.",\r
+                  "required" : true,\r
+                  "type" : "string"\r
+                },\r
+                "service-template-version" : {\r
+                  "description" : "Service Template Version.",\r
+                  "required" : true,\r
+                  "type" : "string"\r
+                },\r
+                "resource-type" : {\r
+                  "description" : "Request type.",\r
+                  "required" : true,\r
+                  "type" : "string"\r
+                },\r
+                "template-names" : {\r
+                  "description" : "Name of the artifact Node Templates, to get the template Content.",\r
+                  "required" : true,\r
+                  "type" : "list",\r
+                  "entry_schema" : {\r
+                    "type" : "string"\r
+                  }\r
+                },\r
+                "request-id" : {\r
+                  "description" : "Request Id, Unique Id for the request.",\r
+                  "required" : true,\r
+                  "type" : "string"\r
+                },\r
+                "resource-id" : {\r
+                  "description" : "Resource Id.",\r
+                  "required" : true,\r
+                  "type" : "string"\r
+                },\r
+                "action-name" : {\r
+                  "description" : "Action Name of the process",\r
+                  "required" : true,\r
+                  "type" : "string"\r
+                }\r
+              },\r
+              "outputs" : {\r
+                "resource-assignment-params" : {\r
+                  "required" : true,\r
+                  "type" : "string"\r
+                },\r
+                "status" : {\r
+                  "required" : true,\r
+                  "type" : "string"\r
+                }\r
+              }\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "derived_from" : "tosca.nodes.Component"\r
+    },\r
+    "artifact-config-template" : {\r
+      "description" : "This is Configuration Velocity Template",\r
+      "version" : "1.0.0",\r
+      "properties" : {\r
+        "action-names" : {\r
+          "required" : true,\r
+          "type" : "list",\r
+          "entry_schema" : {\r
+            "type" : "string"\r
+          }\r
+        }\r
+      },\r
+      "capabilities" : {\r
+        "content" : {\r
+          "type" : "tosca.capability.Content",\r
+          "properties" : {\r
+            "content" : {\r
+              "required" : true,\r
+              "type" : "string"\r
+            }\r
+          }\r
+        },\r
+        "mapping" : {\r
+          "type" : "tosca.capability.Mapping",\r
+          "properties" : {\r
+            "mapping" : {\r
+              "required" : false,\r
+              "type" : "list",\r
+              "entry_schema" : {\r
+                "type" : "datatype-resource-assignment"\r
+              }\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "derived_from" : "tosca.nodes.Artifact"\r
+    },\r
+    "vnf-netconf-device" : {\r
+      "description" : "This is VNF Device with Netconf  Capability",\r
+      "version" : "1.0.0",\r
+      "capabilities" : {\r
+        "netconf" : {\r
+          "type" : "tosca.capability.Netconf",\r
+          "properties" : {\r
+            "login-key" : {\r
+              "required" : true,\r
+              "type" : "string",\r
+              "default" : "sdnc"\r
+            },\r
+            "login-account" : {\r
+              "required" : true,\r
+              "type" : "string",\r
+              "default" : "sdnc-tacacs"\r
+            },\r
+            "source" : {\r
+              "required" : true,\r
+              "type" : "string",\r
+              "default" : "npm"\r
+            },\r
+            "target-ip-address" : {\r
+              "required" : true,\r
+              "type" : "string"\r
+            },\r
+            "port-number" : {\r
+              "required" : true,\r
+              "type" : "integer",\r
+              "default" : 830\r
+            },\r
+            "connection-time-out" : {\r
+              "required" : false,\r
+              "type" : "integer",\r
+              "default" : 30\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "derived_from" : "tosca.nodes.Vnf"\r
+    },\r
+    "component-netconf-executor" : {\r
+      "description" : "This is Netconf Transaction Configuration Component API",\r
+      "version" : "1.0.0",\r
+      "capabilities" : {\r
+        "component-node" : {\r
+          "type" : "tosca.capabilities.Node"\r
+        }\r
+      },\r
+      "requirements" : {\r
+        "netconf-connection" : {\r
+          "capability" : "netconf",\r
+          "node" : "vnf-netconf-device",\r
+          "relationship" : "tosca.relationships.ConnectsTo"\r
+        }\r
+      },\r
+      "interfaces" : {\r
+        "org-openecomp-sdnc-netconf-adaptor-service-NetconfExecutorNode" : {\r
+          "operations" : {\r
+            "process" : {\r
+              "inputs" : {\r
+                "request-id" : {\r
+                  "description" : "Request Id used to store the generated configuration, in the database along with the template-name",\r
+                  "required" : true,\r
+                  "type" : "string"\r
+                },\r
+                "service-template-name" : {\r
+                  "description" : "Service Template Name",\r
+                  "required" : true,\r
+                  "type" : "string"\r
+                },\r
+                "service-template-version" : {\r
+                  "description" : "Service Template Version",\r
+                  "required" : true,\r
+                  "type" : "string"\r
+                },\r
+                "action-name" : {\r
+                  "description" : "Action Name to get from Database, Either (message & mask-info ) or ( resource-id & resource-type & action-name & template-name ) should be present. Message will be given higest priority",\r
+                  "required" : false,\r
+                  "type" : "string"\r
+                },\r
+                "resource-type" : {\r
+                  "description" : "Resource Type to get from Database, Either (message & mask-info ) or( resource-id & resource-type & action-name & template-name ) should be present. Message will be given higest priority",\r
+                  "required" : false,\r
+                  "type" : "string"\r
+                },\r
+                "resource-id" : {\r
+                  "description" : "Resource Id to get from Database, Either (message & mask-info ) or ( resource-id & resource-type & action-name & template-name ) should be present. Message will be given higest priority",\r
+                  "required" : false,\r
+                  "type" : "string"\r
+                },\r
+                "reservation-id" : {\r
+                  "description" : "Reservation Id used to send to NPM",\r
+                  "required" : false,\r
+                  "type" : "string"\r
+                },\r
+                "execution-script" : {\r
+                  "description" : "Python Script to Execute for this Component action, It should refer any one of Prython Artifact Definition for this Node Template.",\r
+                  "required" : true,\r
+                  "type" : "string"\r
+                }\r
+              },\r
+              "outputs" : {\r
+                "response-data" : {\r
+                  "description" : "Execution Response Data in JSON format.",\r
+                  "required" : false,\r
+                  "type" : "string"\r
+                },\r
+                "status" : {\r
+                  "description" : "Status of the Component Execution ( success or failure )",\r
+                  "required" : true,\r
+                  "type" : "string"\r
+                }\r
+              }\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "derived_from" : "tosca.nodes.Component"\r
+    },\r
+    "dg-activate-netconf" : {\r
+      "description" : "This is Download Netconf Directed Graph",\r
+      "version" : "1.0.0",\r
+      "properties" : {\r
+        "mode" : {\r
+          "required" : false,\r
+          "type" : "string",\r
+          "default" : "sync"\r
+        },\r
+        "version" : {\r
+          "required" : false,\r
+          "type" : "string",\r
+          "default" : "LATEST"\r
+        },\r
+        "is-start-flow" : {\r
+          "required" : false,\r
+          "type" : "boolean",\r
+          "default" : "false"\r
+        }\r
+      },\r
+      "capabilities" : {\r
+        "dg-node" : {\r
+          "type" : "tosca.capabilities.Node"\r
+        },\r
+        "content" : {\r
+          "type" : "tosca.capability.Content",\r
+          "properties" : {\r
+            "type" : {\r
+              "required" : false,\r
+              "type" : "string",\r
+              "default" : "json"\r
+            },\r
+            "content" : {\r
+              "required" : true,\r
+              "type" : "string"\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "requirements" : {\r
+        "component-dependency" : {\r
+          "capability" : "component-node",\r
+          "node" : "component-netconf-executor",\r
+          "relationship" : "tosca.relationships.DependsOn"\r
+        }\r
+      },\r
+      "interfaces" : {\r
+        "CONFIG" : {\r
+          "operations" : {\r
+            "ActivateNetconf" : {\r
+              "inputs" : {\r
+                "params" : {\r
+                  "required" : false,\r
+                  "type" : "list",\r
+                  "entry_schema" : {\r
+                    "type" : "datatype-property"\r
+                  }\r
+                }\r
+              }\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "derived_from" : "tosca.nodes.DG"\r
+    }\r
+  },\r
+  "topology_template" : {\r
+    "inputs" : {\r
+      "request-id" : {\r
+        "required" : true,\r
+        "type" : "string"\r
+      },\r
+      "service-instance-id" : {\r
+        "required" : true,\r
+        "type" : "string"\r
+      },\r
+      "scope-type" : {\r
+        "required" : true,\r
+        "type" : "string"\r
+      },\r
+      "action-name" : {\r
+        "required" : true,\r
+        "type" : "string"\r
+      },\r
+      "hostname" : {\r
+        "required" : true,\r
+        "type" : "string"\r
+      },\r
+      "resource-assignment-request" : {\r
+        "description" : "This is Dynamic Data type for the receipe resource-assignment-action.",\r
+        "required" : false,\r
+        "type" : "dt-resource-assignment-request"\r
+      }\r
+    },\r
+    "node_templates" : {\r
+      "vpe-netconf-device" : {\r
+        "type" : "vnf-netconf-device",\r
+        "capabilities" : {\r
+          "netconf" : {\r
+            "properties" : {\r
+              "login-key" : "sdnc",\r
+              "login-account" : "sndc-local",\r
+              "source" : "local",\r
+              "target-ip-address" : "{\"get_attribute\":\"lo0-local-ipv4-address\"}",\r
+              "port-number" : 22,\r
+              "connection-time-out" : 30\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "activate-netconf-component" : {\r
+        "type" : "component-netconf-executor",\r
+        "capabilities" : {\r
+          "component-node" : { }\r
+        },\r
+        "requirements" : {\r
+          "netconf-connection" : {\r
+            "capability" : "netconf",\r
+            "node" : "vpe-netconf-device",\r
+            "relationship" : "tosca.relationships.ConnectsTo"\r
+          }\r
+        },\r
+        "interfaces" : {\r
+          "org-openecomp-sdnc-netconf-adaptor-service-NetconfExecutorNode" : {\r
+            "operations" : {\r
+              "process" : {\r
+                "implementation" : {\r
+                  "primary" : "file://netconf_adaptor/DefaultBaseLicenceConfig.py"\r
+                },\r
+                "inputs" : {\r
+                  "action-name" : "{ \"get_input\" : \"action-name\" }",\r
+                  "template_name" : "{ \"get_attribute\" : \"template_name\" }",\r
+                  "service-template-version" : "{ \"get_attribute\" : \"service-template-version\" }",\r
+                  "resource-type" : "vnf-type",\r
+                  "request-id" : "{ \"get_input\" : \"request-id\" }",\r
+                  "resource-id" : "{ \"get_input\" : \"hostname\" }",\r
+                  "execution-script" : "execution-script"\r
+                },\r
+                "outputs" : {\r
+                  "response-data" : "{ \"get_attribute\" : \"netconf-executor-baseconfig.response-data\" }",\r
+                  "status" : "{ \"get_attribute\" : \"netconf-executor-baseconfig.status\" }"\r
+                }\r
+              }\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "resource-assignment-ra-component" : {\r
+        "type" : "component-resource-assignment",\r
+        "capabilities" : {\r
+          "component-node" : { }\r
+        },\r
+        "interfaces" : {\r
+          "org-openecomp-sdnc-config-assignment-service-ConfigAssignmentNode" : {\r
+            "operations" : {\r
+              "process" : {\r
+                "inputs" : {\r
+                  "template-names" : [ "base-config-template", "licence-template" ],\r
+                  "action-name" : "{ \"get_input\" : \"action-name\" }",\r
+                  "service-template-name" : "{ \"get_attribute\" : \"template_name\" }",\r
+                  "service-template-version" : "{ \"get_attribute\" : \"service-template-version\" }",\r
+                  "resource-type" : "vnf-type",\r
+                  "request-id" : "{ \"get_input\" : \"request-id\" }",\r
+                  "resource-id" : "{ \"get_input\" : \"hostname\" }"\r
+                },\r
+                "outputs" : {\r
+                  "resource-assignment-params" : "success",\r
+                  "status" : "status"\r
+                }\r
+              }\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "resource-assignment-action" : {\r
+        "type" : "dg-resource-assignment",\r
+        "properties" : {\r
+          "mode" : "sync",\r
+          "version" : "LATEST",\r
+          "is-start-flow" : "false"\r
+        },\r
+        "capabilities" : {\r
+          "dg-node" : { },\r
+          "content" : {\r
+            "properties" : {\r
+              "type" : "json"\r
+            }\r
+          }\r
+        },\r
+        "requirements" : {\r
+          "component-dependency" : {\r
+            "capability" : "component-node",\r
+            "node" : "resource-assignment-ra-component",\r
+            "relationship" : "tosca.relationships.DependsOn"\r
+          }\r
+        },\r
+        "interfaces" : {\r
+          "CONFIG" : {\r
+            "operations" : {\r
+              "ResourceAssignment" : {\r
+                "inputs" : {\r
+                  "params" : [ ]\r
+                }\r
+              }\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "activate-action" : {\r
+        "type" : "dg-activate-netconf",\r
+        "properties" : {\r
+          "mode" : "sync",\r
+          "version" : "LATEST",\r
+          "is-start-flow" : "false"\r
+        },\r
+        "capabilities" : {\r
+          "dg-node" : { },\r
+          "content" : {\r
+            "properties" : {\r
+              "type" : "json"\r
+            }\r
+          }\r
+        },\r
+        "requirements" : {\r
+          "component-dependency" : {\r
+            "capability" : "component-node",\r
+            "node" : "activate-netconf-component",\r
+            "relationship" : "tosca.relationships.DependsOn"\r
+          }\r
+        },\r
+        "interfaces" : {\r
+          "CONFIG" : {\r
+            "operations" : {\r
+              "ActivateNetconf" : {\r
+                "inputs" : {\r
+                  "params" : [ ]\r
+                }\r
+              }\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "base-config-template" : {\r
+        "type" : "artifact-config-template",\r
+        "properties" : {\r
+          "action-names" : [ "resource-assignment-action" ]\r
+        },\r
+        "capabilities" : {\r
+          "content" : {\r
+            "properties" : {\r
+              "content" : "db://base-config-template"\r
+            }\r
+          },\r
+          "mapping" : {\r
+            "properties" : {\r
+              "mapping" : [ {\r
+                "name" : "bundle-mac",\r
+                "property" : {\r
+                  "description" : "",\r
+                  "required" : true,\r
+                  "type" : "string",\r
+                  "status" : "",\r
+                  "constraints" : [ { } ],\r
+                  "entry_schema" : {\r
+                    "type" : ""\r
+                  }\r
+                },\r
+                "input-param" : false,\r
+                "dictionary-name" : "bundle-mac",\r
+                "dictionary-source" : "db",\r
+                "dependencies" : [ "hostname" ],\r
+                "version" : 0\r
+              }, {\r
+                "name" : "wan-aggregate-ipv4-addresses",\r
+                "property" : {\r
+                  "description" : "",\r
+                  "required" : true,\r
+                  "type" : "list",\r
+                  "status" : "",\r
+                  "constraints" : [ { } ],\r
+                  "entry_schema" : {\r
+                    "type" : "dt-v4-aggregate"\r
+                  }\r
+                },\r
+                "input-param" : false,\r
+                "dictionary-name" : "wan-aggregate-ipv4-addresses",\r
+                "dictionary-source" : "mdsal",\r
+                "dependencies" : [ "service-instance-id", "oam-network-role", "oam-v4-ip-type ", "oam-vm-type" ],\r
+                "version" : 0\r
+              }, {\r
+                "name" : "hostname",\r
+                "property" : {\r
+                  "required" : true,\r
+                  "type" : "string"\r
+                },\r
+                "dictionary-name" : "hostname",\r
+                "dictionary-source" : "input",\r
+                "version" : 0,\r
+                "input-param" : false\r
+              }, {\r
+                "name" : "service",\r
+                "property" : {\r
+                  "required" : true,\r
+                  "type" : "string"\r
+                },\r
+                "dictionary-name" : "service",\r
+                "dictionary-source" : "input",\r
+                "version" : 0,\r
+                "input-param" : false\r
+              }, {\r
+                "name" : "service-instance-id",\r
+                "property" : {\r
+                  "required" : true,\r
+                  "type" : "string"\r
+                },\r
+                "dictionary-name" : "service-instance-id",\r
+                "dictionary-source" : "input",\r
+                "version" : 0,\r
+                "input-param" : false\r
+              } ]\r
+            }\r
+          }\r
+        }\r
+      },\r
+      "licence-template" : {\r
+        "type" : "artifact-config-template",\r
+        "properties" : {\r
+          "action-names" : [ "resource-assignment-action" ]\r
+        },\r
+        "capabilities" : {\r
+          "content" : {\r
+            "properties" : {\r
+              "content" : "db://licence-template"\r
+            }\r
+          },\r
+          "mapping" : {\r
+            "properties" : {\r
+              "mapping" : [ {\r
+                "name" : "licenses",\r
+                "property" : {\r
+                  "description" : "",\r
+                  "required" : true,\r
+                  "type" : "list",\r
+                  "status" : "",\r
+                  "constraints" : [ { } ],\r
+                  "entry_schema" : {\r
+                    "type" : "dt-license-key"\r
+                  }\r
+                },\r
+                "input-param" : false,\r
+                "dictionary-name" : "licenses",\r
+                "dictionary-source" : "mdsal",\r
+                "dependencies" : [ "service-instance-id" ],\r
+                "version" : 0\r
+              }, {\r
+                "name" : "service-instance-id",\r
+                "property" : {\r
+                  "required" : true,\r
+                  "type" : "string"\r
+                },\r
+                "dictionary-name" : "service-instance-id",\r
+                "dictionary-source" : "input",\r
+                "version" : 0,\r
+                "input-param" : false\r
+              } ]\r
+            }\r
+          }\r
+        }\r
+      }\r
+    }\r
+  }\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/src/test/resources/resourcedictionary/automap.json b/ms/controllerblueprints/modules/service/src/test/resources/resourcedictionary/automap.json
new file mode 100644 (file)
index 0000000..a85e715
--- /dev/null
@@ -0,0 +1,11 @@
+[\r
+       {\r
+               "name": "action-name"\r
+       },\r
+       {\r
+               "name": "v4-ip-type"\r
+       },\r
+       {\r
+               "name": "bundle-id"\r
+       }\r
+]
\ No newline at end of file
diff --git a/ms/controllerblueprints/modules/service/src/test/resources/resourcedictionary/default_definition.json b/ms/controllerblueprints/modules/service/src/test/resources/resourcedictionary/default_definition.json
new file mode 100644 (file)
index 0000000..2b39205
--- /dev/null
@@ -0,0 +1,19 @@
+{\r
+       "name": "v4-aggregat-list",\r
+       "description": "This collection v4-aggregate list",\r
+       "valid-values": null,\r
+       "sample-value": null,\r
+       "updated-by": "Brinda Santh (bs2796)",\r
+       "resource-type": "ONAP",\r
+       "resource-path": "/v4-aggregat-list",\r
+       "data-type": "list",\r
+       "entry-schema": "dt-v4-aggregate",\r
+       "tags": null,\r
+       "default": null,\r
+       "source": {\r
+               "input": {\r
+                       \r
+               }\r
+       },\r
+       "candidate-dependency": null\r
+}
\ No newline at end of file
diff --git a/ms/controllerblueprints/parent/pom.xml b/ms/controllerblueprints/parent/pom.xml
new file mode 100644 (file)
index 0000000..0b19186
--- /dev/null
@@ -0,0 +1,228 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright © 2017-2018 AT&T Intellectual Property.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<project
+        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+        xmlns="http://maven.apache.org/POM/4.0.0"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.onap.ccsdk.apps</groupId>
+    <artifactId>controllerblueprints-parent</artifactId>
+    <name>Controller Blueprints Parent</name>
+    <version>0.3.0-SNAPSHOT</version>
+    <packaging>pom</packaging>
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <maven.compiler.target>1.8</maven.compiler.target>
+        <maven.compiler.source>1.8</maven.compiler.source>
+        <kotlin.version>1.2.51</kotlin.version>
+        <ajsc.version>200.4.2-RELEASE</ajsc.version>
+        <common.version>2.4.2-RELEASE</common.version>
+        <cadi.aaf.version>1.4.2</cadi.aaf.version>
+        <spring.boot.version>1.5.7.RELEASE</spring.boot.version>
+        <sdnc.config.version>20.0.1-SNAPSHOT</sdnc.config.version>
+    </properties>
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-dependencies</artifactId>
+                <version>${spring.boot.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+
+            <dependency>
+                <groupId>org.apache.commons</groupId>
+                <artifactId>commons-lang3</artifactId>
+                <version>3.2.1</version>
+            </dependency>
+            <dependency>
+                <groupId>commons-collections</groupId>
+                <artifactId>commons-collections</artifactId>
+                <version>3.2.2</version>
+            </dependency>
+            <dependency>
+                <groupId>commons-io</groupId>
+                <artifactId>commons-io</artifactId>
+                <version>2.6</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.velocity</groupId>
+                <artifactId>velocity</artifactId>
+                <version>1.7</version>
+            </dependency>
+            <dependency>
+                <groupId>org.json</groupId>
+                <artifactId>json</artifactId>
+                <version>20180130</version>
+            </dependency>
+            <dependency>
+                <groupId>com.google.guava</groupId>
+                <artifactId>guava</artifactId>
+                <version>25.1-jre</version>
+            </dependency>
+
+            <dependency>
+                <groupId>io.swagger</groupId>
+                <artifactId>swagger-jersey2-jaxrs</artifactId>
+                <version>1.5.20</version>
+                <exclusions>
+                    <exclusion>
+                        <groupId>org.glassfish.jersey.containers</groupId>
+                        <artifactId>*</artifactId>
+                    </exclusion>
+                    <exclusion>
+                        <groupId>org.glassfish.jersey.core</groupId>
+                        <artifactId>*</artifactId>
+                    </exclusion>
+                </exclusions>
+            </dependency>
+
+            <!-- Kotlin Dependencies -->
+            <dependency>
+                <groupId>org.jetbrains.kotlin</groupId>
+                <artifactId>kotlin-stdlib</artifactId>
+                <version>${kotlin.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.jetbrains.kotlin</groupId>
+                <artifactId>kotlin-reflect</artifactId>
+                <version>${kotlin.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.fasterxml.jackson.module</groupId>
+                <artifactId>jackson-module-kotlin</artifactId>
+                <version>2.9.6</version>
+            </dependency>
+            <dependency>
+                <groupId>org.jetbrains.kotlin</groupId>
+                <artifactId>kotlin-test</artifactId>
+                <version>${kotlin.version}</version>
+                <scope>test</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.onap.ccsdk.apps</groupId>
+                <artifactId>controllerblueprints-core</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.onap.ccsdk.apps</groupId>
+                <artifactId>controllerblueprints-service</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.onap.ccsdk.apps</groupId>
+                <artifactId>controllerblueprints-resource-dict</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.jetbrains.kotlin</groupId>
+            <artifactId>kotlin-stdlib</artifactId>
+        </dependency>
+    </dependencies>
+
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-source-plugin</artifactId>
+                <version>3.0.1</version>
+                <executions>
+                    <execution>
+                        <id>attach-sources</id>
+                        <goals>
+                            <goal>jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <artifactId>kotlin-maven-plugin</artifactId>
+                <groupId>org.jetbrains.kotlin</groupId>
+                <version>${kotlin.version}</version>
+                <executions>
+                    <execution>
+                        <id>compile</id>
+                        <goals>
+                            <goal>compile</goal>
+                        </goals>
+                        <configuration>
+                            <sourceDirs>
+                                <sourceDir>${project.basedir}/src/main/kotlin</sourceDir>
+                                <sourceDir>${project.basedir}/src/main/java</sourceDir>
+                            </sourceDirs>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>test-compile</id>
+                        <goals>
+                            <goal>test-compile</goal>
+                        </goals>
+                        <configuration>
+                            <sourceDirs>
+                                <sourceDir>${project.basedir}/src/test/kotlin</sourceDir>
+                                <sourceDir>${project.basedir}/src/test/java</sourceDir>
+                            </sourceDirs>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.5.1</version>
+                <configuration>
+                    <source>${maven.compiler.source}</source>
+                    <target>${maven.compiler.target}</target>
+                </configuration>
+                <executions>
+                    <!-- Replacing default-compile as it is treated specially by maven -->
+                    <execution>
+                        <id>default-compile</id>
+                        <phase>none</phase>
+                    </execution>
+                    <!-- Replacing default-testCompile as it is treated specially by maven -->
+                    <execution>
+                        <id>default-testCompile</id>
+                        <phase>none</phase>
+                    </execution>
+                    <execution>
+                        <id>java-compile</id>
+                        <phase>compile</phase>
+                        <goals>
+                            <goal>compile</goal>
+                        </goals>
+                    </execution>
+                    <execution>
+                        <id>java-test-compile</id>
+                        <phase>test-compile</phase>
+                        <goals>
+                            <goal>testCompile</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/ms/controllerblueprints/pom.xml b/ms/controllerblueprints/pom.xml
new file mode 100644 (file)
index 0000000..d76f4c8
--- /dev/null
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright © 2017-2018 AT&T Intellectual Property.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
+         xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <parent>
+        <groupId>org.onap.ccsdk.apps</groupId>
+        <artifactId>ccsdk-apps</artifactId>
+        <version>0.3.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.onap.ccsdk.apps</groupId>
+    <artifactId>controllerblueprints</artifactId>
+    <name>Controller Blueprints Root</name>
+    <version>0.3.0-SNAPSHOT</version>
+    <properties>
+        <service.name>ControllerBlueprints</service.name>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+    <packaging>pom</packaging>
+    <modules>
+        <module>parent</module>
+        <module>modules</module>
+        <module>application</module>
+    </modules>
+</project>
+
diff --git a/ms/controllerblueprints/repoproject.txt b/ms/controllerblueprints/repoproject.txt
new file mode 100644 (file)
index 0000000..91a5c8e
--- /dev/null
@@ -0,0 +1 @@
+ST_SDNCMS
diff --git a/ms/controllerblueprints/time.txt b/ms/controllerblueprints/time.txt
new file mode 100644 (file)
index 0000000..6ed29fb
--- /dev/null
@@ -0,0 +1 @@
+Current time : 17:38:06