velocious 1.0.428 → 1.0.430
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/build/src/application.d.ts +96 -9
- package/build/src/application.d.ts.map +1 -1
- package/build/src/application.js +127 -28
- package/build/src/authorization/ability.d.ts +72 -31
- package/build/src/authorization/ability.d.ts.map +1 -1
- package/build/src/authorization/ability.js +59 -22
- package/build/src/authorization/base-resource.d.ts +47 -20
- package/build/src/authorization/base-resource.d.ts.map +1 -1
- package/build/src/authorization/base-resource.js +43 -14
- package/build/src/background-jobs/client.d.ts +4 -2
- package/build/src/background-jobs/client.d.ts.map +1 -1
- package/build/src/background-jobs/client.js +4 -2
- package/build/src/background-jobs/cron-expression.d.ts +9 -5
- package/build/src/background-jobs/cron-expression.d.ts.map +1 -1
- package/build/src/background-jobs/cron-expression.js +16 -6
- package/build/src/background-jobs/forked-runner-child.js +12 -5
- package/build/src/background-jobs/job-registry.d.ts +7 -1
- package/build/src/background-jobs/job-registry.d.ts.map +1 -1
- package/build/src/background-jobs/job-registry.js +8 -2
- package/build/src/background-jobs/job-runner.d.ts +1 -0
- package/build/src/background-jobs/job-runner.d.ts.map +1 -1
- package/build/src/background-jobs/job-runner.js +8 -3
- package/build/src/background-jobs/job.d.ts +12 -8
- package/build/src/background-jobs/job.d.ts.map +1 -1
- package/build/src/background-jobs/job.js +12 -6
- package/build/src/background-jobs/json-socket.d.ts +17 -5
- package/build/src/background-jobs/json-socket.d.ts.map +1 -1
- package/build/src/background-jobs/json-socket.js +18 -6
- package/build/src/background-jobs/main.d.ts +118 -32
- package/build/src/background-jobs/main.d.ts.map +1 -1
- package/build/src/background-jobs/main.js +123 -35
- package/build/src/background-jobs/normalize-error.d.ts +2 -1
- package/build/src/background-jobs/normalize-error.d.ts.map +1 -1
- package/build/src/background-jobs/normalize-error.js +5 -3
- package/build/src/background-jobs/scheduler.d.ts +31 -10
- package/build/src/background-jobs/scheduler.d.ts.map +1 -1
- package/build/src/background-jobs/scheduler.js +33 -11
- package/build/src/background-jobs/socket-request.d.ts +2 -0
- package/build/src/background-jobs/socket-request.d.ts.map +1 -1
- package/build/src/background-jobs/socket-request.js +11 -3
- package/build/src/background-jobs/status-reporter.d.ts +5 -2
- package/build/src/background-jobs/status-reporter.d.ts.map +1 -1
- package/build/src/background-jobs/status-reporter.js +6 -3
- package/build/src/background-jobs/store.d.ts +57 -19
- package/build/src/background-jobs/store.d.ts.map +1 -1
- package/build/src/background-jobs/store.js +70 -20
- package/build/src/background-jobs/types.d.ts +7 -7
- package/build/src/background-jobs/types.d.ts.map +1 -1
- package/build/src/background-jobs/types.js +6 -6
- package/build/src/background-jobs/web/authorization.d.ts.map +1 -1
- package/build/src/background-jobs/web/authorization.js +3 -1
- package/build/src/background-jobs/web/controller.d.ts +40 -14
- package/build/src/background-jobs/web/controller.d.ts.map +1 -1
- package/build/src/background-jobs/web/controller.js +46 -15
- package/build/src/background-jobs/web/registry.d.ts +5 -0
- package/build/src/background-jobs/web/registry.d.ts.map +1 -1
- package/build/src/background-jobs/web/registry.js +4 -1
- package/build/src/background-jobs/worker.d.ts +41 -8
- package/build/src/background-jobs/worker.d.ts.map +1 -1
- package/build/src/background-jobs/worker.js +64 -16
- package/build/src/beacon/client.d.ts +39 -12
- package/build/src/beacon/client.d.ts.map +1 -1
- package/build/src/beacon/client.js +45 -15
- package/build/src/beacon/in-process-broker.d.ts +4 -0
- package/build/src/beacon/in-process-broker.d.ts.map +1 -1
- package/build/src/beacon/in-process-broker.js +8 -3
- package/build/src/beacon/in-process-client.d.ts +28 -9
- package/build/src/beacon/in-process-client.d.ts.map +1 -1
- package/build/src/beacon/in-process-client.js +27 -9
- package/build/src/beacon/server.d.ts +13 -2
- package/build/src/beacon/server.d.ts.map +1 -1
- package/build/src/beacon/server.js +21 -5
- package/build/src/beacon/types.d.ts +3 -3
- package/build/src/beacon/types.d.ts.map +1 -1
- package/build/src/beacon/types.js +2 -2
- package/build/src/cli/base-command.d.ts +18 -4
- package/build/src/cli/base-command.d.ts.map +1 -1
- package/build/src/cli/base-command.js +15 -4
- package/build/src/cli/browser-cli.d.ts +3 -0
- package/build/src/cli/browser-cli.d.ts.map +1 -1
- package/build/src/cli/browser-cli.js +7 -2
- package/build/src/cli/commands/background-jobs-main.d.ts +0 -1
- package/build/src/cli/commands/background-jobs-main.d.ts.map +1 -1
- package/build/src/cli/commands/background-jobs-runner.d.ts +0 -1
- package/build/src/cli/commands/background-jobs-runner.d.ts.map +1 -1
- package/build/src/cli/commands/background-jobs-worker.d.ts +0 -1
- package/build/src/cli/commands/background-jobs-worker.d.ts.map +1 -1
- package/build/src/cli/commands/beacon.d.ts +0 -1
- package/build/src/cli/commands/beacon.d.ts.map +1 -1
- package/build/src/cli/commands/console.d.ts +0 -2
- package/build/src/cli/commands/console.d.ts.map +1 -1
- package/build/src/cli/commands/console.js +5 -2
- package/build/src/cli/commands/db/base-command.d.ts +11 -2
- package/build/src/cli/commands/db/base-command.d.ts.map +1 -1
- package/build/src/cli/commands/db/base-command.js +12 -3
- package/build/src/cli/commands/db/create.d.ts +3 -0
- package/build/src/cli/commands/db/create.d.ts.map +1 -1
- package/build/src/cli/commands/db/create.js +4 -1
- package/build/src/cli/commands/db/drop.d.ts +3 -0
- package/build/src/cli/commands/db/drop.d.ts.map +1 -1
- package/build/src/cli/commands/db/drop.js +4 -1
- package/build/src/cli/commands/db/schema/dump.d.ts +0 -2
- package/build/src/cli/commands/db/schema/dump.d.ts.map +1 -1
- package/build/src/cli/commands/db/schema/dump.js +5 -2
- package/build/src/cli/commands/db/schema/load.d.ts +0 -2
- package/build/src/cli/commands/db/schema/load.d.ts.map +1 -1
- package/build/src/cli/commands/db/schema/load.js +5 -2
- package/build/src/cli/commands/db/seed.d.ts +0 -2
- package/build/src/cli/commands/db/seed.d.ts.map +1 -1
- package/build/src/cli/commands/db/seed.js +5 -2
- package/build/src/cli/commands/db/tenants/check.d.ts +4 -1
- package/build/src/cli/commands/db/tenants/check.d.ts.map +1 -1
- package/build/src/cli/commands/db/tenants/check.js +5 -2
- package/build/src/cli/commands/db/tenants/create.d.ts +4 -1
- package/build/src/cli/commands/db/tenants/create.d.ts.map +1 -1
- package/build/src/cli/commands/db/tenants/create.js +5 -2
- package/build/src/cli/commands/db/tenants/migrate.d.ts +4 -1
- package/build/src/cli/commands/db/tenants/migrate.d.ts.map +1 -1
- package/build/src/cli/commands/db/tenants/migrate.js +5 -2
- package/build/src/cli/commands/destroy/migration.d.ts +0 -1
- package/build/src/cli/commands/destroy/migration.d.ts.map +1 -1
- package/build/src/cli/commands/generate/base-models.d.ts +0 -1
- package/build/src/cli/commands/generate/base-models.d.ts.map +1 -1
- package/build/src/cli/commands/generate/frontend-models.d.ts +0 -2
- package/build/src/cli/commands/generate/frontend-models.d.ts.map +1 -1
- package/build/src/cli/commands/generate/frontend-models.js +5 -2
- package/build/src/cli/commands/generate/migration.d.ts +0 -1
- package/build/src/cli/commands/generate/migration.d.ts.map +1 -1
- package/build/src/cli/commands/generate/model.d.ts +0 -1
- package/build/src/cli/commands/generate/model.d.ts.map +1 -1
- package/build/src/cli/commands/init.d.ts +0 -1
- package/build/src/cli/commands/init.d.ts.map +1 -1
- package/build/src/cli/commands/routes.d.ts +0 -1
- package/build/src/cli/commands/routes.d.ts.map +1 -1
- package/build/src/cli/commands/run-script.d.ts +0 -2
- package/build/src/cli/commands/run-script.d.ts.map +1 -1
- package/build/src/cli/commands/run-script.js +5 -2
- package/build/src/cli/commands/runner.d.ts +0 -2
- package/build/src/cli/commands/runner.d.ts.map +1 -1
- package/build/src/cli/commands/runner.js +5 -2
- package/build/src/cli/commands/server.d.ts +0 -1
- package/build/src/cli/commands/server.d.ts.map +1 -1
- package/build/src/cli/commands/test.d.ts +0 -1
- package/build/src/cli/commands/test.d.ts.map +1 -1
- package/build/src/cli/index.d.ts +18 -5
- package/build/src/cli/index.d.ts.map +1 -1
- package/build/src/cli/index.js +25 -8
- package/build/src/cli/tenant-database-command-helper.d.ts +24 -9
- package/build/src/cli/tenant-database-command-helper.d.ts.map +1 -1
- package/build/src/cli/tenant-database-command-helper.js +30 -11
- package/build/src/cli/use-browser-cli.d.ts +1 -0
- package/build/src/cli/use-browser-cli.d.ts.map +1 -1
- package/build/src/cli/use-browser-cli.js +5 -2
- package/build/src/configuration-resolver.d.ts +1 -0
- package/build/src/configuration-resolver.d.ts.map +1 -1
- package/build/src/configuration-resolver.js +2 -1
- package/build/src/configuration-types.d.ts +44 -44
- package/build/src/configuration-types.d.ts.map +1 -1
- package/build/src/configuration-types.js +27 -27
- package/build/src/configuration.d.ts +350 -114
- package/build/src/configuration.d.ts.map +1 -1
- package/build/src/configuration.js +416 -128
- package/build/src/controller.d.ts +67 -18
- package/build/src/controller.d.ts.map +1 -1
- package/build/src/controller.js +88 -23
- package/build/src/current-configuration.d.ts +2 -0
- package/build/src/current-configuration.d.ts.map +1 -1
- package/build/src/current-configuration.js +6 -2
- package/build/src/current.d.ts +16 -9
- package/build/src/current.d.ts.map +1 -1
- package/build/src/current.js +15 -8
- package/build/src/database/annotations-async-hooks.js +13 -6
- package/build/src/database/annotations.d.ts +7 -1
- package/build/src/database/annotations.d.ts.map +1 -1
- package/build/src/database/annotations.js +12 -5
- package/build/src/database/drivers/base-column.d.ts +21 -3
- package/build/src/database/drivers/base-column.d.ts.map +1 -1
- package/build/src/database/drivers/base-column.js +21 -3
- package/build/src/database/drivers/base-columns-index.d.ts +9 -0
- package/build/src/database/drivers/base-columns-index.d.ts.map +1 -1
- package/build/src/database/drivers/base-columns-index.js +10 -1
- package/build/src/database/drivers/base-foreign-key.d.ts +15 -3
- package/build/src/database/drivers/base-foreign-key.d.ts.map +1 -1
- package/build/src/database/drivers/base-foreign-key.js +15 -3
- package/build/src/database/drivers/base-table.d.ts +16 -3
- package/build/src/database/drivers/base-table.d.ts.map +1 -1
- package/build/src/database/drivers/base-table.js +16 -3
- package/build/src/database/drivers/base.d.ts +174 -37
- package/build/src/database/drivers/base.d.ts.map +1 -1
- package/build/src/database/drivers/base.js +156 -40
- package/build/src/database/drivers/mssql/column.d.ts +3 -2
- package/build/src/database/drivers/mssql/column.d.ts.map +1 -1
- package/build/src/database/drivers/mssql/column.js +3 -2
- package/build/src/database/drivers/mssql/index.d.ts +5 -6
- package/build/src/database/drivers/mssql/index.d.ts.map +1 -1
- package/build/src/database/drivers/mssql/index.js +38 -7
- package/build/src/database/drivers/mssql/options.d.ts +1 -0
- package/build/src/database/drivers/mssql/options.d.ts.map +1 -1
- package/build/src/database/drivers/mssql/options.js +8 -2
- package/build/src/database/drivers/mssql/sql/create-database.d.ts +1 -0
- package/build/src/database/drivers/mssql/sql/create-database.d.ts.map +1 -1
- package/build/src/database/drivers/mssql/sql/create-database.js +2 -1
- package/build/src/database/drivers/mssql/sql/drop-database.d.ts.map +1 -1
- package/build/src/database/drivers/mssql/sql/drop-database.js +2 -1
- package/build/src/database/drivers/mssql/structure-sql.d.ts +5 -2
- package/build/src/database/drivers/mssql/structure-sql.d.ts.map +1 -1
- package/build/src/database/drivers/mssql/structure-sql.js +5 -2
- package/build/src/database/drivers/mssql/table.d.ts +1 -0
- package/build/src/database/drivers/mssql/table.d.ts.map +1 -1
- package/build/src/database/drivers/mssql/table.js +9 -4
- package/build/src/database/drivers/mysql/column.d.ts +3 -2
- package/build/src/database/drivers/mysql/column.d.ts.map +1 -1
- package/build/src/database/drivers/mysql/column.js +4 -3
- package/build/src/database/drivers/mysql/index.d.ts +11 -3
- package/build/src/database/drivers/mysql/index.d.ts.map +1 -1
- package/build/src/database/drivers/mysql/index.js +54 -10
- package/build/src/database/drivers/mysql/options.d.ts +1 -0
- package/build/src/database/drivers/mysql/options.d.ts.map +1 -1
- package/build/src/database/drivers/mysql/options.js +4 -2
- package/build/src/database/drivers/mysql/query.d.ts +3 -2
- package/build/src/database/drivers/mysql/query.d.ts.map +1 -1
- package/build/src/database/drivers/mysql/query.js +6 -3
- package/build/src/database/drivers/mysql/sql/create-database.d.ts.map +1 -1
- package/build/src/database/drivers/mysql/sql/create-database.js +3 -1
- package/build/src/database/drivers/mysql/structure-sql.d.ts +7 -2
- package/build/src/database/drivers/mysql/structure-sql.d.ts.map +1 -1
- package/build/src/database/drivers/mysql/structure-sql.js +7 -2
- package/build/src/database/drivers/mysql/table.d.ts +1 -0
- package/build/src/database/drivers/mysql/table.d.ts.map +1 -1
- package/build/src/database/drivers/mysql/table.js +7 -3
- package/build/src/database/drivers/pgsql/column.d.ts +3 -2
- package/build/src/database/drivers/pgsql/column.d.ts.map +1 -1
- package/build/src/database/drivers/pgsql/column.js +3 -2
- package/build/src/database/drivers/pgsql/index.d.ts +1 -1
- package/build/src/database/drivers/pgsql/index.d.ts.map +1 -1
- package/build/src/database/drivers/pgsql/index.js +36 -11
- package/build/src/database/drivers/pgsql/options.d.ts +2 -0
- package/build/src/database/drivers/pgsql/options.d.ts.map +1 -1
- package/build/src/database/drivers/pgsql/options.js +3 -1
- package/build/src/database/drivers/pgsql/structure-sql.d.ts +5 -2
- package/build/src/database/drivers/pgsql/structure-sql.d.ts.map +1 -1
- package/build/src/database/drivers/pgsql/structure-sql.js +5 -2
- package/build/src/database/drivers/pgsql/table.d.ts +1 -0
- package/build/src/database/drivers/pgsql/table.d.ts.map +1 -1
- package/build/src/database/drivers/pgsql/table.js +6 -2
- package/build/src/database/drivers/sqlite/base.d.ts +15 -5
- package/build/src/database/drivers/sqlite/base.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/base.js +79 -27
- package/build/src/database/drivers/sqlite/column.d.ts +3 -2
- package/build/src/database/drivers/sqlite/column.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/column.js +3 -2
- package/build/src/database/drivers/sqlite/connection-sql-js.d.ts +4 -2
- package/build/src/database/drivers/sqlite/connection-sql-js.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/connection-sql-js.js +4 -2
- package/build/src/database/drivers/sqlite/foreign-key.d.ts +3 -2
- package/build/src/database/drivers/sqlite/foreign-key.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/foreign-key.js +3 -2
- package/build/src/database/drivers/sqlite/index.d.ts +18 -5
- package/build/src/database/drivers/sqlite/index.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/index.js +40 -16
- package/build/src/database/drivers/sqlite/index.native.d.ts +1 -1
- package/build/src/database/drivers/sqlite/index.native.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/index.native.js +6 -3
- package/build/src/database/drivers/sqlite/index.web.d.ts +16 -4
- package/build/src/database/drivers/sqlite/index.web.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/index.web.js +17 -7
- package/build/src/database/drivers/sqlite/options.d.ts +2 -0
- package/build/src/database/drivers/sqlite/options.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/options.js +3 -1
- package/build/src/database/drivers/sqlite/query.d.ts +3 -2
- package/build/src/database/drivers/sqlite/query.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/query.js +6 -3
- package/build/src/database/drivers/sqlite/query.native.d.ts +2 -2
- package/build/src/database/drivers/sqlite/query.native.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/query.native.js +3 -3
- package/build/src/database/drivers/sqlite/query.web.d.ts +3 -2
- package/build/src/database/drivers/sqlite/query.web.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/query.web.js +6 -3
- package/build/src/database/drivers/sqlite/sql/alter-table.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/sql/alter-table.js +9 -3
- package/build/src/database/drivers/sqlite/structure-sql.d.ts +2 -0
- package/build/src/database/drivers/sqlite/structure-sql.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/structure-sql.js +3 -1
- package/build/src/database/drivers/sqlite/table-rebuilder.d.ts +2 -0
- package/build/src/database/drivers/sqlite/table-rebuilder.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/table-rebuilder.js +3 -1
- package/build/src/database/drivers/sqlite/table.d.ts +2 -0
- package/build/src/database/drivers/sqlite/table.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/table.js +14 -4
- package/build/src/database/drivers/structure-sql/utils.d.ts +2 -0
- package/build/src/database/drivers/structure-sql/utils.d.ts.map +1 -1
- package/build/src/database/drivers/structure-sql/utils.js +3 -1
- package/build/src/database/handler.d.ts +1 -0
- package/build/src/database/handler.d.ts.map +1 -1
- package/build/src/database/handler.js +2 -1
- package/build/src/database/initializer-from-require-context.d.ts +8 -0
- package/build/src/database/initializer-from-require-context.d.ts.map +1 -1
- package/build/src/database/initializer-from-require-context.js +4 -1
- package/build/src/database/migration/index.d.ts +40 -5
- package/build/src/database/migration/index.d.ts.map +1 -1
- package/build/src/database/migration/index.js +34 -6
- package/build/src/database/migrator/files-finder.d.ts +2 -0
- package/build/src/database/migrator/files-finder.d.ts.map +1 -1
- package/build/src/database/migrator/files-finder.js +6 -2
- package/build/src/database/migrator.d.ts +29 -4
- package/build/src/database/migrator.d.ts.map +1 -1
- package/build/src/database/migrator.js +45 -10
- package/build/src/database/pool/async-tracked-multi-connection.d.ts +125 -31
- package/build/src/database/pool/async-tracked-multi-connection.d.ts.map +1 -1
- package/build/src/database/pool/async-tracked-multi-connection.js +189 -52
- package/build/src/database/pool/base-methods-forward.d.ts +1 -0
- package/build/src/database/pool/base-methods-forward.d.ts.map +1 -1
- package/build/src/database/pool/base-methods-forward.js +12 -3
- package/build/src/database/pool/base.d.ts +39 -7
- package/build/src/database/pool/base.d.ts.map +1 -1
- package/build/src/database/pool/base.js +59 -18
- package/build/src/database/pool/single-multi-use.d.ts +1 -0
- package/build/src/database/pool/single-multi-use.d.ts.map +1 -1
- package/build/src/database/pool/single-multi-use.js +16 -4
- package/build/src/database/query/alter-table-base.d.ts +1 -0
- package/build/src/database/query/alter-table-base.d.ts.map +1 -1
- package/build/src/database/query/alter-table-base.js +3 -1
- package/build/src/database/query/base.d.ts +3 -0
- package/build/src/database/query/base.d.ts.map +1 -1
- package/build/src/database/query/base.js +4 -1
- package/build/src/database/query/create-database-base.d.ts +5 -0
- package/build/src/database/query/create-database-base.d.ts.map +1 -1
- package/build/src/database/query/create-database-base.js +4 -1
- package/build/src/database/query/create-index-base.d.ts +5 -0
- package/build/src/database/query/create-index-base.d.ts.map +1 -1
- package/build/src/database/query/create-index-base.js +4 -1
- package/build/src/database/query/create-table-base.d.ts +2 -0
- package/build/src/database/query/create-table-base.d.ts.map +1 -1
- package/build/src/database/query/create-table-base.js +3 -1
- package/build/src/database/query/delete-base.d.ts +3 -2
- package/build/src/database/query/delete-base.d.ts.map +1 -1
- package/build/src/database/query/delete-base.js +3 -2
- package/build/src/database/query/drop-database-base.d.ts +5 -0
- package/build/src/database/query/drop-database-base.d.ts.map +1 -1
- package/build/src/database/query/drop-database-base.js +4 -1
- package/build/src/database/query/drop-table-base.d.ts +1 -0
- package/build/src/database/query/drop-table-base.d.ts.map +1 -1
- package/build/src/database/query/drop-table-base.js +3 -1
- package/build/src/database/query/from-base.d.ts +6 -1
- package/build/src/database/query/from-base.d.ts.map +1 -1
- package/build/src/database/query/from-base.js +7 -2
- package/build/src/database/query/from-plain.d.ts +1 -0
- package/build/src/database/query/from-plain.d.ts.map +1 -1
- package/build/src/database/query/from-plain.js +2 -1
- package/build/src/database/query/from-table.d.ts +1 -0
- package/build/src/database/query/from-table.d.ts.map +1 -1
- package/build/src/database/query/from-table.js +2 -1
- package/build/src/database/query/index.d.ts +72 -12
- package/build/src/database/query/index.d.ts.map +1 -1
- package/build/src/database/query/index.js +79 -19
- package/build/src/database/query/insert-base.d.ts +13 -8
- package/build/src/database/query/insert-base.d.ts.map +1 -1
- package/build/src/database/query/insert-base.js +10 -5
- package/build/src/database/query/join-base.d.ts +4 -0
- package/build/src/database/query/join-base.d.ts.map +1 -1
- package/build/src/database/query/join-base.js +5 -1
- package/build/src/database/query/join-object.d.ts +11 -0
- package/build/src/database/query/join-object.d.ts.map +1 -1
- package/build/src/database/query/join-object.js +15 -4
- package/build/src/database/query/join-plain.d.ts +1 -0
- package/build/src/database/query/join-plain.d.ts.map +1 -1
- package/build/src/database/query/join-plain.js +2 -1
- package/build/src/database/query/join-tracker.d.ts +7 -0
- package/build/src/database/query/join-tracker.d.ts.map +1 -1
- package/build/src/database/query/join-tracker.js +8 -1
- package/build/src/database/query/model-class-query.d.ts +92 -26
- package/build/src/database/query/model-class-query.d.ts.map +1 -1
- package/build/src/database/query/model-class-query.js +230 -76
- package/build/src/database/query/order-base.d.ts +3 -0
- package/build/src/database/query/order-base.d.ts.map +1 -1
- package/build/src/database/query/order-base.js +4 -1
- package/build/src/database/query/order-column.d.ts +9 -1
- package/build/src/database/query/order-column.d.ts.map +1 -1
- package/build/src/database/query/order-column.js +10 -2
- package/build/src/database/query/order-plain.d.ts +1 -0
- package/build/src/database/query/order-plain.d.ts.map +1 -1
- package/build/src/database/query/order-plain.js +2 -1
- package/build/src/database/query/preloader/belongs-to.d.ts +1 -0
- package/build/src/database/query/preloader/belongs-to.d.ts.map +1 -1
- package/build/src/database/query/preloader/belongs-to.js +68 -23
- package/build/src/database/query/preloader/ensure-model-class-initialized.d.ts +1 -0
- package/build/src/database/query/preloader/ensure-model-class-initialized.d.ts.map +1 -1
- package/build/src/database/query/preloader/ensure-model-class-initialized.js +2 -1
- package/build/src/database/query/preloader/has-many.d.ts +5 -3
- package/build/src/database/query/preloader/has-many.d.ts.map +1 -1
- package/build/src/database/query/preloader/has-many.js +66 -24
- package/build/src/database/query/preloader/has-one.d.ts +1 -0
- package/build/src/database/query/preloader/has-one.d.ts.map +1 -1
- package/build/src/database/query/preloader/has-one.js +26 -9
- package/build/src/database/query/preloader/selection.d.ts +7 -1
- package/build/src/database/query/preloader/selection.d.ts.map +1 -1
- package/build/src/database/query/preloader/selection.js +13 -5
- package/build/src/database/query/preloader.d.ts +1 -0
- package/build/src/database/query/preloader.d.ts.map +1 -1
- package/build/src/database/query/preloader.js +28 -9
- package/build/src/database/query/query-data.d.ts +21 -7
- package/build/src/database/query/query-data.d.ts.map +1 -1
- package/build/src/database/query/query-data.js +37 -18
- package/build/src/database/query/select-base.d.ts +3 -0
- package/build/src/database/query/select-base.d.ts.map +1 -1
- package/build/src/database/query/select-base.js +4 -1
- package/build/src/database/query/select-plain.d.ts +1 -0
- package/build/src/database/query/select-plain.d.ts.map +1 -1
- package/build/src/database/query/select-plain.js +2 -1
- package/build/src/database/query/select-table-and-column.d.ts +1 -0
- package/build/src/database/query/select-table-and-column.d.ts.map +1 -1
- package/build/src/database/query/select-table-and-column.js +2 -1
- package/build/src/database/query/update-base.d.ts +9 -6
- package/build/src/database/query/update-base.d.ts.map +1 -1
- package/build/src/database/query/update-base.js +7 -4
- package/build/src/database/query/upsert-base.d.ts +13 -4
- package/build/src/database/query/upsert-base.d.ts.map +1 -1
- package/build/src/database/query/upsert-base.js +12 -3
- package/build/src/database/query/where-base.d.ts +4 -0
- package/build/src/database/query/where-base.d.ts.map +1 -1
- package/build/src/database/query/where-base.js +5 -1
- package/build/src/database/query/where-combinator.d.ts +1 -0
- package/build/src/database/query/where-combinator.d.ts.map +1 -1
- package/build/src/database/query/where-combinator.js +6 -2
- package/build/src/database/query/where-hash.d.ts +6 -0
- package/build/src/database/query/where-hash.d.ts.map +1 -1
- package/build/src/database/query/where-hash.js +5 -1
- package/build/src/database/query/where-model-class-hash.d.ts +30 -16
- package/build/src/database/query/where-model-class-hash.d.ts.map +1 -1
- package/build/src/database/query/where-model-class-hash.js +55 -20
- package/build/src/database/query/where-not.d.ts +1 -0
- package/build/src/database/query/where-not.d.ts.map +1 -1
- package/build/src/database/query/where-not.js +3 -1
- package/build/src/database/query/where-plain.d.ts +1 -0
- package/build/src/database/query/where-plain.d.ts.map +1 -1
- package/build/src/database/query/where-plain.js +2 -1
- package/build/src/database/query/with-count.d.ts +11 -5
- package/build/src/database/query/with-count.d.ts.map +1 -1
- package/build/src/database/query/with-count.js +36 -15
- package/build/src/database/query-parser/base-query-parser.d.ts +1 -0
- package/build/src/database/query-parser/base-query-parser.d.ts.map +1 -1
- package/build/src/database/query-parser/base-query-parser.js +2 -1
- package/build/src/database/query-parser/from-parser.d.ts +5 -1
- package/build/src/database/query-parser/from-parser.d.ts.map +1 -1
- package/build/src/database/query-parser/from-parser.js +6 -2
- package/build/src/database/query-parser/group-parser.d.ts +2 -0
- package/build/src/database/query-parser/group-parser.d.ts.map +1 -1
- package/build/src/database/query-parser/group-parser.js +3 -1
- package/build/src/database/query-parser/joins-parser.d.ts +1 -0
- package/build/src/database/query-parser/joins-parser.d.ts.map +1 -1
- package/build/src/database/query-parser/joins-parser.js +2 -1
- package/build/src/database/query-parser/limit-parser.d.ts +1 -0
- package/build/src/database/query-parser/limit-parser.d.ts.map +1 -1
- package/build/src/database/query-parser/limit-parser.js +2 -1
- package/build/src/database/query-parser/options.d.ts +15 -4
- package/build/src/database/query-parser/options.d.ts.map +1 -1
- package/build/src/database/query-parser/options.js +11 -3
- package/build/src/database/query-parser/order-parser.d.ts +1 -0
- package/build/src/database/query-parser/order-parser.d.ts.map +1 -1
- package/build/src/database/query-parser/order-parser.js +2 -1
- package/build/src/database/query-parser/select-parser.d.ts +1 -0
- package/build/src/database/query-parser/select-parser.d.ts.map +1 -1
- package/build/src/database/query-parser/select-parser.js +2 -1
- package/build/src/database/query-parser/where-parser.d.ts +1 -0
- package/build/src/database/query-parser/where-parser.d.ts.map +1 -1
- package/build/src/database/query-parser/where-parser.js +2 -1
- package/build/src/database/record/acts-as-list.d.ts +0 -1
- package/build/src/database/record/acts-as-list.d.ts.map +1 -1
- package/build/src/database/record/acts-as-list.js +89 -45
- package/build/src/database/record/attachments/download.d.ts +34 -15
- package/build/src/database/record/attachments/download.d.ts.map +1 -1
- package/build/src/database/record/attachments/download.js +34 -22
- package/build/src/database/record/attachments/handle.d.ts +17 -5
- package/build/src/database/record/attachments/handle.d.ts.map +1 -1
- package/build/src/database/record/attachments/handle.js +25 -9
- package/build/src/database/record/attachments/normalize-input.d.ts +6 -1
- package/build/src/database/record/attachments/normalize-input.d.ts.map +1 -1
- package/build/src/database/record/attachments/normalize-input.js +54 -17
- package/build/src/database/record/attachments/storage-drivers/filesystem.d.ts +7 -1
- package/build/src/database/record/attachments/storage-drivers/filesystem.d.ts.map +1 -1
- package/build/src/database/record/attachments/storage-drivers/filesystem.js +10 -2
- package/build/src/database/record/attachments/storage-drivers/native.d.ts +12 -7
- package/build/src/database/record/attachments/storage-drivers/native.d.ts.map +1 -1
- package/build/src/database/record/attachments/storage-drivers/native.js +13 -6
- package/build/src/database/record/attachments/storage-drivers/s3.d.ts +18 -9
- package/build/src/database/record/attachments/storage-drivers/s3.d.ts.map +1 -1
- package/build/src/database/record/attachments/storage-drivers/s3.js +38 -13
- package/build/src/database/record/attachments/store.d.ts +48 -25
- package/build/src/database/record/attachments/store.d.ts.map +1 -1
- package/build/src/database/record/attachments/store.js +63 -25
- package/build/src/database/record/index.d.ts +394 -146
- package/build/src/database/record/index.d.ts.map +1 -1
- package/build/src/database/record/index.js +697 -248
- package/build/src/database/record/instance-relationships/base.d.ts +78 -19
- package/build/src/database/record/instance-relationships/base.d.ts.map +1 -1
- package/build/src/database/record/instance-relationships/base.js +98 -26
- package/build/src/database/record/instance-relationships/belongs-to.d.ts +1 -0
- package/build/src/database/record/instance-relationships/belongs-to.d.ts.map +1 -1
- package/build/src/database/record/instance-relationships/belongs-to.js +13 -5
- package/build/src/database/record/instance-relationships/has-many.d.ts +27 -7
- package/build/src/database/record/instance-relationships/has-many.d.ts.map +1 -1
- package/build/src/database/record/instance-relationships/has-many.js +50 -16
- package/build/src/database/record/instance-relationships/has-one.d.ts +4 -1
- package/build/src/database/record/instance-relationships/has-one.d.ts.map +1 -1
- package/build/src/database/record/instance-relationships/has-one.js +28 -10
- package/build/src/database/record/relationships/base.d.ts +61 -14
- package/build/src/database/record/relationships/base.d.ts.map +1 -1
- package/build/src/database/record/relationships/base.js +60 -15
- package/build/src/database/record/relationships/belongs-to.d.ts.map +1 -1
- package/build/src/database/record/relationships/belongs-to.js +9 -3
- package/build/src/database/record/relationships/has-many.d.ts.map +1 -1
- package/build/src/database/record/relationships/has-many.js +9 -3
- package/build/src/database/record/relationships/has-one.d.ts.map +1 -1
- package/build/src/database/record/relationships/has-one.js +9 -3
- package/build/src/database/record/state-machine.d.ts +9 -1
- package/build/src/database/record/state-machine.d.ts.map +1 -1
- package/build/src/database/record/state-machine.js +35 -14
- package/build/src/database/record/user-module.d.ts +2 -0
- package/build/src/database/record/user-module.d.ts.map +1 -1
- package/build/src/database/record/user-module.js +3 -1
- package/build/src/database/record/validators/base.d.ts +4 -2
- package/build/src/database/record/validators/base.d.ts.map +1 -1
- package/build/src/database/record/validators/base.js +4 -2
- package/build/src/database/record/validators/format.d.ts.map +1 -1
- package/build/src/database/record/validators/format.js +2 -1
- package/build/src/database/record/validators/presence.d.ts.map +1 -1
- package/build/src/database/record/validators/presence.js +5 -2
- package/build/src/database/record/validators/uniqueness.d.ts +0 -2
- package/build/src/database/record/validators/uniqueness.d.ts.map +1 -1
- package/build/src/database/record/validators/uniqueness.js +18 -8
- package/build/src/database/table-data/index.d.ts +40 -4
- package/build/src/database/table-data/index.d.ts.map +1 -1
- package/build/src/database/table-data/index.js +38 -5
- package/build/src/database/table-data/table-column.d.ts +43 -5
- package/build/src/database/table-data/table-column.d.ts.map +1 -1
- package/build/src/database/table-data/table-column.js +37 -4
- package/build/src/database/table-data/table-foreign-key.d.ts +8 -0
- package/build/src/database/table-data/table-foreign-key.d.ts.map +1 -1
- package/build/src/database/table-data/table-foreign-key.js +9 -1
- package/build/src/database/table-data/table-index.d.ts +8 -0
- package/build/src/database/table-data/table-index.d.ts.map +1 -1
- package/build/src/database/table-data/table-index.js +6 -1
- package/build/src/database/table-data/table-reference.d.ts +1 -0
- package/build/src/database/table-data/table-reference.d.ts.map +1 -1
- package/build/src/database/table-data/table-reference.js +2 -1
- package/build/src/database/use-database.d.ts +1 -0
- package/build/src/database/use-database.d.ts.map +1 -1
- package/build/src/database/use-database.js +2 -1
- package/build/src/environment-handlers/base.d.ts +94 -36
- package/build/src/environment-handlers/base.d.ts.map +1 -1
- package/build/src/environment-handlers/base.js +90 -36
- package/build/src/environment-handlers/browser.d.ts +33 -3
- package/build/src/environment-handlers/browser.d.ts.map +1 -1
- package/build/src/environment-handlers/browser.js +36 -9
- package/build/src/environment-handlers/node/cli/commands/cli-command-context.d.ts +5 -0
- package/build/src/environment-handlers/node/cli/commands/cli-command-context.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/cli-command-context.js +6 -2
- package/build/src/environment-handlers/node/cli/commands/console.d.ts +3 -2
- package/build/src/environment-handlers/node/cli/commands/console.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/console.js +23 -9
- package/build/src/environment-handlers/node/cli/commands/db/schema/dump.d.ts +4 -1
- package/build/src/environment-handlers/node/cli/commands/db/schema/dump.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/db/schema/dump.js +5 -2
- package/build/src/environment-handlers/node/cli/commands/db/schema/load.d.ts +6 -2
- package/build/src/environment-handlers/node/cli/commands/db/schema/load.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/db/schema/load.js +11 -5
- package/build/src/environment-handlers/node/cli/commands/db/seed.d.ts +15 -5
- package/build/src/environment-handlers/node/cli/commands/db/seed.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/db/seed.js +20 -6
- package/build/src/environment-handlers/node/cli/commands/destroy/migration.d.ts +5 -0
- package/build/src/environment-handlers/node/cli/commands/destroy/migration.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/destroy/migration.js +3 -1
- package/build/src/environment-handlers/node/cli/commands/generate/base-models.d.ts +2 -0
- package/build/src/environment-handlers/node/cli/commands/generate/base-models.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/generate/base-models.js +6 -4
- package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.d.ts +43 -29
- package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.js +99 -40
- package/build/src/environment-handlers/node/cli/commands/generate/migration.d.ts +5 -0
- package/build/src/environment-handlers/node/cli/commands/generate/migration.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/generate/migration.js +3 -1
- package/build/src/environment-handlers/node/cli/commands/generate/model.d.ts +5 -0
- package/build/src/environment-handlers/node/cli/commands/generate/model.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/generate/model.js +3 -1
- package/build/src/environment-handlers/node/cli/commands/init.d.ts +5 -0
- package/build/src/environment-handlers/node/cli/commands/init.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/init.js +3 -1
- package/build/src/environment-handlers/node/cli/commands/routes.d.ts +3 -0
- package/build/src/environment-handlers/node/cli/commands/routes.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/routes.js +4 -1
- package/build/src/environment-handlers/node/cli/commands/run-script.d.ts +15 -5
- package/build/src/environment-handlers/node/cli/commands/run-script.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/run-script.js +20 -6
- package/build/src/environment-handlers/node/cli/commands/runner.d.ts +18 -6
- package/build/src/environment-handlers/node/cli/commands/runner.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/runner.js +20 -6
- package/build/src/environment-handlers/node/cli/commands/server.d.ts +13 -1
- package/build/src/environment-handlers/node/cli/commands/server.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/server.js +23 -6
- package/build/src/environment-handlers/node.d.ts +14 -2
- package/build/src/environment-handlers/node.d.ts.map +1 -1
- package/build/src/environment-handlers/node.js +107 -39
- package/build/src/error-logger.d.ts +4 -3
- package/build/src/error-logger.d.ts.map +1 -1
- package/build/src/error-logger.js +4 -3
- package/build/src/frontend-model-controller.d.ts +239 -90
- package/build/src/frontend-model-controller.d.ts.map +1 -1
- package/build/src/frontend-model-controller.js +577 -787
- package/build/src/frontend-model-resource/base-resource.d.ts +118 -66
- package/build/src/frontend-model-resource/base-resource.d.ts.map +1 -1
- package/build/src/frontend-model-resource/base-resource.js +205 -82
- package/build/src/frontend-models/base.d.ts +319 -163
- package/build/src/frontend-models/base.d.ts.map +1 -1
- package/build/src/frontend-models/base.js +717 -366
- package/build/src/frontend-models/clear-pending-debounced-callback.d.ts +2 -1
- package/build/src/frontend-models/clear-pending-debounced-callback.d.ts.map +1 -1
- package/build/src/frontend-models/clear-pending-debounced-callback.js +6 -3
- package/build/src/frontend-models/event-hook-models.d.ts +5 -0
- package/build/src/frontend-models/event-hook-models.d.ts.map +1 -1
- package/build/src/frontend-models/event-hook-models.js +10 -3
- package/build/src/frontend-models/model-registry.d.ts +5 -5
- package/build/src/frontend-models/model-registry.d.ts.map +1 -1
- package/build/src/frontend-models/model-registry.js +5 -5
- package/build/src/frontend-models/outgoing-event-buffer.d.ts +11 -3
- package/build/src/frontend-models/outgoing-event-buffer.d.ts.map +1 -1
- package/build/src/frontend-models/outgoing-event-buffer.js +13 -5
- package/build/src/frontend-models/preloader.d.ts +9 -6
- package/build/src/frontend-models/preloader.d.ts.map +1 -1
- package/build/src/frontend-models/preloader.js +21 -9
- package/build/src/frontend-models/query.d.ts +283 -73
- package/build/src/frontend-models/query.d.ts.map +1 -1
- package/build/src/frontend-models/query.js +331 -203
- package/build/src/frontend-models/resource-config-validation.d.ts +2 -0
- package/build/src/frontend-models/resource-config-validation.d.ts.map +1 -1
- package/build/src/frontend-models/resource-config-validation.js +3 -1
- package/build/src/frontend-models/resource-definition.d.ts +12 -5
- package/build/src/frontend-models/resource-definition.d.ts.map +1 -1
- package/build/src/frontend-models/resource-definition.js +39 -13
- package/build/src/frontend-models/transport-serialization.d.ts +14 -11
- package/build/src/frontend-models/transport-serialization.d.ts.map +1 -1
- package/build/src/frontend-models/transport-serialization.js +80 -53
- package/build/src/frontend-models/use-destroyed-event.d.ts +21 -0
- package/build/src/frontend-models/use-destroyed-event.d.ts.map +1 -1
- package/build/src/frontend-models/use-destroyed-event.js +34 -11
- package/build/src/frontend-models/use-model-class-event.d.ts +24 -0
- package/build/src/frontend-models/use-model-class-event.d.ts.map +1 -1
- package/build/src/frontend-models/use-model-class-event.js +39 -12
- package/build/src/frontend-models/use-updated-event.d.ts +21 -0
- package/build/src/frontend-models/use-updated-event.d.ts.map +1 -1
- package/build/src/frontend-models/use-updated-event.js +37 -12
- package/build/src/frontend-models/websocket-channel.d.ts +51 -9
- package/build/src/frontend-models/websocket-channel.d.ts.map +1 -1
- package/build/src/frontend-models/websocket-channel.js +96 -26
- package/build/src/frontend-models/websocket-publishers.d.ts +2 -0
- package/build/src/frontend-models/websocket-publishers.d.ts.map +1 -1
- package/build/src/frontend-models/websocket-publishers.js +33 -11
- package/build/src/http-client/header.d.ts +1 -0
- package/build/src/http-client/header.d.ts.map +1 -1
- package/build/src/http-client/header.js +2 -1
- package/build/src/http-client/index.d.ts +4 -0
- package/build/src/http-client/index.d.ts.map +1 -1
- package/build/src/http-client/index.js +5 -1
- package/build/src/http-client/request.d.ts +5 -0
- package/build/src/http-client/request.d.ts.map +1 -1
- package/build/src/http-client/request.js +6 -1
- package/build/src/http-client/response.d.ts +14 -4
- package/build/src/http-client/response.d.ts.map +1 -1
- package/build/src/http-client/response.js +14 -4
- package/build/src/http-client/websocket-client.d.ts +1 -0
- package/build/src/http-client/websocket-client.d.ts.map +1 -1
- package/build/src/http-client/websocket-client.js +2 -1
- package/build/src/http-server/client/index.d.ts +16 -2
- package/build/src/http-server/client/index.d.ts.map +1 -1
- package/build/src/http-server/client/index.js +44 -13
- package/build/src/http-server/client/params-to-object.d.ts +16 -10
- package/build/src/http-server/client/params-to-object.d.ts.map +1 -1
- package/build/src/http-server/client/params-to-object.js +46 -17
- package/build/src/http-server/client/request-buffer/form-data-part.d.ts +10 -6
- package/build/src/http-server/client/request-buffer/form-data-part.d.ts.map +1 -1
- package/build/src/http-server/client/request-buffer/form-data-part.js +11 -7
- package/build/src/http-server/client/request-buffer/header.d.ts +1 -0
- package/build/src/http-server/client/request-buffer/header.d.ts.map +1 -1
- package/build/src/http-server/client/request-buffer/header.js +2 -1
- package/build/src/http-server/client/request-buffer/index.d.ts +29 -4
- package/build/src/http-server/client/request-buffer/index.d.ts.map +1 -1
- package/build/src/http-server/client/request-buffer/index.js +43 -9
- package/build/src/http-server/client/request-parser.d.ts +52 -13
- package/build/src/http-server/client/request-parser.d.ts.map +1 -1
- package/build/src/http-server/client/request-parser.js +58 -15
- package/build/src/http-server/client/request-runner.d.ts +5 -1
- package/build/src/http-server/client/request-runner.d.ts.map +1 -1
- package/build/src/http-server/client/request-runner.js +32 -8
- package/build/src/http-server/client/request-timing.d.ts +37 -7
- package/build/src/http-server/client/request-timing.d.ts.map +1 -1
- package/build/src/http-server/client/request-timing.js +32 -8
- package/build/src/http-server/client/request.d.ts +15 -5
- package/build/src/http-server/client/request.d.ts.map +1 -1
- package/build/src/http-server/client/request.js +17 -5
- package/build/src/http-server/client/response.d.ts +22 -4
- package/build/src/http-server/client/response.d.ts.map +1 -1
- package/build/src/http-server/client/response.js +29 -7
- package/build/src/http-server/client/uploaded-file/memory-uploaded-file.d.ts +1 -0
- package/build/src/http-server/client/uploaded-file/memory-uploaded-file.d.ts.map +1 -1
- package/build/src/http-server/client/uploaded-file/memory-uploaded-file.js +3 -1
- package/build/src/http-server/client/uploaded-file/temporary-uploaded-file.d.ts +1 -0
- package/build/src/http-server/client/uploaded-file/temporary-uploaded-file.d.ts.map +1 -1
- package/build/src/http-server/client/uploaded-file/temporary-uploaded-file.js +3 -1
- package/build/src/http-server/client/uploaded-file/uploaded-file.d.ts +2 -0
- package/build/src/http-server/client/uploaded-file/uploaded-file.d.ts.map +1 -1
- package/build/src/http-server/client/uploaded-file/uploaded-file.js +3 -1
- package/build/src/http-server/client/websocket-request.d.ts +24 -12
- package/build/src/http-server/client/websocket-request.d.ts.map +1 -1
- package/build/src/http-server/client/websocket-request.js +24 -10
- package/build/src/http-server/client/websocket-session.d.ts +101 -62
- package/build/src/http-server/client/websocket-session.d.ts.map +1 -1
- package/build/src/http-server/client/websocket-session.js +118 -61
- package/build/src/http-server/cookie.d.ts +36 -8
- package/build/src/http-server/cookie.d.ts.map +1 -1
- package/build/src/http-server/cookie.js +37 -9
- package/build/src/http-server/development-reloader.d.ts +32 -7
- package/build/src/http-server/development-reloader.d.ts.map +1 -1
- package/build/src/http-server/development-reloader.js +39 -10
- package/build/src/http-server/index.d.ts +102 -25
- package/build/src/http-server/index.d.ts.map +1 -1
- package/build/src/http-server/index.js +117 -32
- package/build/src/http-server/remote-address.d.ts +1 -0
- package/build/src/http-server/remote-address.d.ts.map +1 -1
- package/build/src/http-server/remote-address.js +15 -4
- package/build/src/http-server/server-client.d.ts +37 -8
- package/build/src/http-server/server-client.d.ts.map +1 -1
- package/build/src/http-server/server-client.js +48 -12
- package/build/src/http-server/server-lock.d.ts +76 -0
- package/build/src/http-server/server-lock.d.ts.map +1 -0
- package/build/src/http-server/server-lock.js +164 -0
- package/build/src/http-server/websocket-channel-subscribers.d.ts +13 -8
- package/build/src/http-server/websocket-channel-subscribers.d.ts.map +1 -1
- package/build/src/http-server/websocket-channel-subscribers.js +16 -7
- package/build/src/http-server/websocket-channel.d.ts +13 -11
- package/build/src/http-server/websocket-channel.d.ts.map +1 -1
- package/build/src/http-server/websocket-channel.js +8 -12
- package/build/src/http-server/websocket-connection.d.ts +10 -14
- package/build/src/http-server/websocket-connection.d.ts.map +1 -1
- package/build/src/http-server/websocket-connection.js +8 -12
- package/build/src/http-server/websocket-event-log-store.d.ts +48 -10
- package/build/src/http-server/websocket-event-log-store.d.ts.map +1 -1
- package/build/src/http-server/websocket-event-log-store.js +76 -34
- package/build/src/http-server/websocket-events-host.d.ts +21 -15
- package/build/src/http-server/websocket-events-host.d.ts.map +1 -1
- package/build/src/http-server/websocket-events-host.js +20 -11
- package/build/src/http-server/websocket-events.d.ts +8 -7
- package/build/src/http-server/websocket-events.d.ts.map +1 -1
- package/build/src/http-server/websocket-events.js +6 -5
- package/build/src/http-server/worker-handler/channel-subscriber-dispatch.d.ts +3 -2
- package/build/src/http-server/worker-handler/channel-subscriber-dispatch.d.ts.map +1 -1
- package/build/src/http-server/worker-handler/channel-subscriber-dispatch.js +3 -2
- package/build/src/http-server/worker-handler/in-process.d.ts +18 -18
- package/build/src/http-server/worker-handler/in-process.d.ts.map +1 -1
- package/build/src/http-server/worker-handler/in-process.js +28 -20
- package/build/src/http-server/worker-handler/index.d.ts +39 -20
- package/build/src/http-server/worker-handler/index.d.ts.map +1 -1
- package/build/src/http-server/worker-handler/index.js +34 -14
- package/build/src/http-server/worker-handler/worker-thread.d.ts +31 -15
- package/build/src/http-server/worker-handler/worker-thread.d.ts.map +1 -1
- package/build/src/http-server/worker-handler/worker-thread.js +31 -12
- package/build/src/initializer.d.ts +4 -0
- package/build/src/initializer.d.ts.map +1 -1
- package/build/src/initializer.js +5 -1
- package/build/src/jobs/mail-delivery.d.ts +1 -0
- package/build/src/jobs/mail-delivery.d.ts.map +1 -1
- package/build/src/jobs/mail-delivery.js +2 -1
- package/build/src/logger/base-logger.js +2 -2
- package/build/src/logger/console-logger.d.ts +2 -0
- package/build/src/logger/console-logger.d.ts.map +1 -1
- package/build/src/logger/console-logger.js +3 -1
- package/build/src/logger/file-logger.d.ts +2 -0
- package/build/src/logger/file-logger.d.ts.map +1 -1
- package/build/src/logger/file-logger.js +3 -1
- package/build/src/logger/outputs/array-output.d.ts +21 -5
- package/build/src/logger/outputs/array-output.d.ts.map +1 -1
- package/build/src/logger/outputs/array-output.js +19 -6
- package/build/src/logger/outputs/console-output.d.ts +10 -2
- package/build/src/logger/outputs/console-output.d.ts.map +1 -1
- package/build/src/logger/outputs/console-output.js +8 -3
- package/build/src/logger/outputs/file-output.d.ts +20 -5
- package/build/src/logger/outputs/file-output.d.ts.map +1 -1
- package/build/src/logger/outputs/file-output.js +18 -6
- package/build/src/logger/outputs/stdout-output.d.ts +7 -1
- package/build/src/logger/outputs/stdout-output.d.ts.map +1 -1
- package/build/src/logger/outputs/stdout-output.js +9 -3
- package/build/src/logger.d.ts +28 -13
- package/build/src/logger.d.ts.map +1 -1
- package/build/src/logger.js +60 -23
- package/build/src/mailer/backends/smtp.d.ts +5 -0
- package/build/src/mailer/backends/smtp.d.ts.map +1 -1
- package/build/src/mailer/backends/smtp.js +17 -4
- package/build/src/mailer/base.d.ts +33 -17
- package/build/src/mailer/base.d.ts.map +1 -1
- package/build/src/mailer/base.js +54 -18
- package/build/src/mailer/delivery.d.ts +16 -5
- package/build/src/mailer/delivery.d.ts.map +1 -1
- package/build/src/mailer/delivery.js +18 -7
- package/build/src/mailer/index.d.ts +5 -5
- package/build/src/mailer/index.d.ts.map +1 -1
- package/build/src/mailer/index.js +2 -2
- package/build/src/mailer.d.ts +5 -5
- package/build/src/mailer.d.ts.map +1 -1
- package/build/src/mailer.js +2 -2
- package/build/src/plugins/sqljs-wasm-route-controller.d.ts +4 -1
- package/build/src/plugins/sqljs-wasm-route-controller.d.ts.map +1 -1
- package/build/src/plugins/sqljs-wasm-route-controller.js +11 -4
- package/build/src/plugins/sqljs-wasm-route.d.ts +6 -0
- package/build/src/plugins/sqljs-wasm-route.d.ts.map +1 -1
- package/build/src/plugins/sqljs-wasm-route.js +4 -1
- package/build/src/record-payload-values.d.ts +54 -0
- package/build/src/record-payload-values.d.ts.map +1 -0
- package/build/src/record-payload-values.js +80 -0
- package/build/src/routes/app-routes.d.ts +1 -0
- package/build/src/routes/app-routes.d.ts.map +1 -1
- package/build/src/routes/app-routes.js +2 -1
- package/build/src/routes/base-route.d.ts +52 -16
- package/build/src/routes/base-route.d.ts.map +1 -1
- package/build/src/routes/base-route.js +50 -14
- package/build/src/routes/basic-route.d.ts +1 -0
- package/build/src/routes/basic-route.d.ts.map +1 -1
- package/build/src/routes/basic-route.js +13 -4
- package/build/src/routes/built-in/debug/controller.d.ts +4 -1
- package/build/src/routes/built-in/debug/controller.d.ts.map +1 -1
- package/build/src/routes/built-in/debug/controller.js +5 -2
- package/build/src/routes/get-route.d.ts +1 -0
- package/build/src/routes/get-route.d.ts.map +1 -1
- package/build/src/routes/get-route.js +7 -4
- package/build/src/routes/hooks/frontend-model-command-route-hook.d.ts +1 -0
- package/build/src/routes/hooks/frontend-model-command-route-hook.d.ts.map +1 -1
- package/build/src/routes/hooks/frontend-model-command-route-hook.js +6 -2
- package/build/src/routes/index.d.ts +3 -2
- package/build/src/routes/index.d.ts.map +1 -1
- package/build/src/routes/index.js +10 -4
- package/build/src/routes/namespace-route.d.ts +1 -0
- package/build/src/routes/namespace-route.d.ts.map +1 -1
- package/build/src/routes/namespace-route.js +5 -3
- package/build/src/routes/plugin-routes.d.ts +10 -1
- package/build/src/routes/plugin-routes.d.ts.map +1 -1
- package/build/src/routes/plugin-routes.js +11 -3
- package/build/src/routes/post-route.d.ts +1 -0
- package/build/src/routes/post-route.d.ts.map +1 -1
- package/build/src/routes/post-route.js +7 -4
- package/build/src/routes/resolver.d.ts +20 -5
- package/build/src/routes/resolver.d.ts.map +1 -1
- package/build/src/routes/resolver.js +47 -14
- package/build/src/routes/resource-route.d.ts +6 -1
- package/build/src/routes/resource-route.d.ts.map +1 -1
- package/build/src/routes/resource-route.js +10 -4
- package/build/src/testing/base-expect.d.ts +2 -0
- package/build/src/testing/base-expect.d.ts.map +1 -1
- package/build/src/testing/base-expect.js +3 -1
- package/build/src/testing/browser-frontend-model-event-hook-scenarios.d.ts +33 -5
- package/build/src/testing/browser-frontend-model-event-hook-scenarios.d.ts.map +1 -1
- package/build/src/testing/browser-frontend-model-event-hook-scenarios.js +95 -23
- package/build/src/testing/expect-to-change.d.ts +3 -0
- package/build/src/testing/expect-to-change.d.ts.map +1 -1
- package/build/src/testing/expect-to-change.js +4 -1
- package/build/src/testing/expect-utils.d.ts +22 -16
- package/build/src/testing/expect-utils.d.ts.map +1 -1
- package/build/src/testing/expect-utils.js +62 -30
- package/build/src/testing/expect.d.ts +50 -21
- package/build/src/testing/expect.d.ts.map +1 -1
- package/build/src/testing/expect.js +58 -17
- package/build/src/testing/request-client.d.ts +16 -3
- package/build/src/testing/request-client.d.ts.map +1 -1
- package/build/src/testing/request-client.js +17 -4
- package/build/src/testing/test-files-finder.d.ts +41 -9
- package/build/src/testing/test-files-finder.d.ts.map +1 -1
- package/build/src/testing/test-files-finder.js +42 -10
- package/build/src/testing/test-filter-parser.d.ts +6 -0
- package/build/src/testing/test-filter-parser.d.ts.map +1 -1
- package/build/src/testing/test-filter-parser.js +12 -3
- package/build/src/testing/test-runner.d.ts +102 -6
- package/build/src/testing/test-runner.d.ts.map +1 -1
- package/build/src/testing/test-runner.js +115 -23
- package/build/src/testing/test-suite-splitter.d.ts +7 -0
- package/build/src/testing/test-suite-splitter.d.ts.map +1 -1
- package/build/src/testing/test-suite-splitter.js +7 -2
- package/build/src/testing/test.d.ts +20 -4
- package/build/src/testing/test.d.ts.map +1 -1
- package/build/src/testing/test.js +67 -20
- package/build/src/utils/backtrace-cleaner-node.d.ts.map +1 -1
- package/build/src/utils/backtrace-cleaner-node.js +6 -1
- package/build/src/utils/backtrace-cleaner.d.ts +16 -1
- package/build/src/utils/backtrace-cleaner.d.ts.map +1 -1
- package/build/src/utils/backtrace-cleaner.js +20 -2
- package/build/src/utils/ensure-error.d.ts +3 -2
- package/build/src/utils/ensure-error.d.ts.map +1 -1
- package/build/src/utils/ensure-error.js +3 -2
- package/build/src/utils/event-emitter.d.ts.map +1 -1
- package/build/src/utils/event-emitter.js +2 -2
- package/build/src/utils/file-exists.d.ts +1 -0
- package/build/src/utils/file-exists.d.ts.map +1 -1
- package/build/src/utils/file-exists.js +2 -1
- package/build/src/utils/format-value.d.ts +5 -4
- package/build/src/utils/format-value.d.ts.map +1 -1
- package/build/src/utils/format-value.js +12 -7
- package/build/src/utils/model-scope.d.ts +18 -12
- package/build/src/utils/model-scope.d.ts.map +1 -1
- package/build/src/utils/model-scope.js +19 -11
- package/build/src/utils/nest-callbacks.d.ts +1 -0
- package/build/src/utils/nest-callbacks.d.ts.map +1 -1
- package/build/src/utils/nest-callbacks.js +2 -1
- package/build/src/utils/plain-object.d.ts +7 -0
- package/build/src/utils/plain-object.d.ts.map +1 -0
- package/build/src/utils/plain-object.js +13 -0
- package/build/src/utils/ransack.d.ts +29 -5
- package/build/src/utils/ransack.d.ts.map +1 -1
- package/build/src/utils/ransack.js +136 -49
- package/build/src/utils/rest-args-error.d.ts +1 -0
- package/build/src/utils/rest-args-error.d.ts.map +1 -1
- package/build/src/utils/rest-args-error.js +2 -1
- package/build/src/utils/singularize-model-name.d.ts +1 -0
- package/build/src/utils/singularize-model-name.d.ts.map +1 -1
- package/build/src/utils/singularize-model-name.js +2 -1
- package/build/src/utils/to-import-specifier.d.ts.map +1 -1
- package/build/src/utils/to-import-specifier.js +3 -1
- package/build/src/utils/with-tracked-stack-async-hooks.d.ts +8 -5
- package/build/src/utils/with-tracked-stack-async-hooks.d.ts.map +1 -1
- package/build/src/utils/with-tracked-stack-async-hooks.js +32 -13
- package/build/src/utils/with-tracked-stack.d.ts +9 -5
- package/build/src/utils/with-tracked-stack.d.ts.map +1 -1
- package/build/src/utils/with-tracked-stack.js +19 -8
- package/build/src/velocious-error.d.ts +4 -2
- package/build/src/velocious-error.d.ts.map +1 -1
- package/build/src/velocious-error.js +5 -3
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -12,10 +12,11 @@ import { testConfig, testEvents, tests } from "./test.js";
|
|
|
12
12
|
import { pathToFileURL } from "url";
|
|
13
13
|
import { clearDeliveries } from "../mailer.js";
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
15
|
+
* Runs run with timeout.
|
|
16
|
+
* @param {Promise<?> | ?} promise - Promise or value.
|
|
16
17
|
* @param {number} timeoutMs - Timeout in milliseconds.
|
|
17
18
|
* @param {string} testDescription - Test description.
|
|
18
|
-
* @returns {Promise
|
|
19
|
+
* @returns {Promise<?>} - Resolves or rejects based on timeout or promise result.
|
|
19
20
|
*/
|
|
20
21
|
function runWithTimeout(promise, timeoutMs, testDescription) {
|
|
21
22
|
const timeoutSeconds = (timeoutMs / 1000).toFixed(3).replace(/\.?0+$/, "");
|
|
@@ -31,15 +32,21 @@ function runWithTimeout(promise, timeoutMs, testDescription) {
|
|
|
31
32
|
});
|
|
32
33
|
});
|
|
33
34
|
}
|
|
34
|
-
/**
|
|
35
|
-
|
|
35
|
+
/**
|
|
36
|
+
* ConsoleMethodName type.
|
|
37
|
+
@typedef {"log" | "info" | "warn" | "error" | "debug"} ConsoleMethodName */
|
|
38
|
+
/**
|
|
39
|
+
* Captured console methods.
|
|
40
|
+
@type {ConsoleMethodName[]} */
|
|
36
41
|
const CAPTURED_CONSOLE_METHODS = ["log", "info", "warn", "error", "debug"];
|
|
37
42
|
/**
|
|
43
|
+
* AttemptConsoleOutput type.
|
|
38
44
|
* @typedef {object} AttemptConsoleOutput
|
|
39
45
|
* @property {number} attemptNumber - Attempt number.
|
|
40
46
|
* @property {string} output - Captured console output.
|
|
41
47
|
*/
|
|
42
48
|
/**
|
|
49
|
+
* Runs to file slug.
|
|
43
50
|
* @param {string} value - Value to sanitize.
|
|
44
51
|
* @returns {string} - Slug-safe value.
|
|
45
52
|
*/
|
|
@@ -51,6 +58,7 @@ function toFileSlug(value) {
|
|
|
51
58
|
.slice(0, 80) || "failed-test";
|
|
52
59
|
}
|
|
53
60
|
/**
|
|
61
|
+
* TestArgs type.
|
|
54
62
|
* @typedef {object} TestArgs
|
|
55
63
|
* @property {Application} [application] - Application instance for integration tests.
|
|
56
64
|
* @property {RequestClient} [client] - HTTP client for request tests.
|
|
@@ -65,6 +73,7 @@ function toFileSlug(value) {
|
|
|
65
73
|
* @property {string} [type] - Test type identifier.
|
|
66
74
|
*/
|
|
67
75
|
/**
|
|
76
|
+
* TestData type.
|
|
68
77
|
* @typedef {object} TestData
|
|
69
78
|
* @property {TestArgs} args - Arguments passed to the test.
|
|
70
79
|
* @property {string} [filePath] - Source file path.
|
|
@@ -72,34 +81,41 @@ function toFileSlug(value) {
|
|
|
72
81
|
* @property {function(TestArgs) : (void|Promise<void>)} function - Test callback to execute.
|
|
73
82
|
*/
|
|
74
83
|
/**
|
|
84
|
+
* FailedTestDetail type.
|
|
75
85
|
* @typedef {object} FailedTestDetail
|
|
76
86
|
* @property {string} fullDescription - Full test description.
|
|
77
87
|
* @property {string} [filePath] - Source file path.
|
|
78
88
|
* @property {number} [line] - Source line number.
|
|
79
|
-
* @property {
|
|
89
|
+
* @property {?} error - Failure error.
|
|
80
90
|
* @property {string} [consoleOutput] - Captured console output while test ran.
|
|
81
91
|
* @property {string} [consoleLogPath] - Saved console log path.
|
|
82
92
|
*/
|
|
83
93
|
/**
|
|
94
|
+
* ActiveAfterAllScopeEntry type.
|
|
84
95
|
* @typedef {object} ActiveAfterAllScopeEntry
|
|
85
96
|
* @property {TestsArgument} tests - Scope test tree.
|
|
86
97
|
* @property {boolean} afterAllsRun - Whether cleanup hooks have run.
|
|
87
98
|
*/
|
|
88
99
|
/**
|
|
100
|
+
* Defines this typedef.
|
|
89
101
|
* @typedef {function({configuration: import("../configuration.js").default, testArgs: TestArgs, testData: TestData}) : (void|Promise<void>)} AfterBeforeEachCallbackType
|
|
90
102
|
*/
|
|
91
103
|
/**
|
|
104
|
+
* AfterBeforeEachCallbackObjectType type.
|
|
92
105
|
* @typedef {object} AfterBeforeEachCallbackObjectType
|
|
93
106
|
* @property {AfterBeforeEachCallbackType} callback - Hook callback to execute.
|
|
94
107
|
*/
|
|
95
108
|
/**
|
|
109
|
+
* Defines this typedef.
|
|
96
110
|
* @typedef {function({configuration: import("../configuration.js").default}) : (void|Promise<void>)} BeforeAfterAllCallbackType
|
|
97
111
|
*/
|
|
98
112
|
/**
|
|
113
|
+
* BeforeAfterAllCallbackObjectType type.
|
|
99
114
|
* @typedef {object} BeforeAfterAllCallbackObjectType
|
|
100
115
|
* @property {BeforeAfterAllCallbackType} callback - Hook callback to execute.
|
|
101
116
|
*/
|
|
102
117
|
/**
|
|
118
|
+
* TestsArgument type.
|
|
103
119
|
* @typedef {object} TestsArgument
|
|
104
120
|
* @property {Record<string, TestData>} args - Arguments keyed by test description.
|
|
105
121
|
* @property {boolean} [anyTestsFocussed] - Whether any tests in the tree are focused.
|
|
@@ -113,11 +129,16 @@ function toFileSlug(value) {
|
|
|
113
129
|
* @property {Record<string, TestsArgument>} subs - Optional child nodes. Each item is another `Node`, allowing recursion.
|
|
114
130
|
*/
|
|
115
131
|
export default class TestRunner {
|
|
116
|
-
/**
|
|
132
|
+
/**
|
|
133
|
+
* Narrows the runtime value to the documented type.
|
|
134
|
+
@type {ActiveAfterAllScopeEntry[]} */
|
|
117
135
|
_activeAfterAllScopes;
|
|
118
|
-
/**
|
|
136
|
+
/**
|
|
137
|
+
* Narrows the runtime value to the documented type.
|
|
138
|
+
@type {FailedTestDetail[]} */
|
|
119
139
|
_failedTestDetails;
|
|
120
140
|
/**
|
|
141
|
+
* Runs constructor.
|
|
121
142
|
* @param {object} args - Options object.
|
|
122
143
|
* @param {import("../configuration.js").default} args.configuration - Configuration instance.
|
|
123
144
|
* @param {string[] | string} [args.excludeTags] - Tags to exclude.
|
|
@@ -145,18 +166,27 @@ export default class TestRunner {
|
|
|
145
166
|
this._failedTestDetails = [];
|
|
146
167
|
}
|
|
147
168
|
/**
|
|
169
|
+
* Runs get configuration.
|
|
148
170
|
* @returns {import("../configuration.js").default} - The configuration.
|
|
149
171
|
*/
|
|
150
172
|
getConfiguration() { return this._configuration; }
|
|
151
173
|
/**
|
|
174
|
+
* Runs get test files.
|
|
152
175
|
* @returns {string[]} - The test files.
|
|
153
176
|
*/
|
|
154
177
|
getTestFiles() { return this._testFiles; }
|
|
155
|
-
/**
|
|
178
|
+
/**
|
|
179
|
+
* Runs get line filters.
|
|
180
|
+
* @returns {Record<string, number[]>} - Line filters.
|
|
181
|
+
*/
|
|
156
182
|
getLineFilters() { return this._lineFilters; }
|
|
157
|
-
/**
|
|
183
|
+
/**
|
|
184
|
+
* Runs get example patterns.
|
|
185
|
+
* @returns {RegExp[]} - Example patterns.
|
|
186
|
+
*/
|
|
158
187
|
getExamplePatterns() { return this._examplePatterns; }
|
|
159
188
|
/**
|
|
189
|
+
* Runs normalize tags.
|
|
160
190
|
* @param {string[] | string | undefined} tags - Tags.
|
|
161
191
|
* @returns {string[]} - Normalized tags.
|
|
162
192
|
*/
|
|
@@ -178,6 +208,7 @@ export default class TestRunner {
|
|
|
178
208
|
return Array.from(new Set(values));
|
|
179
209
|
}
|
|
180
210
|
/**
|
|
211
|
+
* Runs has tag.
|
|
181
212
|
* @param {TestArgs} testArgs - Test args.
|
|
182
213
|
* @param {string} tag - Tag to check for.
|
|
183
214
|
* @returns {boolean} - Whether tag is present.
|
|
@@ -186,12 +217,14 @@ export default class TestRunner {
|
|
|
186
217
|
return this.normalizeTags(testArgs?.tags).includes(tag);
|
|
187
218
|
}
|
|
188
219
|
/**
|
|
220
|
+
* Runs is browser test mode.
|
|
189
221
|
* @returns {boolean} - Whether running browser tests.
|
|
190
222
|
*/
|
|
191
223
|
isBrowserTestMode() {
|
|
192
224
|
return process.env.VELOCIOUS_BROWSER_TESTS === "true";
|
|
193
225
|
}
|
|
194
226
|
/**
|
|
227
|
+
* Runs run with dummy if needed.
|
|
195
228
|
* @param {TestArgs} testArgs - Test args.
|
|
196
229
|
* @param {() => Promise<void>} callback - Callback to run.
|
|
197
230
|
* @returns {Promise<void>} - Resolves when complete.
|
|
@@ -208,6 +241,7 @@ export default class TestRunner {
|
|
|
208
241
|
await this.runNodeDummy(callback);
|
|
209
242
|
}
|
|
210
243
|
/**
|
|
244
|
+
* Runs run node dummy.
|
|
211
245
|
* @param {() => Promise<void>} callback - Callback to run.
|
|
212
246
|
* @returns {Promise<void>} - Resolves when complete.
|
|
213
247
|
*/
|
|
@@ -221,6 +255,7 @@ export default class TestRunner {
|
|
|
221
255
|
await Dummy.run(callback);
|
|
222
256
|
}
|
|
223
257
|
/**
|
|
258
|
+
* Runs default dummy path.
|
|
224
259
|
* @returns {string} - Default dummy helper path.
|
|
225
260
|
*/
|
|
226
261
|
defaultDummyPath() {
|
|
@@ -232,6 +267,7 @@ export default class TestRunner {
|
|
|
232
267
|
return path.join(cwd, "spec/dummy/index.js");
|
|
233
268
|
}
|
|
234
269
|
/**
|
|
270
|
+
* Runs run browser dummy.
|
|
235
271
|
* @param {() => Promise<void>} callback - Callback to run.
|
|
236
272
|
* @returns {Promise<void>} - Resolves when complete.
|
|
237
273
|
*/
|
|
@@ -247,6 +283,7 @@ export default class TestRunner {
|
|
|
247
283
|
});
|
|
248
284
|
}
|
|
249
285
|
/**
|
|
286
|
+
* Runs truncate databases.
|
|
250
287
|
* @param {Record<string, import("../database/drivers/base.js").default>} dbs - Database connections.
|
|
251
288
|
* @returns {Promise<void>} - Resolves when complete.
|
|
252
289
|
*/
|
|
@@ -256,14 +293,18 @@ export default class TestRunner {
|
|
|
256
293
|
}
|
|
257
294
|
}
|
|
258
295
|
/**
|
|
296
|
+
* Runs get exclude tag set.
|
|
259
297
|
* @returns {Set<string>} - Exclude tag set.
|
|
260
298
|
*/
|
|
261
299
|
getExcludeTagSet() {
|
|
262
|
-
/**
|
|
300
|
+
/**
|
|
301
|
+
* Config tags.
|
|
302
|
+
@type {string[]} */
|
|
263
303
|
const configTags = Array.isArray(testConfig.excludeTags) ? testConfig.excludeTags : [];
|
|
264
304
|
return new Set([...this._excludeTags, ...configTags]);
|
|
265
305
|
}
|
|
266
306
|
/**
|
|
307
|
+
* Runs has matching tag.
|
|
267
308
|
* @param {string[] | string | undefined} testTags - Test tags.
|
|
268
309
|
* @param {Set<string>} tagSet - Tag set.
|
|
269
310
|
* @returns {boolean} - Whether any tags match.
|
|
@@ -279,6 +320,7 @@ export default class TestRunner {
|
|
|
279
320
|
return false;
|
|
280
321
|
}
|
|
281
322
|
/**
|
|
323
|
+
* Runs has runnable tests.
|
|
282
324
|
* @param {TestsArgument} tests - Tests.
|
|
283
325
|
* @param {string[]} [descriptions] - Description stack.
|
|
284
326
|
* @param {boolean} [lineMatchedInScope] - Whether line matched in scope.
|
|
@@ -287,7 +329,9 @@ export default class TestRunner {
|
|
|
287
329
|
hasRunnableTests(tests, descriptions = [], lineMatchedInScope = false) {
|
|
288
330
|
for (const testDescription in tests.tests) {
|
|
289
331
|
const testData = tests.tests[testDescription];
|
|
290
|
-
const testArgs = /**
|
|
332
|
+
const testArgs = /**
|
|
333
|
+
* Narrows the runtime value to the documented type.
|
|
334
|
+
@type {TestArgs} */ (Object.assign({}, testData.args));
|
|
291
335
|
const includeByLine = lineMatchedInScope || this.matchesLineFilter(testData);
|
|
292
336
|
if (this._onlyFocussed && !testArgs.focus)
|
|
293
337
|
continue;
|
|
@@ -307,6 +351,7 @@ export default class TestRunner {
|
|
|
307
351
|
return false;
|
|
308
352
|
}
|
|
309
353
|
/**
|
|
354
|
+
* Runs should skip test.
|
|
310
355
|
* @param {TestArgs} testArgs - Test args.
|
|
311
356
|
* @param {TestData} testData - Test data.
|
|
312
357
|
* @param {string} testDescription - Test description.
|
|
@@ -338,6 +383,7 @@ export default class TestRunner {
|
|
|
338
383
|
return false;
|
|
339
384
|
}
|
|
340
385
|
/**
|
|
386
|
+
* Runs matches line filter.
|
|
341
387
|
* @param {TestData | TestsArgument} entry - Test entry.
|
|
342
388
|
* @returns {boolean} - Whether line filter matches entry.
|
|
343
389
|
*/
|
|
@@ -351,6 +397,7 @@ export default class TestRunner {
|
|
|
351
397
|
return lines.includes(entry.line);
|
|
352
398
|
}
|
|
353
399
|
/**
|
|
400
|
+
* Runs build full description.
|
|
354
401
|
* @param {string[]} descriptions - Description stack.
|
|
355
402
|
* @param {string} testDescription - Test description.
|
|
356
403
|
* @returns {string} - Full description.
|
|
@@ -360,6 +407,7 @@ export default class TestRunner {
|
|
|
360
407
|
return parts.join(" ").trim();
|
|
361
408
|
}
|
|
362
409
|
/**
|
|
410
|
+
* Runs application.
|
|
363
411
|
* @returns {Promise<Application>} - Resolves with the application.
|
|
364
412
|
*/
|
|
365
413
|
async application() {
|
|
@@ -375,6 +423,7 @@ export default class TestRunner {
|
|
|
375
423
|
return this._application;
|
|
376
424
|
}
|
|
377
425
|
/**
|
|
426
|
+
* Runs request client.
|
|
378
427
|
* @returns {Promise<RequestClient>} - Resolves with the request client.
|
|
379
428
|
*/
|
|
380
429
|
async requestClient() {
|
|
@@ -384,16 +433,19 @@ export default class TestRunner {
|
|
|
384
433
|
return this._requestClient;
|
|
385
434
|
}
|
|
386
435
|
/**
|
|
436
|
+
* Runs import test files.
|
|
387
437
|
* @returns {Promise<void>} - Resolves when complete.
|
|
388
438
|
*/
|
|
389
439
|
async importTestFiles() {
|
|
390
440
|
await this.getConfiguration().getEnvironmentHandler().importTestFiles(this.getTestFiles());
|
|
391
441
|
}
|
|
392
442
|
/**
|
|
443
|
+
* Runs is failed.
|
|
393
444
|
* @returns {boolean} - Whether failed.
|
|
394
445
|
*/
|
|
395
446
|
isFailed() { return this._failedTests !== undefined && this._failedTests > 0; }
|
|
396
447
|
/**
|
|
448
|
+
* Runs get failed tests.
|
|
397
449
|
* @returns {number} - The failed tests.
|
|
398
450
|
*/
|
|
399
451
|
getFailedTests() {
|
|
@@ -401,11 +453,15 @@ export default class TestRunner {
|
|
|
401
453
|
throw new Error("Tests hasn't been run yet");
|
|
402
454
|
return this._failedTests;
|
|
403
455
|
}
|
|
404
|
-
/**
|
|
456
|
+
/**
|
|
457
|
+
* Runs get failed test details.
|
|
458
|
+
* @returns {FailedTestDetail[]} - Failed test details.
|
|
459
|
+
*/
|
|
405
460
|
getFailedTestDetails() {
|
|
406
461
|
return this._failedTestDetails;
|
|
407
462
|
}
|
|
408
463
|
/**
|
|
464
|
+
* Runs persist failed test console outputs to assets.
|
|
409
465
|
* @param {object} [args] - Options object.
|
|
410
466
|
* @param {string} [args.assetsPath] - Assets directory path.
|
|
411
467
|
* @returns {Promise<string[]>} - Written log file paths.
|
|
@@ -443,6 +499,7 @@ export default class TestRunner {
|
|
|
443
499
|
return writtenLogPaths;
|
|
444
500
|
}
|
|
445
501
|
/**
|
|
502
|
+
* Runs get successful tests.
|
|
446
503
|
* @returns {number} - The successful tests.
|
|
447
504
|
*/
|
|
448
505
|
getSuccessfulTests() {
|
|
@@ -451,6 +508,7 @@ export default class TestRunner {
|
|
|
451
508
|
return this._successfulTests;
|
|
452
509
|
}
|
|
453
510
|
/**
|
|
511
|
+
* Runs get tests count.
|
|
454
512
|
* @returns {number} - The tests count.
|
|
455
513
|
*/
|
|
456
514
|
getTestsCount() {
|
|
@@ -459,6 +517,7 @@ export default class TestRunner {
|
|
|
459
517
|
return this._testsCount;
|
|
460
518
|
}
|
|
461
519
|
/**
|
|
520
|
+
* Runs get executed tests count.
|
|
462
521
|
* @returns {number} - The executed tests count.
|
|
463
522
|
*/
|
|
464
523
|
getExecutedTestsCount() {
|
|
@@ -468,6 +527,7 @@ export default class TestRunner {
|
|
|
468
527
|
return this._successfulTests + this._failedTests;
|
|
469
528
|
}
|
|
470
529
|
/**
|
|
530
|
+
* Runs prepare.
|
|
471
531
|
* @returns {Promise<void>} - Resolves when complete.
|
|
472
532
|
*/
|
|
473
533
|
async prepare() {
|
|
@@ -485,6 +545,7 @@ export default class TestRunner {
|
|
|
485
545
|
}
|
|
486
546
|
}
|
|
487
547
|
/**
|
|
548
|
+
* Runs are any tests focussed.
|
|
488
549
|
* @returns {boolean} - Whether any tests focussed.
|
|
489
550
|
*/
|
|
490
551
|
areAnyTestsFocussed() {
|
|
@@ -494,6 +555,7 @@ export default class TestRunner {
|
|
|
494
555
|
return this.anyTestsFocussed;
|
|
495
556
|
}
|
|
496
557
|
/**
|
|
558
|
+
* Runs run.
|
|
497
559
|
* @returns {Promise<void>} - Resolves when complete.
|
|
498
560
|
*/
|
|
499
561
|
async run() {
|
|
@@ -508,6 +570,7 @@ export default class TestRunner {
|
|
|
508
570
|
});
|
|
509
571
|
}
|
|
510
572
|
/**
|
|
573
|
+
* Runs run after alls for active scopes.
|
|
511
574
|
* @returns {Promise<void>} - Resolves when cleanup hooks finish.
|
|
512
575
|
*/
|
|
513
576
|
async runAfterAllsForActiveScopes() {
|
|
@@ -518,6 +581,7 @@ export default class TestRunner {
|
|
|
518
581
|
this._activeAfterAllScopes = [];
|
|
519
582
|
}
|
|
520
583
|
/**
|
|
584
|
+
* Runs analyze tests.
|
|
521
585
|
* @param {TestsArgument} tests - Tests.
|
|
522
586
|
* @returns {{anyTestsFocussed: boolean}} - Whether any tests in the tree are focused.
|
|
523
587
|
*/
|
|
@@ -543,6 +607,7 @@ export default class TestRunner {
|
|
|
543
607
|
return { anyTestsFocussed: anyTestsFocussedFound };
|
|
544
608
|
}
|
|
545
609
|
/**
|
|
610
|
+
* Runs run tests.
|
|
546
611
|
* @param {object} args - Options object.
|
|
547
612
|
* @param {Array<AfterBeforeEachCallbackObjectType>} args.afterEaches - After eaches.
|
|
548
613
|
* @param {Array<AfterBeforeEachCallbackObjectType>} args.beforeEaches - Before eaches.
|
|
@@ -560,7 +625,7 @@ export default class TestRunner {
|
|
|
560
625
|
const shouldRunAnyTests = this.hasRunnableTests(tests, descriptions, scopeLineMatch);
|
|
561
626
|
if (!shouldRunAnyTests)
|
|
562
627
|
return;
|
|
563
|
-
/** @type {ActiveAfterAllScopeEntry} */
|
|
628
|
+
/** Scope entry. @type {ActiveAfterAllScopeEntry} */
|
|
564
629
|
const scopeEntry = { tests, afterAllsRun: false };
|
|
565
630
|
this._activeAfterAllScopes.push(scopeEntry);
|
|
566
631
|
try {
|
|
@@ -569,7 +634,9 @@ export default class TestRunner {
|
|
|
569
634
|
}
|
|
570
635
|
for (const testDescription in tests.tests) {
|
|
571
636
|
const testData = tests.tests[testDescription];
|
|
572
|
-
const testArgs = /**
|
|
637
|
+
const testArgs = /**
|
|
638
|
+
* Narrows the runtime value to the documented type.
|
|
639
|
+
@type {TestArgs} */ (Object.assign({}, testData.args));
|
|
573
640
|
const includeByLine = scopeLineMatch || this.matchesLineFilter(testData);
|
|
574
641
|
if (this._onlyFocussed && !testArgs.focus)
|
|
575
642
|
continue;
|
|
@@ -590,16 +657,24 @@ export default class TestRunner {
|
|
|
590
657
|
const timeoutMs = useTimeout ? timeoutSeconds * 1000 : undefined;
|
|
591
658
|
let retriesUsed = 0;
|
|
592
659
|
let attemptNumber = 1;
|
|
593
|
-
/**
|
|
660
|
+
/**
|
|
661
|
+
* Attempt console outputs.
|
|
662
|
+
@type {AttemptConsoleOutput[]} */
|
|
594
663
|
const attemptConsoleOutputs = [];
|
|
595
664
|
console.log(`${leftPadding}it ${testDescription}`);
|
|
596
665
|
while (true) {
|
|
597
666
|
let shouldRetry = false;
|
|
598
|
-
/**
|
|
667
|
+
/**
|
|
668
|
+
* Defines caughtError.
|
|
669
|
+
@type {?} */
|
|
599
670
|
let caughtError;
|
|
600
|
-
/**
|
|
671
|
+
/**
|
|
672
|
+
* Defines failedError.
|
|
673
|
+
@type {?} */
|
|
601
674
|
let failedError;
|
|
602
|
-
/**
|
|
675
|
+
/**
|
|
676
|
+
* Defines lastError.
|
|
677
|
+
@type {?} */
|
|
603
678
|
let lastError;
|
|
604
679
|
let willRetry = false;
|
|
605
680
|
const stopConsoleCapture = this.startConsoleCapture({
|
|
@@ -780,6 +855,7 @@ export default class TestRunner {
|
|
|
780
855
|
}
|
|
781
856
|
}
|
|
782
857
|
/**
|
|
858
|
+
* Runs run after alls for scope.
|
|
783
859
|
* @param {ActiveAfterAllScopeEntry} scopeEntry - Scope entry.
|
|
784
860
|
* @returns {Promise<void>} - Resolves when scope cleanup finishes.
|
|
785
861
|
*/
|
|
@@ -792,6 +868,7 @@ export default class TestRunner {
|
|
|
792
868
|
}
|
|
793
869
|
}
|
|
794
870
|
/**
|
|
871
|
+
* Runs emit event.
|
|
795
872
|
* @param {string} eventName - Event name.
|
|
796
873
|
* @param {object} payload - Event payload.
|
|
797
874
|
* @returns {Promise<void>} - Resolves when all listeners complete.
|
|
@@ -803,6 +880,7 @@ export default class TestRunner {
|
|
|
803
880
|
}
|
|
804
881
|
}
|
|
805
882
|
/**
|
|
883
|
+
* Runs print rerun command.
|
|
806
884
|
* @param {object} args - Options object.
|
|
807
885
|
* @param {string[]} args.descriptions - Description stack.
|
|
808
886
|
* @param {string} args.testDescription - Test description.
|
|
@@ -817,6 +895,7 @@ export default class TestRunner {
|
|
|
817
895
|
}
|
|
818
896
|
}
|
|
819
897
|
/**
|
|
898
|
+
* Runs build rerun command.
|
|
820
899
|
* @param {object} args - Options object.
|
|
821
900
|
* @param {string[]} args.descriptions - Description stack.
|
|
822
901
|
* @param {string} args.testDescription - Test description.
|
|
@@ -838,6 +917,7 @@ export default class TestRunner {
|
|
|
838
917
|
return undefined;
|
|
839
918
|
}
|
|
840
919
|
/**
|
|
920
|
+
* Runs build console output.
|
|
841
921
|
* @param {AttemptConsoleOutput[]} attemptConsoleOutputs - Attempt output entries.
|
|
842
922
|
* @returns {string} - Combined console output.
|
|
843
923
|
*/
|
|
@@ -851,6 +931,7 @@ export default class TestRunner {
|
|
|
851
931
|
}).join("\n");
|
|
852
932
|
}
|
|
853
933
|
/**
|
|
934
|
+
* Runs get failed console output max lines.
|
|
854
935
|
* @returns {number} - Maximum failed console lines.
|
|
855
936
|
*/
|
|
856
937
|
getFailedConsoleOutputMaxLines() {
|
|
@@ -860,6 +941,7 @@ export default class TestRunner {
|
|
|
860
941
|
return Math.max(0, Math.floor(maxLines));
|
|
861
942
|
}
|
|
862
943
|
/**
|
|
944
|
+
* Runs truncate failed console output lines.
|
|
863
945
|
* @param {string} consoleOutput - Console output.
|
|
864
946
|
* @returns {string[]} - Lines for inline output.
|
|
865
947
|
*/
|
|
@@ -878,6 +960,7 @@ export default class TestRunner {
|
|
|
878
960
|
];
|
|
879
961
|
}
|
|
880
962
|
/**
|
|
963
|
+
* Runs print failed console output.
|
|
881
964
|
* @param {object} args - Options object.
|
|
882
965
|
* @param {string} args.consoleOutput - Console output.
|
|
883
966
|
* @param {string} args.leftPadding - Left padding.
|
|
@@ -897,16 +980,25 @@ export default class TestRunner {
|
|
|
897
980
|
}
|
|
898
981
|
}
|
|
899
982
|
/**
|
|
983
|
+
* Runs start console capture.
|
|
900
984
|
* @param {object} [args] - Options object.
|
|
901
985
|
* @param {boolean} [args.passthrough] - Whether to pass through to the original console.
|
|
902
986
|
* @returns {() => string} - Stops the capture and returns captured text.
|
|
903
987
|
*/
|
|
904
988
|
startConsoleCapture({ passthrough = false } = {}) {
|
|
905
|
-
/**
|
|
989
|
+
/**
|
|
990
|
+
* Lines.
|
|
991
|
+
@type {string[]} */
|
|
906
992
|
const lines = [];
|
|
907
|
-
/**
|
|
908
|
-
|
|
909
|
-
|
|
993
|
+
/**
|
|
994
|
+
* Console object.
|
|
995
|
+
@type {Record<ConsoleMethodName, (...args: Array<?>) => void>} */
|
|
996
|
+
const consoleObject = /**
|
|
997
|
+
* Narrows the runtime value to the documented type.
|
|
998
|
+
@type {Record<ConsoleMethodName, (...args: Array<?>) => void>} */ (console);
|
|
999
|
+
/**
|
|
1000
|
+
* Original console methods.
|
|
1001
|
+
@type {Record<ConsoleMethodName, (...args: Array<?>) => void>} */
|
|
910
1002
|
const originalConsoleMethods = {
|
|
911
1003
|
debug: consoleObject.debug.bind(console),
|
|
912
1004
|
error: consoleObject.error.bind(console),
|
|
@@ -936,4 +1028,4 @@ export default class TestRunner {
|
|
|
936
1028
|
};
|
|
937
1029
|
}
|
|
938
1030
|
}
|
|
939
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC1ydW5uZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdGVzdGluZy90ZXN0LXJ1bm5lci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxFQUFDLHNCQUFzQixFQUFDLE1BQU0sZ0NBQWdDLENBQUE7QUFDckUsT0FBTyxFQUFFLE1BQU0sa0JBQWtCLENBQUE7QUFDakMsT0FBTyxJQUFJLE1BQU0sTUFBTSxDQUFBO0FBQ3ZCLE9BQU8sRUFBQyxNQUFNLEVBQUMsTUFBTSxXQUFXLENBQUE7QUFDaEMsT0FBTyxXQUFXLE1BQU0sMEJBQTBCLENBQUE7QUFDbEQsT0FBTyxnQkFBZ0IsTUFBTSxvQ0FBb0MsQ0FBQTtBQUNqRSxPQUFPLGFBQWEsTUFBTSxxQkFBcUIsQ0FBQTtBQUMvQyxPQUFPLFVBQVUsTUFBTSxZQUFZLENBQUE7QUFDbkMsT0FBTyxhQUFhLE1BQU0sNkJBQTZCLENBQUE7QUFDdkQsT0FBTyxFQUFDLFVBQVUsRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFDLE1BQU0sV0FBVyxDQUFBO0FBQ3ZELE9BQU8sRUFBQyxhQUFhLEVBQUMsTUFBTSxLQUFLLENBQUE7QUFDakMsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLGNBQWMsQ0FBQTtBQUU1Qzs7Ozs7R0FLRztBQUNILFNBQVMsY0FBYyxDQUFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsZUFBZTtJQUN6RCxNQUFNLGNBQWMsR0FBRyxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQTtJQUMxRSxNQUFNLFlBQVksR0FBRyxJQUFJLEtBQUssQ0FBQyxtQkFBbUIsY0FBYyxNQUFNLGVBQWUsRUFBRSxDQUFDLENBQUE7SUFFeEYsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTtRQUNyQyxN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b3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IHthZGRUcmFja2VkU3RhY2tUb0Vycm9yfSBmcm9tIFwiLi4vdXRpbHMvd2l0aC10cmFja2VkLXN0YWNrLmpzXCJcbmltcG9ydCBmcyBmcm9tIFwibm9kZTpmcy9wcm9taXNlc1wiXG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiXG5pbXBvcnQge2Zvcm1hdH0gZnJvbSBcIm5vZGU6dXRpbFwiXG5pbXBvcnQgQXBwbGljYXRpb24gZnJvbSBcIi4uLy4uL3NyYy9hcHBsaWNhdGlvbi5qc1wiXG5pbXBvcnQgQmFja3RyYWNlQ2xlYW5lciBmcm9tIFwiLi4vdXRpbHMvYmFja3RyYWNlLWNsZWFuZXItbm9kZS5qc1wiXG5pbXBvcnQgUmVxdWVzdENsaWVudCBmcm9tIFwiLi9yZXF1ZXN0LWNsaWVudC5qc1wiXG5pbXBvcnQgcGljb2NvbG9ycyBmcm9tIFwicGljb2NvbG9yc1wiXG5pbXBvcnQgcmVzdEFyZ3NFcnJvciBmcm9tIFwiLi4vdXRpbHMvcmVzdC1hcmdzLWVycm9yLmpzXCJcbmltcG9ydCB7dGVzdENvbmZpZywgdGVzdEV2ZW50cywgdGVzdHN9IGZyb20gXCIuL3Rlc3QuanNcIlxuaW1wb3J0IHtwYXRoVG9GaWxlVVJMfSBmcm9tIFwidXJsXCJcbmltcG9ydCB7Y2xlYXJEZWxpdmVyaWVzfSBmcm9tIFwiLi4vbWFpbGVyLmpzXCJcblxuLyoqXG4gKiBAcGFyYW0ge1Byb21pc2U8dW5rbm93bj4gfCB1bmtub3dufSBwcm9taXNlIC0gUHJvbWlzZSBvciB2YWx1ZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB0aW1lb3V0TXMgLSBUaW1lb3V0IGluIG1pbGxpc2Vjb25kcy5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXN0RGVzY3JpcHRpb24gLSBUZXN0IGRlc2NyaXB0aW9uLlxuICogQHJldHVybnMge1Byb21pc2U8dW5rbm93bj59IC0gUmVzb2x2ZXMgb3IgcmVqZWN0cyBiYXNlZCBvbiB0aW1lb3V0IG9yIHByb21pc2UgcmVzdWx0LlxuICovXG5mdW5jdGlvbiBydW5XaXRoVGltZW91dChwcm9taXNlLCB0aW1lb3V0TXMsIHRlc3REZXNjcmlwdGlvbikge1xuICBjb25zdCB0aW1lb3V0U2Vjb25kcyA9ICh0aW1lb3V0TXMgLyAxMDAwKS50b0ZpeGVkKDMpLnJlcGxhY2UoL1xcLj8wKyQvLCBcIlwiKVxuICBjb25zdCB0aW1lb3V0RXJyb3IgPSBuZXcgRXJyb3IoYFRpbWVkIG91dCBhZnRlciAke3RpbWVvdXRTZWNvbmRzfXM6ICR7dGVzdERlc2NyaXB0aW9ufWApXG5cbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCB0aW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiByZWplY3QodGltZW91dEVycm9yKSwgdGltZW91dE1zKVxuXG4gICAgUHJvbWlzZS5yZXNvbHZlKHByb21pc2UpLnRoZW4oKHJlc3VsdCkgPT4ge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpXG4gICAgICByZXNvbHZlKHJlc3VsdClcbiAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KVxuICAgICAgcmVqZWN0KGVycm9yKVxuICAgIH0pXG4gIH0pXG59XG5cbi8qKiBAdHlwZWRlZiB7XCJsb2dcIiB8IFwiaW5mb1wiIHwgXCJ3YXJuXCIgfCBcImVycm9yXCIgfCBcImRlYnVnXCJ9IENvbnNvbGVNZXRob2ROYW1lICovXG5cbi8qKiBAdHlwZSB7Q29uc29sZU1ldGhvZE5hbWVbXX0gKi9cbmNvbnN0IENBUFRVUkVEX0NPTlNPTEVfTUVUSE9EUyA9IFtcImxvZ1wiLCBcImluZm9cIiwgXCJ3YXJuXCIsIFwiZXJyb3JcIiwgXCJkZWJ1Z1wiXVxuXG4vKipcbiAqIEB0eXBlZGVmIHtvYmplY3R9IEF0dGVtcHRDb25zb2xlT3V0cHV0XG4gKiBAcHJvcGVydHkge251bWJlcn0gYXR0ZW1wdE51bWJlciAtIEF0dGVtcHQgbnVtYmVyLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IG91dHB1dCAtIENhcHR1cmVkIGNvbnNvbGUgb3V0cHV0LlxuICovXG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlIC0gVmFsdWUgdG8gc2FuaXRpemUuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSAtIFNsdWctc2FmZSB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gdG9GaWxlU2x1Zyh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWVcbiAgICAudG9Mb3dlckNhc2UoKVxuICAgIC5yZXBsYWNlKC9bXmEtejAtOV0rL2csIFwiLVwiKVxuICAgIC5yZXBsYWNlKC9eLSt8LSskL2csIFwiXCIpXG4gICAgLnNsaWNlKDAsIDgwKSB8fCBcImZhaWxlZC10ZXN0XCJcbn1cblxuLyoqXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBUZXN0QXJnc1xuICogQHByb3BlcnR5IHtBcHBsaWNhdGlvbn0gW2FwcGxpY2F0aW9uXSAtIEFwcGxpY2F0aW9uIGluc3RhbmNlIGZvciBpbnRlZ3JhdGlvbiB0ZXN0cy5cbiAqIEBwcm9wZXJ0eSB7UmVxdWVzdENsaWVudH0gW2NsaWVudF0gLSBIVFRQIGNsaWVudCBmb3IgcmVxdWVzdCB0ZXN0cy5cbiAqIEBwcm9wZXJ0eSB7b2JqZWN0fSBbZGF0YWJhc2VDbGVhbmluZ10gLSBEYXRhYmFzZSBjbGVhbnVwIG9wdGlvbnMgZm9yIHRlc3RzLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbZGF0YWJhc2VDbGVhbmluZy50cmFuc2FjdGlvbl0gLSBVc2UgdHJhbnNhY3Rpb25zIHRvIHJvbGxiYWNrIGJldHdlZW4gdGVzdHMuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtkYXRhYmFzZUNsZWFuaW5nLnRydW5jYXRlXSAtIFRydW5jYXRlIHRhYmxlcyBiZXR3ZWVuIHRlc3RzLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbZm9jdXNdIC0gV2hldGhlciB0aGlzIHRlc3QgaXMgZm9jdXNlZC5cbiAqIEBwcm9wZXJ0eSB7KCkgPT4gKHZvaWR8UHJvbWlzZTx2b2lkPil9IFtmdW5jdGlvbl0gLSBUZXN0IGNhbGxiYWNrIGZ1bmN0aW9uLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtyZXRyeV0gLSBOdW1iZXIgb2YgcmV0cmllcyB3aGVuIGEgdGVzdCBmYWlscy5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nW10gfCBzdHJpbmd9IFt0YWdzXSAtIFRhZ3MgZm9yIGZpbHRlcmluZy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbdGltZW91dFNlY29uZHNdIC0gVGltZW91dCBpbiBzZWNvbmRzIGZvciB0aGUgdGVzdC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbdHlwZV0gLSBUZXN0IHR5cGUgaWRlbnRpZmllci5cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtvYmplY3R9IFRlc3REYXRhXG4gKiBAcHJvcGVydHkge1Rlc3RBcmdzfSBhcmdzIC0gQXJndW1lbnRzIHBhc3NlZCB0byB0aGUgdGVzdC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbZmlsZVBhdGhdIC0gU291cmNlIGZpbGUgcGF0aC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbGluZV0gLSBTb3VyY2UgbGluZSBudW1iZXIuXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9uKFRlc3RBcmdzKSA6ICh2b2lkfFByb21pc2U8dm9pZD4pfSBmdW5jdGlvbiAtIFRlc3QgY2FsbGJhY2sgdG8gZXhlY3V0ZS5cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtvYmplY3R9IEZhaWxlZFRlc3REZXRhaWxcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBmdWxsRGVzY3JpcHRpb24gLSBGdWxsIHRlc3QgZGVzY3JpcHRpb24uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2ZpbGVQYXRoXSAtIFNvdXJjZSBmaWxlIHBhdGguXG4gKiBAcHJvcGVydHkge251bWJlcn0gW2xpbmVdIC0gU291cmNlIGxpbmUgbnVtYmVyLlxuICogQHByb3BlcnR5IHt1bmtub3dufSBlcnJvciAtIEZhaWx1cmUgZXJyb3IuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2NvbnNvbGVPdXRwdXRdIC0gQ2FwdHVyZWQgY29uc29sZSBvdXRwdXQgd2hpbGUgdGVzdCByYW4uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2NvbnNvbGVMb2dQYXRoXSAtIFNhdmVkIGNvbnNvbGUgbG9nIHBhdGguXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBBY3RpdmVBZnRlckFsbFNjb3BlRW50cnlcbiAqIEBwcm9wZXJ0eSB7VGVzdHNBcmd1bWVudH0gdGVzdHMgLSBTY29wZSB0ZXN0IHRyZWUuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IGFmdGVyQWxsc1J1biAtIFdoZXRoZXIgY2xlYW51cCBob29rcyBoYXZlIHJ1bi5cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtmdW5jdGlvbih7Y29uZmlndXJhdGlvbjogaW1wb3J0KFwiLi4vY29uZmlndXJhdGlvbi5qc1wiKS5kZWZhdWx0LCB0ZXN0QXJnczogVGVzdEFyZ3MsIHRlc3REYXRhOiBUZXN0RGF0YX0pIDogKHZvaWR8UHJvbWlzZTx2b2lkPil9IEFmdGVyQmVmb3JlRWFjaENhbGxiYWNrVHlwZVxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge29iamVjdH0gQWZ0ZXJCZWZvcmVFYWNoQ2FsbGJhY2tPYmplY3RUeXBlXG4gKiBAcHJvcGVydHkge0FmdGVyQmVmb3JlRWFjaENhbGxiYWNrVHlwZX0gY2FsbGJhY2sgLSBIb29rIGNhbGxiYWNrIHRvIGV4ZWN1dGUuXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7ZnVuY3Rpb24oe2NvbmZpZ3VyYXRpb246IGltcG9ydChcIi4uL2NvbmZpZ3VyYXRpb24uanNcIikuZGVmYXVsdH0pIDogKHZvaWR8UHJvbWlzZTx2b2lkPil9IEJlZm9yZUFmdGVyQWxsQ2FsbGJhY2tUeXBlXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBCZWZvcmVBZnRlckFsbENhbGxiYWNrT2JqZWN0VHlwZVxuICogQHByb3BlcnR5IHtCZWZvcmVBZnRlckFsbENhbGxiYWNrVHlwZX0gY2FsbGJhY2sgLSBIb29rIGNhbGxiYWNrIHRvIGV4ZWN1dGUuXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBUZXN0c0FyZ3VtZW50XG4gKiBAcHJvcGVydHkge1JlY29yZDxzdHJpbmcsIFRlc3REYXRhPn0gYXJncyAtIEFyZ3VtZW50cyBrZXllZCBieSB0ZXN0IGRlc2NyaXB0aW9uLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbYW55VGVzdHNGb2N1c3NlZF0gLSBXaGV0aGVyIGFueSB0ZXN0cyBpbiB0aGUgdHJlZSBhcmUgZm9jdXNlZC5cbiAqIEBwcm9wZXJ0eSB7QWZ0ZXJCZWZvcmVFYWNoQ2FsbGJhY2tPYmplY3RUeXBlW119IGFmdGVyRWFjaGVzIC0gQWZ0ZXItZWFjaCBob29rcyBmb3IgdGhpcyBzY29wZS5cbiAqIEBwcm9wZXJ0eSB7QmVmb3JlQWZ0ZXJBbGxDYWxsYmFja09iamVjdFR5cGVbXX0gYWZ0ZXJBbGxzIC0gQWZ0ZXItYWxsIGhvb2tzIGZvciB0aGlzIHNjb3BlLlxuICogQHByb3BlcnR5IHtCZWZvcmVBZnRlckFsbENhbGxiYWNrT2JqZWN0VHlwZVtdfSBiZWZvcmVBbGxzIC0gQmVmb3JlLWFsbCBob29rcyBmb3IgdGhpcyBzY29wZS5cbiAqIEBwcm9wZXJ0eSB7QWZ0ZXJCZWZvcmVFYWNoQ2FsbGJhY2tPYmplY3RUeXBlW119IGJlZm9yZUVhY2hlcyAtIEJlZm9yZS1lYWNoIGhvb2tzIGZvciB0aGlzIHNjb3BlLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFtmaWxlUGF0aF0gLSBTb3VyY2UgZmlsZSBwYXRoLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtsaW5lXSAtIFNvdXJjZSBsaW5lIG51bWJlci5cbiAqIEBwcm9wZXJ0eSB7UmVjb3JkPHN0cmluZywgVGVzdERhdGE+fSB0ZXN0cyAtIEEgdW5pcXVlIGlkZW50aWZpZXIgZm9yIHRoZSBub2RlLlxuICogQHByb3BlcnR5IHtSZWNvcmQ8c3RyaW5nLCBUZXN0c0FyZ3VtZW50Pn0gc3VicyAtIE9wdGlvbmFsIGNoaWxkIG5vZGVzLiBFYWNoIGl0ZW0gaXMgYW5vdGhlciBgTm9kZWAsIGFsbG93aW5nIHJlY3Vyc2lvbi5cbiAqL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUZXN0UnVubmVyIHtcbiAgLyoqIEB0eXBlIHtBY3RpdmVBZnRlckFsbFNjb3BlRW50cnlbXX0gKi9cbiAgX2FjdGl2ZUFmdGVyQWxsU2NvcGVzXG5cbiAgLyoqIEB0eXBlIHtGYWlsZWRUZXN0RGV0YWlsW119ICovXG4gIF9mYWlsZWRUZXN0RGV0YWlsc1xuXG4gIC8qKlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2NvbmZpZ3VyYXRpb24uanNcIikuZGVmYXVsdH0gYXJncy5jb25maWd1cmF0aW9uIC0gQ29uZmlndXJhdGlvbiBpbnN0YW5jZS5cbiAgICogQHBhcmFtIHtzdHJpbmdbXSB8IHN0cmluZ30gW2FyZ3MuZXhjbHVkZVRhZ3NdIC0gVGFncyB0byBleGNsdWRlLlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdIHwgc3RyaW5nfSBbYXJncy5pbmNsdWRlVGFnc10gLSBUYWdzIHRvIGluY2x1ZGUuXG4gICAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nPn0gYXJncy50ZXN0RmlsZXMgLSBUZXN0IGZpbGVzLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIG51bWJlcltdPn0gW2FyZ3MubGluZUZpbHRlcnNdIC0gTGluZSBmaWx0ZXJzIGJ5IGZpbGUuXG4gICAqIEBwYXJhbSB7UmVnRXhwW119IFthcmdzLmV4YW1wbGVQYXR0ZXJuc10gLSBFeGFtcGxlIHBhdHRlcm5zLlxuICAgKi9cbiAgY29uc3RydWN0b3Ioe2NvbmZpZ3VyYXRpb24sIGV4Y2x1ZGVUYWdzLCBpbmNsdWRlVGFncywgdGVzdEZpbGVzLCBsaW5lRmlsdGVycywgZXhhbXBsZVBhdHRlcm5zLCAuLi5yZXN0QXJnc30pIHtcbiAgICByZXN0QXJnc0Vycm9yKHJlc3RBcmdzKVxuXG4gICAgaWYgKCFjb25maWd1cmF0aW9uKSB0aHJvdyBuZXcgRXJyb3IoXCJjb25maWd1cmF0aW9uIGlzIHJlcXVpcmVkXCIpXG5cbiAgICB0aGlzLl9jb25maWd1cmF0aW9uID0gY29uZmlndXJhdGlvblxuICAgIHRoaXMuX2V4Y2x1ZGVUYWdzID0gdGhpcy5ub3JtYWxpemVUYWdzKGV4Y2x1ZGVUYWdzKVxuICAgIHRoaXMuX2V4Y2x1ZGVUYWdTZXQgPSBuZXcgU2V0KHRoaXMuX2V4Y2x1ZGVUYWdzKVxuICAgIHRoaXMuX2luY2x1ZGVUYWdzID0gdGhpcy5ub3JtYWxpemVUYWdzKGluY2x1ZGVUYWdzKVxuICAgIHRoaXMuX2luY2x1ZGVUYWdTZXQgPSBuZXcgU2V0KHRoaXMuX2luY2x1ZGVUYWdzKVxuICAgIHRoaXMuX3Rlc3RGaWxlcyA9IHRlc3RGaWxlc1xuICAgIHRoaXMuX2xpbmVGaWx0ZXJzID0gbGluZUZpbHRlcnMgfHwge31cbiAgICB0aGlzLl9leGFtcGxlUGF0dGVybnMgPSBleGFtcGxlUGF0dGVybnMgfHwgW11cblxuICAgIHRoaXMuX2ZhaWxlZFRlc3RzID0gMFxuICAgIHRoaXMuX3N1Y2Nlc3NmdWxUZXN0cyA9IDBcbiAgICB0aGlzLl90ZXN0c0NvdW50ID0gMFxuICAgIHRoaXMuX2FjdGl2ZUFmdGVyQWxsU2NvcGVzID0gW11cbiAgICB0aGlzLl9mYWlsZWRUZXN0RGV0YWlscyA9IFtdXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL2NvbmZpZ3VyYXRpb24uanNcIikuZGVmYXVsdH0gLSBUaGUgY29uZmlndXJhdGlvbi5cbiAgICovXG4gIGdldENvbmZpZ3VyYXRpb24oKSB7IHJldHVybiB0aGlzLl9jb25maWd1cmF0aW9uIH1cblxuICAvKipcbiAgICogQHJldHVybnMge3N0cmluZ1tdfSAtIFRoZSB0ZXN0IGZpbGVzLlxuICAgKi9cbiAgZ2V0VGVzdEZpbGVzKCkgeyByZXR1cm4gdGhpcy5fdGVzdEZpbGVzIH1cblxuICAvKiogQHJldHVybnMge1JlY29yZDxzdHJpbmcsIG51bWJlcltdPn0gLSBMaW5lIGZpbHRlcnMuICovXG4gIGdldExpbmVGaWx0ZXJzKCkgeyByZXR1cm4gdGhpcy5fbGluZUZpbHRlcnMgfVxuXG4gIC8qKiBAcmV0dXJucyB7UmVnRXhwW119IC0gRXhhbXBsZSBwYXR0ZXJucy4gKi9cbiAgZ2V0RXhhbXBsZVBhdHRlcm5zKCkgeyByZXR1cm4gdGhpcy5fZXhhbXBsZVBhdHRlcm5zIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmdbXSB8IHN0cmluZyB8IHVuZGVmaW5lZH0gdGFncyAtIFRhZ3MuXG4gICAqIEByZXR1cm5zIHtzdHJpbmdbXX0gLSBOb3JtYWxpemVkIHRhZ3MuXG4gICAqL1xuICBub3JtYWxpemVUYWdzKHRhZ3MpIHtcbiAgICBpZiAoIXRhZ3MpIHJldHVybiBbXVxuXG4gICAgY29uc3QgdmFsdWVzID0gW11cbiAgICBjb25zdCByYXdUYWdzID0gQXJyYXkuaXNBcnJheSh0YWdzKSA/IHRhZ3MgOiBbdGFnc11cblxuICAgIGZvciAoY29uc3QgcmF3VGFnIG9mIHJhd1RhZ3MpIHtcbiAgICAgIGlmIChyYXdUYWcgPT09IHVuZGVmaW5lZCB8fCByYXdUYWcgPT09IG51bGwpIGNvbnRpbnVlXG5cbiAgICAgIGNvbnN0IHBhcnRzID0gU3RyaW5nKHJhd1RhZykuc3BsaXQoXCIsXCIpXG5cbiAgICAgIGZvciAoY29uc3QgcGFydCBvZiBwYXJ0cykge1xuICAgICAgICBjb25zdCB0cmltbWVkID0gcGFydC50cmltKClcblxuICAgICAgICBpZiAodHJpbW1lZCkgdmFsdWVzLnB1c2godHJpbW1lZClcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gQXJyYXkuZnJvbShuZXcgU2V0KHZhbHVlcykpXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtUZXN0QXJnc30gdGVzdEFyZ3MgLSBUZXN0IGFyZ3MuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0YWcgLSBUYWcgdG8gY2hlY2sgZm9yLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIHRhZyBpcyBwcmVzZW50LlxuICAgKi9cbiAgaGFzVGFnKHRlc3RBcmdzLCB0YWcpIHtcbiAgICByZXR1cm4gdGhpcy5ub3JtYWxpemVUYWdzKHRlc3RBcmdzPy50YWdzKS5pbmNsdWRlcyh0YWcpXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gV2hldGhlciBydW5uaW5nIGJyb3dzZXIgdGVzdHMuXG4gICAqL1xuICBpc0Jyb3dzZXJUZXN0TW9kZSgpIHtcbiAgICByZXR1cm4gcHJvY2Vzcy5lbnYuVkVMT0NJT1VTX0JST1dTRVJfVEVTVFMgPT09IFwidHJ1ZVwiXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtUZXN0QXJnc30gdGVzdEFyZ3MgLSBUZXN0IGFyZ3MuXG4gICAqIEBwYXJhbSB7KCkgPT4gUHJvbWlzZTx2b2lkPn0gY2FsbGJhY2sgLSBDYWxsYmFjayB0byBydW4uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBydW5XaXRoRHVtbXlJZk5lZWRlZCh0ZXN0QXJncywgY2FsbGJhY2spIHtcbiAgICBpZiAoIXRoaXMuaGFzVGFnKHRlc3RBcmdzLCBcImR1bW15XCIpKSB7XG4gICAgICBhd2FpdCBjYWxsYmFjaygpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAodGhpcy5pc0Jyb3dzZXJUZXN0TW9kZSgpKSB7XG4gICAgICBhd2FpdCB0aGlzLnJ1bkJyb3dzZXJEdW1teShjYWxsYmFjaylcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGF3YWl0IHRoaXMucnVuTm9kZUR1bW15KGNhbGxiYWNrKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7KCkgPT4gUHJvbWlzZTx2b2lkPn0gY2FsbGJhY2sgLSBDYWxsYmFjayB0byBydW4uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBydW5Ob2RlRHVtbXkoY2FsbGJhY2spIHtcbiAgICBjb25zdCBkdW1teVBhdGggPSBwcm9jZXNzLmVudi5WRUxPQ0lPVVNfRFVNTVlfUEFUSCB8fCB0aGlzLmRlZmF1bHREdW1teVBhdGgoKVxuICAgIGNvbnN0IGR1bW15SW1wb3J0ID0gYXdhaXQgaW1wb3J0KHBhdGhUb0ZpbGVVUkwoZHVtbXlQYXRoKS5ocmVmKVxuICAgIGNvbnN0IER1bW15ID0gZHVtbXlJbXBvcnQuZGVmYXVsdFxuXG4gICAgaWYgKCFEdW1teT8ucnVuKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYER1bW15IGhlbHBlciBub3QgZm91bmQgYXQgJHtkdW1teVBhdGh9YClcbiAgICB9XG5cbiAgICBhd2FpdCBEdW1teS5ydW4oY2FsbGJhY2spXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge3N0cmluZ30gLSBEZWZhdWx0IGR1bW15IGhlbHBlciBwYXRoLlxuICAgKi9cbiAgZGVmYXVsdER1bW15UGF0aCgpIHtcbiAgICBjb25zdCBjd2QgPSBwYXRoLnJlc29sdmUocHJvY2Vzcy5jd2QoKSlcbiAgICBjb25zdCBub3JtYWxpemVkID0gY3dkLnNwbGl0KHBhdGguc2VwKS5qb2luKFwiL1wiKVxuXG4gICAgaWYgKG5vcm1hbGl6ZWQuZW5kc1dpdGgoXCIvc3BlYy9kdW1teVwiKSkge1xuICAgICAgcmV0dXJuIHBhdGguam9pbihjd2QsIFwiaW5kZXguanNcIilcbiAgICB9XG5cbiAgICByZXR1cm4gcGF0aC5qb2luKGN3ZCwgXCJzcGVjL2R1bW15L2luZGV4LmpzXCIpXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHsoKSA9PiBQcm9taXNlPHZvaWQ+fSBjYWxsYmFjayAtIENhbGxiYWNrIHRvIHJ1bi5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIHJ1bkJyb3dzZXJEdW1teShjYWxsYmFjaykge1xuICAgIGF3YWl0IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpLmVuc3VyZUNvbm5lY3Rpb25zKHtuYW1lOiBcIlRlc3QgcnVubmVyIGJyb3dzZXIgZHVtbXlcIn0sIGFzeW5jIChkYnMpID0+IHtcbiAgICAgIGF3YWl0IHRoaXMudHJ1bmNhdGVEYXRhYmFzZXMoZGJzKVxuXG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBjYWxsYmFjaygpXG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCB0aGlzLnRydW5jYXRlRGF0YWJhc2VzKGRicylcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgaW1wb3J0KFwiLi4vZGF0YWJhc2UvZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQ+fSBkYnMgLSBEYXRhYmFzZSBjb25uZWN0aW9ucy5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIHRydW5jYXRlRGF0YWJhc2VzKGRicykge1xuICAgIGZvciAoY29uc3QgaWRlbnRpZmllciBvZiBPYmplY3Qua2V5cyhkYnMpKSB7XG4gICAgICBhd2FpdCBkYnNbaWRlbnRpZmllcl0udHJ1bmNhdGVBbGxUYWJsZXMoKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7U2V0PHN0cmluZz59IC0gRXhjbHVkZSB0YWcgc2V0LlxuICAgKi9cbiAgZ2V0RXhjbHVkZVRhZ1NldCgpIHtcbiAgICAvKiogQHR5cGUge3N0cmluZ1tdfSAqL1xuICAgIGNvbnN0IGNvbmZpZ1RhZ3MgPSBBcnJheS5pc0FycmF5KHRlc3RDb25maWcuZXhjbHVkZVRhZ3MpID8gdGVzdENvbmZpZy5leGNsdWRlVGFncyA6IFtdXG5cbiAgICByZXR1cm4gbmV3IFNldChbLi4udGhpcy5fZXhjbHVkZVRhZ3MsIC4uLmNvbmZpZ1RhZ3NdKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nW10gfCBzdHJpbmcgfCB1bmRlZmluZWR9IHRlc3RUYWdzIC0gVGVzdCB0YWdzLlxuICAgKiBAcGFyYW0ge1NldDxzdHJpbmc+fSB0YWdTZXQgLSBUYWcgc2V0LlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIGFueSB0YWdzIG1hdGNoLlxuICAgKi9cbiAgaGFzTWF0Y2hpbmdUYWcodGVzdFRhZ3MsIHRhZ1NldCkge1xuICAgIGlmICghdGFnU2V0LnNpemUpIHJldHVybiBmYWxzZVxuXG4gICAgY29uc3Qgbm9ybWFsaXplZCA9IHRoaXMubm9ybWFsaXplVGFncyh0ZXN0VGFncylcblxuICAgIGZvciAoY29uc3QgdGFnIG9mIG5vcm1hbGl6ZWQpIHtcbiAgICAgIGlmICh0YWdTZXQuaGFzKHRhZykpIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtUZXN0c0FyZ3VtZW50fSB0ZXN0cyAtIFRlc3RzLlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBbZGVzY3JpcHRpb25zXSAtIERlc2NyaXB0aW9uIHN0YWNrLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtsaW5lTWF0Y2hlZEluU2NvcGVdIC0gV2hldGhlciBsaW5lIG1hdGNoZWQgaW4gc2NvcGUuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgYW55IHRlc3RzIGluIHRoaXMgc2NvcGUgd2lsbCBydW4uXG4gICAqL1xuICBoYXNSdW5uYWJsZVRlc3RzKHRlc3RzLCBkZXNjcmlwdGlvbnMgPSBbXSwgbGluZU1hdGNoZWRJblNjb3BlID0gZmFsc2UpIHtcbiAgICBmb3IgKGNvbnN0IHRlc3REZXNjcmlwdGlvbiBpbiB0ZXN0cy50ZXN0cykge1xuICAgICAgY29uc3QgdGVzdERhdGEgPSB0ZXN0cy50ZXN0c1t0ZXN0RGVzY3JpcHRpb25dXG4gICAgICBjb25zdCB0ZXN0QXJncyA9IC8qKiBAdHlwZSB7VGVzdEFyZ3N9ICovIChPYmplY3QuYXNzaWduKHt9LCB0ZXN0RGF0YS5hcmdzKSlcbiAgICAgIGNvbnN0IGluY2x1ZGVCeUxpbmUgPSBsaW5lTWF0Y2hlZEluU2NvcGUgfHwgdGhpcy5tYXRjaGVzTGluZUZpbHRlcih0ZXN0RGF0YSlcblxuICAgICAgaWYgKHRoaXMuX29ubHlGb2N1c3NlZCAmJiAhdGVzdEFyZ3MuZm9jdXMpIGNvbnRpbnVlXG4gICAgICBpZiAodGhpcy5zaG91bGRTa2lwVGVzdCh0ZXN0QXJncywgdGVzdERhdGEsIHRlc3REZXNjcmlwdGlvbiwgZGVzY3JpcHRpb25zLCBpbmNsdWRlQnlMaW5lKSkgY29udGludWVcblxuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHN1YkRlc2NyaXB0aW9uIGluIHRlc3RzLnN1YnMpIHtcbiAgICAgIGNvbnN0IHN1YlRlc3QgPSB0ZXN0cy5zdWJzW3N1YkRlc2NyaXB0aW9uXVxuICAgICAgY29uc3Qgc2NvcGVMaW5lTWF0Y2ggPSBsaW5lTWF0Y2hlZEluU2NvcGUgfHwgdGhpcy5tYXRjaGVzTGluZUZpbHRlcihzdWJUZXN0KVxuICAgICAgY29uc3QgbmV4dERlc2NyaXB0aW9ucyA9IGRlc2NyaXB0aW9ucy5jb25jYXQoW3N1YkRlc2NyaXB0aW9uXSlcblxuICAgICAgaWYgKHRoaXMuX29ubHlGb2N1c3NlZCAmJiAhc3ViVGVzdC5hbnlUZXN0c0ZvY3Vzc2VkKSBjb250aW51ZVxuICAgICAgaWYgKHRoaXMuaGFzUnVubmFibGVUZXN0cyhzdWJUZXN0LCBuZXh0RGVzY3JpcHRpb25zLCBzY29wZUxpbmVNYXRjaCkpIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtUZXN0QXJnc30gdGVzdEFyZ3MgLSBUZXN0IGFyZ3MuXG4gICAqIEBwYXJhbSB7VGVzdERhdGF9IHRlc3REYXRhIC0gVGVzdCBkYXRhLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGVzdERlc2NyaXB0aW9uIC0gVGVzdCBkZXNjcmlwdGlvbi5cbiAgICogQHBhcmFtIHtzdHJpbmdbXX0gZGVzY3JpcHRpb25zIC0gRGVzY3JpcHRpb24gc3RhY2suXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gbGluZU1hdGNoZWRJblNjb3BlIC0gV2hldGhlciBsaW5lIG1hdGNoZWQgaW4gc2NvcGUuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgdGhlIHRlc3Qgc2hvdWxkIGJlIHNraXBwZWQuXG4gICAqL1xuICBzaG91bGRTa2lwVGVzdCh0ZXN0QXJncywgdGVzdERhdGEsIHRlc3REZXNjcmlwdGlvbiwgZGVzY3JpcHRpb25zLCBsaW5lTWF0Y2hlZEluU2NvcGUpIHtcbiAgICBpZiAodGhpcy5oYXNNYXRjaGluZ1RhZyh0ZXN0QXJncy50YWdzLCB0aGlzLmdldEV4Y2x1ZGVUYWdTZXQoKSkpIHJldHVybiB0cnVlXG5cbiAgICBpZiAodGhpcy5faW5jbHVkZVRhZ1NldC5zaXplID4gMCAmJiAhdGVzdEFyZ3MuZm9jdXMpIHtcbiAgICAgIGlmICghdGhpcy5oYXNNYXRjaGluZ1RhZyh0ZXN0QXJncy50YWdzLCB0aGlzLl9pbmNsdWRlVGFnU2V0KSkgcmV0dXJuIHRydWVcbiAgICB9XG5cbiAgICBpZiAodGhpcy5nZXRFeGFtcGxlUGF0dGVybnMoKS5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBmdWxsRGVzY3JpcHRpb24gPSB0aGlzLmJ1aWxkRnVsbERlc2NyaXB0aW9uKGRlc2NyaXB0aW9ucywgdGVzdERlc2NyaXB0aW9uKVxuICAgICAgY29uc3QgbWF0Y2hlcyA9IHRoaXMuZ2V0RXhhbXBsZVBhdHRlcm5zKCkuc29tZSgocGF0dGVybikgPT4ge1xuICAgICAgICBwYXR0ZXJuLmxhc3RJbmRleCA9IDBcbiAgICAgICAgcmV0dXJuIHBhdHRlcm4udGVzdChmdWxsRGVzY3JpcHRpb24pXG4gICAgICB9KVxuXG4gICAgICBpZiAoIW1hdGNoZXMpIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgY29uc3QgbGluZUZpbHRlcnMgPSB0aGlzLmdldExpbmVGaWx0ZXJzKClcblxuICAgIGlmIChPYmplY3Qua2V5cyhsaW5lRmlsdGVycykubGVuZ3RoID4gMCkge1xuICAgICAgaWYgKCFsaW5lTWF0Y2hlZEluU2NvcGUgJiYgIXRoaXMubWF0Y2hlc0xpbmVGaWx0ZXIodGVzdERhdGEpKSByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7VGVzdERhdGEgfCBUZXN0c0FyZ3VtZW50fSBlbnRyeSAtIFRlc3QgZW50cnkuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgbGluZSBmaWx0ZXIgbWF0Y2hlcyBlbnRyeS5cbiAgICovXG4gIG1hdGNoZXNMaW5lRmlsdGVyKGVudHJ5KSB7XG4gICAgaWYgKCFlbnRyeSB8fCAhZW50cnkuZmlsZVBhdGggfHwgIWVudHJ5LmxpbmUpIHJldHVybiBmYWxzZVxuXG4gICAgY29uc3QgZmlsZVBhdGggPSBwYXRoLnJlc29sdmUoZW50cnkuZmlsZVBhdGgpXG4gICAgY29uc3QgbGluZXMgPSB0aGlzLmdldExpbmVGaWx0ZXJzKClbZmlsZVBhdGhdXG5cbiAgICBpZiAoIWxpbmVzIHx8IGxpbmVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIGZhbHNlXG5cbiAgICByZXR1cm4gbGluZXMuaW5jbHVkZXMoZW50cnkubGluZSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBkZXNjcmlwdGlvbnMgLSBEZXNjcmlwdGlvbiBzdGFjay5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRlc3REZXNjcmlwdGlvbiAtIFRlc3QgZGVzY3JpcHRpb24uXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IC0gRnVsbCBkZXNjcmlwdGlvbi5cbiAgICovXG4gIGJ1aWxkRnVsbERlc2NyaXB0aW9uKGRlc2NyaXB0aW9ucywgdGVzdERlc2NyaXB0aW9uKSB7XG4gICAgY29uc3QgcGFydHMgPSBkZXNjcmlwdGlvbnMuY29uY2F0KFt0ZXN0RGVzY3JpcHRpb25dKVxuXG4gICAgcmV0dXJuIHBhcnRzLmpvaW4oXCIgXCIpLnRyaW0oKVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPEFwcGxpY2F0aW9uPn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBhcHBsaWNhdGlvbi5cbiAgICovXG4gIGFzeW5jIGFwcGxpY2F0aW9uKCkge1xuICAgIGlmICghdGhpcy5fYXBwbGljYXRpb24pIHtcbiAgICAgIHRoaXMuX2FwcGxpY2F0aW9uID0gbmV3IEFwcGxpY2F0aW9uKHtcbiAgICAgICAgY29uZmlndXJhdGlvbjogdGhpcy5nZXRDb25maWd1cmF0aW9uKCksXG4gICAgICAgIGh0dHBTZXJ2ZXI6IHtwb3J0OiAzMTAwNn0sXG4gICAgICAgIHR5cGU6IFwidGVzdC1ydW5uZXJcIlxuICAgICAgfSlcblxuICAgICAgYXdhaXQgdGhpcy5fYXBwbGljYXRpb24uaW5pdGlhbGl6ZSgpXG4gICAgICBhd2FpdCB0aGlzLl9hcHBsaWNhdGlvbi5zdGFydEh0dHBTZXJ2ZXIoKVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9hcHBsaWNhdGlvblxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFJlcXVlc3RDbGllbnQ+fSAtIFJlc29sdmVzIHdpdGggdGhlIHJlcXVlc3QgY2xpZW50LlxuICAgKi9cbiAgYXN5bmMgcmVxdWVzdENsaWVudCgpIHtcbiAgICBpZiAoIXRoaXMuX3JlcXVlc3RDbGllbnQpIHtcbiAgICAgIHRoaXMuX3JlcXVlc3RDbGllbnQgPSBuZXcgUmVxdWVzdENsaWVudCgpXG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX3JlcXVlc3RDbGllbnRcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgaW1wb3J0VGVzdEZpbGVzKCkge1xuICAgIGF3YWl0IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpLmdldEVudmlyb25tZW50SGFuZGxlcigpLmltcG9ydFRlc3RGaWxlcyh0aGlzLmdldFRlc3RGaWxlcygpKVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgZmFpbGVkLlxuICAgKi9cbiAgaXNGYWlsZWQoKSB7IHJldHVybiB0aGlzLl9mYWlsZWRUZXN0cyAhPT0gdW5kZWZpbmVkICYmIHRoaXMuX2ZhaWxlZFRlc3RzID4gMCB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IC0gVGhlIGZhaWxlZCB0ZXN0cy5cbiAgICovXG4gIGdldEZhaWxlZFRlc3RzKCkge1xuICAgIGlmICh0aGlzLl9mYWlsZWRUZXN0cyA9PT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgRXJyb3IoXCJUZXN0cyBoYXNuJ3QgYmVlbiBydW4geWV0XCIpXG5cbiAgICByZXR1cm4gdGhpcy5fZmFpbGVkVGVzdHNcbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7RmFpbGVkVGVzdERldGFpbFtdfSAtIEZhaWxlZCB0ZXN0IGRldGFpbHMuICovXG4gIGdldEZhaWxlZFRlc3REZXRhaWxzKCkge1xuICAgIHJldHVybiB0aGlzLl9mYWlsZWRUZXN0RGV0YWlsc1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBbYXJnc10gLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IFthcmdzLmFzc2V0c1BhdGhdIC0gQXNzZXRzIGRpcmVjdG9yeSBwYXRoLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmdbXT59IC0gV3JpdHRlbiBsb2cgZmlsZSBwYXRocy5cbiAgICovXG4gIGFzeW5jIHBlcnNpc3RGYWlsZWRUZXN0Q29uc29sZU91dHB1dHNUb0Fzc2V0cyh7YXNzZXRzUGF0aCA9IHBhdGguam9pbihwcm9jZXNzLmN3ZCgpLCBcInRtcC9zY3JlZW5zaG90c1wiKX0gPSB7fSkge1xuICAgIGNvbnN0IGZhaWxlZFRlc3REZXRhaWxzID0gdGhpcy5nZXRGYWlsZWRUZXN0RGV0YWlscygpXG4gICAgY29uc3Qgd3JpdHRlbkxvZ1BhdGhzID0gW11cbiAgICBsZXQgY3JlYXRlZERpcmVjdG9yeSA9IGZhbHNlXG5cbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgZmFpbGVkVGVzdERldGFpbHMubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICBjb25zdCBmYWlsZWRUZXN0RGV0YWlsID0gZmFpbGVkVGVzdERldGFpbHNbaW5kZXhdXG4gICAgICBjb25zdCBjb25zb2xlT3V0cHV0ID0gZmFpbGVkVGVzdERldGFpbC5jb25zb2xlT3V0cHV0XG5cbiAgICAgIGlmICghY29uc29sZU91dHB1dCkgY29udGludWVcblxuICAgICAgaWYgKCFjcmVhdGVkRGlyZWN0b3J5KSB7XG4gICAgICAgIGF3YWl0IGZzLm1rZGlyKGFzc2V0c1BhdGgsIHtyZWN1cnNpdmU6IHRydWV9KVxuICAgICAgICBjcmVhdGVkRGlyZWN0b3J5ID0gdHJ1ZVxuICAgICAgfVxuXG4gICAgICBjb25zdCBub3cgPSBuZXcgRGF0ZSgpXG4gICAgICBjb25zdCB0aW1lc3RhbXAgPSBbXG4gICAgICAgIFN0cmluZyhub3cuZ2V0RnVsbFllYXIoKSksXG4gICAgICAgIFN0cmluZyhub3cuZ2V0TW9udGgoKSArIDEpLnBhZFN0YXJ0KDIsIFwiMFwiKSxcbiAgICAgICAgU3RyaW5nKG5vdy5nZXREYXRlKCkpLnBhZFN0YXJ0KDIsIFwiMFwiKSxcbiAgICAgICAgU3RyaW5nKG5vdy5nZXRIb3VycygpKS5wYWRTdGFydCgyLCBcIjBcIiksXG4gICAgICAgIFN0cmluZyhub3cuZ2V0TWludXRlcygpKS5wYWRTdGFydCgyLCBcIjBcIiksXG4gICAgICAgIFN0cmluZyhub3cuZ2V0U2Vjb25kcygpKS5wYWRTdGFydCgyLCBcIjBcIiksXG4gICAgICAgIFN0cmluZyhub3cuZ2V0TWlsbGlzZWNvbmRzKCkpLnBhZFN0YXJ0KDMsIFwiMFwiKVxuICAgICAgXS5qb2luKFwiXCIpXG4gICAgICBjb25zdCBzbHVnID0gdG9GaWxlU2x1ZyhmYWlsZWRUZXN0RGV0YWlsLmZ1bGxEZXNjcmlwdGlvbilcbiAgICAgIGNvbnN0IGZpbGVOYW1lID0gYCR7dGltZXN0YW1wfS0ke1N0cmluZyhpbmRleCArIDEpLnBhZFN0YXJ0KDIsIFwiMFwiKX0tJHtzbHVnfS5jb25zb2xlLmxvZ2BcbiAgICAgIGNvbnN0IGZpbGVQYXRoID0gcGF0aC5qb2luKGFzc2V0c1BhdGgsIGZpbGVOYW1lKVxuXG4gICAgICBhd2FpdCBmcy53cml0ZUZpbGUoZmlsZVBhdGgsIGNvbnNvbGVPdXRwdXQsIFwidXRmOFwiKVxuICAgICAgZmFpbGVkVGVzdERldGFpbC5jb25zb2xlTG9nUGF0aCA9IGZpbGVQYXRoXG4gICAgICB3cml0dGVuTG9nUGF0aHMucHVzaChmaWxlUGF0aClcbiAgICB9XG5cbiAgICByZXR1cm4gd3JpdHRlbkxvZ1BhdGhzXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge251bWJlcn0gLSBUaGUgc3VjY2Vzc2Z1bCB0ZXN0cy5cbiAgICovXG4gIGdldFN1Y2Nlc3NmdWxUZXN0cygpIHtcbiAgICBpZiAodGhpcy5fc3VjY2Vzc2Z1bFRlc3RzID09PSB1bmRlZmluZWQpIHRocm93IG5ldyBFcnJvcihcIlRlc3RzIGhhc24ndCBiZWVuIHJ1biB5ZXRcIilcblxuICAgIHJldHVybiB0aGlzLl9zdWNjZXNzZnVsVGVzdHNcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSAtIFRoZSB0ZXN0cyBjb3VudC5cbiAgICovXG4gIGdldFRlc3RzQ291bnQoKSB7XG4gICAgaWYgKHRoaXMuX3Rlc3RzQ291bnQgPT09IHVuZGVmaW5lZCkgdGhyb3cgbmV3IEVycm9yKFwiVGVzdHMgaGFzbid0IGJlZW4gcnVuIHlldFwiKVxuXG4gICAgcmV0dXJuIHRoaXMuX3Rlc3RzQ291bnRcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSAtIFRoZSBleGVjdXRlZCB0ZXN0cyBjb3VudC5cbiAgICovXG4gIGdldEV4ZWN1dGVkVGVzdHNDb3VudCgpIHtcbiAgICBpZiAodGhpcy5fc3VjY2Vzc2Z1bFRlc3RzID09PSB1bmRlZmluZWQgfHwgdGhpcy5fZmFpbGVkVGVzdHMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGVzdHMgaGFzbid0IGJlZW4gcnVuIHlldFwiKVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9zdWNjZXNzZnVsVGVzdHMgKyB0aGlzLl9mYWlsZWRUZXN0c1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBwcmVwYXJlKCkge1xuICAgIHRoaXMuYW55VGVzdHNGb2N1c3NlZCA9IGZhbHNlXG4gICAgdGhpcy5fZmFpbGVkVGVzdHMgPSAwXG4gICAgdGhpcy5fc3VjY2Vzc2Z1bFRlc3RzID0gMFxuICAgIHRoaXMuX3Rlc3RzQ291bnQgPSAwXG4gICAgdGhpcy5fZmFpbGVkVGVzdERldGFpbHMgPSBbXVxuICAgIGF3YWl0IHRoaXMuaW1wb3J0VGVzdEZpbGVzKClcbiAgICBhd2FpdCB0aGlzLmFuYWx5emVUZXN0cyh0ZXN0cylcbiAgICB0aGlzLl9vbmx5Rm9jdXNzZWQgPSB0aGlzLmFueVRlc3RzRm9jdXNzZWRcblxuICAgIGNvbnN0IHRlc3RpbmdDb25maWdQYXRoID0gdGhpcy5nZXRDb25maWd1cmF0aW9uKCkuZ2V0VGVzdGluZygpXG5cbiAgICBpZiAodGVzdGluZ0NvbmZpZ1BhdGgpIHtcbiAgICAgIGF3YWl0IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpLmdldEVudmlyb25tZW50SGFuZGxlcigpLmltcG9ydFRlc3RpbmdDb25maWdQYXRoKClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gV2hldGhlciBhbnkgdGVzdHMgZm9jdXNzZWQuXG4gICAqL1xuICBhcmVBbnlUZXN0c0ZvY3Vzc2VkKCkge1xuICAgIGlmICh0aGlzLmFueVRlc3RzRm9jdXNzZWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSGFzbid0IGJlZW4gZGV0ZWN0ZWQgeWV0XCIpXG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuYW55VGVzdHNGb2N1c3NlZFxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBydW4oKSB7XG4gICAgYXdhaXQgdGhpcy5nZXRDb25maWd1cmF0aW9uKCkuZW5zdXJlQ29ubmVjdGlvbnMoe25hbWU6IFwiVGVzdCBydW5uZXIgc3VpdGVcIn0sIGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHRoaXMucnVuVGVzdHMoe1xuICAgICAgICBhZnRlckVhY2hlczogW10sXG4gICAgICAgIGJlZm9yZUVhY2hlczogW10sXG4gICAgICAgIHRlc3RzLFxuICAgICAgICBkZXNjcmlwdGlvbnM6IFtdLFxuICAgICAgICBpbmRlbnRMZXZlbDogMFxuICAgICAgfSlcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY2xlYW51cCBob29rcyBmaW5pc2guXG4gICAqL1xuICBhc3luYyBydW5BZnRlckFsbHNGb3JBY3RpdmVTY29wZXMoKSB7XG4gICAgY29uc3Qgc2NvcGVzID0gWy4uLnRoaXMuX2FjdGl2ZUFmdGVyQWxsU2NvcGVzXS5yZXZlcnNlKClcblxuICAgIGZvciAoY29uc3Qgc2NvcGUgb2Ygc2NvcGVzKSB7XG4gICAgICBhd2FpdCB0aGlzLnJ1bkFmdGVyQWxsc0ZvclNjb3BlKHNjb3BlKVxuICAgIH1cblxuICAgIHRoaXMuX2FjdGl2ZUFmdGVyQWxsU2NvcGVzID0gW11cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1Rlc3RzQXJndW1lbnR9IHRlc3RzIC0gVGVzdHMuXG4gICAqIEByZXR1cm5zIHt7YW55VGVzdHNGb2N1c3NlZDogYm9vbGVhbn19IC0gV2hldGhlciBhbnkgdGVzdHMgaW4gdGhlIHRyZWUgYXJlIGZvY3VzZWQuXG4gICAqL1xuICBhbmFseXplVGVzdHModGVzdHMpIHtcbiAgICBsZXQgYW55VGVzdHNGb2N1c3NlZEZvdW5kID0gZmFsc2VcblxuICAgIGZvciAoY29uc3QgdGVzdERlc2NyaXB0aW9uIGluIHRlc3RzLnRlc3RzKSB7XG4gICAgICBjb25zdCB0ZXN0RGF0YSA9IHRlc3RzLnRlc3RzW3Rlc3REZXNjcmlwdGlvbl1cbiAgICAgIGNvbnN0IHRlc3RBcmdzID0gT2JqZWN0LmFzc2lnbih7fSwgdGVzdERhdGEuYXJncylcblxuICAgICAgdGhpcy5fdGVzdHNDb3VudCsrXG5cbiAgICAgIGlmICh0ZXN0QXJncy5mb2N1cykge1xuICAgICAgICBhbnlUZXN0c0ZvY3Vzc2VkRm91bmQgPSB0cnVlXG4gICAgICAgIHRoaXMuYW55VGVzdHNGb2N1c3NlZCA9IHRydWVcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHN1YkRlc2NyaXB0aW9uIGluIHRlc3RzLnN1YnMpIHtcbiAgICAgIGNvbnN0IHN1YlRlc3QgPSB0ZXN0cy5zdWJzW3N1YkRlc2NyaXB0aW9uXVxuICAgICAgY29uc3Qge2FueVRlc3RzRm9jdXNzZWR9ID0gdGhpcy5hbmFseXplVGVzdHMoc3ViVGVzdClcblxuICAgICAgaWYgKGFueVRlc3RzRm9jdXNzZWQpIHtcbiAgICAgICAgYW55VGVzdHNGb2N1c3NlZEZvdW5kID0gdHJ1ZVxuICAgICAgfVxuXG4gICAgICBzdWJUZXN0LmFueVRlc3RzRm9jdXNzZWQgPSBhbnlUZXN0c0ZvY3Vzc2VkXG4gICAgfVxuXG4gICAgcmV0dXJuIHthbnlUZXN0c0ZvY3Vzc2VkOiBhbnlUZXN0c0ZvY3Vzc2VkRm91bmR9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHBhcmFtIHtBcnJheTxBZnRlckJlZm9yZUVhY2hDYWxsYmFja09iamVjdFR5cGU+fSBhcmdzLmFmdGVyRWFjaGVzIC0gQWZ0ZXIgZWFjaGVzLlxuICAgKiBAcGFyYW0ge0FycmF5PEFmdGVyQmVmb3JlRWFjaENhbGxiYWNrT2JqZWN0VHlwZT59IGFyZ3MuYmVmb3JlRWFjaGVzIC0gQmVmb3JlIGVhY2hlcy5cbiAgICogQHBhcmFtIHtUZXN0c0FyZ3VtZW50fSBhcmdzLnRlc3RzIC0gVGVzdHMuXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IGFyZ3MuZGVzY3JpcHRpb25zIC0gRGVzY3JpcHRpb25zLlxuICAgKiBAcGFyYW0ge251bWJlcn0gYXJncy5pbmRlbnRMZXZlbCAtIEluZGVudCBsZXZlbC5cbiAgICogQHBhcmFtIHtib29sZWFufSBbYXJncy5saW5lTWF0Y2hlZEluU2NvcGVdIC0gV2hldGhlciBsaW5lIG1hdGNoZWQgaW4gc2NvcGUuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBydW5UZXN0cyh7YWZ0ZXJFYWNoZXMsIGJlZm9yZUVhY2hlcywgdGVzdHMsIGRlc2NyaXB0aW9ucywgaW5kZW50TGV2ZWwsIGxpbmVNYXRjaGVkSW5TY29wZSA9IGZhbHNlfSkge1xuICAgIGNvbnN0IGxlZnRQYWRkaW5nID0gXCIgXCIucmVwZWF0KGluZGVudExldmVsICogMilcbiAgICBjb25zdCBuZXdBZnRlckVhY2hlcyA9IFsuLi5hZnRlckVhY2hlcywgLi4udGVzdHMuYWZ0ZXJFYWNoZXNdXG4gICAgY29uc3QgbmV3QmVmb3JlRWFjaGVzID0gWy4uLmJlZm9yZUVhY2hlcywgLi4udGVzdHMuYmVmb3JlRWFjaGVzXVxuICAgIGNvbnN0IHNjb3BlTGluZU1hdGNoID0gbGluZU1hdGNoZWRJblNjb3BlIHx8IHRoaXMubWF0Y2hlc0xpbmVGaWx0ZXIodGVzdHMpXG4gICAgY29uc3Qgc2hvdWxkUnVuQW55VGVzdHMgPSB0aGlzLmhhc1J1bm5hYmxlVGVzdHModGVzdHMsIGRlc2NyaXB0aW9ucywgc2NvcGVMaW5lTWF0Y2gpXG5cbiAgICBpZiAoIXNob3VsZFJ1bkFueVRlc3RzKSByZXR1cm5cblxuICAgIC8qKiBAdHlwZSB7QWN0aXZlQWZ0ZXJBbGxTY29wZUVudHJ5fSAqL1xuICAgIGNvbnN0IHNjb3BlRW50cnkgPSB7dGVzdHMsIGFmdGVyQWxsc1J1bjogZmFsc2V9XG4gICAgdGhpcy5fYWN0aXZlQWZ0ZXJBbGxTY29wZXMucHVzaChzY29wZUVudHJ5KVxuXG4gICAgdHJ5IHtcbiAgICAgIGZvciAoY29uc3QgYmVmb3JlQWxsRGF0YSBvZiB0ZXN0cy5iZWZvcmVBbGxzIHx8IFtdKSB7XG4gICAgICAgIGF3YWl0IGJlZm9yZUFsbERhdGEuY2FsbGJhY2soe2NvbmZpZ3VyYXRpb246IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpfSlcbiAgICAgIH1cblxuICAgICAgZm9yIChjb25zdCB0ZXN0RGVzY3JpcHRpb24gaW4gdGVzdHMudGVzdHMpIHtcbiAgICAgICAgY29uc3QgdGVzdERhdGEgPSB0ZXN0cy50ZXN0c1t0ZXN0RGVzY3JpcHRpb25dXG4gICAgICAgIGNvbnN0IHRlc3RBcmdzID0gLyoqIEB0eXBlIHtUZXN0QXJnc30gKi8gKE9iamVjdC5hc3NpZ24oe30sIHRlc3REYXRhLmFyZ3MpKVxuICAgICAgICBjb25zdCBpbmNsdWRlQnlMaW5lID0gc2NvcGVMaW5lTWF0Y2ggfHwgdGhpcy5tYXRjaGVzTGluZUZpbHRlcih0ZXN0RGF0YSlcblxuICAgICAgICBpZiAodGhpcy5fb25seUZvY3Vzc2VkICYmICF0ZXN0QXJncy5mb2N1cykgY29udGludWVcbiAgICAgICAgaWYgKHRoaXMuc2hvdWxkU2tpcFRlc3QodGVzdEFyZ3MsIHRlc3REYXRhLCB0ZXN0RGVzY3JpcHRpb24sIGRlc2NyaXB0aW9ucywgaW5jbHVkZUJ5TGluZSkpIGNvbnRpbnVlXG5cbiAgICAgICAgaWYgKHRlc3RBcmdzLnR5cGUgPT0gXCJtb2RlbFwiIHx8IHRlc3RBcmdzLnR5cGUgPT0gXCJyZXF1ZXN0XCIpIHtcbiAgICAgICAgICB0ZXN0QXJncy5hcHBsaWNhdGlvbiA9IGF3YWl0IHRoaXMuYXBwbGljYXRpb24oKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRlc3RBcmdzLnR5cGUgPT0gXCJyZXF1ZXN0XCIpIHtcbiAgICAgICAgICB0ZXN0QXJncy5jbGllbnQgPSBhd2FpdCB0aGlzLnJlcXVlc3RDbGllbnQoKVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmV0cnlDb3VudCA9IHR5cGVvZiB0ZXN0QXJncy5yZXRyeSA9PT0gXCJudW1iZXJcIiAmJiBOdW1iZXIuaXNGaW5pdGUodGVzdEFyZ3MucmV0cnkpXG4gICAgICAgICAgPyBNYXRoLm1heCgwLCBNYXRoLmZsb29yKHRlc3RBcmdzLnJldHJ5KSlcbiAgICAgICAgICA6IDBcbiAgICAgICAgY29uc3QgY29uZmlnVGltZW91dFNlY29uZHMgPSB0eXBlb2YgdGVzdENvbmZpZy5kZWZhdWx0VGltZW91dFNlY29uZHMgPT09IFwibnVtYmVyXCIgPyB0ZXN0Q29uZmlnLmRlZmF1bHRUaW1lb3V0U2Vjb25kcyA6IHVuZGVmaW5lZFxuICAgICAgICBjb25zdCB0aW1lb3V0U2Vjb25kcyA9IHR5cGVvZiB0ZXN0QXJncy50aW1lb3V0U2Vjb25kcyA9PT0gXCJudW1iZXJcIiA/IHRlc3RBcmdzLnRpbWVvdXRTZWNvbmRzIDogY29uZmlnVGltZW91dFNlY29uZHNcbiAgICAgICAgY29uc3QgdXNlVGltZW91dCA9IHR5cGVvZiB0aW1lb3V0U2Vjb25kcyA9PT0gXCJudW1iZXJcIiAmJiBOdW1iZXIuaXNGaW5pdGUodGltZW91dFNlY29uZHMpICYmIHRpbWVvdXRTZWNvbmRzID4gMFxuICAgICAgICBjb25zdCB0aW1lb3V0TXMgPSB1c2VUaW1lb3V0ID8gdGltZW91dFNlY29uZHMgKiAxMDAwIDogdW5kZWZpbmVkXG4gICAgICAgIGxldCByZXRyaWVzVXNlZCA9IDBcbiAgICAgICAgbGV0IGF0dGVtcHROdW1iZXIgPSAxXG4gICAgICAgIC8qKiBAdHlwZSB7QXR0ZW1wdENvbnNvbGVPdXRwdXRbXX0gKi9cbiAgICAgICAgY29uc3QgYXR0ZW1wdENvbnNvbGVPdXRwdXRzID0gW11cblxuICAgICAgICBjb25zb2xlLmxvZyhgJHtsZWZ0UGFkZGluZ31pdCAke3Rlc3REZXNjcmlwdGlvbn1gKVxuXG4gICAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgICAgbGV0IHNob3VsZFJldHJ5ID0gZmFsc2VcbiAgICAgICAgICAvKiogQHR5cGUge3Vua25vd259ICovXG4gICAgICAgICAgbGV0IGNhdWdodEVycm9yXG4gICAgICAgICAgLyoqIEB0eXBlIHt1bmtub3dufSAqL1xuICAgICAgICAgIGxldCBmYWlsZWRFcnJvclxuICAgICAgICAgIC8qKiBAdHlwZSB7dW5rbm93bn0gKi9cbiAgICAgICAgICBsZXQgbGFzdEVycm9yXG4gICAgICAgICAgbGV0IHdpbGxSZXRyeSA9IGZhbHNlXG4gICAgICAgICAgY29uc3Qgc3RvcENvbnNvbGVDYXB0dXJlID0gdGhpcy5zdGFydENvbnNvbGVDYXB0dXJlKHtcbiAgICAgICAgICAgIHBhc3N0aHJvdWdoOiB0ZXN0Q29uZmlnLmNvbnNvbGVPdXRwdXQgPT09IFwibGl2ZVwiXG4gICAgICAgICAgfSlcblxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBSdW4gdGhlIHdob2xlIHBlci10ZXN0IGxpZmVjeWNsZSAoZHVtbXkvc2VydmVyIHN0YXJ0dXAsIGNvbm5lY3Rpb25cbiAgICAgICAgICAgIC8vIGFjcXVpc2l0aW9uLCBiZWZvcmVFYWNoIGhvb2tzLCB0aGUgdGVzdCBib2R5IGFuZCBhZnRlckVhY2ggaG9va3MpIGFzXG4gICAgICAgICAgICAvLyBvbmUgcHJvbWlzZSBzbyB0aGUgdGltZW91dCBiZWxvdyBjYW4gY292ZXIgYWxsIG9mIGl0LlxuICAgICAgICAgICAgY29uc3QgdGVzdExpZmVjeWNsZSA9IHRoaXMucnVuV2l0aER1bW15SWZOZWVkZWQodGVzdEFyZ3MsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgLy8gUGluIG9uZSBjb25uZWN0aW9uIHBlciB0ZXN0IHNvIGJlZm9yZUVhY2gsIHRoZSB0ZXN0IGJvZHkgYW5kIGFmdGVyRWFjaFxuICAgICAgICAgICAgICAvLyBhbGwgcnVuIG9uIHRoZSBTQU1FIGNvbm5lY3Rpb24uIFRoaXMgaXMgcmVxdWlyZWQgZm9yIHRyYW5zYWN0aW9uLWJhc2VkXG4gICAgICAgICAgICAgIC8vIGRhdGFiYXNlIGNsZWFuaW5nIChiZWZvcmVFYWNoIHN0YXJ0cyBhIHRyYW5zYWN0aW9uLCBhZnRlckVhY2ggcm9sbHMgaXRcbiAgICAgICAgICAgICAgLy8gYmFjaykuIGVuc3VyZUNvbm5lY3Rpb25zIHJldXNlcyB0aGUgc3VpdGUtbGV2ZWwgcGlubmVkIGNvbm5lY3Rpb24gd2hpbGVcbiAgICAgICAgICAgICAgLy8gaXQgaXMgaGVhbHRoeSBhbmQgdHJhbnNwYXJlbnRseSByZS1lc3RhYmxpc2hlcyBhIHBlci10ZXN0IHBpbiBpZiBhblxuICAgICAgICAgICAgICAvLyBlYXJsaWVyIHNwZWMgY2xvc2VkIHRoZSBzdWl0ZSBjb25uZWN0aW9uICh3aGljaCB3b3VsZCBvdGhlcndpc2UgbGVhdmUgYVxuICAgICAgICAgICAgICAvLyBzdGFsZSBhc3luYy1jb250ZXh0IHBpbiBhbmQgZm9yY2UgZXZlcnkgbGF0ZXIgdGVzdCBvbnRvIGEgZnJlc2ggY2hlY2tvdXQsXG4gICAgICAgICAgICAgIC8vIGJyZWFraW5nIGlzb2xhdGlvbikuXG4gICAgICAgICAgICAgIGF3YWl0IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpLmVuc3VyZUNvbm5lY3Rpb25zKHtuYW1lOiBgVGVzdDogJHt0ZXN0RGVzY3JpcHRpb259YH0sIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgY2xlYXJEZWxpdmVyaWVzKClcbiAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgYmVmb3JlRWFjaERhdGEgb2YgbmV3QmVmb3JlRWFjaGVzKSB7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IGJlZm9yZUVhY2hEYXRhLmNhbGxiYWNrKHtjb25maWd1cmF0aW9uOiB0aGlzLmdldENvbmZpZ3VyYXRpb24oKSwgdGVzdEFyZ3MsIHRlc3REYXRhfSlcbiAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgYXdhaXQgdGVzdERhdGEuZnVuY3Rpb24odGVzdEFyZ3MpXG4gICAgICAgICAgICAgICAgICB0aGlzLl9zdWNjZXNzZnVsVGVzdHMrK1xuICAgICAgICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGFmdGVyRWFjaERhdGEgb2YgbmV3QWZ0ZXJFYWNoZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgYWZ0ZXJFYWNoRGF0YS5jYWxsYmFjayh7Y29uZmlndXJhdGlvbjogdGhpcy5nZXRDb25maWd1cmF0aW9uKCksIHRlc3RBcmdzLCB0ZXN0RGF0YX0pXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgLy8gVGltZSBvdXQgdGhlIEVOVElSRSBsaWZlY3ljbGUsIG5vdCBqdXN0IHRoZSB0ZXN0IGJvZHkuIEEgaGFuZyBpbiBhbnlcbiAgICAgICAgICAgIC8vIHBoYXNlIOKAlCBhIGNvbm5lY3Rpb24gY2hlY2tvdXQgdGhhdCBuZXZlciByZXNvbHZlcywgYSBiZWZvcmVFYWNoL2FmdGVyRWFjaFxuICAgICAgICAgICAgLy8gd2FpdGluZyBvbiBhIGxvY2ssIG9yIGR1bW15IHNlcnZlciBzdGFydHVwIOKAlCB3b3VsZCBvdGhlcndpc2Ugc3RhbGwgdGhlXG4gICAgICAgICAgICAvLyB3aG9sZSBydW4gaW5kZWZpbml0ZWx5ICh1bnRpbCBDSSBraWxscyB0aGUgYnVpbGQpIGluc3RlYWQgb2YgZmFpbGluZyB0aGVcbiAgICAgICAgICAgIC8vIHNpbmdsZSBvZmZlbmRpbmcgdGVzdC5cbiAgICAgICAgICAgIGlmICh1c2VUaW1lb3V0ICYmIHRpbWVvdXRNcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgIGF3YWl0IHJ1bldpdGhUaW1lb3V0KHRlc3RMaWZlY3ljbGUsIHRpbWVvdXRNcywgdGVzdERlc2NyaXB0aW9uKVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgYXdhaXQgdGVzdExpZmVjeWNsZVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjYXVnaHRFcnJvciA9IGVycm9yXG4gICAgICAgICAgICBsYXN0RXJyb3IgPSBlcnJvclxuICAgICAgICAgICAgd2lsbFJldHJ5ID0gcmV0cmllc1VzZWQgPCByZXRyeUNvdW50XG5cbiAgICAgICAgICAgIGlmICh3aWxsUmV0cnkpIHtcbiAgICAgICAgICAgICAgcmV0cmllc1VzZWQrK1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAod2lsbFJldHJ5KSB7XG4gICAgICAgICAgICAgIHNob3VsZFJldHJ5ID0gdHJ1ZVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgZmFpbGVkRXJyb3IgPSBlcnJvclxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICBjb25zdCBjb25zb2xlT3V0cHV0ID0gc3RvcENvbnNvbGVDYXB0dXJlKClcblxuICAgICAgICAgICAgaWYgKGNvbnNvbGVPdXRwdXQpIHtcbiAgICAgICAgICAgICAgYXR0ZW1wdENvbnNvbGVPdXRwdXRzLnB1c2goe2F0dGVtcHROdW1iZXIsIG91dHB1dDogY29uc29sZU91dHB1dH0pXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGNhdWdodEVycm9yICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZW1pdEV2ZW50KFwidGVzdEF0dGVtcHRGYWlsZWRcIiwge1xuICAgICAgICAgICAgICBjb25maWd1cmF0aW9uOiB0aGlzLmdldENvbmZpZ3VyYXRpb24oKSxcbiAgICAgICAgICAgICAgZGVzY3JpcHRpb25zLFxuICAgICAgICAgICAgICBlcnJvcjogY2F1Z2h0RXJyb3IsXG4gICAgICAgICAgICAgIGF0dGVtcHROdW1iZXIsXG4gICAgICAgICAgICAgIG5leHRBdHRlbXB0OiB3aWxsUmV0cnkgPyBhdHRlbXB0TnVtYmVyICsgMSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgcmV0cmllc1VzZWQsXG4gICAgICAgICAgICAgIHJldHJ5Q291bnQsXG4gICAgICAgICAgICAgIHRlc3RBcmdzLFxuICAgICAgICAgICAgICB0ZXN0RGF0YSxcbiAgICAgICAgICAgICAgdGVzdERlc2NyaXB0aW9uLFxuICAgICAgICAgICAgICB0ZXN0UnVubmVyOiB0aGlzLFxuICAgICAgICAgICAgICB3aWxsUmV0cnlcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHNob3VsZFJldHJ5KSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4ocGljb2NvbG9ycy5yZWQoYCR7bGVmdFBhZGRpbmd9ICBSZXRyeWluZyAoJHtyZXRyaWVzVXNlZH0vJHtyZXRyeUNvdW50fSkgYWZ0ZXIgZXJyb3I6ICR7bGFzdEVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBsYXN0RXJyb3IubWVzc2FnZSA6IFN0cmluZyhsYXN0RXJyb3IpfWApKVxuICAgICAgICAgICAgYXdhaXQgdGhpcy5lbWl0RXZlbnQoXCJ0ZXN0UmV0cnlpbmdcIiwge1xuICAgICAgICAgICAgICBjb25maWd1cmF0aW9uOiB0aGlzLmdldENvbmZpZ3VyYXRpb24oKSxcbiAgICAgICAgICAgICAgZGVzY3JpcHRpb25zLFxuICAgICAgICAgICAgICBlcnJvcjogbGFzdEVycm9yLFxuICAgICAgICAgICAgICBuZXh0QXR0ZW1wdDogYXR0ZW1wdE51bWJlciArIDEsXG4gICAgICAgICAgICAgIHJldHJpZXNVc2VkLFxuICAgICAgICAgICAgICByZXRyeUNvdW50LFxuICAgICAgICAgICAgICB0ZXN0QXJncyxcbiAgICAgICAgICAgICAgdGVzdERhdGEsXG4gICAgICAgICAgICAgIHRlc3REZXNjcmlwdGlvbixcbiAgICAgICAgICAgICAgdGVzdFJ1bm5lcjogdGhpc1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoYXR0ZW1wdE51bWJlciA+IDEpIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZW1pdEV2ZW50KFwidGVzdFJldHJpZWRcIiwge1xuICAgICAgICAgICAgICBjb25maWd1cmF0aW9uOiB0aGlzLmdldENvbmZpZ3VyYXRpb24oKSxcbiAgICAgICAgICAgICAgZGVzY3JpcHRpb25zLFxuICAgICAgICAgICAgICBlcnJvcjogbGFzdEVycm9yLFxuICAgICAgICAgICAgICBhdHRlbXB0TnVtYmVyLFxuICAgICAgICAgICAgICByZXRyaWVzVXNlZCxcbiAgICAgICAgICAgICAgcmV0cnlDb3VudCxcbiAgICAgICAgICAgICAgdGVzdEFyZ3MsXG4gICAgICAgICAgICAgIHRlc3REYXRhLFxuICAgICAgICAgICAgICB0ZXN0RGVzY3JpcHRpb24sXG4gICAgICAgICAgICAgIHRlc3RSdW5uZXI6IHRoaXNcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYXR0ZW1wdE51bWJlcisrXG5cbiAgICAgICAgICBpZiAoc2hvdWxkUmV0cnkpIGNvbnRpbnVlXG5cbiAgICAgICAgICBpZiAoZmFpbGVkRXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnN0IGNvbnNvbGVPdXRwdXQgPSB0aGlzLmJ1aWxkQ29uc29sZU91dHB1dChhdHRlbXB0Q29uc29sZU91dHB1dHMpXG5cbiAgICAgICAgICAgIGlmIChmYWlsZWRFcnJvciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IocGljb2NvbG9ycy5yZWQoYCR7bGVmdFBhZGRpbmd9ICBUZXN0IGZhaWxlZDogJHtmYWlsZWRFcnJvci5tZXNzYWdlfWApKVxuICAgICAgICAgICAgICBhZGRUcmFja2VkU3RhY2tUb0Vycm9yKGZhaWxlZEVycm9yKVxuXG4gICAgICAgICAgICAgIGNvbnN0IGJhY2t0cmFjZUNsZWFuZXIgPSBuZXcgQmFja3RyYWNlQ2xlYW5lcihmYWlsZWRFcnJvcilcbiAgICAgICAgICAgICAgY29uc3QgY2xlYW5lZFN0YWNrID0gYmFja3RyYWNlQ2xlYW5lci5nZXRDbGVhbmVkU3RhY2soKVxuICAgICAgICAgICAgICBjb25zdCBzdGFja0xpbmVzID0gY2xlYW5lZFN0YWNrPy5zcGxpdChcIlxcblwiKVxuXG4gICAgICAgICAgICAgIGlmIChzdGFja0xpbmVzKSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBzdGFja0xpbmUgb2Ygc3RhY2tMaW5lcykge1xuICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihwaWNvY29sb3JzLnJlZChgJHtsZWZ0UGFkZGluZ30gICR7c3RhY2tMaW5lfWApKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihwaWNvY29sb3JzLnJlZChgJHtsZWZ0UGFkZGluZ30gIFRlc3QgZmFpbGVkIHdpdGggYSAke3R5cGVvZiBmYWlsZWRFcnJvcn06ICR7U3RyaW5nKGZhaWxlZEVycm9yKX1gKSlcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5wcmludEZhaWxlZENvbnNvbGVPdXRwdXQoe2NvbnNvbGVPdXRwdXQsIGxlZnRQYWRkaW5nfSlcbiAgICAgICAgICAgIHRoaXMuX2ZhaWxlZFRlc3RzKytcbiAgICAgICAgICAgIHRoaXMuX2ZhaWxlZFRlc3REZXRhaWxzLnB1c2goe1xuICAgICAgICAgICAgICBmdWxsRGVzY3JpcHRpb246IHRoaXMuYnVpbGRGdWxsRGVzY3JpcHRpb24oZGVzY3JpcHRpb25zLCB0ZXN0RGVzY3JpcHRpb24pLFxuICAgICAgICAgICAgICBmaWxlUGF0aDogdGVzdERhdGEuZmlsZVBhdGgsXG4gICAgICAgICAgICAgIGxpbmU6IHRlc3REYXRhLmxpbmUsXG4gICAgICAgICAgICAgIGVycm9yOiBmYWlsZWRFcnJvcixcbiAgICAgICAgICAgICAgY29uc29sZU91dHB1dDogY29uc29sZU91dHB1dCB8fCB1bmRlZmluZWRcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZW1pdEV2ZW50KFwidGVzdEZhaWxlZFwiLCB7XG4gICAgICAgICAgICAgIGNvbmZpZ3VyYXRpb246IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpLFxuICAgICAgICAgICAgICBkZXNjcmlwdGlvbnMsXG4gICAgICAgICAgICAgIGVycm9yOiBmYWlsZWRFcnJvcixcbiAgICAgICAgICAgICAgdGVzdEFyZ3MsXG4gICAgICAgICAgICAgIHRlc3REYXRhLFxuICAgICAgICAgICAgICB0ZXN0RGVzY3JpcHRpb24sXG4gICAgICAgICAgICAgIHRlc3RSdW5uZXI6IHRoaXNcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIHRoaXMucHJpbnRSZXJ1bkNvbW1hbmQoe2Rlc2NyaXB0aW9ucywgdGVzdERlc2NyaXB0aW9uLCB0ZXN0RGF0YSwgbGVmdFBhZGRpbmd9KVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZm9yIChjb25zdCBzdWJEZXNjcmlwdGlvbiBpbiB0ZXN0cy5zdWJzKSB7XG4gICAgICAgIGNvbnN0IHN1YlRlc3QgPSB0ZXN0cy5zdWJzW3N1YkRlc2NyaXB0aW9uXVxuICAgICAgICBjb25zdCBuZXdEZWNyaXB0aW9ucyA9IGRlc2NyaXB0aW9ucy5jb25jYXQoW3N1YkRlc2NyaXB0aW9uXSlcbiAgICAgICAgY29uc3QgY2hpbGRTY29wZUxpbmVNYXRjaCA9IHNjb3BlTGluZU1hdGNoIHx8IHRoaXMubWF0Y2hlc0xpbmVGaWx0ZXIoc3ViVGVzdClcblxuICAgICAgICBpZiAoIXRoaXMuX29ubHlGb2N1c3NlZCB8fCBzdWJUZXN0LmFueVRlc3RzRm9jdXNzZWQpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhgJHtsZWZ0UGFkZGluZ30ke3N1YkRlc2NyaXB0aW9ufWApXG4gICAgICAgICAgYXdhaXQgdGhpcy5ydW5UZXN0cyh7XG4gICAgICAgICAgICBhZnRlckVhY2hlczogbmV3QWZ0ZXJFYWNoZXMsXG4gICAgICAgICAgICBiZWZvcmVFYWNoZXM6IG5ld0JlZm9yZUVhY2hlcyxcbiAgICAgICAgICAgIHRlc3RzOiBzdWJUZXN0LFxuICAgICAgICAgICAgZGVzY3JpcHRpb25zOiBuZXdEZWNyaXB0aW9ucyxcbiAgICAgICAgICAgIGluZGVudExldmVsOiBpbmRlbnRMZXZlbCArIDEsXG4gICAgICAgICAgICBsaW5lTWF0Y2hlZEluU2NvcGU6IGNoaWxkU2NvcGVMaW5lTWF0Y2hcbiAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGF3YWl0IHRoaXMucnVuQWZ0ZXJBbGxzRm9yU2NvcGUoc2NvcGVFbnRyeSlcbiAgICAgIGNvbnN0IHNjb3BlSW5kZXggPSB0aGlzLl9hY3RpdmVBZnRlckFsbFNjb3Blcy5pbmRleE9mKHNjb3BlRW50cnkpXG5cbiAgICAgIGlmIChzY29wZUluZGV4ID49IDApIHtcbiAgICAgICAgdGhpcy5fYWN0aXZlQWZ0ZXJBbGxTY29wZXMuc3BsaWNlKHNjb3BlSW5kZXgsIDEpXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7QWN0aXZlQWZ0ZXJBbGxTY29wZUVudHJ5fSBzY29wZUVudHJ5IC0gU2NvcGUgZW50cnkuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gc2NvcGUgY2xlYW51cCBmaW5pc2hlcy5cbiAgICovXG4gIGFzeW5jIHJ1bkFmdGVyQWxsc0ZvclNjb3BlKHNjb3BlRW50cnkpIHtcbiAgICBpZiAoc2NvcGVFbnRyeS5hZnRlckFsbHNSdW4pIHJldHVyblxuXG4gICAgc2NvcGVFbnRyeS5hZnRlckFsbHNSdW4gPSB0cnVlXG5cbiAgICBmb3IgKGNvbnN0IGFmdGVyQWxsRGF0YSBvZiBzY29wZUVudHJ5LnRlc3RzLmFmdGVyQWxscyB8fCBbXSkge1xuICAgICAgYXdhaXQgYWZ0ZXJBbGxEYXRhLmNhbGxiYWNrKHtjb25maWd1cmF0aW9uOiB0aGlzLmdldENvbmZpZ3VyYXRpb24oKX0pXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWUgLSBFdmVudCBuYW1lLlxuICAgKiBAcGFyYW0ge29iamVjdH0gcGF5bG9hZCAtIEV2ZW50IHBheWxvYWQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gYWxsIGxpc3RlbmVycyBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIGVtaXRFdmVudChldmVudE5hbWUsIHBheWxvYWQpIHtcbiAgICBjb25zdCBsaXN0ZW5lcnMgPSB0ZXN0RXZlbnRzLmxpc3RlbmVycyhldmVudE5hbWUpXG5cbiAgICBmb3IgKGNvbnN0IGxpc3RlbmVyIG9mIGxpc3RlbmVycykge1xuICAgICAgYXdhaXQgbGlzdGVuZXIocGF5bG9hZClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHBhcmFtIHtzdHJpbmdbXX0gYXJncy5kZXNjcmlwdGlvbnMgLSBEZXNjcmlwdGlvbiBzdGFjay5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MudGVzdERlc2NyaXB0aW9uIC0gVGVzdCBkZXNjcmlwdGlvbi5cbiAgICogQHBhcmFtIHtUZXN0RGF0YX0gYXJncy50ZXN0RGF0YSAtIFRlc3QgZGF0YS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MubGVmdFBhZGRpbmcgLSBMZWZ0IHBhZGRpbmcuXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIHByaW50UmVydW5Db21tYW5kKHtkZXNjcmlwdGlvbnMsIHRlc3REZXNjcmlwdGlvbiwgdGVzdERhdGEsIGxlZnRQYWRkaW5nfSkge1xuICAgIGNvbnN0IHJlcnVuID0gdGhpcy5idWlsZFJlcnVuQ29tbWFuZCh7ZGVzY3JpcHRpb25zLCB0ZXN0RGVzY3JpcHRpb24sIHRlc3REYXRhfSlcblxuICAgIGlmIChyZXJ1bikge1xuICAgICAgY29uc29sZS5lcnJvcihgJHtsZWZ0UGFkZGluZ30gIFJlLXJ1bjogJHtyZXJ1bn1gKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBhcmdzLmRlc2NyaXB0aW9ucyAtIERlc2NyaXB0aW9uIHN0YWNrLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy50ZXN0RGVzY3JpcHRpb24gLSBUZXN0IGRlc2NyaXB0aW9uLlxuICAgKiBAcGFyYW0ge1Rlc3REYXRhfSBhcmdzLnRlc3REYXRhIC0gVGVzdCBkYXRhLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nIHwgdW5kZWZpbmVkfSAtIFJlcnVuIGNvbW1hbmQuXG4gICAqL1xuICBidWlsZFJlcnVuQ29tbWFuZCh7ZGVzY3JpcHRpb25zLCB0ZXN0RGVzY3JpcHRpb24sIHRlc3REYXRhfSkge1xuICAgIGNvbnN0IGJhc2VDb21tYW5kID0gXCJucHggdmVsb2Npb3VzIHRlc3RcIlxuICAgIGNvbnN0IGZpbGVQYXRoID0gdGVzdERhdGEuZmlsZVBhdGhcbiAgICBjb25zdCBsaW5lID0gdGVzdERhdGEubGluZVxuXG4gICAgaWYgKGZpbGVQYXRoICYmIGxpbmUpIHtcbiAgICAgIGNvbnN0IHJlbGF0aXZlUGF0aCA9IHBhdGgucmVsYXRpdmUocHJvY2Vzcy5jd2QoKSwgZmlsZVBhdGgpXG4gICAgICByZXR1cm4gYCR7YmFzZUNvbW1hbmR9ICR7cmVsYXRpdmVQYXRofToke2xpbmV9YFxuICAgIH1cblxuICAgIGNvbnN0IGZ1bGxEZXNjcmlwdGlvbiA9IHRoaXMuYnVpbGRGdWxsRGVzY3JpcHRpb24oZGVzY3JpcHRpb25zLCB0ZXN0RGVzY3JpcHRpb24pXG5cbiAgICBpZiAoZnVsbERlc2NyaXB0aW9uKSB7XG4gICAgICByZXR1cm4gYCR7YmFzZUNvbW1hbmR9IC0tZXhhbXBsZSAke0pTT04uc3RyaW5naWZ5KGZ1bGxEZXNjcmlwdGlvbil9YFxuICAgIH1cblxuICAgIHJldHVybiB1bmRlZmluZWRcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0F0dGVtcHRDb25zb2xlT3V0cHV0W119IGF0dGVtcHRDb25zb2xlT3V0cHV0cyAtIEF0dGVtcHQgb3V0cHV0IGVudHJpZXMuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IC0gQ29tYmluZWQgY29uc29sZSBvdXRwdXQuXG4gICAqL1xuICBidWlsZENvbnNvbGVPdXRwdXQoYXR0ZW1wdENvbnNvbGVPdXRwdXRzKSB7XG4gICAgaWYgKGF0dGVtcHRDb25zb2xlT3V0cHV0cy5sZW5ndGggPT09IDApIHJldHVybiBcIlwiXG4gICAgaWYgKGF0dGVtcHRDb25zb2xlT3V0cHV0cy5sZW5ndGggPT09IDEpIHJldHVybiBhdHRlbXB0Q29uc29sZU91dHB1dHNbMF0ub3V0cHV0XG5cbiAgICByZXR1cm4gYXR0ZW1wdENvbnNvbGVPdXRwdXRzLm1hcCgoYXR0ZW1wdENvbnNvbGVPdXRwdXQpID0+IHtcbiAgICAgIHJldHVybiBgLS0tIEF0dGVtcHQgJHthdHRlbXB0Q29uc29sZU91dHB1dC5hdHRlbXB0TnVtYmVyfSAtLS1cXG4ke2F0dGVtcHRDb25zb2xlT3V0cHV0Lm91dHB1dH1gXG4gICAgfSkuam9pbihcIlxcblwiKVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IC0gTWF4aW11bSBmYWlsZWQgY29uc29sZSBsaW5lcy5cbiAgICovXG4gIGdldEZhaWxlZENvbnNvbGVPdXRwdXRNYXhMaW5lcygpIHtcbiAgICBjb25zdCBtYXhMaW5lcyA9IHRlc3RDb25maWcuZmFpbGVkQ29uc29sZU91dHB1dE1heExpbmVzXG5cbiAgICBpZiAodHlwZW9mIG1heExpbmVzICE9PSBcIm51bWJlclwiIHx8ICFOdW1iZXIuaXNGaW5pdGUobWF4TGluZXMpKSByZXR1cm4gMjAwXG5cbiAgICByZXR1cm4gTWF0aC5tYXgoMCwgTWF0aC5mbG9vcihtYXhMaW5lcykpXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IGNvbnNvbGVPdXRwdXQgLSBDb25zb2xlIG91dHB1dC5cbiAgICogQHJldHVybnMge3N0cmluZ1tdfSAtIExpbmVzIGZvciBpbmxpbmUgb3V0cHV0LlxuICAgKi9cbiAgdHJ1bmNhdGVGYWlsZWRDb25zb2xlT3V0cHV0TGluZXMoY29uc29sZU91dHB1dCkge1xuICAgIGNvbnN0IGxpbmVzID0gY29uc29sZU91dHB1dC5zcGxpdChcIlxcblwiKVxuICAgIGNvbnN0IG1heExpbmVzID0gdGhpcy5nZXRGYWlsZWRDb25zb2xlT3V0cHV0TWF4TGluZXMoKVxuXG4gICAgaWYgKG1heExpbmVzID09PSAwKSByZXR1cm4gW11cbiAgICBpZiAobGluZXMubGVuZ3RoIDw9IG1heExpbmVzKSByZXR1cm4gbGluZXNcblxuICAgIGNvbnN0IG9taXR0ZWRMaW5lcyA9IGxpbmVzLmxlbmd0aCAtIG1heExpbmVzXG4gICAgY29uc3QgcGx1cmFsID0gb21pdHRlZExpbmVzID09PSAxID8gXCJcIiA6IFwic1wiXG5cbiAgICByZXR1cm4gW1xuICAgICAgYC4uLiAke29taXR0ZWRMaW5lc30gY29uc29sZSBvdXRwdXQgbGluZSR7cGx1cmFsfSBvbWl0dGVkIC4uLmAsXG4gICAgICAuLi5saW5lcy5zbGljZSgtbWF4TGluZXMpXG4gICAgXVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucyBvYmplY3QuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLmNvbnNvbGVPdXRwdXQgLSBDb25zb2xlIG91dHB1dC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MubGVmdFBhZGRpbmcgLSBMZWZ0IHBhZGRpbmcuXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIHByaW50RmFpbGVkQ29uc29sZU91dHB1dCh7Y29uc29sZU91dHB1dCwgbGVmdFBhZGRpbmd9KSB7XG4gICAgaWYgKHRlc3RDb25maWcuY29uc29sZU91dHB1dCAhPT0gXCJmYWlsdXJlXCIpIHJldHVyblxuICAgIGlmICghY29uc29sZU91dHB1dCkgcmV0dXJuXG5cbiAgICBjb25zdCBsaW5lcyA9IHRoaXMudHJ1bmNhdGVGYWlsZWRDb25zb2xlT3V0cHV0TGluZXMoY29uc29sZU91dHB1dClcblxuICAgIGlmIChsaW5lcy5sZW5ndGggPT09IDApIHJldHVyblxuXG4gICAgY29uc29sZS5lcnJvcihwaWNvY29sb3JzLnJlZChgJHtsZWZ0UGFkZGluZ30gIENvbnNvbGUgb3V0cHV0OmApKVxuXG4gICAgZm9yIChjb25zdCBsaW5lIG9mIGxpbmVzKSB7XG4gICAgICBjb25zb2xlLmVycm9yKHBpY29jb2xvcnMucmVkKGAke2xlZnRQYWRkaW5nfSAgICAke2xpbmV9YCkpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBbYXJnc10gLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHBhcmFtIHtib29sZWFufSBbYXJncy5wYXNzdGhyb3VnaF0gLSBXaGV0aGVyIHRvIHBhc3MgdGhyb3VnaCB0byB0aGUgb3JpZ2luYWwgY29uc29sZS5cbiAgICogQHJldHVybnMgeygpID0+IHN0cmluZ30gLSBTdG9wcyB0aGUgY2FwdHVyZSBhbmQgcmV0dXJucyBjYXB0dXJlZCB0ZXh0LlxuICAgKi9cbiAgc3RhcnRDb25zb2xlQ2FwdHVyZSh7cGFzc3Rocm91Z2ggPSBmYWxzZX0gPSB7fSkge1xuICAgIC8qKiBAdHlwZSB7c3RyaW5nW119ICovXG4gICAgY29uc3QgbGluZXMgPSBbXVxuICAgIC8qKiBAdHlwZSB7UmVjb3JkPENvbnNvbGVNZXRob2ROYW1lLCAoLi4uYXJnczogdW5rbm93bltdKSA9PiB2b2lkPn0gKi9cbiAgICBjb25zdCBjb25zb2xlT2JqZWN0ID0gLyoqIEB0eXBlIHtSZWNvcmQ8Q29uc29sZU1ldGhvZE5hbWUsICguLi5hcmdzOiB1bmtub3duW10pID0+IHZvaWQ+fSAqLyAoY29uc29sZSlcbiAgICAvKiogQHR5cGUge1JlY29yZDxDb25zb2xlTWV0aG9kTmFtZSwgKC4uLmFyZ3M6IHVua25vd25bXSkgPT4gdm9pZD59ICovXG4gICAgY29uc3Qgb3JpZ2luYWxDb25zb2xlTWV0aG9kcyA9IHtcbiAgICAgIGRlYnVnOiBjb25zb2xlT2JqZWN0LmRlYnVnLmJpbmQoY29uc29sZSksXG4gICAgICBlcnJvcjogY29uc29sZU9iamVjdC5lcnJvci5iaW5kKGNvbnNvbGUpLFxuICAgICAgaW5mbzogY29uc29sZU9iamVjdC5pbmZvLmJpbmQoY29uc29sZSksXG4gICAgICBsb2c6IGNvbnNvbGVPYmplY3QubG9nLmJpbmQoY29uc29sZSksXG4gICAgICB3YXJuOiBjb25zb2xlT2JqZWN0Lndhcm4uYmluZChjb25zb2xlKVxuICAgIH1cbiAgICBsZXQgc3RvcHBlZCA9IGZhbHNlXG4gICAgbGV0IG91dHB1dFRleHQgPSBcIlwiXG5cbiAgICBmb3IgKGNvbnN0IG1ldGhvZE5hbWUgb2YgQ0FQVFVSRURfQ09OU09MRV9NRVRIT0RTKSB7XG4gICAgICBjb25zb2xlT2JqZWN0W21ldGhvZE5hbWVdID0gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgbGluZXMucHVzaChgWyR7bmV3IERhdGUoKS50b0lTT1N0cmluZygpfV0gWyR7bWV0aG9kTmFtZX1dICR7Zm9ybWF0KC4uLmFyZ3MpfWApXG5cbiAgICAgICAgaWYgKHBhc3N0aHJvdWdoKSB7XG4gICAgICAgICAgb3JpZ2luYWxDb25zb2xlTWV0aG9kc1ttZXRob2ROYW1lXSguLi5hcmdzKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGlmICghc3RvcHBlZCkge1xuICAgICAgICBzdG9wcGVkID0gdHJ1ZVxuXG4gICAgICAgIGZvciAoY29uc3QgbWV0aG9kTmFtZSBvZiBDQVBUVVJFRF9DT05TT0xFX01FVEhPRFMpIHtcbiAgICAgICAgICBjb25zb2xlT2JqZWN0W21ldGhvZE5hbWVdID0gb3JpZ2luYWxDb25zb2xlTWV0aG9kc1ttZXRob2ROYW1lXVxuICAgICAgICB9XG5cbiAgICAgICAgb3V0cHV0VGV4dCA9IGxpbmVzLmpvaW4oXCJcXG5cIilcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG91dHB1dFRleHRcbiAgICB9XG4gIH1cbn1cbiJdfQ==
|
|
1031
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC1ydW5uZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdGVzdGluZy90ZXN0LXJ1bm5lci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxFQUFDLHNCQUFzQixFQUFDLE1BQU0sZ0NBQWdDLENBQUE7QUFDckUsT0FBTyxFQUFFLE1BQU0sa0JBQWtCLENBQUE7QUFDakMsT0FBTyxJQUFJLE1BQU0sTUFBTSxDQUFBO0FBQ3ZCLE9BQU8sRUFBQyxNQUFNLEVBQUMsTUFBTSxXQUFXLENBQUE7QUFDaEMsT0FBTyxXQUFXLE1BQU0sMEJBQTBCLENBQUE7QUFDbEQsT0FBTyxnQkFBZ0IsTUFBTSxvQ0FBb0MsQ0FBQTtBQUNqRSxPQUFPLGFBQWEsTUFBTSxxQkFBcUIsQ0FBQTtBQUMvQyxPQUFPLFVBQVUsTUFBTSxZQUFZLENBQUE7QUFDbkMsT0FBTyxhQUFhLE1BQU0sNkJBQTZCLENBQUE7QUFDdkQsT0FBTyxFQUFDLFVBQVUsRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFDLE1BQU0sV0FBVyxDQUFBO0FBQ3ZELE9BQU8sRUFBQyxhQUFhLEVBQUMsTUFBTSxLQUFLLENBQUE7QUFDakMsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLGNBQWMsQ0FBQTtBQUU1Qzs7Ozs7O0dBTUc7QUFDSCxTQUFTLGNBQWMsQ0FBQyxPQUFPLEVBQUUsU0FBUyxFQUFFLGVBQWU7SUFDekQsTUFBTSxjQUFjLEdBQUcsQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDLENBQUE7SUFDMUUsTUFBTSxZQUFZLEdBQUcsSUFBSSxLQUFLLENBQUMsbUJBQW1CLGNBQWMsTUFBTSxlQUFlLEVBQUUsQ0FBQyxDQUFBO0lBRXhGLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7UUFDckMs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Q0FBQztZQUVELE9BQU8sVUFBVSxDQUFBO1FBQ25CLENBQUMsQ0FBQTtJQUNILENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQge2FkZFRyYWNrZWRTdGFja1RvRXJyb3J9IGZyb20gXCIuLi91dGlscy93aXRoLXRyYWNrZWQtc3RhY2suanNcIlxuaW1wb3J0IGZzIGZyb20gXCJub2RlOmZzL3Byb21pc2VzXCJcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCJcbmltcG9ydCB7Zm9ybWF0fSBmcm9tIFwibm9kZTp1dGlsXCJcbmltcG9ydCBBcHBsaWNhdGlvbiBmcm9tIFwiLi4vLi4vc3JjL2FwcGxpY2F0aW9uLmpzXCJcbmltcG9ydCBCYWNrdHJhY2VDbGVhbmVyIGZyb20gXCIuLi91dGlscy9iYWNrdHJhY2UtY2xlYW5lci1ub2RlLmpzXCJcbmltcG9ydCBSZXF1ZXN0Q2xpZW50IGZyb20gXCIuL3JlcXVlc3QtY2xpZW50LmpzXCJcbmltcG9ydCBwaWNvY29sb3JzIGZyb20gXCJwaWNvY29sb3JzXCJcbmltcG9ydCByZXN0QXJnc0Vycm9yIGZyb20gXCIuLi91dGlscy9yZXN0LWFyZ3MtZXJyb3IuanNcIlxuaW1wb3J0IHt0ZXN0Q29uZmlnLCB0ZXN0RXZlbnRzLCB0ZXN0c30gZnJvbSBcIi4vdGVzdC5qc1wiXG5pbXBvcnQge3BhdGhUb0ZpbGVVUkx9IGZyb20gXCJ1cmxcIlxuaW1wb3J0IHtjbGVhckRlbGl2ZXJpZXN9IGZyb20gXCIuLi9tYWlsZXIuanNcIlxuXG4vKipcbiAqIFJ1bnMgcnVuIHdpdGggdGltZW91dC5cbiAqIEBwYXJhbSB7UHJvbWlzZTw/PiB8ID99IHByb21pc2UgLSBQcm9taXNlIG9yIHZhbHVlLlxuICogQHBhcmFtIHtudW1iZXJ9IHRpbWVvdXRNcyAtIFRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzLlxuICogQHBhcmFtIHtzdHJpbmd9IHRlc3REZXNjcmlwdGlvbiAtIFRlc3QgZGVzY3JpcHRpb24uXG4gKiBAcmV0dXJucyB7UHJvbWlzZTw/Pn0gLSBSZXNvbHZlcyBvciByZWplY3RzIGJhc2VkIG9uIHRpbWVvdXQgb3IgcHJvbWlzZSByZXN1bHQuXG4gKi9cbmZ1bmN0aW9uIHJ1bldpdGhUaW1lb3V0KHByb21pc2UsIHRpbWVvdXRNcywgdGVzdERlc2NyaXB0aW9uKSB7XG4gIGNvbnN0IHRpbWVvdXRTZWNvbmRzID0gKHRpbWVvdXRNcyAvIDEwMDApLnRvRml4ZWQoMykucmVwbGFjZSgvXFwuPzArJC8sIFwiXCIpXG4gIGNvbnN0IHRpbWVvdXRFcnJvciA9IG5ldyBFcnJvcihgVGltZWQgb3V0IGFmdGVyICR7dGltZW91dFNlY29uZHN9czogJHt0ZXN0RGVzY3JpcHRpb259YClcblxuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGNvbnN0IHRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHJlamVjdCh0aW1lb3V0RXJyb3IpLCB0aW1lb3V0TXMpXG5cbiAgICBQcm9taXNlLnJlc29sdmUocHJvbWlzZSkudGhlbigocmVzdWx0KSA9PiB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZW91dClcbiAgICAgIHJlc29sdmUocmVzdWx0KVxuICAgIH0pLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpXG4gICAgICByZWplY3QoZXJyb3IpXG4gICAgfSlcbiAgfSlcbn1cblxuLyoqXG4gKiBDb25zb2xlTWV0aG9kTmFtZSB0eXBlLlxuICBAdHlwZWRlZiB7XCJsb2dcIiB8IFwiaW5mb1wiIHwgXCJ3YXJuXCIgfCBcImVycm9yXCIgfCBcImRlYnVnXCJ9IENvbnNvbGVNZXRob2ROYW1lICovXG5cbi8qKlxuICogQ2FwdHVyZWQgY29uc29sZSBtZXRob2RzLlxuICBAdHlwZSB7Q29uc29sZU1ldGhvZE5hbWVbXX0gKi9cbmNvbnN0IENBUFRVUkVEX0NPTlNPTEVfTUVUSE9EUyA9IFtcImxvZ1wiLCBcImluZm9cIiwgXCJ3YXJuXCIsIFwiZXJyb3JcIiwgXCJkZWJ1Z1wiXVxuXG4vKipcbiAqIEF0dGVtcHRDb25zb2xlT3V0cHV0IHR5cGUuXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBBdHRlbXB0Q29uc29sZU91dHB1dFxuICogQHByb3BlcnR5IHtudW1iZXJ9IGF0dGVtcHROdW1iZXIgLSBBdHRlbXB0IG51bWJlci5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBvdXRwdXQgLSBDYXB0dXJlZCBjb25zb2xlIG91dHB1dC5cbiAqL1xuXG4vKipcbiAqIFJ1bnMgdG8gZmlsZSBzbHVnLlxuICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlIC0gVmFsdWUgdG8gc2FuaXRpemUuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSAtIFNsdWctc2FmZSB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gdG9GaWxlU2x1Zyh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWVcbiAgICAudG9Mb3dlckNhc2UoKVxuICAgIC5yZXBsYWNlKC9bXmEtejAtOV0rL2csIFwiLVwiKVxuICAgIC5yZXBsYWNlKC9eLSt8LSskL2csIFwiXCIpXG4gICAgLnNsaWNlKDAsIDgwKSB8fCBcImZhaWxlZC10ZXN0XCJcbn1cblxuLyoqXG4gKiBUZXN0QXJncyB0eXBlLlxuICogQHR5cGVkZWYge29iamVjdH0gVGVzdEFyZ3NcbiAqIEBwcm9wZXJ0eSB7QXBwbGljYXRpb259IFthcHBsaWNhdGlvbl0gLSBBcHBsaWNhdGlvbiBpbnN0YW5jZSBmb3IgaW50ZWdyYXRpb24gdGVzdHMuXG4gKiBAcHJvcGVydHkge1JlcXVlc3RDbGllbnR9IFtjbGllbnRdIC0gSFRUUCBjbGllbnQgZm9yIHJlcXVlc3QgdGVzdHMuXG4gKiBAcHJvcGVydHkge29iamVjdH0gW2RhdGFiYXNlQ2xlYW5pbmddIC0gRGF0YWJhc2UgY2xlYW51cCBvcHRpb25zIGZvciB0ZXN0cy5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW2RhdGFiYXNlQ2xlYW5pbmcudHJhbnNhY3Rpb25dIC0gVXNlIHRyYW5zYWN0aW9ucyB0byByb2xsYmFjayBiZXR3ZWVuIHRlc3RzLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbZGF0YWJhc2VDbGVhbmluZy50cnVuY2F0ZV0gLSBUcnVuY2F0ZSB0YWJsZXMgYmV0d2VlbiB0ZXN0cy5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW2ZvY3VzXSAtIFdoZXRoZXIgdGhpcyB0ZXN0IGlzIGZvY3VzZWQuXG4gKiBAcHJvcGVydHkgeygpID0+ICh2b2lkfFByb21pc2U8dm9pZD4pfSBbZnVuY3Rpb25dIC0gVGVzdCBjYWxsYmFjayBmdW5jdGlvbi5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbcmV0cnldIC0gTnVtYmVyIG9mIHJldHJpZXMgd2hlbiBhIHRlc3QgZmFpbHMuXG4gKiBAcHJvcGVydHkge3N0cmluZ1tdIHwgc3RyaW5nfSBbdGFnc10gLSBUYWdzIGZvciBmaWx0ZXJpbmcuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3RpbWVvdXRTZWNvbmRzXSAtIFRpbWVvdXQgaW4gc2Vjb25kcyBmb3IgdGhlIHRlc3QuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW3R5cGVdIC0gVGVzdCB0eXBlIGlkZW50aWZpZXIuXG4gKi9cblxuLyoqXG4gKiBUZXN0RGF0YSB0eXBlLlxuICogQHR5cGVkZWYge29iamVjdH0gVGVzdERhdGFcbiAqIEBwcm9wZXJ0eSB7VGVzdEFyZ3N9IGFyZ3MgLSBBcmd1bWVudHMgcGFzc2VkIHRvIHRoZSB0ZXN0LlxuICogQHByb3BlcnR5IHtzdHJpbmd9IFtmaWxlUGF0aF0gLSBTb3VyY2UgZmlsZSBwYXRoLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtsaW5lXSAtIFNvdXJjZSBsaW5lIG51bWJlci5cbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24oVGVzdEFyZ3MpIDogKHZvaWR8UHJvbWlzZTx2b2lkPil9IGZ1bmN0aW9uIC0gVGVzdCBjYWxsYmFjayB0byBleGVjdXRlLlxuICovXG5cbi8qKlxuICogRmFpbGVkVGVzdERldGFpbCB0eXBlLlxuICogQHR5cGVkZWYge29iamVjdH0gRmFpbGVkVGVzdERldGFpbFxuICogQHByb3BlcnR5IHtzdHJpbmd9IGZ1bGxEZXNjcmlwdGlvbiAtIEZ1bGwgdGVzdCBkZXNjcmlwdGlvbi5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbZmlsZVBhdGhdIC0gU291cmNlIGZpbGUgcGF0aC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBbbGluZV0gLSBTb3VyY2UgbGluZSBudW1iZXIuXG4gKiBAcHJvcGVydHkgez99IGVycm9yIC0gRmFpbHVyZSBlcnJvci5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbY29uc29sZU91dHB1dF0gLSBDYXB0dXJlZCBjb25zb2xlIG91dHB1dCB3aGlsZSB0ZXN0IHJhbi5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbY29uc29sZUxvZ1BhdGhdIC0gU2F2ZWQgY29uc29sZSBsb2cgcGF0aC5cbiAqL1xuXG4vKipcbiAqIEFjdGl2ZUFmdGVyQWxsU2NvcGVFbnRyeSB0eXBlLlxuICogQHR5cGVkZWYge29iamVjdH0gQWN0aXZlQWZ0ZXJBbGxTY29wZUVudHJ5XG4gKiBAcHJvcGVydHkge1Rlc3RzQXJndW1lbnR9IHRlc3RzIC0gU2NvcGUgdGVzdCB0cmVlLlxuICogQHByb3BlcnR5IHtib29sZWFufSBhZnRlckFsbHNSdW4gLSBXaGV0aGVyIGNsZWFudXAgaG9va3MgaGF2ZSBydW4uXG4gKi9cblxuLyoqXG4gKiBEZWZpbmVzIHRoaXMgdHlwZWRlZi5cbiAqIEB0eXBlZGVmIHtmdW5jdGlvbih7Y29uZmlndXJhdGlvbjogaW1wb3J0KFwiLi4vY29uZmlndXJhdGlvbi5qc1wiKS5kZWZhdWx0LCB0ZXN0QXJnczogVGVzdEFyZ3MsIHRlc3REYXRhOiBUZXN0RGF0YX0pIDogKHZvaWR8UHJvbWlzZTx2b2lkPil9IEFmdGVyQmVmb3JlRWFjaENhbGxiYWNrVHlwZVxuICovXG5cbi8qKlxuICogQWZ0ZXJCZWZvcmVFYWNoQ2FsbGJhY2tPYmplY3RUeXBlIHR5cGUuXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBBZnRlckJlZm9yZUVhY2hDYWxsYmFja09iamVjdFR5cGVcbiAqIEBwcm9wZXJ0eSB7QWZ0ZXJCZWZvcmVFYWNoQ2FsbGJhY2tUeXBlfSBjYWxsYmFjayAtIEhvb2sgY2FsbGJhY2sgdG8gZXhlY3V0ZS5cbiAqL1xuXG4vKipcbiAqIERlZmluZXMgdGhpcyB0eXBlZGVmLlxuICogQHR5cGVkZWYge2Z1bmN0aW9uKHtjb25maWd1cmF0aW9uOiBpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLmpzXCIpLmRlZmF1bHR9KSA6ICh2b2lkfFByb21pc2U8dm9pZD4pfSBCZWZvcmVBZnRlckFsbENhbGxiYWNrVHlwZVxuICovXG5cbi8qKlxuICogQmVmb3JlQWZ0ZXJBbGxDYWxsYmFja09iamVjdFR5cGUgdHlwZS5cbiAqIEB0eXBlZGVmIHtvYmplY3R9IEJlZm9yZUFmdGVyQWxsQ2FsbGJhY2tPYmplY3RUeXBlXG4gKiBAcHJvcGVydHkge0JlZm9yZUFmdGVyQWxsQ2FsbGJhY2tUeXBlfSBjYWxsYmFjayAtIEhvb2sgY2FsbGJhY2sgdG8gZXhlY3V0ZS5cbiAqL1xuXG4vKipcbiAqIFRlc3RzQXJndW1lbnQgdHlwZS5cbiAqIEB0eXBlZGVmIHtvYmplY3R9IFRlc3RzQXJndW1lbnRcbiAqIEBwcm9wZXJ0eSB7UmVjb3JkPHN0cmluZywgVGVzdERhdGE+fSBhcmdzIC0gQXJndW1lbnRzIGtleWVkIGJ5IHRlc3QgZGVzY3JpcHRpb24uXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFthbnlUZXN0c0ZvY3Vzc2VkXSAtIFdoZXRoZXIgYW55IHRlc3RzIGluIHRoZSB0cmVlIGFyZSBmb2N1c2VkLlxuICogQHByb3BlcnR5IHtBZnRlckJlZm9yZUVhY2hDYWxsYmFja09iamVjdFR5cGVbXX0gYWZ0ZXJFYWNoZXMgLSBBZnRlci1lYWNoIGhvb2tzIGZvciB0aGlzIHNjb3BlLlxuICogQHByb3BlcnR5IHtCZWZvcmVBZnRlckFsbENhbGxiYWNrT2JqZWN0VHlwZVtdfSBhZnRlckFsbHMgLSBBZnRlci1hbGwgaG9va3MgZm9yIHRoaXMgc2NvcGUuXG4gKiBAcHJvcGVydHkge0JlZm9yZUFmdGVyQWxsQ2FsbGJhY2tPYmplY3RUeXBlW119IGJlZm9yZUFsbHMgLSBCZWZvcmUtYWxsIGhvb2tzIGZvciB0aGlzIHNjb3BlLlxuICogQHByb3BlcnR5IHtBZnRlckJlZm9yZUVhY2hDYWxsYmFja09iamVjdFR5cGVbXX0gYmVmb3JlRWFjaGVzIC0gQmVmb3JlLWVhY2ggaG9va3MgZm9yIHRoaXMgc2NvcGUuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW2ZpbGVQYXRoXSAtIFNvdXJjZSBmaWxlIHBhdGguXG4gKiBAcHJvcGVydHkge251bWJlcn0gW2xpbmVdIC0gU291cmNlIGxpbmUgbnVtYmVyLlxuICogQHByb3BlcnR5IHtSZWNvcmQ8c3RyaW5nLCBUZXN0RGF0YT59IHRlc3RzIC0gQSB1bmlxdWUgaWRlbnRpZmllciBmb3IgdGhlIG5vZGUuXG4gKiBAcHJvcGVydHkge1JlY29yZDxzdHJpbmcsIFRlc3RzQXJndW1lbnQ+fSBzdWJzIC0gT3B0aW9uYWwgY2hpbGQgbm9kZXMuIEVhY2ggaXRlbSBpcyBhbm90aGVyIGBOb2RlYCwgYWxsb3dpbmcgcmVjdXJzaW9uLlxuICovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRlc3RSdW5uZXIge1xuICAvKipcbiAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgIEB0eXBlIHtBY3RpdmVBZnRlckFsbFNjb3BlRW50cnlbXX0gKi9cbiAgX2FjdGl2ZUFmdGVyQWxsU2NvcGVzXG5cbiAgLyoqXG4gICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICBAdHlwZSB7RmFpbGVkVGVzdERldGFpbFtdfSAqL1xuICBfZmFpbGVkVGVzdERldGFpbHNcblxuICAvKipcbiAgICogUnVucyBjb25zdHJ1Y3Rvci5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLmpzXCIpLmRlZmF1bHR9IGFyZ3MuY29uZmlndXJhdGlvbiAtIENvbmZpZ3VyYXRpb24gaW5zdGFuY2UuXG4gICAqIEBwYXJhbSB7c3RyaW5nW10gfCBzdHJpbmd9IFthcmdzLmV4Y2x1ZGVUYWdzXSAtIFRhZ3MgdG8gZXhjbHVkZS5cbiAgICogQHBhcmFtIHtzdHJpbmdbXSB8IHN0cmluZ30gW2FyZ3MuaW5jbHVkZVRhZ3NdIC0gVGFncyB0byBpbmNsdWRlLlxuICAgKiBAcGFyYW0ge0FycmF5PHN0cmluZz59IGFyZ3MudGVzdEZpbGVzIC0gVGVzdCBmaWxlcy5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBudW1iZXJbXT59IFthcmdzLmxpbmVGaWx0ZXJzXSAtIExpbmUgZmlsdGVycyBieSBmaWxlLlxuICAgKiBAcGFyYW0ge1JlZ0V4cFtdfSBbYXJncy5leGFtcGxlUGF0dGVybnNdIC0gRXhhbXBsZSBwYXR0ZXJucy5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHtjb25maWd1cmF0aW9uLCBleGNsdWRlVGFncywgaW5jbHVkZVRhZ3MsIHRlc3RGaWxlcywgbGluZUZpbHRlcnMsIGV4YW1wbGVQYXR0ZXJucywgLi4ucmVzdEFyZ3N9KSB7XG4gICAgcmVzdEFyZ3NFcnJvcihyZXN0QXJncylcblxuICAgIGlmICghY29uZmlndXJhdGlvbikgdGhyb3cgbmV3IEVycm9yKFwiY29uZmlndXJhdGlvbiBpcyByZXF1aXJlZFwiKVxuXG4gICAgdGhpcy5fY29uZmlndXJhdGlvbiA9IGNvbmZpZ3VyYXRpb25cbiAgICB0aGlzLl9leGNsdWRlVGFncyA9IHRoaXMubm9ybWFsaXplVGFncyhleGNsdWRlVGFncylcbiAgICB0aGlzLl9leGNsdWRlVGFnU2V0ID0gbmV3IFNldCh0aGlzLl9leGNsdWRlVGFncylcbiAgICB0aGlzLl9pbmNsdWRlVGFncyA9IHRoaXMubm9ybWFsaXplVGFncyhpbmNsdWRlVGFncylcbiAgICB0aGlzLl9pbmNsdWRlVGFnU2V0ID0gbmV3IFNldCh0aGlzLl9pbmNsdWRlVGFncylcbiAgICB0aGlzLl90ZXN0RmlsZXMgPSB0ZXN0RmlsZXNcbiAgICB0aGlzLl9saW5lRmlsdGVycyA9IGxpbmVGaWx0ZXJzIHx8IHt9XG4gICAgdGhpcy5fZXhhbXBsZVBhdHRlcm5zID0gZXhhbXBsZVBhdHRlcm5zIHx8IFtdXG5cbiAgICB0aGlzLl9mYWlsZWRUZXN0cyA9IDBcbiAgICB0aGlzLl9zdWNjZXNzZnVsVGVzdHMgPSAwXG4gICAgdGhpcy5fdGVzdHNDb3VudCA9IDBcbiAgICB0aGlzLl9hY3RpdmVBZnRlckFsbFNjb3BlcyA9IFtdXG4gICAgdGhpcy5fZmFpbGVkVGVzdERldGFpbHMgPSBbXVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZ2V0IGNvbmZpZ3VyYXRpb24uXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLmpzXCIpLmRlZmF1bHR9IC0gVGhlIGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICBnZXRDb25maWd1cmF0aW9uKCkgeyByZXR1cm4gdGhpcy5fY29uZmlndXJhdGlvbiB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZ2V0IHRlc3QgZmlsZXMuXG4gICAqIEByZXR1cm5zIHtzdHJpbmdbXX0gLSBUaGUgdGVzdCBmaWxlcy5cbiAgICovXG4gIGdldFRlc3RGaWxlcygpIHsgcmV0dXJuIHRoaXMuX3Rlc3RGaWxlcyB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZ2V0IGxpbmUgZmlsdGVycy5cbiAgICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsIG51bWJlcltdPn0gLSBMaW5lIGZpbHRlcnMuXG4gICAqL1xuICBnZXRMaW5lRmlsdGVycygpIHsgcmV0dXJuIHRoaXMuX2xpbmVGaWx0ZXJzIH1cblxuICAvKipcbiAgICogUnVucyBnZXQgZXhhbXBsZSBwYXR0ZXJucy5cbiAgICogQHJldHVybnMge1JlZ0V4cFtdfSAtIEV4YW1wbGUgcGF0dGVybnMuXG4gICAqL1xuICBnZXRFeGFtcGxlUGF0dGVybnMoKSB7IHJldHVybiB0aGlzLl9leGFtcGxlUGF0dGVybnMgfVxuXG4gIC8qKlxuICAgKiBSdW5zIG5vcm1hbGl6ZSB0YWdzLlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdIHwgc3RyaW5nIHwgdW5kZWZpbmVkfSB0YWdzIC0gVGFncy5cbiAgICogQHJldHVybnMge3N0cmluZ1tdfSAtIE5vcm1hbGl6ZWQgdGFncy5cbiAgICovXG4gIG5vcm1hbGl6ZVRhZ3ModGFncykge1xuICAgIGlmICghdGFncykgcmV0dXJuIFtdXG5cbiAgICBjb25zdCB2YWx1ZXMgPSBbXVxuICAgIGNvbnN0IHJhd1RhZ3MgPSBBcnJheS5pc0FycmF5KHRhZ3MpID8gdGFncyA6IFt0YWdzXVxuXG4gICAgZm9yIChjb25zdCByYXdUYWcgb2YgcmF3VGFncykge1xuICAgICAgaWYgKHJhd1RhZyA9PT0gdW5kZWZpbmVkIHx8IHJhd1RhZyA9PT0gbnVsbCkgY29udGludWVcblxuICAgICAgY29uc3QgcGFydHMgPSBTdHJpbmcocmF3VGFnKS5zcGxpdChcIixcIilcblxuICAgICAgZm9yIChjb25zdCBwYXJ0IG9mIHBhcnRzKSB7XG4gICAgICAgIGNvbnN0IHRyaW1tZWQgPSBwYXJ0LnRyaW0oKVxuXG4gICAgICAgIGlmICh0cmltbWVkKSB2YWx1ZXMucHVzaCh0cmltbWVkKVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBBcnJheS5mcm9tKG5ldyBTZXQodmFsdWVzKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGhhcyB0YWcuXG4gICAqIEBwYXJhbSB7VGVzdEFyZ3N9IHRlc3RBcmdzIC0gVGVzdCBhcmdzLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGFnIC0gVGFnIHRvIGNoZWNrIGZvci5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gV2hldGhlciB0YWcgaXMgcHJlc2VudC5cbiAgICovXG4gIGhhc1RhZyh0ZXN0QXJncywgdGFnKSB7XG4gICAgcmV0dXJuIHRoaXMubm9ybWFsaXplVGFncyh0ZXN0QXJncz8udGFncykuaW5jbHVkZXModGFnKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgaXMgYnJvd3NlciB0ZXN0IG1vZGUuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgcnVubmluZyBicm93c2VyIHRlc3RzLlxuICAgKi9cbiAgaXNCcm93c2VyVGVzdE1vZGUoKSB7XG4gICAgcmV0dXJuIHByb2Nlc3MuZW52LlZFTE9DSU9VU19CUk9XU0VSX1RFU1RTID09PSBcInRydWVcIlxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgcnVuIHdpdGggZHVtbXkgaWYgbmVlZGVkLlxuICAgKiBAcGFyYW0ge1Rlc3RBcmdzfSB0ZXN0QXJncyAtIFRlc3QgYXJncy5cbiAgICogQHBhcmFtIHsoKSA9PiBQcm9taXNlPHZvaWQ+fSBjYWxsYmFjayAtIENhbGxiYWNrIHRvIHJ1bi5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIHJ1bldpdGhEdW1teUlmTmVlZGVkKHRlc3RBcmdzLCBjYWxsYmFjaykge1xuICAgIGlmICghdGhpcy5oYXNUYWcodGVzdEFyZ3MsIFwiZHVtbXlcIikpIHtcbiAgICAgIGF3YWl0IGNhbGxiYWNrKClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmICh0aGlzLmlzQnJvd3NlclRlc3RNb2RlKCkpIHtcbiAgICAgIGF3YWl0IHRoaXMucnVuQnJvd3NlckR1bW15KGNhbGxiYWNrKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5ydW5Ob2RlRHVtbXkoY2FsbGJhY2spXG4gIH1cblxuICAvKipcbiAgICogUnVucyBydW4gbm9kZSBkdW1teS5cbiAgICogQHBhcmFtIHsoKSA9PiBQcm9taXNlPHZvaWQ+fSBjYWxsYmFjayAtIENhbGxiYWNrIHRvIHJ1bi5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIHJ1bk5vZGVEdW1teShjYWxsYmFjaykge1xuICAgIGNvbnN0IGR1bW15UGF0aCA9IHByb2Nlc3MuZW52LlZFTE9DSU9VU19EVU1NWV9QQVRIIHx8IHRoaXMuZGVmYXVsdER1bW15UGF0aCgpXG4gICAgY29uc3QgZHVtbXlJbXBvcnQgPSBhd2FpdCBpbXBvcnQocGF0aFRvRmlsZVVSTChkdW1teVBhdGgpLmhyZWYpXG4gICAgY29uc3QgRHVtbXkgPSBkdW1teUltcG9ydC5kZWZhdWx0XG5cbiAgICBpZiAoIUR1bW15Py5ydW4pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRHVtbXkgaGVscGVyIG5vdCBmb3VuZCBhdCAke2R1bW15UGF0aH1gKVxuICAgIH1cblxuICAgIGF3YWl0IER1bW15LnJ1bihjYWxsYmFjaylcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGRlZmF1bHQgZHVtbXkgcGF0aC5cbiAgICogQHJldHVybnMge3N0cmluZ30gLSBEZWZhdWx0IGR1bW15IGhlbHBlciBwYXRoLlxuICAgKi9cbiAgZGVmYXVsdER1bW15UGF0aCgpIHtcbiAgICBjb25zdCBjd2QgPSBwYXRoLnJlc29sdmUocHJvY2Vzcy5jd2QoKSlcbiAgICBjb25zdCBub3JtYWxpemVkID0gY3dkLnNwbGl0KHBhdGguc2VwKS5qb2luKFwiL1wiKVxuXG4gICAgaWYgKG5vcm1hbGl6ZWQuZW5kc1dpdGgoXCIvc3BlYy9kdW1teVwiKSkge1xuICAgICAgcmV0dXJuIHBhdGguam9pbihjd2QsIFwiaW5kZXguanNcIilcbiAgICB9XG5cbiAgICByZXR1cm4gcGF0aC5qb2luKGN3ZCwgXCJzcGVjL2R1bW15L2luZGV4LmpzXCIpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBydW4gYnJvd3NlciBkdW1teS5cbiAgICogQHBhcmFtIHsoKSA9PiBQcm9taXNlPHZvaWQ+fSBjYWxsYmFjayAtIENhbGxiYWNrIHRvIHJ1bi5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIHJ1bkJyb3dzZXJEdW1teShjYWxsYmFjaykge1xuICAgIGF3YWl0IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpLmVuc3VyZUNvbm5lY3Rpb25zKHtuYW1lOiBcIlRlc3QgcnVubmVyIGJyb3dzZXIgZHVtbXlcIn0sIGFzeW5jIChkYnMpID0+IHtcbiAgICAgIGF3YWl0IHRoaXMudHJ1bmNhdGVEYXRhYmFzZXMoZGJzKVxuXG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBjYWxsYmFjaygpXG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCB0aGlzLnRydW5jYXRlRGF0YWJhc2VzKGRicylcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgdHJ1bmNhdGUgZGF0YWJhc2VzLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGltcG9ydChcIi4uL2RhdGFiYXNlL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pn0gZGJzIC0gRGF0YWJhc2UgY29ubmVjdGlvbnMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyB0cnVuY2F0ZURhdGFiYXNlcyhkYnMpIHtcbiAgICBmb3IgKGNvbnN0IGlkZW50aWZpZXIgb2YgT2JqZWN0LmtleXMoZGJzKSkge1xuICAgICAgYXdhaXQgZGJzW2lkZW50aWZpZXJdLnRydW5jYXRlQWxsVGFibGVzKClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBnZXQgZXhjbHVkZSB0YWcgc2V0LlxuICAgKiBAcmV0dXJucyB7U2V0PHN0cmluZz59IC0gRXhjbHVkZSB0YWcgc2V0LlxuICAgKi9cbiAgZ2V0RXhjbHVkZVRhZ1NldCgpIHtcbiAgICAvKipcbiAgICAgKiBDb25maWcgdGFncy5cbiAgICAgIEB0eXBlIHtzdHJpbmdbXX0gKi9cbiAgICBjb25zdCBjb25maWdUYWdzID0gQXJyYXkuaXNBcnJheSh0ZXN0Q29uZmlnLmV4Y2x1ZGVUYWdzKSA/IHRlc3RDb25maWcuZXhjbHVkZVRhZ3MgOiBbXVxuXG4gICAgcmV0dXJuIG5ldyBTZXQoWy4uLnRoaXMuX2V4Y2x1ZGVUYWdzLCAuLi5jb25maWdUYWdzXSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGhhcyBtYXRjaGluZyB0YWcuXG4gICAqIEBwYXJhbSB7c3RyaW5nW10gfCBzdHJpbmcgfCB1bmRlZmluZWR9IHRlc3RUYWdzIC0gVGVzdCB0YWdzLlxuICAgKiBAcGFyYW0ge1NldDxzdHJpbmc+fSB0YWdTZXQgLSBUYWcgc2V0LlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIGFueSB0YWdzIG1hdGNoLlxuICAgKi9cbiAgaGFzTWF0Y2hpbmdUYWcodGVzdFRhZ3MsIHRhZ1NldCkge1xuICAgIGlmICghdGFnU2V0LnNpemUpIHJldHVybiBmYWxzZVxuXG4gICAgY29uc3Qgbm9ybWFsaXplZCA9IHRoaXMubm9ybWFsaXplVGFncyh0ZXN0VGFncylcblxuICAgIGZvciAoY29uc3QgdGFnIG9mIG5vcm1hbGl6ZWQpIHtcbiAgICAgIGlmICh0YWdTZXQuaGFzKHRhZykpIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICAvKipcbiAgICogUnVucyBoYXMgcnVubmFibGUgdGVzdHMuXG4gICAqIEBwYXJhbSB7VGVzdHNBcmd1bWVudH0gdGVzdHMgLSBUZXN0cy5cbiAgICogQHBhcmFtIHtzdHJpbmdbXX0gW2Rlc2NyaXB0aW9uc10gLSBEZXNjcmlwdGlvbiBzdGFjay5cbiAgICogQHBhcmFtIHtib29sZWFufSBbbGluZU1hdGNoZWRJblNjb3BlXSAtIFdoZXRoZXIgbGluZSBtYXRjaGVkIGluIHNjb3BlLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIGFueSB0ZXN0cyBpbiB0aGlzIHNjb3BlIHdpbGwgcnVuLlxuICAgKi9cbiAgaGFzUnVubmFibGVUZXN0cyh0ZXN0cywgZGVzY3JpcHRpb25zID0gW10sIGxpbmVNYXRjaGVkSW5TY29wZSA9IGZhbHNlKSB7XG4gICAgZm9yIChjb25zdCB0ZXN0RGVzY3JpcHRpb24gaW4gdGVzdHMudGVzdHMpIHtcbiAgICAgIGNvbnN0IHRlc3REYXRhID0gdGVzdHMudGVzdHNbdGVzdERlc2NyaXB0aW9uXVxuICAgICAgY29uc3QgdGVzdEFyZ3MgPSAvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgICAgICAgICAgICAgICAgICAgICAgIEB0eXBlIHtUZXN0QXJnc30gKi8gKE9iamVjdC5hc3NpZ24oe30sIHRlc3REYXRhLmFyZ3MpKVxuICAgICAgY29uc3QgaW5jbHVkZUJ5TGluZSA9IGxpbmVNYXRjaGVkSW5TY29wZSB8fCB0aGlzLm1hdGNoZXNMaW5lRmlsdGVyKHRlc3REYXRhKVxuXG4gICAgICBpZiAodGhpcy5fb25seUZvY3Vzc2VkICYmICF0ZXN0QXJncy5mb2N1cykgY29udGludWVcbiAgICAgIGlmICh0aGlzLnNob3VsZFNraXBUZXN0KHRlc3RBcmdzLCB0ZXN0RGF0YSwgdGVzdERlc2NyaXB0aW9uLCBkZXNjcmlwdGlvbnMsIGluY2x1ZGVCeUxpbmUpKSBjb250aW51ZVxuXG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIGZvciAoY29uc3Qgc3ViRGVzY3JpcHRpb24gaW4gdGVzdHMuc3Vicykge1xuICAgICAgY29uc3Qgc3ViVGVzdCA9IHRlc3RzLnN1YnNbc3ViRGVzY3JpcHRpb25dXG4gICAgICBjb25zdCBzY29wZUxpbmVNYXRjaCA9IGxpbmVNYXRjaGVkSW5TY29wZSB8fCB0aGlzLm1hdGNoZXNMaW5lRmlsdGVyKHN1YlRlc3QpXG4gICAgICBjb25zdCBuZXh0RGVzY3JpcHRpb25zID0gZGVzY3JpcHRpb25zLmNvbmNhdChbc3ViRGVzY3JpcHRpb25dKVxuXG4gICAgICBpZiAodGhpcy5fb25seUZvY3Vzc2VkICYmICFzdWJUZXN0LmFueVRlc3RzRm9jdXNzZWQpIGNvbnRpbnVlXG4gICAgICBpZiAodGhpcy5oYXNSdW5uYWJsZVRlc3RzKHN1YlRlc3QsIG5leHREZXNjcmlwdGlvbnMsIHNjb3BlTGluZU1hdGNoKSkgcmV0dXJuIHRydWVcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHNob3VsZCBza2lwIHRlc3QuXG4gICAqIEBwYXJhbSB7VGVzdEFyZ3N9IHRlc3RBcmdzIC0gVGVzdCBhcmdzLlxuICAgKiBAcGFyYW0ge1Rlc3REYXRhfSB0ZXN0RGF0YSAtIFRlc3QgZGF0YS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRlc3REZXNjcmlwdGlvbiAtIFRlc3QgZGVzY3JpcHRpb24uXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IGRlc2NyaXB0aW9ucyAtIERlc2NyaXB0aW9uIHN0YWNrLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IGxpbmVNYXRjaGVkSW5TY29wZSAtIFdoZXRoZXIgbGluZSBtYXRjaGVkIGluIHNjb3BlLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIHRoZSB0ZXN0IHNob3VsZCBiZSBza2lwcGVkLlxuICAgKi9cbiAgc2hvdWxkU2tpcFRlc3QodGVzdEFyZ3MsIHRlc3REYXRhLCB0ZXN0RGVzY3JpcHRpb24sIGRlc2NyaXB0aW9ucywgbGluZU1hdGNoZWRJblNjb3BlKSB7XG4gICAgaWYgKHRoaXMuaGFzTWF0Y2hpbmdUYWcodGVzdEFyZ3MudGFncywgdGhpcy5nZXRFeGNsdWRlVGFnU2V0KCkpKSByZXR1cm4gdHJ1ZVxuXG4gICAgaWYgKHRoaXMuX2luY2x1ZGVUYWdTZXQuc2l6ZSA+IDAgJiYgIXRlc3RBcmdzLmZvY3VzKSB7XG4gICAgICBpZiAoIXRoaXMuaGFzTWF0Y2hpbmdUYWcodGVzdEFyZ3MudGFncywgdGhpcy5faW5jbHVkZVRhZ1NldCkpIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuZ2V0RXhhbXBsZVBhdHRlcm5zKCkubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgZnVsbERlc2NyaXB0aW9uID0gdGhpcy5idWlsZEZ1bGxEZXNjcmlwdGlvbihkZXNjcmlwdGlvbnMsIHRlc3REZXNjcmlwdGlvbilcbiAgICAgIGNvbnN0IG1hdGNoZXMgPSB0aGlzLmdldEV4YW1wbGVQYXR0ZXJucygpLnNvbWUoKHBhdHRlcm4pID0+IHtcbiAgICAgICAgcGF0dGVybi5sYXN0SW5kZXggPSAwXG4gICAgICAgIHJldHVybiBwYXR0ZXJuLnRlc3QoZnVsbERlc2NyaXB0aW9uKVxuICAgICAgfSlcblxuICAgICAgaWYgKCFtYXRjaGVzKSByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIGNvbnN0IGxpbmVGaWx0ZXJzID0gdGhpcy5nZXRMaW5lRmlsdGVycygpXG5cbiAgICBpZiAoT2JqZWN0LmtleXMobGluZUZpbHRlcnMpLmxlbmd0aCA+IDApIHtcbiAgICAgIGlmICghbGluZU1hdGNoZWRJblNjb3BlICYmICF0aGlzLm1hdGNoZXNMaW5lRmlsdGVyKHRlc3REYXRhKSkgcmV0dXJuIHRydWVcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIG1hdGNoZXMgbGluZSBmaWx0ZXIuXG4gICAqIEBwYXJhbSB7VGVzdERhdGEgfCBUZXN0c0FyZ3VtZW50fSBlbnRyeSAtIFRlc3QgZW50cnkuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgbGluZSBmaWx0ZXIgbWF0Y2hlcyBlbnRyeS5cbiAgICovXG4gIG1hdGNoZXNMaW5lRmlsdGVyKGVudHJ5KSB7XG4gICAgaWYgKCFlbnRyeSB8fCAhZW50cnkuZmlsZVBhdGggfHwgIWVudHJ5LmxpbmUpIHJldHVybiBmYWxzZVxuXG4gICAgY29uc3QgZmlsZVBhdGggPSBwYXRoLnJlc29sdmUoZW50cnkuZmlsZVBhdGgpXG4gICAgY29uc3QgbGluZXMgPSB0aGlzLmdldExpbmVGaWx0ZXJzKClbZmlsZVBhdGhdXG5cbiAgICBpZiAoIWxpbmVzIHx8IGxpbmVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIGZhbHNlXG5cbiAgICByZXR1cm4gbGluZXMuaW5jbHVkZXMoZW50cnkubGluZSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGJ1aWxkIGZ1bGwgZGVzY3JpcHRpb24uXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IGRlc2NyaXB0aW9ucyAtIERlc2NyaXB0aW9uIHN0YWNrLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGVzdERlc2NyaXB0aW9uIC0gVGVzdCBkZXNjcmlwdGlvbi5cbiAgICogQHJldHVybnMge3N0cmluZ30gLSBGdWxsIGRlc2NyaXB0aW9uLlxuICAgKi9cbiAgYnVpbGRGdWxsRGVzY3JpcHRpb24oZGVzY3JpcHRpb25zLCB0ZXN0RGVzY3JpcHRpb24pIHtcbiAgICBjb25zdCBwYXJ0cyA9IGRlc2NyaXB0aW9ucy5jb25jYXQoW3Rlc3REZXNjcmlwdGlvbl0pXG5cbiAgICByZXR1cm4gcGFydHMuam9pbihcIiBcIikudHJpbSgpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBhcHBsaWNhdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8QXBwbGljYXRpb24+fSAtIFJlc29sdmVzIHdpdGggdGhlIGFwcGxpY2F0aW9uLlxuICAgKi9cbiAgYXN5bmMgYXBwbGljYXRpb24oKSB7XG4gICAgaWYgKCF0aGlzLl9hcHBsaWNhdGlvbikge1xuICAgICAgdGhpcy5fYXBwbGljYXRpb24gPSBuZXcgQXBwbGljYXRpb24oe1xuICAgICAgICBjb25maWd1cmF0aW9uOiB0aGlzLmdldENvbmZpZ3VyYXRpb24oKSxcbiAgICAgICAgaHR0cFNlcnZlcjoge3BvcnQ6IDMxMDA2fSxcbiAgICAgICAgdHlwZTogXCJ0ZXN0LXJ1bm5lclwiXG4gICAgICB9KVxuXG4gICAgICBhd2FpdCB0aGlzLl9hcHBsaWNhdGlvbi5pbml0aWFsaXplKClcbiAgICAgIGF3YWl0IHRoaXMuX2FwcGxpY2F0aW9uLnN0YXJ0SHR0cFNlcnZlcigpXG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX2FwcGxpY2F0aW9uXG4gIH1cblxuICAvKipcbiAgICogUnVucyByZXF1ZXN0IGNsaWVudC5cbiAgICogQHJldHVybnMge1Byb21pc2U8UmVxdWVzdENsaWVudD59IC0gUmVzb2x2ZXMgd2l0aCB0aGUgcmVxdWVzdCBjbGllbnQuXG4gICAqL1xuICBhc3luYyByZXF1ZXN0Q2xpZW50KCkge1xuICAgIGlmICghdGhpcy5fcmVxdWVzdENsaWVudCkge1xuICAgICAgdGhpcy5fcmVxdWVzdENsaWVudCA9IG5ldyBSZXF1ZXN0Q2xpZW50KClcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fcmVxdWVzdENsaWVudFxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgaW1wb3J0IHRlc3QgZmlsZXMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBpbXBvcnRUZXN0RmlsZXMoKSB7XG4gICAgYXdhaXQgdGhpcy5nZXRDb25maWd1cmF0aW9uKCkuZ2V0RW52aXJvbm1lbnRIYW5kbGVyKCkuaW1wb3J0VGVzdEZpbGVzKHRoaXMuZ2V0VGVzdEZpbGVzKCkpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBpcyBmYWlsZWQuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgZmFpbGVkLlxuICAgKi9cbiAgaXNGYWlsZWQoKSB7IHJldHVybiB0aGlzLl9mYWlsZWRUZXN0cyAhPT0gdW5kZWZpbmVkICYmIHRoaXMuX2ZhaWxlZFRlc3RzID4gMCB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZ2V0IGZhaWxlZCB0ZXN0cy5cbiAgICogQHJldHVybnMge251bWJlcn0gLSBUaGUgZmFpbGVkIHRlc3RzLlxuICAgKi9cbiAgZ2V0RmFpbGVkVGVzdHMoKSB7XG4gICAgaWYgKHRoaXMuX2ZhaWxlZFRlc3RzID09PSB1bmRlZmluZWQpIHRocm93IG5ldyBFcnJvcihcIlRlc3RzIGhhc24ndCBiZWVuIHJ1biB5ZXRcIilcblxuICAgIHJldHVybiB0aGlzLl9mYWlsZWRUZXN0c1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZ2V0IGZhaWxlZCB0ZXN0IGRldGFpbHMuXG4gICAqIEByZXR1cm5zIHtGYWlsZWRUZXN0RGV0YWlsW119IC0gRmFpbGVkIHRlc3QgZGV0YWlscy5cbiAgICovXG4gIGdldEZhaWxlZFRlc3REZXRhaWxzKCkge1xuICAgIHJldHVybiB0aGlzLl9mYWlsZWRUZXN0RGV0YWlsc1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgcGVyc2lzdCBmYWlsZWQgdGVzdCBjb25zb2xlIG91dHB1dHMgdG8gYXNzZXRzLlxuICAgKiBAcGFyYW0ge29iamVjdH0gW2FyZ3NdIC0gT3B0aW9ucyBvYmplY3QuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbYXJncy5hc3NldHNQYXRoXSAtIEFzc2V0cyBkaXJlY3RvcnkgcGF0aC5cbiAgICogQHJldHVybnMge1Byb21pc2U8c3RyaW5nW10+fSAtIFdyaXR0ZW4gbG9nIGZpbGUgcGF0aHMuXG4gICAqL1xuICBhc3luYyBwZXJzaXN0RmFpbGVkVGVzdENvbnNvbGVPdXRwdXRzVG9Bc3NldHMoe2Fzc2V0c1BhdGggPSBwYXRoLmpvaW4ocHJvY2Vzcy5jd2QoKSwgXCJ0bXAvc2NyZWVuc2hvdHNcIil9ID0ge30pIHtcbiAgICBjb25zdCBmYWlsZWRUZXN0RGV0YWlscyA9IHRoaXMuZ2V0RmFpbGVkVGVzdERldGFpbHMoKVxuICAgIGNvbnN0IHdyaXR0ZW5Mb2dQYXRocyA9IFtdXG4gICAgbGV0IGNyZWF0ZWREaXJlY3RvcnkgPSBmYWxzZVxuXG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGZhaWxlZFRlc3REZXRhaWxzLmxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgY29uc3QgZmFpbGVkVGVzdERldGFpbCA9IGZhaWxlZFRlc3REZXRhaWxzW2luZGV4XVxuICAgICAgY29uc3QgY29uc29sZU91dHB1dCA9IGZhaWxlZFRlc3REZXRhaWwuY29uc29sZU91dHB1dFxuXG4gICAgICBpZiAoIWNvbnNvbGVPdXRwdXQpIGNvbnRpbnVlXG5cbiAgICAgIGlmICghY3JlYXRlZERpcmVjdG9yeSkge1xuICAgICAgICBhd2FpdCBmcy5ta2Rpcihhc3NldHNQYXRoLCB7cmVjdXJzaXZlOiB0cnVlfSlcbiAgICAgICAgY3JlYXRlZERpcmVjdG9yeSA9IHRydWVcbiAgICAgIH1cblxuICAgICAgY29uc3Qgbm93ID0gbmV3IERhdGUoKVxuICAgICAgY29uc3QgdGltZXN0YW1wID0gW1xuICAgICAgICBTdHJpbmcobm93LmdldEZ1bGxZZWFyKCkpLFxuICAgICAgICBTdHJpbmcobm93LmdldE1vbnRoKCkgKyAxKS5wYWRTdGFydCgyLCBcIjBcIiksXG4gICAgICAgIFN0cmluZyhub3cuZ2V0RGF0ZSgpKS5wYWRTdGFydCgyLCBcIjBcIiksXG4gICAgICAgIFN0cmluZyhub3cuZ2V0SG91cnMoKSkucGFkU3RhcnQoMiwgXCIwXCIpLFxuICAgICAgICBTdHJpbmcobm93LmdldE1pbnV0ZXMoKSkucGFkU3RhcnQoMiwgXCIwXCIpLFxuICAgICAgICBTdHJpbmcobm93LmdldFNlY29uZHMoKSkucGFkU3RhcnQoMiwgXCIwXCIpLFxuICAgICAgICBTdHJpbmcobm93LmdldE1pbGxpc2Vjb25kcygpKS5wYWRTdGFydCgzLCBcIjBcIilcbiAgICAgIF0uam9pbihcIlwiKVxuICAgICAgY29uc3Qgc2x1ZyA9IHRvRmlsZVNsdWcoZmFpbGVkVGVzdERldGFpbC5mdWxsRGVzY3JpcHRpb24pXG4gICAgICBjb25zdCBmaWxlTmFtZSA9IGAke3RpbWVzdGFtcH0tJHtTdHJpbmcoaW5kZXggKyAxKS5wYWRTdGFydCgyLCBcIjBcIil9LSR7c2x1Z30uY29uc29sZS5sb2dgXG4gICAgICBjb25zdCBmaWxlUGF0aCA9IHBhdGguam9pbihhc3NldHNQYXRoLCBmaWxlTmFtZSlcblxuICAgICAgYXdhaXQgZnMud3JpdGVGaWxlKGZpbGVQYXRoLCBjb25zb2xlT3V0cHV0LCBcInV0ZjhcIilcbiAgICAgIGZhaWxlZFRlc3REZXRhaWwuY29uc29sZUxvZ1BhdGggPSBmaWxlUGF0aFxuICAgICAgd3JpdHRlbkxvZ1BhdGhzLnB1c2goZmlsZVBhdGgpXG4gICAgfVxuXG4gICAgcmV0dXJuIHdyaXR0ZW5Mb2dQYXRoc1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZ2V0IHN1Y2Nlc3NmdWwgdGVzdHMuXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IC0gVGhlIHN1Y2Nlc3NmdWwgdGVzdHMuXG4gICAqL1xuICBnZXRTdWNjZXNzZnVsVGVzdHMoKSB7XG4gICAgaWYgKHRoaXMuX3N1Y2Nlc3NmdWxUZXN0cyA9PT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgRXJyb3IoXCJUZXN0cyBoYXNuJ3QgYmVlbiBydW4geWV0XCIpXG5cbiAgICByZXR1cm4gdGhpcy5fc3VjY2Vzc2Z1bFRlc3RzXG4gIH1cblxuICAvKipcbiAgICogUnVucyBnZXQgdGVzdHMgY291bnQuXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IC0gVGhlIHRlc3RzIGNvdW50LlxuICAgKi9cbiAgZ2V0VGVzdHNDb3VudCgpIHtcbiAgICBpZiAodGhpcy5fdGVzdHNDb3VudCA9PT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgRXJyb3IoXCJUZXN0cyBoYXNuJ3QgYmVlbiBydW4geWV0XCIpXG5cbiAgICByZXR1cm4gdGhpcy5fdGVzdHNDb3VudFxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZ2V0IGV4ZWN1dGVkIHRlc3RzIGNvdW50LlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSAtIFRoZSBleGVjdXRlZCB0ZXN0cyBjb3VudC5cbiAgICovXG4gIGdldEV4ZWN1dGVkVGVzdHNDb3VudCgpIHtcbiAgICBpZiAodGhpcy5fc3VjY2Vzc2Z1bFRlc3RzID09PSB1bmRlZmluZWQgfHwgdGhpcy5fZmFpbGVkVGVzdHMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGVzdHMgaGFzbid0IGJlZW4gcnVuIHlldFwiKVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9zdWNjZXNzZnVsVGVzdHMgKyB0aGlzLl9mYWlsZWRUZXN0c1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgcHJlcGFyZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIHByZXBhcmUoKSB7XG4gICAgdGhpcy5hbnlUZXN0c0ZvY3Vzc2VkID0gZmFsc2VcbiAgICB0aGlzLl9mYWlsZWRUZXN0cyA9IDBcbiAgICB0aGlzLl9zdWNjZXNzZnVsVGVzdHMgPSAwXG4gICAgdGhpcy5fdGVzdHNDb3VudCA9IDBcbiAgICB0aGlzLl9mYWlsZWRUZXN0RGV0YWlscyA9IFtdXG4gICAgYXdhaXQgdGhpcy5pbXBvcnRUZXN0RmlsZXMoKVxuICAgIGF3YWl0IHRoaXMuYW5hbHl6ZVRlc3RzKHRlc3RzKVxuICAgIHRoaXMuX29ubHlGb2N1c3NlZCA9IHRoaXMuYW55VGVzdHNGb2N1c3NlZFxuXG4gICAgY29uc3QgdGVzdGluZ0NvbmZpZ1BhdGggPSB0aGlzLmdldENvbmZpZ3VyYXRpb24oKS5nZXRUZXN0aW5nKClcblxuICAgIGlmICh0ZXN0aW5nQ29uZmlnUGF0aCkge1xuICAgICAgYXdhaXQgdGhpcy5nZXRDb25maWd1cmF0aW9uKCkuZ2V0RW52aXJvbm1lbnRIYW5kbGVyKCkuaW1wb3J0VGVzdGluZ0NvbmZpZ1BhdGgoKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGFyZSBhbnkgdGVzdHMgZm9jdXNzZWQuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgYW55IHRlc3RzIGZvY3Vzc2VkLlxuICAgKi9cbiAgYXJlQW55VGVzdHNGb2N1c3NlZCgpIHtcbiAgICBpZiAodGhpcy5hbnlUZXN0c0ZvY3Vzc2VkID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkhhc24ndCBiZWVuIGRldGVjdGVkIHlldFwiKVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmFueVRlc3RzRm9jdXNzZWRcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHJ1bi5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIHJ1bigpIHtcbiAgICBhd2FpdCB0aGlzLmdldENvbmZpZ3VyYXRpb24oKS5lbnN1cmVDb25uZWN0aW9ucyh7bmFtZTogXCJUZXN0IHJ1bm5lciBzdWl0ZVwifSwgYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgdGhpcy5ydW5UZXN0cyh7XG4gICAgICAgIGFmdGVyRWFjaGVzOiBbXSxcbiAgICAgICAgYmVmb3JlRWFjaGVzOiBbXSxcbiAgICAgICAgdGVzdHMsXG4gICAgICAgIGRlc2NyaXB0aW9uczogW10sXG4gICAgICAgIGluZGVudExldmVsOiAwXG4gICAgICB9KVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogUnVucyBydW4gYWZ0ZXIgYWxscyBmb3IgYWN0aXZlIHNjb3Blcy5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjbGVhbnVwIGhvb2tzIGZpbmlzaC5cbiAgICovXG4gIGFzeW5jIHJ1bkFmdGVyQWxsc0ZvckFjdGl2ZVNjb3BlcygpIHtcbiAgICBjb25zdCBzY29wZXMgPSBbLi4udGhpcy5fYWN0aXZlQWZ0ZXJBbGxTY29wZXNdLnJldmVyc2UoKVxuXG4gICAgZm9yIChjb25zdCBzY29wZSBvZiBzY29wZXMpIHtcbiAgICAgIGF3YWl0IHRoaXMucnVuQWZ0ZXJBbGxzRm9yU2NvcGUoc2NvcGUpXG4gICAgfVxuXG4gICAgdGhpcy5fYWN0aXZlQWZ0ZXJBbGxTY29wZXMgPSBbXVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYW5hbHl6ZSB0ZXN0cy5cbiAgICogQHBhcmFtIHtUZXN0c0FyZ3VtZW50fSB0ZXN0cyAtIFRlc3RzLlxuICAgKiBAcmV0dXJucyB7e2FueVRlc3RzRm9jdXNzZWQ6IGJvb2xlYW59fSAtIFdoZXRoZXIgYW55IHRlc3RzIGluIHRoZSB0cmVlIGFyZSBmb2N1c2VkLlxuICAgKi9cbiAgYW5hbHl6ZVRlc3RzKHRlc3RzKSB7XG4gICAgbGV0IGFueVRlc3RzRm9jdXNzZWRGb3VuZCA9IGZhbHNlXG5cbiAgICBmb3IgKGNvbnN0IHRlc3REZXNjcmlwdGlvbiBpbiB0ZXN0cy50ZXN0cykge1xuICAgICAgY29uc3QgdGVzdERhdGEgPSB0ZXN0cy50ZXN0c1t0ZXN0RGVzY3JpcHRpb25dXG4gICAgICBjb25zdCB0ZXN0QXJncyA9IE9iamVjdC5hc3NpZ24oe30sIHRlc3REYXRhLmFyZ3MpXG5cbiAgICAgIHRoaXMuX3Rlc3RzQ291bnQrK1xuXG4gICAgICBpZiAodGVzdEFyZ3MuZm9jdXMpIHtcbiAgICAgICAgYW55VGVzdHNGb2N1c3NlZEZvdW5kID0gdHJ1ZVxuICAgICAgICB0aGlzLmFueVRlc3RzRm9jdXNzZWQgPSB0cnVlXG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBzdWJEZXNjcmlwdGlvbiBpbiB0ZXN0cy5zdWJzKSB7XG4gICAgICBjb25zdCBzdWJUZXN0ID0gdGVzdHMuc3Vic1tzdWJEZXNjcmlwdGlvbl1cbiAgICAgIGNvbnN0IHthbnlUZXN0c0ZvY3Vzc2VkfSA9IHRoaXMuYW5hbHl6ZVRlc3RzKHN1YlRlc3QpXG5cbiAgICAgIGlmIChhbnlUZXN0c0ZvY3Vzc2VkKSB7XG4gICAgICAgIGFueVRlc3RzRm9jdXNzZWRGb3VuZCA9IHRydWVcbiAgICAgIH1cblxuICAgICAgc3ViVGVzdC5hbnlUZXN0c0ZvY3Vzc2VkID0gYW55VGVzdHNGb2N1c3NlZFxuICAgIH1cblxuICAgIHJldHVybiB7YW55VGVzdHNGb2N1c3NlZDogYW55VGVzdHNGb2N1c3NlZEZvdW5kfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgcnVuIHRlc3RzLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcGFyYW0ge0FycmF5PEFmdGVyQmVmb3JlRWFjaENhbGxiYWNrT2JqZWN0VHlwZT59IGFyZ3MuYWZ0ZXJFYWNoZXMgLSBBZnRlciBlYWNoZXMuXG4gICAqIEBwYXJhbSB7QXJyYXk8QWZ0ZXJCZWZvcmVFYWNoQ2FsbGJhY2tPYmplY3RUeXBlPn0gYXJncy5iZWZvcmVFYWNoZXMgLSBCZWZvcmUgZWFjaGVzLlxuICAgKiBAcGFyYW0ge1Rlc3RzQXJndW1lbnR9IGFyZ3MudGVzdHMgLSBUZXN0cy5cbiAgICogQHBhcmFtIHtzdHJpbmdbXX0gYXJncy5kZXNjcmlwdGlvbnMgLSBEZXNjcmlwdGlvbnMuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBhcmdzLmluZGVudExldmVsIC0gSW5kZW50IGxldmVsLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFthcmdzLmxpbmVNYXRjaGVkSW5TY29wZV0gLSBXaGV0aGVyIGxpbmUgbWF0Y2hlZCBpbiBzY29wZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIHJ1blRlc3RzKHthZnRlckVhY2hlcywgYmVmb3JlRWFjaGVzLCB0ZXN0cywgZGVzY3JpcHRpb25zLCBpbmRlbnRMZXZlbCwgbGluZU1hdGNoZWRJblNjb3BlID0gZmFsc2V9KSB7XG4gICAgY29uc3QgbGVmdFBhZGRpbmcgPSBcIiBcIi5yZXBlYXQoaW5kZW50TGV2ZWwgKiAyKVxuICAgIGNvbnN0IG5ld0FmdGVyRWFjaGVzID0gWy4uLmFmdGVyRWFjaGVzLCAuLi50ZXN0cy5hZnRlckVhY2hlc11cbiAgICBjb25zdCBuZXdCZWZvcmVFYWNoZXMgPSBbLi4uYmVmb3JlRWFjaGVzLCAuLi50ZXN0cy5iZWZvcmVFYWNoZXNdXG4gICAgY29uc3Qgc2NvcGVMaW5lTWF0Y2ggPSBsaW5lTWF0Y2hlZEluU2NvcGUgfHwgdGhpcy5tYXRjaGVzTGluZUZpbHRlcih0ZXN0cylcbiAgICBjb25zdCBzaG91bGRSdW5BbnlUZXN0cyA9IHRoaXMuaGFzUnVubmFibGVUZXN0cyh0ZXN0cywgZGVzY3JpcHRpb25zLCBzY29wZUxpbmVNYXRjaClcblxuICAgIGlmICghc2hvdWxkUnVuQW55VGVzdHMpIHJldHVyblxuXG4gICAgLyoqIFNjb3BlIGVudHJ5LiBAdHlwZSB7QWN0aXZlQWZ0ZXJBbGxTY29wZUVudHJ5fSAqL1xuICAgIGNvbnN0IHNjb3BlRW50cnkgPSB7dGVzdHMsIGFmdGVyQWxsc1J1bjogZmFsc2V9XG4gICAgdGhpcy5fYWN0aXZlQWZ0ZXJBbGxTY29wZXMucHVzaChzY29wZUVudHJ5KVxuXG4gICAgdHJ5IHtcbiAgICAgIGZvciAoY29uc3QgYmVmb3JlQWxsRGF0YSBvZiB0ZXN0cy5iZWZvcmVBbGxzIHx8IFtdKSB7XG4gICAgICAgIGF3YWl0IGJlZm9yZUFsbERhdGEuY2FsbGJhY2soe2NvbmZpZ3VyYXRpb246IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpfSlcbiAgICAgIH1cblxuICAgICAgZm9yIChjb25zdCB0ZXN0RGVzY3JpcHRpb24gaW4gdGVzdHMudGVzdHMpIHtcbiAgICAgICAgY29uc3QgdGVzdERhdGEgPSB0ZXN0cy50ZXN0c1t0ZXN0RGVzY3JpcHRpb25dXG4gICAgICAgIGNvbnN0IHRlc3RBcmdzID0gLyoqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUge1Rlc3RBcmdzfSAqLyAoT2JqZWN0LmFzc2lnbih7fSwgdGVzdERhdGEuYXJncykpXG4gICAgICAgIGNvbnN0IGluY2x1ZGVCeUxpbmUgPSBzY29wZUxpbmVNYXRjaCB8fCB0aGlzLm1hdGNoZXNMaW5lRmlsdGVyKHRlc3REYXRhKVxuXG4gICAgICAgIGlmICh0aGlzLl9vbmx5Rm9jdXNzZWQgJiYgIXRlc3RBcmdzLmZvY3VzKSBjb250aW51ZVxuICAgICAgICBpZiAodGhpcy5zaG91bGRTa2lwVGVzdCh0ZXN0QXJncywgdGVzdERhdGEsIHRlc3REZXNjcmlwdGlvbiwgZGVzY3JpcHRpb25zLCBpbmNsdWRlQnlMaW5lKSkgY29udGludWVcblxuICAgICAgICBpZiAodGVzdEFyZ3MudHlwZSA9PSBcIm1vZGVsXCIgfHwgdGVzdEFyZ3MudHlwZSA9PSBcInJlcXVlc3RcIikge1xuICAgICAgICAgIHRlc3RBcmdzLmFwcGxpY2F0aW9uID0gYXdhaXQgdGhpcy5hcHBsaWNhdGlvbigpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGVzdEFyZ3MudHlwZSA9PSBcInJlcXVlc3RcIikge1xuICAgICAgICAgIHRlc3RBcmdzLmNsaWVudCA9IGF3YWl0IHRoaXMucmVxdWVzdENsaWVudCgpXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXRyeUNvdW50ID0gdHlwZW9mIHRlc3RBcmdzLnJldHJ5ID09PSBcIm51bWJlclwiICYmIE51bWJlci5pc0Zpbml0ZSh0ZXN0QXJncy5yZXRyeSlcbiAgICAgICAgICA/IE1hdGgubWF4KDAsIE1hdGguZmxvb3IodGVzdEFyZ3MucmV0cnkpKVxuICAgICAgICAgIDogMFxuICAgICAgICBjb25zdCBjb25maWdUaW1lb3V0U2Vjb25kcyA9IHR5cGVvZiB0ZXN0Q29uZmlnLmRlZmF1bHRUaW1lb3V0U2Vjb25kcyA9PT0gXCJudW1iZXJcIiA/IHRlc3RDb25maWcuZGVmYXVsdFRpbWVvdXRTZWNvbmRzIDogdW5kZWZpbmVkXG4gICAgICAgIGNvbnN0IHRpbWVvdXRTZWNvbmRzID0gdHlwZW9mIHRlc3RBcmdzLnRpbWVvdXRTZWNvbmRzID09PSBcIm51bWJlclwiID8gdGVzdEFyZ3MudGltZW91dFNlY29uZHMgOiBjb25maWdUaW1lb3V0U2Vjb25kc1xuICAgICAgICBjb25zdCB1c2VUaW1lb3V0ID0gdHlwZW9mIHRpbWVvdXRTZWNvbmRzID09PSBcIm51bWJlclwiICYmIE51bWJlci5pc0Zpbml0ZSh0aW1lb3V0U2Vjb25kcykgJiYgdGltZW91dFNlY29uZHMgPiAwXG4gICAgICAgIGNvbnN0IHRpbWVvdXRNcyA9IHVzZVRpbWVvdXQgPyB0aW1lb3V0U2Vjb25kcyAqIDEwMDAgOiB1bmRlZmluZWRcbiAgICAgICAgbGV0IHJldHJpZXNVc2VkID0gMFxuICAgICAgICBsZXQgYXR0ZW1wdE51bWJlciA9IDFcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEF0dGVtcHQgY29uc29sZSBvdXRwdXRzLlxuICAgICAgICAgIEB0eXBlIHtBdHRlbXB0Q29uc29sZU91dHB1dFtdfSAqL1xuICAgICAgICBjb25zdCBhdHRlbXB0Q29uc29sZU91dHB1dHMgPSBbXVxuXG4gICAgICAgIGNvbnNvbGUubG9nKGAke2xlZnRQYWRkaW5nfWl0ICR7dGVzdERlc2NyaXB0aW9ufWApXG5cbiAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICBsZXQgc2hvdWxkUmV0cnkgPSBmYWxzZVxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIERlZmluZXMgY2F1Z2h0RXJyb3IuXG4gICAgICAgICAgICBAdHlwZSB7P30gKi9cbiAgICAgICAgICBsZXQgY2F1Z2h0RXJyb3JcbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBEZWZpbmVzIGZhaWxlZEVycm9yLlxuICAgICAgICAgICAgQHR5cGUgez99ICovXG4gICAgICAgICAgbGV0IGZhaWxlZEVycm9yXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogRGVmaW5lcyBsYXN0RXJyb3IuXG4gICAgICAgICAgICBAdHlwZSB7P30gKi9cbiAgICAgICAgICBsZXQgbGFzdEVycm9yXG4gICAgICAgICAgbGV0IHdpbGxSZXRyeSA9IGZhbHNlXG4gICAgICAgICAgY29uc3Qgc3RvcENvbnNvbGVDYXB0dXJlID0gdGhpcy5zdGFydENvbnNvbGVDYXB0dXJlKHtcbiAgICAgICAgICAgIHBhc3N0aHJvdWdoOiB0ZXN0Q29uZmlnLmNvbnNvbGVPdXRwdXQgPT09IFwibGl2ZVwiXG4gICAgICAgICAgfSlcblxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBSdW4gdGhlIHdob2xlIHBlci10ZXN0IGxpZmVjeWNsZSAoZHVtbXkvc2VydmVyIHN0YXJ0dXAsIGNvbm5lY3Rpb25cbiAgICAgICAgICAgIC8vIGFjcXVpc2l0aW9uLCBiZWZvcmVFYWNoIGhvb2tzLCB0aGUgdGVzdCBib2R5IGFuZCBhZnRlckVhY2ggaG9va3MpIGFzXG4gICAgICAgICAgICAvLyBvbmUgcHJvbWlzZSBzbyB0aGUgdGltZW91dCBiZWxvdyBjYW4gY292ZXIgYWxsIG9mIGl0LlxuICAgICAgICAgICAgY29uc3QgdGVzdExpZmVjeWNsZSA9IHRoaXMucnVuV2l0aER1bW15SWZOZWVkZWQodGVzdEFyZ3MsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgLy8gUGluIG9uZSBjb25uZWN0aW9uIHBlciB0ZXN0IHNvIGJlZm9yZUVhY2gsIHRoZSB0ZXN0IGJvZHkgYW5kIGFmdGVyRWFjaFxuICAgICAgICAgICAgICAvLyBhbGwgcnVuIG9uIHRoZSBTQU1FIGNvbm5lY3Rpb24uIFRoaXMgaXMgcmVxdWlyZWQgZm9yIHRyYW5zYWN0aW9uLWJhc2VkXG4gICAgICAgICAgICAgIC8vIGRhdGFiYXNlIGNsZWFuaW5nIChiZWZvcmVFYWNoIHN0YXJ0cyBhIHRyYW5zYWN0aW9uLCBhZnRlckVhY2ggcm9sbHMgaXRcbiAgICAgICAgICAgICAgLy8gYmFjaykuIGVuc3VyZUNvbm5lY3Rpb25zIHJldXNlcyB0aGUgc3VpdGUtbGV2ZWwgcGlubmVkIGNvbm5lY3Rpb24gd2hpbGVcbiAgICAgICAgICAgICAgLy8gaXQgaXMgaGVhbHRoeSBhbmQgdHJhbnNwYXJlbnRseSByZS1lc3RhYmxpc2hlcyBhIHBlci10ZXN0IHBpbiBpZiBhblxuICAgICAgICAgICAgICAvLyBlYXJsaWVyIHNwZWMgY2xvc2VkIHRoZSBzdWl0ZSBjb25uZWN0aW9uICh3aGljaCB3b3VsZCBvdGhlcndpc2UgbGVhdmUgYVxuICAgICAgICAgICAgICAvLyBzdGFsZSBhc3luYy1jb250ZXh0IHBpbiBhbmQgZm9yY2UgZXZlcnkgbGF0ZXIgdGVzdCBvbnRvIGEgZnJlc2ggY2hlY2tvdXQsXG4gICAgICAgICAgICAgIC8vIGJyZWFraW5nIGlzb2xhdGlvbikuXG4gICAgICAgICAgICAgIGF3YWl0IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpLmVuc3VyZUNvbm5lY3Rpb25zKHtuYW1lOiBgVGVzdDogJHt0ZXN0RGVzY3JpcHRpb259YH0sIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgY2xlYXJEZWxpdmVyaWVzKClcbiAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgYmVmb3JlRWFjaERhdGEgb2YgbmV3QmVmb3JlRWFjaGVzKSB7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IGJlZm9yZUVhY2hEYXRhLmNhbGxiYWNrKHtjb25maWd1cmF0aW9uOiB0aGlzLmdldENvbmZpZ3VyYXRpb24oKSwgdGVzdEFyZ3MsIHRlc3REYXRhfSlcbiAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgYXdhaXQgdGVzdERhdGEuZnVuY3Rpb24odGVzdEFyZ3MpXG4gICAgICAgICAgICAgICAgICB0aGlzLl9zdWNjZXNzZnVsVGVzdHMrK1xuICAgICAgICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGFmdGVyRWFjaERhdGEgb2YgbmV3QWZ0ZXJFYWNoZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgYWZ0ZXJFYWNoRGF0YS5jYWxsYmFjayh7Y29uZmlndXJhdGlvbjogdGhpcy5nZXRDb25maWd1cmF0aW9uKCksIHRlc3RBcmdzLCB0ZXN0RGF0YX0pXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgLy8gVGltZSBvdXQgdGhlIEVOVElSRSBsaWZlY3ljbGUsIG5vdCBqdXN0IHRoZSB0ZXN0IGJvZHkuIEEgaGFuZyBpbiBhbnlcbiAgICAgICAgICAgIC8vIHBoYXNlIOKAlCBhIGNvbm5lY3Rpb24gY2hlY2tvdXQgdGhhdCBuZXZlciByZXNvbHZlcywgYSBiZWZvcmVFYWNoL2FmdGVyRWFjaFxuICAgICAgICAgICAgLy8gd2FpdGluZyBvbiBhIGxvY2ssIG9yIGR1bW15IHNlcnZlciBzdGFydHVwIOKAlCB3b3VsZCBvdGhlcndpc2Ugc3RhbGwgdGhlXG4gICAgICAgICAgICAvLyB3aG9sZSBydW4gaW5kZWZpbml0ZWx5ICh1bnRpbCBDSSBraWxscyB0aGUgYnVpbGQpIGluc3RlYWQgb2YgZmFpbGluZyB0aGVcbiAgICAgICAgICAgIC8vIHNpbmdsZSBvZmZlbmRpbmcgdGVzdC5cbiAgICAgICAgICAgIGlmICh1c2VUaW1lb3V0ICYmIHRpbWVvdXRNcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgIGF3YWl0IHJ1bldpdGhUaW1lb3V0KHRlc3RMaWZlY3ljbGUsIHRpbWVvdXRNcywgdGVzdERlc2NyaXB0aW9uKVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgYXdhaXQgdGVzdExpZmVjeWNsZVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjYXVnaHRFcnJvciA9IGVycm9yXG4gICAgICAgICAgICBsYXN0RXJyb3IgPSBlcnJvclxuICAgICAgICAgICAgd2lsbFJldHJ5ID0gcmV0cmllc1VzZWQgPCByZXRyeUNvdW50XG5cbiAgICAgICAgICAgIGlmICh3aWxsUmV0cnkpIHtcbiAgICAgICAgICAgICAgcmV0cmllc1VzZWQrK1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAod2lsbFJldHJ5KSB7XG4gICAgICAgICAgICAgIHNob3VsZFJldHJ5ID0gdHJ1ZVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgZmFpbGVkRXJyb3IgPSBlcnJvclxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICBjb25zdCBjb25zb2xlT3V0cHV0ID0gc3RvcENvbnNvbGVDYXB0dXJlKClcblxuICAgICAgICAgICAgaWYgKGNvbnNvbGVPdXRwdXQpIHtcbiAgICAgICAgICAgICAgYXR0ZW1wdENvbnNvbGVPdXRwdXRzLnB1c2goe2F0dGVtcHROdW1iZXIsIG91dHB1dDogY29uc29sZU91dHB1dH0pXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGNhdWdodEVycm9yICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZW1pdEV2ZW50KFwidGVzdEF0dGVtcHRGYWlsZWRcIiwge1xuICAgICAgICAgICAgICBjb25maWd1cmF0aW9uOiB0aGlzLmdldENvbmZpZ3VyYXRpb24oKSxcbiAgICAgICAgICAgICAgZGVzY3JpcHRpb25zLFxuICAgICAgICAgICAgICBlcnJvcjogY2F1Z2h0RXJyb3IsXG4gICAgICAgICAgICAgIGF0dGVtcHROdW1iZXIsXG4gICAgICAgICAgICAgIG5leHRBdHRlbXB0OiB3aWxsUmV0cnkgPyBhdHRlbXB0TnVtYmVyICsgMSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgcmV0cmllc1VzZWQsXG4gICAgICAgICAgICAgIHJldHJ5Q291bnQsXG4gICAgICAgICAgICAgIHRlc3RBcmdzLFxuICAgICAgICAgICAgICB0ZXN0RGF0YSxcbiAgICAgICAgICAgICAgdGVzdERlc2NyaXB0aW9uLFxuICAgICAgICAgICAgICB0ZXN0UnVubmVyOiB0aGlzLFxuICAgICAgICAgICAgICB3aWxsUmV0cnlcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHNob3VsZFJldHJ5KSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4ocGljb2NvbG9ycy5yZWQoYCR7bGVmdFBhZGRpbmd9ICBSZXRyeWluZyAoJHtyZXRyaWVzVXNlZH0vJHtyZXRyeUNvdW50fSkgYWZ0ZXIgZXJyb3I6ICR7bGFzdEVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBsYXN0RXJyb3IubWVzc2FnZSA6IFN0cmluZyhsYXN0RXJyb3IpfWApKVxuICAgICAgICAgICAgYXdhaXQgdGhpcy5lbWl0RXZlbnQoXCJ0ZXN0UmV0cnlpbmdcIiwge1xuICAgICAgICAgICAgICBjb25maWd1cmF0aW9uOiB0aGlzLmdldENvbmZpZ3VyYXRpb24oKSxcbiAgICAgICAgICAgICAgZGVzY3JpcHRpb25zLFxuICAgICAgICAgICAgICBlcnJvcjogbGFzdEVycm9yLFxuICAgICAgICAgICAgICBuZXh0QXR0ZW1wdDogYXR0ZW1wdE51bWJlciArIDEsXG4gICAgICAgICAgICAgIHJldHJpZXNVc2VkLFxuICAgICAgICAgICAgICByZXRyeUNvdW50LFxuICAgICAgICAgICAgICB0ZXN0QXJncyxcbiAgICAgICAgICAgICAgdGVzdERhdGEsXG4gICAgICAgICAgICAgIHRlc3REZXNjcmlwdGlvbixcbiAgICAgICAgICAgICAgdGVzdFJ1bm5lcjogdGhpc1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoYXR0ZW1wdE51bWJlciA+IDEpIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZW1pdEV2ZW50KFwidGVzdFJldHJpZWRcIiwge1xuICAgICAgICAgICAgICBjb25maWd1cmF0aW9uOiB0aGlzLmdldENvbmZpZ3VyYXRpb24oKSxcbiAgICAgICAgICAgICAgZGVzY3JpcHRpb25zLFxuICAgICAgICAgICAgICBlcnJvcjogbGFzdEVycm9yLFxuICAgICAgICAgICAgICBhdHRlbXB0TnVtYmVyLFxuICAgICAgICAgICAgICByZXRyaWVzVXNlZCxcbiAgICAgICAgICAgICAgcmV0cnlDb3VudCxcbiAgICAgICAgICAgICAgdGVzdEFyZ3MsXG4gICAgICAgICAgICAgIHRlc3REYXRhLFxuICAgICAgICAgICAgICB0ZXN0RGVzY3JpcHRpb24sXG4gICAgICAgICAgICAgIHRlc3RSdW5uZXI6IHRoaXNcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYXR0ZW1wdE51bWJlcisrXG5cbiAgICAgICAgICBpZiAoc2hvdWxkUmV0cnkpIGNvbnRpbnVlXG5cbiAgICAgICAgICBpZiAoZmFpbGVkRXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnN0IGNvbnNvbGVPdXRwdXQgPSB0aGlzLmJ1aWxkQ29uc29sZU91dHB1dChhdHRlbXB0Q29uc29sZU91dHB1dHMpXG5cbiAgICAgICAgICAgIGlmIChmYWlsZWRFcnJvciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IocGljb2NvbG9ycy5yZWQoYCR7bGVmdFBhZGRpbmd9ICBUZXN0IGZhaWxlZDogJHtmYWlsZWRFcnJvci5tZXNzYWdlfWApKVxuICAgICAgICAgICAgICBhZGRUcmFja2VkU3RhY2tUb0Vycm9yKGZhaWxlZEVycm9yKVxuXG4gICAgICAgICAgICAgIGNvbnN0IGJhY2t0cmFjZUNsZWFuZXIgPSBuZXcgQmFja3RyYWNlQ2xlYW5lcihmYWlsZWRFcnJvcilcbiAgICAgICAgICAgICAgY29uc3QgY2xlYW5lZFN0YWNrID0gYmFja3RyYWNlQ2xlYW5lci5nZXRDbGVhbmVkU3RhY2soKVxuICAgICAgICAgICAgICBjb25zdCBzdGFja0xpbmVzID0gY2xlYW5lZFN0YWNrPy5zcGxpdChcIlxcblwiKVxuXG4gICAgICAgICAgICAgIGlmIChzdGFja0xpbmVzKSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBzdGFja0xpbmUgb2Ygc3RhY2tMaW5lcykge1xuICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihwaWNvY29sb3JzLnJlZChgJHtsZWZ0UGFkZGluZ30gICR7c3RhY2tMaW5lfWApKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihwaWNvY29sb3JzLnJlZChgJHtsZWZ0UGFkZGluZ30gIFRlc3QgZmFpbGVkIHdpdGggYSAke3R5cGVvZiBmYWlsZWRFcnJvcn06ICR7U3RyaW5nKGZhaWxlZEVycm9yKX1gKSlcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5wcmludEZhaWxlZENvbnNvbGVPdXRwdXQoe2NvbnNvbGVPdXRwdXQsIGxlZnRQYWRkaW5nfSlcbiAgICAgICAgICAgIHRoaXMuX2ZhaWxlZFRlc3RzKytcbiAgICAgICAgICAgIHRoaXMuX2ZhaWxlZFRlc3REZXRhaWxzLnB1c2goe1xuICAgICAgICAgICAgICBmdWxsRGVzY3JpcHRpb246IHRoaXMuYnVpbGRGdWxsRGVzY3JpcHRpb24oZGVzY3JpcHRpb25zLCB0ZXN0RGVzY3JpcHRpb24pLFxuICAgICAgICAgICAgICBmaWxlUGF0aDogdGVzdERhdGEuZmlsZVBhdGgsXG4gICAgICAgICAgICAgIGxpbmU6IHRlc3REYXRhLmxpbmUsXG4gICAgICAgICAgICAgIGVycm9yOiBmYWlsZWRFcnJvcixcbiAgICAgICAgICAgICAgY29uc29sZU91dHB1dDogY29uc29sZU91dHB1dCB8fCB1bmRlZmluZWRcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZW1pdEV2ZW50KFwidGVzdEZhaWxlZFwiLCB7XG4gICAgICAgICAgICAgIGNvbmZpZ3VyYXRpb246IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpLFxuICAgICAgICAgICAgICBkZXNjcmlwdGlvbnMsXG4gICAgICAgICAgICAgIGVycm9yOiBmYWlsZWRFcnJvcixcbiAgICAgICAgICAgICAgdGVzdEFyZ3MsXG4gICAgICAgICAgICAgIHRlc3REYXRhLFxuICAgICAgICAgICAgICB0ZXN0RGVzY3JpcHRpb24sXG4gICAgICAgICAgICAgIHRlc3RSdW5uZXI6IHRoaXNcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIHRoaXMucHJpbnRSZXJ1bkNvbW1hbmQoe2Rlc2NyaXB0aW9ucywgdGVzdERlc2NyaXB0aW9uLCB0ZXN0RGF0YSwgbGVmdFBhZGRpbmd9KVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZm9yIChjb25zdCBzdWJEZXNjcmlwdGlvbiBpbiB0ZXN0cy5zdWJzKSB7XG4gICAgICAgIGNvbnN0IHN1YlRlc3QgPSB0ZXN0cy5zdWJzW3N1YkRlc2NyaXB0aW9uXVxuICAgICAgICBjb25zdCBuZXdEZWNyaXB0aW9ucyA9IGRlc2NyaXB0aW9ucy5jb25jYXQoW3N1YkRlc2NyaXB0aW9uXSlcbiAgICAgICAgY29uc3QgY2hpbGRTY29wZUxpbmVNYXRjaCA9IHNjb3BlTGluZU1hdGNoIHx8IHRoaXMubWF0Y2hlc0xpbmVGaWx0ZXIoc3ViVGVzdClcblxuICAgICAgICBpZiAoIXRoaXMuX29ubHlGb2N1c3NlZCB8fCBzdWJUZXN0LmFueVRlc3RzRm9jdXNzZWQpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhgJHtsZWZ0UGFkZGluZ30ke3N1YkRlc2NyaXB0aW9ufWApXG4gICAgICAgICAgYXdhaXQgdGhpcy5ydW5UZXN0cyh7XG4gICAgICAgICAgICBhZnRlckVhY2hlczogbmV3QWZ0ZXJFYWNoZXMsXG4gICAgICAgICAgICBiZWZvcmVFYWNoZXM6IG5ld0JlZm9yZUVhY2hlcyxcbiAgICAgICAgICAgIHRlc3RzOiBzdWJUZXN0LFxuICAgICAgICAgICAgZGVzY3JpcHRpb25zOiBuZXdEZWNyaXB0aW9ucyxcbiAgICAgICAgICAgIGluZGVudExldmVsOiBpbmRlbnRMZXZlbCArIDEsXG4gICAgICAgICAgICBsaW5lTWF0Y2hlZEluU2NvcGU6IGNoaWxkU2NvcGVMaW5lTWF0Y2hcbiAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGF3YWl0IHRoaXMucnVuQWZ0ZXJBbGxzRm9yU2NvcGUoc2NvcGVFbnRyeSlcbiAgICAgIGNvbnN0IHNjb3BlSW5kZXggPSB0aGlzLl9hY3RpdmVBZnRlckFsbFNjb3Blcy5pbmRleE9mKHNjb3BlRW50cnkpXG5cbiAgICAgIGlmIChzY29wZUluZGV4ID49IDApIHtcbiAgICAgICAgdGhpcy5fYWN0aXZlQWZ0ZXJBbGxTY29wZXMuc3BsaWNlKHNjb3BlSW5kZXgsIDEpXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgcnVuIGFmdGVyIGFsbHMgZm9yIHNjb3BlLlxuICAgKiBAcGFyYW0ge0FjdGl2ZUFmdGVyQWxsU2NvcGVFbnRyeX0gc2NvcGVFbnRyeSAtIFNjb3BlIGVudHJ5LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIHNjb3BlIGNsZWFudXAgZmluaXNoZXMuXG4gICAqL1xuICBhc3luYyBydW5BZnRlckFsbHNGb3JTY29wZShzY29wZUVudHJ5KSB7XG4gICAgaWYgKHNjb3BlRW50cnkuYWZ0ZXJBbGxzUnVuKSByZXR1cm5cblxuICAgIHNjb3BlRW50cnkuYWZ0ZXJBbGxzUnVuID0gdHJ1ZVxuXG4gICAgZm9yIChjb25zdCBhZnRlckFsbERhdGEgb2Ygc2NvcGVFbnRyeS50ZXN0cy5hZnRlckFsbHMgfHwgW10pIHtcbiAgICAgIGF3YWl0IGFmdGVyQWxsRGF0YS5jYWxsYmFjayh7Y29uZmlndXJhdGlvbjogdGhpcy5nZXRDb25maWd1cmF0aW9uKCl9KVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGVtaXQgZXZlbnQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWUgLSBFdmVudCBuYW1lLlxuICAgKiBAcGFyYW0ge29iamVjdH0gcGF5bG9hZCAtIEV2ZW50IHBheWxvYWQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gYWxsIGxpc3RlbmVycyBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIGVtaXRFdmVudChldmVudE5hbWUsIHBheWxvYWQpIHtcbiAgICBjb25zdCBsaXN0ZW5lcnMgPSB0ZXN0RXZlbnRzLmxpc3RlbmVycyhldmVudE5hbWUpXG5cbiAgICBmb3IgKGNvbnN0IGxpc3RlbmVyIG9mIGxpc3RlbmVycykge1xuICAgICAgYXdhaXQgbGlzdGVuZXIocGF5bG9hZClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBwcmludCByZXJ1biBjb21tYW5kLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBhcmdzLmRlc2NyaXB0aW9ucyAtIERlc2NyaXB0aW9uIHN0YWNrLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy50ZXN0RGVzY3JpcHRpb24gLSBUZXN0IGRlc2NyaXB0aW9uLlxuICAgKiBAcGFyYW0ge1Rlc3REYXRhfSBhcmdzLnRlc3REYXRhIC0gVGVzdCBkYXRhLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy5sZWZ0UGFkZGluZyAtIExlZnQgcGFkZGluZy5cbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgcHJpbnRSZXJ1bkNvbW1hbmQoe2Rlc2NyaXB0aW9ucywgdGVzdERlc2NyaXB0aW9uLCB0ZXN0RGF0YSwgbGVmdFBhZGRpbmd9KSB7XG4gICAgY29uc3QgcmVydW4gPSB0aGlzLmJ1aWxkUmVydW5Db21tYW5kKHtkZXNjcmlwdGlvbnMsIHRlc3REZXNjcmlwdGlvbiwgdGVzdERhdGF9KVxuXG4gICAgaWYgKHJlcnVuKSB7XG4gICAgICBjb25zb2xlLmVycm9yKGAke2xlZnRQYWRkaW5nfSAgUmUtcnVuOiAke3JlcnVufWApXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYnVpbGQgcmVydW4gY29tbWFuZC5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHBhcmFtIHtzdHJpbmdbXX0gYXJncy5kZXNjcmlwdGlvbnMgLSBEZXNjcmlwdGlvbiBzdGFjay5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MudGVzdERlc2NyaXB0aW9uIC0gVGVzdCBkZXNjcmlwdGlvbi5cbiAgICogQHBhcmFtIHtUZXN0RGF0YX0gYXJncy50ZXN0RGF0YSAtIFRlc3QgZGF0YS5cbiAgICogQHJldHVybnMge3N0cmluZyB8IHVuZGVmaW5lZH0gLSBSZXJ1biBjb21tYW5kLlxuICAgKi9cbiAgYnVpbGRSZXJ1bkNvbW1hbmQoe2Rlc2NyaXB0aW9ucywgdGVzdERlc2NyaXB0aW9uLCB0ZXN0RGF0YX0pIHtcbiAgICBjb25zdCBiYXNlQ29tbWFuZCA9IFwibnB4IHZlbG9jaW91cyB0ZXN0XCJcbiAgICBjb25zdCBmaWxlUGF0aCA9IHRlc3REYXRhLmZpbGVQYXRoXG4gICAgY29uc3QgbGluZSA9IHRlc3REYXRhLmxpbmVcblxuICAgIGlmIChmaWxlUGF0aCAmJiBsaW5lKSB7XG4gICAgICBjb25zdCByZWxhdGl2ZVBhdGggPSBwYXRoLnJlbGF0aXZlKHByb2Nlc3MuY3dkKCksIGZpbGVQYXRoKVxuICAgICAgcmV0dXJuIGAke2Jhc2VDb21tYW5kfSAke3JlbGF0aXZlUGF0aH06JHtsaW5lfWBcbiAgICB9XG5cbiAgICBjb25zdCBmdWxsRGVzY3JpcHRpb24gPSB0aGlzLmJ1aWxkRnVsbERlc2NyaXB0aW9uKGRlc2NyaXB0aW9ucywgdGVzdERlc2NyaXB0aW9uKVxuXG4gICAgaWYgKGZ1bGxEZXNjcmlwdGlvbikge1xuICAgICAgcmV0dXJuIGAke2Jhc2VDb21tYW5kfSAtLWV4YW1wbGUgJHtKU09OLnN0cmluZ2lmeShmdWxsRGVzY3JpcHRpb24pfWBcbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkXG4gIH1cblxuICAvKipcbiAgICogUnVucyBidWlsZCBjb25zb2xlIG91dHB1dC5cbiAgICogQHBhcmFtIHtBdHRlbXB0Q29uc29sZU91dHB1dFtdfSBhdHRlbXB0Q29uc29sZU91dHB1dHMgLSBBdHRlbXB0IG91dHB1dCBlbnRyaWVzLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSAtIENvbWJpbmVkIGNvbnNvbGUgb3V0cHV0LlxuICAgKi9cbiAgYnVpbGRDb25zb2xlT3V0cHV0KGF0dGVtcHRDb25zb2xlT3V0cHV0cykge1xuICAgIGlmIChhdHRlbXB0Q29uc29sZU91dHB1dHMubGVuZ3RoID09PSAwKSByZXR1cm4gXCJcIlxuICAgIGlmIChhdHRlbXB0Q29uc29sZU91dHB1dHMubGVuZ3RoID09PSAxKSByZXR1cm4gYXR0ZW1wdENvbnNvbGVPdXRwdXRzWzBdLm91dHB1dFxuXG4gICAgcmV0dXJuIGF0dGVtcHRDb25zb2xlT3V0cHV0cy5tYXAoKGF0dGVtcHRDb25zb2xlT3V0cHV0KSA9PiB7XG4gICAgICByZXR1cm4gYC0tLSBBdHRlbXB0ICR7YXR0ZW1wdENvbnNvbGVPdXRwdXQuYXR0ZW1wdE51bWJlcn0gLS0tXFxuJHthdHRlbXB0Q29uc29sZU91dHB1dC5vdXRwdXR9YFxuICAgIH0pLmpvaW4oXCJcXG5cIilcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGdldCBmYWlsZWQgY29uc29sZSBvdXRwdXQgbWF4IGxpbmVzLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSAtIE1heGltdW0gZmFpbGVkIGNvbnNvbGUgbGluZXMuXG4gICAqL1xuICBnZXRGYWlsZWRDb25zb2xlT3V0cHV0TWF4TGluZXMoKSB7XG4gICAgY29uc3QgbWF4TGluZXMgPSB0ZXN0Q29uZmlnLmZhaWxlZENvbnNvbGVPdXRwdXRNYXhMaW5lc1xuXG4gICAgaWYgKHR5cGVvZiBtYXhMaW5lcyAhPT0gXCJudW1iZXJcIiB8fCAhTnVtYmVyLmlzRmluaXRlKG1heExpbmVzKSkgcmV0dXJuIDIwMFxuXG4gICAgcmV0dXJuIE1hdGgubWF4KDAsIE1hdGguZmxvb3IobWF4TGluZXMpKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgdHJ1bmNhdGUgZmFpbGVkIGNvbnNvbGUgb3V0cHV0IGxpbmVzLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gY29uc29sZU91dHB1dCAtIENvbnNvbGUgb3V0cHV0LlxuICAgKiBAcmV0dXJucyB7c3RyaW5nW119IC0gTGluZXMgZm9yIGlubGluZSBvdXRwdXQuXG4gICAqL1xuICB0cnVuY2F0ZUZhaWxlZENvbnNvbGVPdXRwdXRMaW5lcyhjb25zb2xlT3V0cHV0KSB7XG4gICAgY29uc3QgbGluZXMgPSBjb25zb2xlT3V0cHV0LnNwbGl0KFwiXFxuXCIpXG4gICAgY29uc3QgbWF4TGluZXMgPSB0aGlzLmdldEZhaWxlZENvbnNvbGVPdXRwdXRNYXhMaW5lcygpXG5cbiAgICBpZiAobWF4TGluZXMgPT09IDApIHJldHVybiBbXVxuICAgIGlmIChsaW5lcy5sZW5ndGggPD0gbWF4TGluZXMpIHJldHVybiBsaW5lc1xuXG4gICAgY29uc3Qgb21pdHRlZExpbmVzID0gbGluZXMubGVuZ3RoIC0gbWF4TGluZXNcbiAgICBjb25zdCBwbHVyYWwgPSBvbWl0dGVkTGluZXMgPT09IDEgPyBcIlwiIDogXCJzXCJcblxuICAgIHJldHVybiBbXG4gICAgICBgLi4uICR7b21pdHRlZExpbmVzfSBjb25zb2xlIG91dHB1dCBsaW5lJHtwbHVyYWx9IG9taXR0ZWQgLi4uYCxcbiAgICAgIC4uLmxpbmVzLnNsaWNlKC1tYXhMaW5lcylcbiAgICBdXG4gIH1cblxuICAvKipcbiAgICogUnVucyBwcmludCBmYWlsZWQgY29uc29sZSBvdXRwdXQuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucyBvYmplY3QuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLmNvbnNvbGVPdXRwdXQgLSBDb25zb2xlIG91dHB1dC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MubGVmdFBhZGRpbmcgLSBMZWZ0IHBhZGRpbmcuXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIHByaW50RmFpbGVkQ29uc29sZU91dHB1dCh7Y29uc29sZU91dHB1dCwgbGVmdFBhZGRpbmd9KSB7XG4gICAgaWYgKHRlc3RDb25maWcuY29uc29sZU91dHB1dCAhPT0gXCJmYWlsdXJlXCIpIHJldHVyblxuICAgIGlmICghY29uc29sZU91dHB1dCkgcmV0dXJuXG5cbiAgICBjb25zdCBsaW5lcyA9IHRoaXMudHJ1bmNhdGVGYWlsZWRDb25zb2xlT3V0cHV0TGluZXMoY29uc29sZU91dHB1dClcblxuICAgIGlmIChsaW5lcy5sZW5ndGggPT09IDApIHJldHVyblxuXG4gICAgY29uc29sZS5lcnJvcihwaWNvY29sb3JzLnJlZChgJHtsZWZ0UGFkZGluZ30gIENvbnNvbGUgb3V0cHV0OmApKVxuXG4gICAgZm9yIChjb25zdCBsaW5lIG9mIGxpbmVzKSB7XG4gICAgICBjb25zb2xlLmVycm9yKHBpY29jb2xvcnMucmVkKGAke2xlZnRQYWRkaW5nfSAgICAke2xpbmV9YCkpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgc3RhcnQgY29uc29sZSBjYXB0dXJlLlxuICAgKiBAcGFyYW0ge29iamVjdH0gW2FyZ3NdIC0gT3B0aW9ucyBvYmplY3QuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2FyZ3MucGFzc3Rocm91Z2hdIC0gV2hldGhlciB0byBwYXNzIHRocm91Z2ggdG8gdGhlIG9yaWdpbmFsIGNvbnNvbGUuXG4gICAqIEByZXR1cm5zIHsoKSA9PiBzdHJpbmd9IC0gU3RvcHMgdGhlIGNhcHR1cmUgYW5kIHJldHVybnMgY2FwdHVyZWQgdGV4dC5cbiAgICovXG4gIHN0YXJ0Q29uc29sZUNhcHR1cmUoe3Bhc3N0aHJvdWdoID0gZmFsc2V9ID0ge30pIHtcbiAgICAvKipcbiAgICAgKiBMaW5lcy5cbiAgICAgIEB0eXBlIHtzdHJpbmdbXX0gKi9cbiAgICBjb25zdCBsaW5lcyA9IFtdXG4gICAgLyoqXG4gICAgICogQ29uc29sZSBvYmplY3QuXG4gICAgICBAdHlwZSB7UmVjb3JkPENvbnNvbGVNZXRob2ROYW1lLCAoLi4uYXJnczogQXJyYXk8Pz4pID0+IHZvaWQ+fSAqL1xuICAgIGNvbnN0IGNvbnNvbGVPYmplY3QgPSAvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEB0eXBlIHtSZWNvcmQ8Q29uc29sZU1ldGhvZE5hbWUsICguLi5hcmdzOiBBcnJheTw/PikgPT4gdm9pZD59ICovIChjb25zb2xlKVxuICAgIC8qKlxuICAgICAqIE9yaWdpbmFsIGNvbnNvbGUgbWV0aG9kcy5cbiAgICAgIEB0eXBlIHtSZWNvcmQ8Q29uc29sZU1ldGhvZE5hbWUsICguLi5hcmdzOiBBcnJheTw/PikgPT4gdm9pZD59ICovXG4gICAgY29uc3Qgb3JpZ2luYWxDb25zb2xlTWV0aG9kcyA9IHtcbiAgICAgIGRlYnVnOiBjb25zb2xlT2JqZWN0LmRlYnVnLmJpbmQoY29uc29sZSksXG4gICAgICBlcnJvcjogY29uc29sZU9iamVjdC5lcnJvci5iaW5kKGNvbnNvbGUpLFxuICAgICAgaW5mbzogY29uc29sZU9iamVjdC5pbmZvLmJpbmQoY29uc29sZSksXG4gICAgICBsb2c6IGNvbnNvbGVPYmplY3QubG9nLmJpbmQoY29uc29sZSksXG4gICAgICB3YXJuOiBjb25zb2xlT2JqZWN0Lndhcm4uYmluZChjb25zb2xlKVxuICAgIH1cbiAgICBsZXQgc3RvcHBlZCA9IGZhbHNlXG4gICAgbGV0IG91dHB1dFRleHQgPSBcIlwiXG5cbiAgICBmb3IgKGNvbnN0IG1ldGhvZE5hbWUgb2YgQ0FQVFVSRURfQ09OU09MRV9NRVRIT0RTKSB7XG4gICAgICBjb25zb2xlT2JqZWN0W21ldGhvZE5hbWVdID0gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgbGluZXMucHVzaChgWyR7bmV3IERhdGUoKS50b0lTT1N0cmluZygpfV0gWyR7bWV0aG9kTmFtZX1dICR7Zm9ybWF0KC4uLmFyZ3MpfWApXG5cbiAgICAgICAgaWYgKHBhc3N0aHJvdWdoKSB7XG4gICAgICAgICAgb3JpZ2luYWxDb25zb2xlTWV0aG9kc1ttZXRob2ROYW1lXSguLi5hcmdzKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGlmICghc3RvcHBlZCkge1xuICAgICAgICBzdG9wcGVkID0gdHJ1ZVxuXG4gICAgICAgIGZvciAoY29uc3QgbWV0aG9kTmFtZSBvZiBDQVBUVVJFRF9DT05TT0xFX01FVEhPRFMpIHtcbiAgICAgICAgICBjb25zb2xlT2JqZWN0W21ldGhvZE5hbWVdID0gb3JpZ2luYWxDb25zb2xlTWV0aG9kc1ttZXRob2ROYW1lXVxuICAgICAgICB9XG5cbiAgICAgICAgb3V0cHV0VGV4dCA9IGxpbmVzLmpvaW4oXCJcXG5cIilcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG91dHB1dFRleHRcbiAgICB9XG4gIH1cbn1cbiJdfQ==
|