velocious 1.0.427 → 1.0.429
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 +126 -37
- package/build/src/database/pool/async-tracked-multi-connection.d.ts.map +1 -1
- package/build/src/database/pool/async-tracked-multi-connection.js +187 -57
- 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 +61 -23
- 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 +388 -146
- package/build/src/database/record/index.d.ts.map +1 -1
- package/build/src/database/record/index.js +686 -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
|
@@ -6,6 +6,7 @@ const IDLE_CONNECTION_CHECKED_IN_AT = Symbol("velociousIdleConnectionCheckedInAt
|
|
|
6
6
|
const CONNECTION_CHECKED_OUT_AT = Symbol("velociousConnectionCheckedOutAt");
|
|
7
7
|
const DEFAULT_IDLE_TIMEOUT_MILLIS = 5000;
|
|
8
8
|
/**
|
|
9
|
+
* PendingCheckout type.
|
|
9
10
|
* @typedef {object} PendingCheckout
|
|
10
11
|
* @property {import("../../configuration-types.js").DatabaseConfigurationType} databaseConfig - Resolved database configuration needed by the checkout.
|
|
11
12
|
* @property {number} enqueuedAt - Timestamp when the checkout started waiting.
|
|
@@ -28,17 +29,29 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
28
29
|
* @type {import("../drivers/base.js").default | undefined}
|
|
29
30
|
*/
|
|
30
31
|
_testSharedConnection = undefined;
|
|
31
|
-
/**
|
|
32
|
+
/**
|
|
33
|
+
* Connections.
|
|
34
|
+
@type {import("../drivers/base.js").default[]} */
|
|
32
35
|
connections = [];
|
|
33
|
-
/**
|
|
36
|
+
/**
|
|
37
|
+
* Connections in use.
|
|
38
|
+
@type {Record<number, import("../drivers/base.js").default>} */
|
|
34
39
|
connectionsInUse = {};
|
|
35
|
-
/**
|
|
40
|
+
/**
|
|
41
|
+
* Pending checkouts.
|
|
42
|
+
@type {PendingCheckout[]} */
|
|
36
43
|
pendingCheckouts = [];
|
|
37
|
-
/**
|
|
44
|
+
/**
|
|
45
|
+
* Connections being spawned.
|
|
46
|
+
@type {number} */
|
|
38
47
|
connectionsBeingSpawned = 0;
|
|
39
|
-
/**
|
|
48
|
+
/**
|
|
49
|
+
* Pending checkout drain promise.
|
|
50
|
+
@type {Promise<void> | undefined} */
|
|
40
51
|
pendingCheckoutDrainPromise = undefined;
|
|
41
|
-
/**
|
|
52
|
+
/**
|
|
53
|
+
* Idle connection reaper timer.
|
|
54
|
+
@type {ReturnType<typeof setTimeout> | undefined} */
|
|
42
55
|
idleConnectionReaperTimer = undefined;
|
|
43
56
|
/**
|
|
44
57
|
* In-flight connection-close promises. The idle reaper is armed on check-in
|
|
@@ -58,20 +71,28 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
58
71
|
connectionClosePromises = new WeakMap();
|
|
59
72
|
idSeq = 0;
|
|
60
73
|
/**
|
|
74
|
+
* Runs constructor.
|
|
61
75
|
* @param {object} args - Options object.
|
|
62
76
|
* @param {import("../../configuration.js").default} args.configuration - Configuration instance.
|
|
63
77
|
* @param {string} args.identifier - Identifier.
|
|
64
78
|
*/
|
|
65
79
|
constructor({ configuration, identifier }) {
|
|
66
80
|
super({ configuration, identifier });
|
|
81
|
+
this._withoutCurrentConnectionContext = /**
|
|
82
|
+
* Narrows the runtime value to the documented type.
|
|
83
|
+
@type {(callback: () => ?) => ?} */
|
|
84
|
+
((callback) => this.asyncLocalStorage.run(undefined, callback));
|
|
67
85
|
}
|
|
68
86
|
/**
|
|
87
|
+
* Runs checkin.
|
|
69
88
|
* @param {import("../drivers/base.js").default} connection - Database connection instance.
|
|
70
89
|
* @returns {Promise<void>} - Resolves when the connection is checked in or closed.
|
|
71
90
|
*/
|
|
72
91
|
async checkin(connection) {
|
|
73
92
|
const id = connection.getIdSeq();
|
|
74
|
-
const trackedConnection = /**
|
|
93
|
+
const trackedConnection = /**
|
|
94
|
+
* Narrows the runtime value to the documented type.
|
|
95
|
+
@type {import("../drivers/base.js").default & {[CLOSED_CONNECTION]?: boolean, [CONNECTION_CHECKED_OUT_AT]?: number, [IDLE_CONNECTION_CHECKED_IN_AT]?: number}} */ (connection);
|
|
75
96
|
if (trackedConnection[CLOSED_CONNECTION]) {
|
|
76
97
|
this.untrackConnectionInUse(connection, id);
|
|
77
98
|
await this.drainPendingCheckouts();
|
|
@@ -94,9 +115,10 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
94
115
|
await this.handleCheckedInIdleConnection();
|
|
95
116
|
}
|
|
96
117
|
/**
|
|
118
|
+
* Runs close checked out connection after checkin failure.
|
|
97
119
|
* @param {import("../drivers/base.js").default} connection - Connection that failed check-in cleanup.
|
|
98
120
|
* @param {number | undefined} id - Connection checkout id.
|
|
99
|
-
* @param {
|
|
121
|
+
* @param {?} originalError - Error that caused check-in cleanup to fail.
|
|
100
122
|
* @returns {Promise<void>} - Resolves when cleanup has been attempted.
|
|
101
123
|
*/
|
|
102
124
|
async closeCheckedOutConnectionAfterCheckinFailure(connection, id, originalError) {
|
|
@@ -115,6 +137,7 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
115
137
|
}
|
|
116
138
|
}
|
|
117
139
|
/**
|
|
140
|
+
* Runs untrack connection in use.
|
|
118
141
|
* @param {import("../drivers/base.js").default} connection - Connection being checked in.
|
|
119
142
|
* @param {number | undefined} id - Connection checkout id.
|
|
120
143
|
* @returns {void}
|
|
@@ -126,7 +149,10 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
126
149
|
delete this.connectionsInUse[id];
|
|
127
150
|
connection.setIdSeq(undefined);
|
|
128
151
|
}
|
|
129
|
-
/**
|
|
152
|
+
/**
|
|
153
|
+
* Runs handle checked in idle connection.
|
|
154
|
+
* @returns {Promise<void>} - Resolves once idle reaping has been scheduled or run.
|
|
155
|
+
*/
|
|
130
156
|
async handleCheckedInIdleConnection() {
|
|
131
157
|
if (this.idleTimeoutMillis() === 0) {
|
|
132
158
|
await this.reapIdleConnections();
|
|
@@ -136,6 +162,7 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
136
162
|
}
|
|
137
163
|
}
|
|
138
164
|
/**
|
|
165
|
+
* Runs checkout.
|
|
139
166
|
* @param {import("./base.js").ConnectionCheckoutOptions} [options] - Checkout options.
|
|
140
167
|
* @returns {Promise<import("../drivers/base.js").default>} - Resolves with the checkout.
|
|
141
168
|
*/
|
|
@@ -161,6 +188,7 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
161
188
|
return await this.waitForCheckout(databaseConfig, reuseKey, options);
|
|
162
189
|
}
|
|
163
190
|
/**
|
|
191
|
+
* Runs take idle connection for reuse key.
|
|
164
192
|
* @param {string} reuseKey - Database configuration reuse key.
|
|
165
193
|
* @param {object} [args] - Options.
|
|
166
194
|
* @param {boolean} [args.includeOpenTransactions] - Whether connections with open transactions may be returned.
|
|
@@ -176,15 +204,19 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
176
204
|
return connection;
|
|
177
205
|
}
|
|
178
206
|
/**
|
|
207
|
+
* Runs connection matches reuse key.
|
|
179
208
|
* @param {import("../drivers/base.js").default} connection - Connection.
|
|
180
209
|
* @param {string} reuseKey - Database configuration reuse key.
|
|
181
210
|
* @returns {boolean} - Whether the connection matches the reuse key.
|
|
182
211
|
*/
|
|
183
212
|
connectionMatchesReuseKey(connection, reuseKey) {
|
|
184
|
-
const connectionWithPoolKey = /**
|
|
213
|
+
const connectionWithPoolKey = /**
|
|
214
|
+
* Narrows the runtime value to the documented type.
|
|
215
|
+
@type {import("../drivers/base.js").default & {[POOL_CONFIGURATION_KEY]?: string}} */ (connection);
|
|
185
216
|
return connectionWithPoolKey[POOL_CONFIGURATION_KEY] === reuseKey;
|
|
186
217
|
}
|
|
187
218
|
/**
|
|
219
|
+
* Runs activate connection.
|
|
188
220
|
* @param {import("../drivers/base.js").default} connection - Connection.
|
|
189
221
|
* @param {import("./base.js").ConnectionCheckoutOptions} [options] - Checkout options.
|
|
190
222
|
* @returns {Promise<import("../drivers/base.js").default>} - Activated connection.
|
|
@@ -193,7 +225,9 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
193
225
|
if (connection.getIdSeq() !== undefined)
|
|
194
226
|
throw new Error(`Connection already has an ID-seq - is it in use? ${connection.getIdSeq()}`);
|
|
195
227
|
const id = this.idSeq++;
|
|
196
|
-
const trackedConnection = /**
|
|
228
|
+
const trackedConnection = /**
|
|
229
|
+
* Narrows the runtime value to the documented type.
|
|
230
|
+
@type {import("../drivers/base.js").default & {[CONNECTION_CHECKED_OUT_AT]?: number, [IDLE_CONNECTION_CHECKED_IN_AT]?: number}} */ (connection);
|
|
197
231
|
delete trackedConnection[IDLE_CONNECTION_CHECKED_IN_AT];
|
|
198
232
|
trackedConnection[CONNECTION_CHECKED_OUT_AT] = Date.now();
|
|
199
233
|
connection.setIdSeq(id);
|
|
@@ -209,7 +243,10 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
209
243
|
}
|
|
210
244
|
return connection;
|
|
211
245
|
}
|
|
212
|
-
/**
|
|
246
|
+
/**
|
|
247
|
+
* Runs max connections.
|
|
248
|
+
* @returns {number | undefined} - Configured max live connections.
|
|
249
|
+
*/
|
|
213
250
|
maxConnections() {
|
|
214
251
|
const value = this.getConfiguration().pool?.max;
|
|
215
252
|
if (this.validMaxConnections(value))
|
|
@@ -217,13 +254,17 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
217
254
|
return;
|
|
218
255
|
}
|
|
219
256
|
/**
|
|
220
|
-
*
|
|
257
|
+
* Runs valid max connections.
|
|
258
|
+
* @param {?} value - Candidate max connection count.
|
|
221
259
|
* @returns {value is number} - Whether the value is a valid max connection count.
|
|
222
260
|
*/
|
|
223
261
|
validMaxConnections(value) {
|
|
224
262
|
return typeof value === "number" && Number.isFinite(value) && value >= 1;
|
|
225
263
|
}
|
|
226
|
-
/**
|
|
264
|
+
/**
|
|
265
|
+
* Runs live connection count.
|
|
266
|
+
* @returns {number} - Number of live and in-progress connections.
|
|
267
|
+
*/
|
|
227
268
|
liveConnectionCount() {
|
|
228
269
|
const connections = new Set([
|
|
229
270
|
...this.connections,
|
|
@@ -232,12 +273,16 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
232
273
|
].filter(Boolean));
|
|
233
274
|
return connections.size + this.connectionsBeingSpawned;
|
|
234
275
|
}
|
|
235
|
-
/**
|
|
276
|
+
/**
|
|
277
|
+
* Runs can spawn connection.
|
|
278
|
+
* @returns {boolean} - Whether a new connection can be spawned.
|
|
279
|
+
*/
|
|
236
280
|
canSpawnConnection() {
|
|
237
281
|
const maxConnections = this.maxConnections();
|
|
238
282
|
return maxConnections === undefined || this.liveConnectionCount() < maxConnections;
|
|
239
283
|
}
|
|
240
284
|
/**
|
|
285
|
+
* Runs spawn connection for checkout.
|
|
241
286
|
* @param {import("../../configuration-types.js").DatabaseConfigurationType} databaseConfig - Resolved database config for the checkout.
|
|
242
287
|
* @param {string} reuseKey - Database configuration reuse key for the checkout.
|
|
243
288
|
* @returns {Promise<import("../drivers/base.js").default>} - Spawned connection.
|
|
@@ -246,7 +291,9 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
246
291
|
this.connectionsBeingSpawned++;
|
|
247
292
|
try {
|
|
248
293
|
const connection = await this.spawnConnectionWithConfiguration(databaseConfig);
|
|
249
|
-
const connectionWithPoolKey = /**
|
|
294
|
+
const connectionWithPoolKey = /**
|
|
295
|
+
* Narrows the runtime value to the documented type.
|
|
296
|
+
@type {import("../drivers/base.js").default & {[POOL_CONFIGURATION_KEY]?: string}} */ (connection);
|
|
250
297
|
connectionWithPoolKey[POOL_CONFIGURATION_KEY] = reuseKey;
|
|
251
298
|
connection.setSchemaCacheInvalidator(() => {
|
|
252
299
|
this.clearSchemaCache();
|
|
@@ -259,6 +306,7 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
259
306
|
}
|
|
260
307
|
}
|
|
261
308
|
/**
|
|
309
|
+
* Runs wait for checkout.
|
|
262
310
|
* @param {import("../../configuration-types.js").DatabaseConfigurationType} databaseConfig - Resolved database config for the checkout.
|
|
263
311
|
* @param {string} reuseKey - Database configuration reuse key.
|
|
264
312
|
* @param {import("./base.js").ConnectionCheckoutOptions} [options] - Checkout options.
|
|
@@ -273,7 +321,10 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
273
321
|
});
|
|
274
322
|
});
|
|
275
323
|
}
|
|
276
|
-
/**
|
|
324
|
+
/**
|
|
325
|
+
* Runs drain pending checkouts.
|
|
326
|
+
* @returns {Promise<void>} - Resolves when pending checkouts have been drained as far as possible.
|
|
327
|
+
*/
|
|
277
328
|
async drainPendingCheckouts() {
|
|
278
329
|
if (this.pendingCheckoutDrainPromise) {
|
|
279
330
|
await this.pendingCheckoutDrainPromise;
|
|
@@ -287,7 +338,10 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
287
338
|
this.pendingCheckoutDrainPromise = undefined;
|
|
288
339
|
}
|
|
289
340
|
}
|
|
290
|
-
/**
|
|
341
|
+
/**
|
|
342
|
+
* Runs drain pending checkouts actual.
|
|
343
|
+
* @returns {Promise<void>} - Resolves when pending checkouts have been drained as far as possible.
|
|
344
|
+
*/
|
|
291
345
|
async drainPendingCheckoutsActual() {
|
|
292
346
|
while (this.pendingCheckouts.length > 0) {
|
|
293
347
|
if (await this.resolvePendingCheckoutWithMatchingIdleConnection())
|
|
@@ -307,7 +361,10 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
307
361
|
await this.resolvePendingCheckout(checkout, reapedConnection);
|
|
308
362
|
}
|
|
309
363
|
}
|
|
310
|
-
/**
|
|
364
|
+
/**
|
|
365
|
+
* Runs resolve pending checkout with matching idle connection.
|
|
366
|
+
* @returns {Promise<boolean>} - Whether a pending checkout was resolved with an idle connection.
|
|
367
|
+
*/
|
|
311
368
|
async resolvePendingCheckoutWithMatchingIdleConnection() {
|
|
312
369
|
for (let index = 0; index < this.pendingCheckouts.length; index++) {
|
|
313
370
|
const checkout = this.pendingCheckouts[index];
|
|
@@ -321,6 +378,7 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
321
378
|
return false;
|
|
322
379
|
}
|
|
323
380
|
/**
|
|
381
|
+
* Runs close idle connection for pending checkout capacity.
|
|
324
382
|
* @param {PendingCheckout} checkout - Checkout waiting for a connection.
|
|
325
383
|
* @returns {Promise<boolean>} - Whether an idle connection was closed to free capacity.
|
|
326
384
|
*/
|
|
@@ -334,6 +392,7 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
334
392
|
return this.canSpawnConnection() ? false : await this.closeOneIdleConnectionForCapacity();
|
|
335
393
|
}
|
|
336
394
|
/**
|
|
395
|
+
* Runs find idle connection for reuse key.
|
|
337
396
|
* @param {string} reuseKey - Database configuration reuse key.
|
|
338
397
|
* @returns {import("../drivers/base.js").default | undefined} - Matching idle connection, if present.
|
|
339
398
|
*/
|
|
@@ -341,6 +400,7 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
341
400
|
return this.connections.find((connection) => !this.connectionHasOpenTransaction(connection) && this.connectionMatchesReuseKey(connection, reuseKey));
|
|
342
401
|
}
|
|
343
402
|
/**
|
|
403
|
+
* Runs idle connection for pending checkout.
|
|
344
404
|
* @param {PendingCheckout} checkout - Checkout waiting for a connection.
|
|
345
405
|
* @returns {Promise<import("../drivers/base.js").default | undefined>} - Matching idle connection, if one can be reused.
|
|
346
406
|
*/
|
|
@@ -353,6 +413,7 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
353
413
|
return connection;
|
|
354
414
|
}
|
|
355
415
|
/**
|
|
416
|
+
* Runs spawn and resolve pending checkout.
|
|
356
417
|
* @param {PendingCheckout} checkout - Checkout request to resolve.
|
|
357
418
|
* @returns {Promise<void>} - Resolves when the checkout has been handled.
|
|
358
419
|
*/
|
|
@@ -368,6 +429,7 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
368
429
|
await this.resolvePendingCheckout(checkout, connection);
|
|
369
430
|
}
|
|
370
431
|
/**
|
|
432
|
+
* Runs resolve pending checkout.
|
|
371
433
|
* @param {PendingCheckout} checkout - Checkout request to resolve.
|
|
372
434
|
* @param {import("../drivers/base.js").default} connection - Connection to activate.
|
|
373
435
|
* @returns {Promise<void>} - Resolves when the checkout has been handled.
|
|
@@ -380,7 +442,10 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
380
442
|
checkout.reject(error instanceof Error ? error : new Error("Failed to activate database connection.", { cause: error }));
|
|
381
443
|
}
|
|
382
444
|
}
|
|
383
|
-
/**
|
|
445
|
+
/**
|
|
446
|
+
* Runs close one idle connection for capacity.
|
|
447
|
+
* @returns {Promise<boolean>} - Whether an idle connection was closed to free capacity.
|
|
448
|
+
*/
|
|
384
449
|
async closeOneIdleConnectionForCapacity() {
|
|
385
450
|
const connection = this.connections.find((candidate) => !this.connectionHasOpenTransaction(candidate));
|
|
386
451
|
if (!connection)
|
|
@@ -390,6 +455,7 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
390
455
|
return true;
|
|
391
456
|
}
|
|
392
457
|
/**
|
|
458
|
+
* Runs with connection.
|
|
393
459
|
* @template T
|
|
394
460
|
* @param {import("./base.js").ConnectionCheckoutOptions | function(import("../drivers/base.js").default) : Promise<T>} optionsOrCallback - Checkout options or callback to invoke with the connection.
|
|
395
461
|
* @param {function(import("../drivers/base.js").default) : Promise<T>} [callback] - Callback to invoke with the connection.
|
|
@@ -411,7 +477,10 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
411
477
|
}
|
|
412
478
|
});
|
|
413
479
|
}
|
|
414
|
-
/**
|
|
480
|
+
/**
|
|
481
|
+
* Runs get current connection.
|
|
482
|
+
* @returns {import("../drivers/base.js").default} - The current connection.
|
|
483
|
+
*/
|
|
415
484
|
getCurrentConnection() {
|
|
416
485
|
const id = this.asyncLocalStorage.getStore();
|
|
417
486
|
if (id === undefined)
|
|
@@ -423,7 +492,10 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
423
492
|
}
|
|
424
493
|
return currentConnection;
|
|
425
494
|
}
|
|
426
|
-
/**
|
|
495
|
+
/**
|
|
496
|
+
* Runs current fallback connection or fail.
|
|
497
|
+
* @returns {import("../drivers/base.js").default} - Fallback connection, if present.
|
|
498
|
+
*/
|
|
427
499
|
currentFallbackConnectionOrFail() {
|
|
428
500
|
const fallbackConnection = this.getGlobalConnection();
|
|
429
501
|
if (fallbackConnection)
|
|
@@ -431,6 +503,7 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
431
503
|
throw new Error("ID hasn't been set for this async context");
|
|
432
504
|
}
|
|
433
505
|
/**
|
|
506
|
+
* Runs ensure connection is in use.
|
|
434
507
|
* @param {number} id - Checked-out connection id.
|
|
435
508
|
* @returns {void}
|
|
436
509
|
*/
|
|
@@ -445,7 +518,9 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
445
518
|
* @returns {void} - No return value.
|
|
446
519
|
*/
|
|
447
520
|
setGlobalConnection(connection) {
|
|
448
|
-
const klass = /**
|
|
521
|
+
const klass = /**
|
|
522
|
+
* Narrows the runtime value to the documented type.
|
|
523
|
+
@type {typeof VelociousDatabasePoolAsyncTrackedMultiConnection} */ (this.constructor);
|
|
449
524
|
let mapForConfiguration = klass.globalConnections.get(this.configuration);
|
|
450
525
|
if (!mapForConfiguration) {
|
|
451
526
|
mapForConfiguration = {};
|
|
@@ -476,7 +551,9 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
476
551
|
setTestSharedConnection(connection) {
|
|
477
552
|
this._testSharedConnection = connection;
|
|
478
553
|
}
|
|
479
|
-
/**
|
|
554
|
+
/**
|
|
555
|
+
* Runs clear test shared connection.
|
|
556
|
+
@returns {void} */
|
|
480
557
|
clearTestSharedConnection() {
|
|
481
558
|
this._testSharedConnection = undefined;
|
|
482
559
|
}
|
|
@@ -492,14 +569,9 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
492
569
|
return this.getCurrentConnection();
|
|
493
570
|
}
|
|
494
571
|
/**
|
|
495
|
-
*
|
|
496
|
-
* @
|
|
497
|
-
* @returns {T} - Callback result.
|
|
572
|
+
* Runs get debug snapshot.
|
|
573
|
+
* @returns {import("./base.js").DatabasePoolDebugSnapshot} - Diagnostic snapshot for this pool.
|
|
498
574
|
*/
|
|
499
|
-
_withoutCurrentConnectionContext = (callback) => {
|
|
500
|
-
return this.asyncLocalStorage.run(undefined, callback);
|
|
501
|
-
};
|
|
502
|
-
/** @returns {import("./base.js").DatabasePoolDebugSnapshot} - Diagnostic snapshot for this pool. */
|
|
503
575
|
getDebugSnapshot() {
|
|
504
576
|
const snapshot = super.getDebugSnapshot();
|
|
505
577
|
const now = Date.now();
|
|
@@ -515,11 +587,14 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
515
587
|
};
|
|
516
588
|
}
|
|
517
589
|
/**
|
|
590
|
+
* Runs debug connection snapshots.
|
|
518
591
|
* @param {number} now - Current timestamp.
|
|
519
|
-
* @returns {{connections: Array<Record<string,
|
|
592
|
+
* @returns {{connections: Array<Record<string, ?>>, seenConnections: Set<import("../drivers/base.js").default>}} - Connection snapshots and seen set.
|
|
520
593
|
*/
|
|
521
594
|
debugConnectionSnapshots(now) {
|
|
522
|
-
/**
|
|
595
|
+
/**
|
|
596
|
+
* Connections.
|
|
597
|
+
@type {Array<Record<string, ?>>} */
|
|
523
598
|
const connections = [];
|
|
524
599
|
const seenConnections = new Set();
|
|
525
600
|
this.addInUseDebugConnectionSnapshots({ connections, now, seenConnections });
|
|
@@ -528,12 +603,15 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
528
603
|
return { connections, seenConnections };
|
|
529
604
|
}
|
|
530
605
|
/**
|
|
531
|
-
*
|
|
606
|
+
* Runs add in use debug connection snapshots.
|
|
607
|
+
* @param {{connections: Array<Record<string, ?>>, now: number, seenConnections: Set<import("../drivers/base.js").default>}} args - Snapshot collection state.
|
|
532
608
|
* @returns {void}
|
|
533
609
|
*/
|
|
534
610
|
addInUseDebugConnectionSnapshots({ connections, now, seenConnections }) {
|
|
535
611
|
for (const [id, connection] of Object.entries(this.connectionsInUse)) {
|
|
536
|
-
const trackedConnection = /**
|
|
612
|
+
const trackedConnection = /**
|
|
613
|
+
* Narrows the runtime value to the documented type.
|
|
614
|
+
@type {import("../drivers/base.js").default & {[CONNECTION_CHECKED_OUT_AT]?: number}} */ (connection);
|
|
537
615
|
const checkedOutAt = trackedConnection[CONNECTION_CHECKED_OUT_AT];
|
|
538
616
|
const checkedOutForMs = typeof checkedOutAt === "number" ? Math.max(0, now - checkedOutAt) : undefined;
|
|
539
617
|
seenConnections.add(connection);
|
|
@@ -541,7 +619,8 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
541
619
|
}
|
|
542
620
|
}
|
|
543
621
|
/**
|
|
544
|
-
*
|
|
622
|
+
* Runs add idle debug connection snapshots.
|
|
623
|
+
* @param {{connections: Array<Record<string, ?>>, now: number, seenConnections: Set<import("../drivers/base.js").default>}} args - Snapshot collection state.
|
|
545
624
|
* @returns {void}
|
|
546
625
|
*/
|
|
547
626
|
addIdleDebugConnectionSnapshots({ connections, now, seenConnections }) {
|
|
@@ -549,14 +628,17 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
549
628
|
if (seenConnections.has(connection))
|
|
550
629
|
continue;
|
|
551
630
|
seenConnections.add(connection);
|
|
552
|
-
const trackedConnection = /**
|
|
631
|
+
const trackedConnection = /**
|
|
632
|
+
* Narrows the runtime value to the documented type.
|
|
633
|
+
@type {import("../drivers/base.js").default & {[IDLE_CONNECTION_CHECKED_IN_AT]?: number}} */ (connection);
|
|
553
634
|
const checkedInAt = trackedConnection[IDLE_CONNECTION_CHECKED_IN_AT];
|
|
554
635
|
const idleForMs = typeof checkedInAt === "number" ? Math.max(0, now - checkedInAt) : undefined;
|
|
555
636
|
connections.push(this.debugConnectionSnapshot(connection, { checkedInAt, idleForMs, state: "idle" }));
|
|
556
637
|
}
|
|
557
638
|
}
|
|
558
639
|
/**
|
|
559
|
-
*
|
|
640
|
+
* Runs add fallback debug connection snapshots.
|
|
641
|
+
* @param {{connections: Array<Record<string, ?>>, seenConnections: Set<import("../drivers/base.js").default>}} args - Snapshot collection state.
|
|
560
642
|
* @returns {void}
|
|
561
643
|
*/
|
|
562
644
|
addFallbackDebugConnectionSnapshots({ connections, seenConnections }) {
|
|
@@ -564,7 +646,8 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
564
646
|
this.addDebugConnectionSnapshotIfUnseen({ connection: this._testSharedConnection, connections, reapable: false, seenConnections, state: "test-shared" });
|
|
565
647
|
}
|
|
566
648
|
/**
|
|
567
|
-
*
|
|
649
|
+
* Runs add debug connection snapshot if unseen.
|
|
650
|
+
* @param {{connection: import("../drivers/base.js").default | undefined, connections: Array<Record<string, ?>>, reapable?: boolean, seenConnections: Set<import("../drivers/base.js").default>, state: string}} args - Snapshot collection state.
|
|
568
651
|
* @returns {void}
|
|
569
652
|
*/
|
|
570
653
|
addDebugConnectionSnapshotIfUnseen({ connection, connections, reapable, seenConnections, state }) {
|
|
@@ -574,8 +657,9 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
574
657
|
connections.push(this.debugConnectionSnapshot(connection, { reapable, state }));
|
|
575
658
|
}
|
|
576
659
|
/**
|
|
660
|
+
* Runs pending checkout debug snapshots.
|
|
577
661
|
* @param {number} now - Current timestamp.
|
|
578
|
-
* @returns {Array<Record<string,
|
|
662
|
+
* @returns {Array<Record<string, ?>>} - Pending checkout snapshots.
|
|
579
663
|
*/
|
|
580
664
|
pendingCheckoutDebugSnapshots(now) {
|
|
581
665
|
return this.pendingCheckouts.map((checkout, index) => ({
|
|
@@ -587,6 +671,7 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
587
671
|
}));
|
|
588
672
|
}
|
|
589
673
|
/**
|
|
674
|
+
* Runs get global connection.
|
|
590
675
|
* @returns {import("../drivers/base.js").default | undefined} - The global connection.
|
|
591
676
|
*/
|
|
592
677
|
getGlobalConnection() {
|
|
@@ -598,16 +683,24 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
598
683
|
return connection;
|
|
599
684
|
}
|
|
600
685
|
/**
|
|
686
|
+
* Runs get global connection for identifier.
|
|
601
687
|
* @returns {import("../drivers/base.js").default | undefined} - The global connection for this pool identifier.
|
|
602
688
|
*/
|
|
603
689
|
getGlobalConnectionForIdentifier() {
|
|
604
|
-
const klass = /**
|
|
690
|
+
const klass = /**
|
|
691
|
+
* Narrows the runtime value to the documented type.
|
|
692
|
+
@type {typeof VelociousDatabasePoolAsyncTrackedMultiConnection} */ (this.constructor);
|
|
605
693
|
const mapForConfiguration = klass.globalConnections.get(this.configuration);
|
|
606
694
|
return mapForConfiguration?.[this.identifier];
|
|
607
695
|
}
|
|
608
|
-
/**
|
|
696
|
+
/**
|
|
697
|
+
* Runs clear global connection for identifier.
|
|
698
|
+
* @returns {void} - No return value.
|
|
699
|
+
*/
|
|
609
700
|
clearGlobalConnectionForIdentifier() {
|
|
610
|
-
const klass = /**
|
|
701
|
+
const klass = /**
|
|
702
|
+
* Narrows the runtime value to the documented type.
|
|
703
|
+
@type {typeof VelociousDatabasePoolAsyncTrackedMultiConnection} */ (this.constructor);
|
|
611
704
|
const mapForConfiguration = klass.globalConnections.get(this.configuration);
|
|
612
705
|
if (!mapForConfiguration)
|
|
613
706
|
return;
|
|
@@ -629,7 +722,10 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
629
722
|
this._clearConnectionSchemaCache(connection);
|
|
630
723
|
}
|
|
631
724
|
}
|
|
632
|
-
/**
|
|
725
|
+
/**
|
|
726
|
+
* Runs idle timeout millis.
|
|
727
|
+
* @returns {number | null} - Idle timeout in milliseconds, or null when disabled.
|
|
728
|
+
*/
|
|
633
729
|
idleTimeoutMillis() {
|
|
634
730
|
const value = this.getConfiguration().pool?.idleTimeoutMillis;
|
|
635
731
|
if (value === null)
|
|
@@ -639,19 +735,24 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
639
735
|
return DEFAULT_IDLE_TIMEOUT_MILLIS;
|
|
640
736
|
}
|
|
641
737
|
/**
|
|
642
|
-
*
|
|
738
|
+
* Runs valid idle timeout millis.
|
|
739
|
+
* @param {?} value - Candidate idle timeout value.
|
|
643
740
|
* @returns {value is number} - Whether the value is a valid idle timeout.
|
|
644
741
|
*/
|
|
645
742
|
validIdleTimeoutMillis(value) {
|
|
646
743
|
return typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
647
744
|
}
|
|
648
|
-
/**
|
|
745
|
+
/**
|
|
746
|
+
* Runs schedule idle connection reaper.
|
|
747
|
+
@returns {void} */
|
|
649
748
|
scheduleIdleConnectionReaper() {
|
|
650
749
|
if (this.idleConnectionReaperTimer)
|
|
651
750
|
return;
|
|
652
751
|
if (!this.hasIdleConnectionsToReap())
|
|
653
752
|
return;
|
|
654
|
-
const delay = this.nextIdleConnectionReapDelay(/**
|
|
753
|
+
const delay = this.nextIdleConnectionReapDelay(/**
|
|
754
|
+
* Narrows the runtime value to the documented type.
|
|
755
|
+
@type {number} */ (this.idleTimeoutMillis()));
|
|
655
756
|
this.idleConnectionReaperTimer = setTimeout(() => {
|
|
656
757
|
this.idleConnectionReaperTimer = undefined;
|
|
657
758
|
void this.reapIdleConnections().catch((error) => {
|
|
@@ -662,11 +763,15 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
662
763
|
this.idleConnectionReaperTimer.unref();
|
|
663
764
|
}
|
|
664
765
|
}
|
|
665
|
-
/**
|
|
766
|
+
/**
|
|
767
|
+
* Runs has idle connections to reap.
|
|
768
|
+
* @returns {boolean} - Whether an idle reaper timer should be scheduled.
|
|
769
|
+
*/
|
|
666
770
|
hasIdleConnectionsToReap() {
|
|
667
771
|
return this.connections.length > 0 && this.idleTimeoutMillis() !== null;
|
|
668
772
|
}
|
|
669
773
|
/**
|
|
774
|
+
* Runs next idle connection reap delay.
|
|
670
775
|
* @param {number} idleTimeoutMillis - Idle timeout in milliseconds.
|
|
671
776
|
* @returns {number} - Delay before the next reap.
|
|
672
777
|
*/
|
|
@@ -676,7 +781,9 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
676
781
|
for (const connection of this.connections) {
|
|
677
782
|
if (this.connectionHasOpenTransaction(connection))
|
|
678
783
|
continue;
|
|
679
|
-
const trackedConnection = /**
|
|
784
|
+
const trackedConnection = /**
|
|
785
|
+
* Narrows the runtime value to the documented type.
|
|
786
|
+
@type {import("../drivers/base.js").default & {[IDLE_CONNECTION_CHECKED_IN_AT]?: number}} */ (connection);
|
|
680
787
|
const checkedInAt = trackedConnection[IDLE_CONNECTION_CHECKED_IN_AT];
|
|
681
788
|
if (typeof checkedInAt !== "number")
|
|
682
789
|
continue;
|
|
@@ -702,6 +809,7 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
702
809
|
this.scheduleIdleConnectionReaper();
|
|
703
810
|
}
|
|
704
811
|
/**
|
|
812
|
+
* Runs close expired idle connections.
|
|
705
813
|
* @param {import("../drivers/base.js").default[]} expiredConnections - Connections to close.
|
|
706
814
|
* @returns {Promise<void>} - Resolves when closed.
|
|
707
815
|
*/
|
|
@@ -710,20 +818,28 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
710
818
|
await this.closeConnection(connection);
|
|
711
819
|
}
|
|
712
820
|
}
|
|
713
|
-
/**
|
|
821
|
+
/**
|
|
822
|
+
* Runs await inflight connection closes.
|
|
823
|
+
* @returns {Promise<void>} - Resolves once in-flight connection closes settle.
|
|
824
|
+
*/
|
|
714
825
|
async awaitInflightConnectionCloses() {
|
|
715
826
|
if (this.inflightConnectionCloses.size > 0) {
|
|
716
827
|
await Promise.allSettled([...this.inflightConnectionCloses]);
|
|
717
828
|
}
|
|
718
829
|
}
|
|
719
830
|
/**
|
|
831
|
+
* Runs classify idle connections for reaping.
|
|
720
832
|
* @param {{idleTimeoutMillis: number, now: number}} args - Reaper classification inputs.
|
|
721
833
|
* @returns {{expiredConnections: import("../drivers/base.js").default[], keptConnections: import("../drivers/base.js").default[]}} - Classified idle connections.
|
|
722
834
|
*/
|
|
723
835
|
classifyIdleConnectionsForReaping({ idleTimeoutMillis, now }) {
|
|
724
|
-
/**
|
|
836
|
+
/**
|
|
837
|
+
* Kept connections.
|
|
838
|
+
@type {import("../drivers/base.js").default[]} */
|
|
725
839
|
const keptConnections = [];
|
|
726
|
-
/**
|
|
840
|
+
/**
|
|
841
|
+
* Expired connections.
|
|
842
|
+
@type {import("../drivers/base.js").default[]} */
|
|
727
843
|
const expiredConnections = [];
|
|
728
844
|
for (const connection of this.connections) {
|
|
729
845
|
this.classifyIdleConnectionForReaping({ connection, expiredConnections, idleTimeoutMillis, keptConnections, now });
|
|
@@ -731,6 +847,7 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
731
847
|
return { expiredConnections, keptConnections };
|
|
732
848
|
}
|
|
733
849
|
/**
|
|
850
|
+
* Runs classify idle connection for reaping.
|
|
734
851
|
* @param {{connection: import("../drivers/base.js").default, expiredConnections: import("../drivers/base.js").default[], idleTimeoutMillis: number, keptConnections: import("../drivers/base.js").default[], now: number}} args - Classification state.
|
|
735
852
|
* @returns {void}
|
|
736
853
|
*/
|
|
@@ -745,23 +862,30 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
745
862
|
target.push(connection);
|
|
746
863
|
}
|
|
747
864
|
/**
|
|
865
|
+
* Runs connection is closed.
|
|
748
866
|
* @param {import("../drivers/base.js").default} connection - Connection to inspect.
|
|
749
867
|
* @returns {boolean} - Whether the connection is marked closed.
|
|
750
868
|
*/
|
|
751
869
|
connectionIsClosed(connection) {
|
|
752
|
-
const trackedConnection = /**
|
|
870
|
+
const trackedConnection = /**
|
|
871
|
+
* Narrows the runtime value to the documented type.
|
|
872
|
+
@type {import("../drivers/base.js").default & {[CLOSED_CONNECTION]?: boolean}} */ (connection);
|
|
753
873
|
return Boolean(trackedConnection[CLOSED_CONNECTION]);
|
|
754
874
|
}
|
|
755
875
|
/**
|
|
876
|
+
* Runs idle connection expired.
|
|
756
877
|
* @param {{connection: import("../drivers/base.js").default, idleTimeoutMillis: number, now: number}} args - Expiry inputs.
|
|
757
878
|
* @returns {boolean} - Whether the idle connection expired.
|
|
758
879
|
*/
|
|
759
880
|
idleConnectionExpired({ connection, idleTimeoutMillis, now }) {
|
|
760
|
-
const trackedConnection = /**
|
|
881
|
+
const trackedConnection = /**
|
|
882
|
+
* Narrows the runtime value to the documented type.
|
|
883
|
+
@type {import("../drivers/base.js").default & {[IDLE_CONNECTION_CHECKED_IN_AT]?: number}} */ (connection);
|
|
761
884
|
const checkedInAt = trackedConnection[IDLE_CONNECTION_CHECKED_IN_AT];
|
|
762
885
|
return typeof checkedInAt === "number" && now - checkedInAt >= idleTimeoutMillis;
|
|
763
886
|
}
|
|
764
887
|
/**
|
|
888
|
+
* Runs connection has open transaction.
|
|
765
889
|
* @param {import("../drivers/base.js").default} connection - Connection to inspect.
|
|
766
890
|
* @returns {boolean} - Whether the connection has an open transaction.
|
|
767
891
|
*/
|
|
@@ -786,6 +910,7 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
786
910
|
}
|
|
787
911
|
}
|
|
788
912
|
/**
|
|
913
|
+
* Runs close connection.
|
|
789
914
|
* @param {import("../drivers/base.js").default} connection - Connection to close.
|
|
790
915
|
* @returns {Promise<void>} - Resolves when complete.
|
|
791
916
|
*/
|
|
@@ -798,7 +923,9 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
798
923
|
if (existingClose) {
|
|
799
924
|
return await existingClose;
|
|
800
925
|
}
|
|
801
|
-
const trackedConnection = /**
|
|
926
|
+
const trackedConnection = /**
|
|
927
|
+
* Narrows the runtime value to the documented type.
|
|
928
|
+
@type {import("../drivers/base.js").default & {[CLOSED_CONNECTION]?: boolean, [CONNECTION_CHECKED_OUT_AT]?: number, [IDLE_CONNECTION_CHECKED_IN_AT]?: number}} */ (connection);
|
|
802
929
|
trackedConnection[CLOSED_CONNECTION] = true;
|
|
803
930
|
delete trackedConnection[CONNECTION_CHECKED_OUT_AT];
|
|
804
931
|
delete trackedConnection[IDLE_CONNECTION_CHECKED_IN_AT];
|
|
@@ -814,7 +941,9 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
814
941
|
this.inflightConnectionCloses.delete(closePromise);
|
|
815
942
|
}
|
|
816
943
|
}
|
|
817
|
-
/**
|
|
944
|
+
/**
|
|
945
|
+
* Runs clear idle connection reaper timer.
|
|
946
|
+
@returns {void} */
|
|
818
947
|
clearIdleConnectionReaperTimer() {
|
|
819
948
|
if (!this.idleConnectionReaperTimer)
|
|
820
949
|
return;
|
|
@@ -845,6 +974,7 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
845
974
|
}
|
|
846
975
|
}
|
|
847
976
|
/**
|
|
977
|
+
* Runs reject pending checkouts.
|
|
848
978
|
* @param {Error} error - Error to reject pending checkouts with.
|
|
849
979
|
* @returns {void}
|
|
850
980
|
*/
|
|
@@ -881,4 +1011,4 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
881
1011
|
this.globalConnections.delete(configuration);
|
|
882
1012
|
}
|
|
883
1013
|
}
|
|
884
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXN5bmMtdHJhY2tlZC1tdWx0aS1jb25uZWN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2RhdGFiYXNlL3Bvb2wvYXN5bmMtdHJhY2tlZC1tdWx0aS1jb25uZWN0aW9uLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSxhQUFhLENBQUE7QUFDN0MsT0FBTyxRQUFRLEVBQUUsRUFBQyxzQkFBc0IsRUFBQyxNQUFNLFdBQVcsQ0FBQTtBQUUxRCxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRyxNQUFNLENBQUMsMkJBQTJCLENBQUMsQ0FBQTtBQUNwRSxNQUFNLDZCQUE2QixHQUFHLE1BQU0sQ0FBQyxvQ0FBb0MsQ0FBQyxDQUFBO0FBQ2xGLE1BQU0seUJBQXlCLEdBQUcsTUFBTSxDQUFDLGlDQUFpQyxDQUFDLENBQUE7QUFDM0UsTUFBTSwyQkFBMkIsR0FBRyxJQUFJLENBQUE7QUFFeEM7Ozs7Ozs7O0dBUUc7QUFFSCxNQUFNLENBQUMsT0FBTyxPQUFPLGdEQUFpRCxTQUFRLFFBQVE7SUFDcEY7OztPQUdHO0lBQ0gsTUFBTSxDQUFDLGlCQUFpQixHQUFHLElBQUksT0FBTyxFQUFFLENBQUE7SUFFeEMsaUJBQWlCLEdBQUcsSUFBSSxpQkFBaUIsRUFBRSxDQUFBO0lBRTNDOzs7OztPQUtHO0lBQ0gscUJBQXFCLEdBQUcsU0FBUyxDQUFBO0lBRWpDLHFEQUFxRDtJQUNyRCxXQUFXLEdBQUcsRUFBRSxDQUFBO0lBRWhCLG1FQUFtRTtJQUNuRSxnQkFBZ0IsR0FBRyxFQUFFLENBQUE7SUFFckIsZ0NBQWdDO0lBQ2hDLGdCQUFnQixHQUFHLEVBQUUsQ0FBQTtJQUVyQixxQkFBcUI7SUFDckIsdUJBQXVCLEdBQUcsQ0FBQyxDQUFBO0lBRTNCLHdDQUF3QztJQUN4QywyQkFBMkIsR0FBRyxTQUFTLENBQUE7SUFFdkMsd0RBQXdEO0lBQ3hELHlCQUF5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UixDQUFDO1FBRUQsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQTtJQUM5QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCB7QXN5bmNMb2NhbFN0b3JhZ2V9IGZyb20gXCJhc3luY19ob29rc1wiXG5pbXBvcnQgQmFzZVBvb2wsIHtQT09MX0NPTkZJR1VSQVRJT05fS0VZfSBmcm9tIFwiLi9iYXNlLmpzXCJcblxuZXhwb3J0IGNvbnN0IENMT1NFRF9DT05ORUNUSU9OID0gU3ltYm9sKFwidmVsb2Npb3VzQ2xvc2VkQ29ubmVjdGlvblwiKVxuY29uc3QgSURMRV9DT05ORUNUSU9OX0NIRUNLRURfSU5fQVQgPSBTeW1ib2woXCJ2ZWxvY2lvdXNJZGxlQ29ubmVjdGlvbkNoZWNrZWRJbkF0XCIpXG5jb25zdCBDT05ORUNUSU9OX0NIRUNLRURfT1VUX0FUID0gU3ltYm9sKFwidmVsb2Npb3VzQ29ubmVjdGlvbkNoZWNrZWRPdXRBdFwiKVxuY29uc3QgREVGQVVMVF9JRExFX1RJTUVPVVRfTUlMTElTID0gNTAwMFxuXG4vKipcbiAqIEB0eXBlZGVmIHtvYmplY3R9IFBlbmRpbmdDaGVja291dFxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi8uLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLkRhdGFiYXNlQ29uZmlndXJhdGlvblR5cGV9IGRhdGFiYXNlQ29uZmlnIC0gUmVzb2x2ZWQgZGF0YWJhc2UgY29uZmlndXJhdGlvbiBuZWVkZWQgYnkgdGhlIGNoZWNrb3V0LlxuICogQHByb3BlcnR5IHtudW1iZXJ9IGVucXVldWVkQXQgLSBUaW1lc3RhbXAgd2hlbiB0aGUgY2hlY2tvdXQgc3RhcnRlZCB3YWl0aW5nLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL2Jhc2UuanNcIikuQ29ubmVjdGlvbkNoZWNrb3V0T3B0aW9uc30gb3B0aW9ucyAtIENoZWNrb3V0IG9wdGlvbnMuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gcmV1c2VLZXkgLSBEYXRhYmFzZSBjb25maWd1cmF0aW9uIHJldXNlIGtleSBuZWVkZWQgYnkgdGhlIGNoZWNrb3V0LlxuICogQHByb3BlcnR5IHsoY29ubmVjdGlvbjogaW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQpID0+IHZvaWR9IHJlc29sdmUgLSBSZXNvbHZlcyB3aXRoIGFuIGFjdGl2YXRlZCBjb25uZWN0aW9uLlxuICogQHByb3BlcnR5IHsoZXJyb3I6IEVycm9yKSA9PiB2b2lkfSByZWplY3QgLSBSZWplY3RzIHdoZW4gY2hlY2tvdXQgY2Fubm90IGNvbXBsZXRlLlxuICovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFZlbG9jaW91c0RhdGFiYXNlUG9vbEFzeW5jVHJhY2tlZE11bHRpQ29ubmVjdGlvbiBleHRlbmRzIEJhc2VQb29sIHtcbiAgLyoqXG4gICAqIEdsb2JhbCBmYWxsYmFjayBjb25uZWN0aW9ucyBrZXllZCBieSBjb25maWd1cmF0aW9uIGluc3RhbmNlIGFuZCBwb29sIGlkZW50aWZpZXIuXG4gICAqIEB0eXBlIHtXZWFrTWFwPGltcG9ydChcIi4uLy4uL2NvbmZpZ3VyYXRpb24uanNcIikuZGVmYXVsdCwgUmVjb3JkPHN0cmluZywgaW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQ+Pn1cbiAgICovXG4gIHN0YXRpYyBnbG9iYWxDb25uZWN0aW9ucyA9IG5ldyBXZWFrTWFwKClcblxuICBhc3luY0xvY2FsU3RvcmFnZSA9IG5ldyBBc3luY0xvY2FsU3RvcmFnZSgpXG5cbiAgLyoqXG4gICAqIFdoZW4gc2V0LCByZXR1cm5lZCBieSBnZXRDdXJyZW50Q29udGV4dENvbm5lY3Rpb24gd2hlbiBubyBhc3luYyBjb250ZXh0IGV4aXN0cy5cbiAgICogVXNlZCBieSB0aGUgdGVzdCBydW5uZXIgdG8gc2hhcmUgYSBjb25uZWN0aW9uIGJldHdlZW4gdGVzdCBjb2RlIGFuZCBIVFRQIGhhbmRsZXJzXG4gICAqIHJ1bm5pbmcgaW4gdGhlIHNhbWUgcHJvY2VzcyAoaW4tcHJvY2VzcyB0ZXN0IHNlcnZlciBtb2RlKS5cbiAgICogQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0IHwgdW5kZWZpbmVkfVxuICAgKi9cbiAgX3Rlc3RTaGFyZWRDb25uZWN0aW9uID0gdW5kZWZpbmVkXG5cbiAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdFtdfSAqL1xuICBjb25uZWN0aW9ucyA9IFtdXG5cbiAgLyoqIEB0eXBlIHtSZWNvcmQ8bnVtYmVyLCBpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdD59ICovXG4gIGNvbm5lY3Rpb25zSW5Vc2UgPSB7fVxuXG4gIC8qKiBAdHlwZSB7UGVuZGluZ0NoZWNrb3V0W119ICovXG4gIHBlbmRpbmdDaGVja291dHMgPSBbXVxuXG4gIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICBjb25uZWN0aW9uc0JlaW5nU3Bhd25lZCA9IDBcblxuICAvKiogQHR5cGUge1Byb21pc2U8dm9pZD4gfCB1bmRlZmluZWR9ICovXG4gIHBlbmRpbmdDaGVja291dERyYWluUHJvbWlzZSA9IHVuZGVmaW5lZFxuXG4gIC8qKiBAdHlwZSB7UmV0dXJuVHlwZTx0eXBlb2Ygc2V0VGltZW91dD4gfCB1bmRlZmluZWR9ICovXG4gIGlkbGVDb25uZWN0aW9uUmVhcGVyVGltZXIgPSB1bmRlZmluZWRcblxuICAvKipcbiAgICogSW4tZmxpZ2h0IGNvbm5lY3Rpb24tY2xvc2UgcHJvbWlzZXMuIFRoZSBpZGxlIHJlYXBlciBpcyBhcm1lZCBvbiBjaGVjay1pblxuICAgKiBhbmQgcnVucyBmaXJlLWFuZC1mb3JnZXQgd2hlbiBpdHMgdGltZXIgZmlyZXMsIHNvIGEgc2NoZWR1bGVkIHJlYXAgY2FuIGJlXG4gICAqIGNsb3NpbmcgYSBjb25uZWN0aW9uIHdoaWxlIGFuIGV4cGxpY2l0IGByZWFwSWRsZUNvbm5lY3Rpb25zKClgIChvclxuICAgKiBgY2xlYXJJZGxlQ29ubmVjdGlvblJlYXBlclRpbWVyKClgKSBydW5zLiBUcmFja2luZyB0aGUgaW4tZmxpZ2h0IGNsb3NlcyBsZXRzXG4gICAqIHRob3NlIGNhbGxlcnMgYXdhaXQgdGhlbSwgc28gb25jZSBhIHJlYXAgcmVzb2x2ZXMgdGhlIGNvbm5lY3Rpb25zIGl0XG4gICAqIGV4cGlyZWQgYXJlIGZ1bGx5IGNsb3NlZCBpbnN0ZWFkIG9mIGhhbGYtY2xvc2VkIG1pZC1gY2xvc2UoKWAuXG4gICAqIEB0eXBlIHtTZXQ8UHJvbWlzZTx2b2lkPj59XG4gICAqL1xuICBpbmZsaWdodENvbm5lY3Rpb25DbG9zZXMgPSBuZXcgU2V0KClcblxuICAvKipcbiAgICogSW4tZmxpZ2h0IGNsb3NlIHByb21pc2UgcGVyIGNvbm5lY3Rpb24sIHNvIGNvbmN1cnJlbnQgY2xvc2VzIG9mIHRoZSBzYW1lXG4gICAqIGNvbm5lY3Rpb24gYXdhaXQgdGhlIHNhbWUgY2xvc2UgcmF0aGVyIHRoYW4gY2xvc2luZyB0aGUgZHJpdmVyIGhhbmRsZSB0d2ljZS5cbiAgICogQHR5cGUge1dlYWtNYXA8b2JqZWN0LCBQcm9taXNlPHZvaWQ+Pn1cbiAgICovXG4gIGNvbm5lY3Rpb25DbG9zZVByb21pc2VzID0gbmV3IFdlYWtNYXAoKVxuXG4gIGlkU2VxID0gMFxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2NvbmZpZ3VyYXRpb24uanNcIikuZGVmYXVsdH0gYXJncy5jb25maWd1cmF0aW9uIC0gQ29uZmlndXJhdGlvbiBpbnN0YW5jZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MuaWRlbnRpZmllciAtIElkZW50aWZpZXIuXG4gICAqL1xuICBjb25zdHJ1Y3Rvcih7Y29uZmlndXJhdGlvbiwgaWRlbnRpZmllcn0pIHtcbiAgICBzdXBlcih7Y29uZmlndXJhdGlvbiwgaWRlbnRpZmllcn0pXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gY29ubmVjdGlvbiAtIERhdGFiYXNlIGNvbm5lY3Rpb24gaW5zdGFuY2UuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gdGhlIGNvbm5lY3Rpb24gaXMgY2hlY2tlZCBpbiBvciBjbG9zZWQuXG4gICAqL1xuICBhc3luYyBjaGVja2luKGNvbm5lY3Rpb24pIHtcbiAgICBjb25zdCBpZCA9IGNvbm5lY3Rpb24uZ2V0SWRTZXEoKVxuICAgIGNvbnN0IHRyYWNrZWRDb25uZWN0aW9uID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCAmIHtbQ0xPU0VEX0NPTk5FQ1RJT05dPzogYm9vbGVhbiwgW0NPTk5FQ1RJT05fQ0hFQ0tFRF9PVVRfQVRdPzogbnVtYmVyLCBbSURMRV9DT05ORUNUSU9OX0NIRUNLRURfSU5fQVRdPzogbnVtYmVyfX0gKi8gKGNvbm5lY3Rpb24pXG5cbiAgICBpZiAodHJhY2tlZENvbm5lY3Rpb25bQ0xPU0VEX0NPTk5FQ1RJT05dKSB7XG4gICAgICB0aGlzLnVudHJhY2tDb25uZWN0aW9uSW5Vc2UoY29ubmVjdGlvbiwgaWQpXG4gICAgICBhd2FpdCB0aGlzLmRyYWluUGVuZGluZ0NoZWNrb3V0cygpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5yb2xsYmFja0xlZnRPcGVuVHJhbnNhY3Rpb24oY29ubmVjdGlvbilcbiAgICAgIGF3YWl0IGNvbm5lY3Rpb24uY2xlYXJDb25uZWN0aW9uQ2hlY2tvdXROYW1lKClcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgYXdhaXQgdGhpcy5jbG9zZUNoZWNrZWRPdXRDb25uZWN0aW9uQWZ0ZXJDaGVja2luRmFpbHVyZShjb25uZWN0aW9uLCBpZCwgZXJyb3IpXG4gICAgICB0aHJvdyBlcnJvclxuICAgIH1cblxuICAgIHRoaXMudW50cmFja0Nvbm5lY3Rpb25JblVzZShjb25uZWN0aW9uLCBpZClcbiAgICB0cmFja2VkQ29ubmVjdGlvbltJRExFX0NPTk5FQ1RJT05fQ0hFQ0tFRF9JTl9BVF0gPSBEYXRlLm5vdygpXG4gICAgZGVsZXRlIHRyYWNrZWRDb25uZWN0aW9uW0NPTk5FQ1RJT05fQ0hFQ0tFRF9PVVRfQVRdXG4gICAgdGhpcy5jb25uZWN0aW9ucy5wdXNoKGNvbm5lY3Rpb24pXG4gICAgYXdhaXQgdGhpcy5kcmFpblBlbmRpbmdDaGVja291dHMoKVxuICAgIGlmICh0aGlzLmNvbm5lY3Rpb25zLmluY2x1ZGVzKGNvbm5lY3Rpb24pKSBhd2FpdCB0aGlzLmhhbmRsZUNoZWNrZWRJbklkbGVDb25uZWN0aW9uKClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBjb25uZWN0aW9uIC0gQ29ubmVjdGlvbiB0aGF0IGZhaWxlZCBjaGVjay1pbiBjbGVhbnVwLlxuICAgKiBAcGFyYW0ge251bWJlciB8IHVuZGVmaW5lZH0gaWQgLSBDb25uZWN0aW9uIGNoZWNrb3V0IGlkLlxuICAgKiBAcGFyYW0ge3Vua25vd259IG9yaWdpbmFsRXJyb3IgLSBFcnJvciB0aGF0IGNhdXNlZCBjaGVjay1pbiBjbGVhbnVwIHRvIGZhaWwuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY2xlYW51cCBoYXMgYmVlbiBhdHRlbXB0ZWQuXG4gICAqL1xuICBhc3luYyBjbG9zZUNoZWNrZWRPdXRDb25uZWN0aW9uQWZ0ZXJDaGVja2luRmFpbHVyZShjb25uZWN0aW9uLCBpZCwgb3JpZ2luYWxFcnJvcikge1xuICAgIHRoaXMudW50cmFja0Nvbm5lY3Rpb25JblVzZShjb25uZWN0aW9uLCBpZClcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLmNsb3NlQ29ubmVjdGlvbihjb25uZWN0aW9uKVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLmxvZ2dlci53YXJuKFwiRmFpbGVkIHRvIGNsb3NlIGRhdGFiYXNlIGNvbm5lY3Rpb24gYWZ0ZXIgY2hlY2staW4gY2xlYW51cCBmYWlsZWRcIiwge2Vycm9yLCBvcmlnaW5hbEVycm9yfSlcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5kcmFpblBlbmRpbmdDaGVja291dHMoKVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLmxvZ2dlci53YXJuKFwiRmFpbGVkIHRvIGRyYWluIHBlbmRpbmcgZGF0YWJhc2UgY2hlY2tvdXRzIGFmdGVyIGNoZWNrLWluIGNsZWFudXAgZmFpbGVkXCIsIHtlcnJvciwgb3JpZ2luYWxFcnJvcn0pXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGNvbm5lY3Rpb24gLSBDb25uZWN0aW9uIGJlaW5nIGNoZWNrZWQgaW4uXG4gICAqIEBwYXJhbSB7bnVtYmVyIHwgdW5kZWZpbmVkfSBpZCAtIENvbm5lY3Rpb24gY2hlY2tvdXQgaWQuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgdW50cmFja0Nvbm5lY3Rpb25JblVzZShjb25uZWN0aW9uLCBpZCkge1xuICAgIGlmICh0eXBlb2YgaWQgIT09IFwibnVtYmVyXCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgaWRTZXEgb24gY29ubmVjdGlvbiB3YXNuJ3Qgc2V0PyAnJHt0eXBlb2YgaWR9JyA9ICR7aWR9YClcbiAgICB9XG5cbiAgICBkZWxldGUgdGhpcy5jb25uZWN0aW9uc0luVXNlW2lkXVxuICAgIGNvbm5lY3Rpb24uc2V0SWRTZXEodW5kZWZpbmVkKVxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIG9uY2UgaWRsZSByZWFwaW5nIGhhcyBiZWVuIHNjaGVkdWxlZCBvciBydW4uICovXG4gIGFzeW5jIGhhbmRsZUNoZWNrZWRJbklkbGVDb25uZWN0aW9uKCkge1xuICAgIGlmICh0aGlzLmlkbGVUaW1lb3V0TWlsbGlzKCkgPT09IDApIHtcbiAgICAgIGF3YWl0IHRoaXMucmVhcElkbGVDb25uZWN0aW9ucygpXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2NoZWR1bGVJZGxlQ29ubmVjdGlvblJlYXBlcigpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9iYXNlLmpzXCIpLkNvbm5lY3Rpb25DaGVja291dE9wdGlvbnN9IFtvcHRpb25zXSAtIENoZWNrb3V0IG9wdGlvbnMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBjaGVja291dC5cbiAgICovXG4gIGFzeW5jIGNoZWNrb3V0KG9wdGlvbnMgPSB7fSkge1xuICAgIGNvbnN0IGRhdGFiYXNlQ29uZmlnID0gdGhpcy5nZXRDb25maWd1cmF0aW9uKClcbiAgICBjb25zdCByZXVzZUtleSA9IHRoaXMuZ2V0Q29uZmlndXJhdGlvblJldXNlS2V5KClcbiAgICBsZXQgY29ubmVjdGlvbiA9IHRoaXMudGFrZUlkbGVDb25uZWN0aW9uRm9yUmV1c2VLZXkocmV1c2VLZXkpXG5cbiAgICBpZiAoY29ubmVjdGlvbikgcmV0dXJuIGF3YWl0IHRoaXMuYWN0aXZhdGVDb25uZWN0aW9uKGNvbm5lY3Rpb24sIG9wdGlvbnMpXG5cbiAgICBhd2FpdCB0aGlzLnJlYXBJZGxlQ29ubmVjdGlvbnMoKVxuICAgIGNvbm5lY3Rpb24gPSB0aGlzLnRha2VJZGxlQ29ubmVjdGlvbkZvclJldXNlS2V5KHJldXNlS2V5KVxuXG4gICAgaWYgKGNvbm5lY3Rpb24pIHJldHVybiBhd2FpdCB0aGlzLmFjdGl2YXRlQ29ubmVjdGlvbihjb25uZWN0aW9uLCBvcHRpb25zKVxuXG4gICAgaWYgKHRoaXMuY2FuU3Bhd25Db25uZWN0aW9uKCkpIHtcbiAgICAgIC8vIFNwYXduIHZpYSBzcGF3bkNvbm5lY3Rpb24oKSBzbyB0aGUgdGVuYW50LWF3YXJlIGNvbmZpZ3VyYXRpb24gaXMgcmVzb2x2ZWQgRlJFU0ggYXRcbiAgICAgIC8vIHNwYXduIHRpbWUgZm9yIHRoZSBjdXJyZW50IGNhbGxlci4gUmV1c2luZyB0aGUgZGF0YWJhc2VDb25maWcgY2FwdHVyZWQgYXQgdGhlIHRvcCBvZlxuICAgICAgLy8gY2hlY2tvdXQoKSBjb3VsZCBiaW5kIHRoZSBjb25uZWN0aW9uIHRvIGEgc3RhbGUgdGVuYW50L2RhdGFiYXNlLCB3aGljaCBicmVha3NcbiAgICAgIC8vIHBlci1yZXF1ZXN0IGlzb2xhdGlvbiAoZS5nLiB0ZXN0IHRydW5jYXRpb24gYXBwZWFyaW5nIG5vdCB0byB0YWtlIGVmZmVjdCkuIFRoZSBxdWV1ZWRcbiAgICAgIC8vIHBhdGggYmVsb3cga2VlcHMgdGhlIHdhaXRpbmcgY2FsbGVyJ3MgY2FwdHVyZWQgY29uZmlnIHZpYSB3YWl0Rm9yQ2hlY2tvdXQoKS5cbiAgICAgIGNvbm5lY3Rpb24gPSBhd2FpdCB0aGlzLnNwYXduQ29ubmVjdGlvbkZvckNoZWNrb3V0KHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpLCB0aGlzLmdldENvbmZpZ3VyYXRpb25SZXVzZUtleSgpKVxuXG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5hY3RpdmF0ZUNvbm5lY3Rpb24oY29ubmVjdGlvbiwgb3B0aW9ucylcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy53YWl0Rm9yQ2hlY2tvdXQoZGF0YWJhc2VDb25maWcsIHJldXNlS2V5LCBvcHRpb25zKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByZXVzZUtleSAtIERhdGFiYXNlIGNvbmZpZ3VyYXRpb24gcmV1c2Uga2V5LlxuICAgKiBAcGFyYW0ge29iamVjdH0gW2FyZ3NdIC0gT3B0aW9ucy5cbiAgICogQHBhcmFtIHtib29sZWFufSBbYXJncy5pbmNsdWRlT3BlblRyYW5zYWN0aW9uc10gLSBXaGV0aGVyIGNvbm5lY3Rpb25zIHdpdGggb3BlbiB0cmFuc2FjdGlvbnMgbWF5IGJlIHJldHVybmVkLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgfCB1bmRlZmluZWR9IC0gTWF0Y2hpbmcgaWRsZSBjb25uZWN0aW9uLlxuICAgKi9cbiAgdGFrZUlkbGVDb25uZWN0aW9uRm9yUmV1c2VLZXkocmV1c2VLZXksIHtpbmNsdWRlT3BlblRyYW5zYWN0aW9ucyA9IHRydWV9ID0ge30pIHtcbiAgICBjb25zdCBjb25uZWN0aW9uSW5kZXggPSB0aGlzLmNvbm5lY3Rpb25zLmZpbmRJbmRleCgocXVldWVkQ29ubmVjdGlvbikgPT4ge1xuICAgICAgaWYgKCFpbmNsdWRlT3BlblRyYW5zYWN0aW9ucyAmJiB0aGlzLmNvbm5lY3Rpb25IYXNPcGVuVHJhbnNhY3Rpb24ocXVldWVkQ29ubmVjdGlvbikpIHJldHVybiBmYWxzZVxuXG4gICAgICByZXR1cm4gdGhpcy5jb25uZWN0aW9uTWF0Y2hlc1JldXNlS2V5KHF1ZXVlZENvbm5lY3Rpb24sIHJldXNlS2V5KVxuICAgIH0pXG4gICAgY29uc3QgY29ubmVjdGlvbiA9IGNvbm5lY3Rpb25JbmRleCA9PT0gLTEgPyB1bmRlZmluZWQgOiB0aGlzLmNvbm5lY3Rpb25zLnNwbGljZShjb25uZWN0aW9uSW5kZXgsIDEpWzBdXG5cbiAgICByZXR1cm4gY29ubmVjdGlvblxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGNvbm5lY3Rpb24gLSBDb25uZWN0aW9uLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcmV1c2VLZXkgLSBEYXRhYmFzZSBjb25maWd1cmF0aW9uIHJldXNlIGtleS5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gV2hldGhlciB0aGUgY29ubmVjdGlvbiBtYXRjaGVzIHRoZSByZXVzZSBrZXkuXG4gICAqL1xuICBjb25uZWN0aW9uTWF0Y2hlc1JldXNlS2V5KGNvbm5lY3Rpb24sIHJldXNlS2V5KSB7XG4gICAgY29uc3QgY29ubmVjdGlvbldpdGhQb29sS2V5ID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCAmIHtbUE9PTF9DT05GSUdVUkFUSU9OX0tFWV0/OiBzdHJpbmd9fSAqLyAoY29ubmVjdGlvbilcblxuICAgIHJldHVybiBjb25uZWN0aW9uV2l0aFBvb2xLZXlbUE9PTF9DT05GSUdVUkFUSU9OX0tFWV0gPT09IHJldXNlS2V5XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gY29ubmVjdGlvbiAtIENvbm5lY3Rpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9iYXNlLmpzXCIpLkNvbm5lY3Rpb25DaGVja291dE9wdGlvbnN9IFtvcHRpb25zXSAtIENoZWNrb3V0IG9wdGlvbnMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pn0gLSBBY3RpdmF0ZWQgY29ubmVjdGlvbi5cbiAgICovXG4gIGFzeW5jIGFjdGl2YXRlQ29ubmVjdGlvbihjb25uZWN0aW9uLCBvcHRpb25zID0ge30pIHtcbiAgICBpZiAoY29ubmVjdGlvbi5nZXRJZFNlcSgpICE9PSB1bmRlZmluZWQpIHRocm93IG5ldyBFcnJvcihgQ29ubmVjdGlvbiBhbHJlYWR5IGhhcyBhbiBJRC1zZXEgLSBpcyBpdCBpbiB1c2U/ICR7Y29ubmVjdGlvbi5nZXRJZFNlcSgpfWApXG5cbiAgICBjb25zdCBpZCA9IHRoaXMuaWRTZXErK1xuXG4gICAgY29uc3QgdHJhY2tlZENvbm5lY3Rpb24gPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0ICYge1tDT05ORUNUSU9OX0NIRUNLRURfT1VUX0FUXT86IG51bWJlciwgW0lETEVfQ09OTkVDVElPTl9DSEVDS0VEX0lOX0FUXT86IG51bWJlcn19ICovIChjb25uZWN0aW9uKVxuICAgIGRlbGV0ZSB0cmFja2VkQ29ubmVjdGlvbltJRExFX0NPTk5FQ1RJT05fQ0hFQ0tFRF9JTl9BVF1cbiAgICB0cmFja2VkQ29ubmVjdGlvbltDT05ORUNUSU9OX0NIRUNLRURfT1VUX0FUXSA9IERhdGUubm93KClcblxuICAgIGNvbm5lY3Rpb24uc2V0SWRTZXEoaWQpXG4gICAgdGhpcy5jb25uZWN0aW9uc0luVXNlW2lkXSA9IGNvbm5lY3Rpb25cblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCBjb25uZWN0aW9uLnNldENvbm5lY3Rpb25DaGVja291dE5hbWUob3B0aW9ucy5uYW1lKVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBkZWxldGUgdGhpcy5jb25uZWN0aW9uc0luVXNlW2lkXVxuICAgICAgY29ubmVjdGlvbi5zZXRJZFNlcSh1bmRlZmluZWQpXG4gICAgICBhd2FpdCB0aGlzLmNsb3NlQ29ubmVjdGlvbihjb25uZWN0aW9uKVxuXG4gICAgICB0aHJvdyBlcnJvclxuICAgIH1cblxuICAgIHJldHVybiBjb25uZWN0aW9uXG4gIH1cblxuICAvKiogQHJldHVybnMge251bWJlciB8IHVuZGVmaW5lZH0gLSBDb25maWd1cmVkIG1heCBsaXZlIGNvbm5lY3Rpb25zLiAqL1xuICBtYXhDb25uZWN0aW9ucygpIHtcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpLnBvb2w/Lm1heFxuXG4gICAgaWYgKHRoaXMudmFsaWRNYXhDb25uZWN0aW9ucyh2YWx1ZSkpIHJldHVybiB2YWx1ZVxuXG4gICAgcmV0dXJuXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHt1bmtub3dufSB2YWx1ZSAtIENhbmRpZGF0ZSBtYXggY29ubmVjdGlvbiBjb3VudC5cbiAgICogQHJldHVybnMge3ZhbHVlIGlzIG51bWJlcn0gLSBXaGV0aGVyIHRoZSB2YWx1ZSBpcyBhIHZhbGlkIG1heCBjb25uZWN0aW9uIGNvdW50LlxuICAgKi9cbiAgdmFsaWRNYXhDb25uZWN0aW9ucyh2YWx1ZSkge1xuICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwibnVtYmVyXCIgJiYgTnVtYmVyLmlzRmluaXRlKHZhbHVlKSAmJiB2YWx1ZSA+PSAxXG4gIH1cblxuICAvKiogQHJldHVybnMge251bWJlcn0gLSBOdW1iZXIgb2YgbGl2ZSBhbmQgaW4tcHJvZ3Jlc3MgY29ubmVjdGlvbnMuICovXG4gIGxpdmVDb25uZWN0aW9uQ291bnQoKSB7XG4gICAgY29uc3QgY29ubmVjdGlvbnMgPSBuZXcgU2V0KFtcbiAgICAgIC4uLnRoaXMuY29ubmVjdGlvbnMsXG4gICAgICAuLi5PYmplY3QudmFsdWVzKHRoaXMuY29ubmVjdGlvbnNJblVzZSksXG4gICAgICB0aGlzLmdldEdsb2JhbENvbm5lY3Rpb25Gb3JJZGVudGlmaWVyKClcbiAgICBdLmZpbHRlcihCb29sZWFuKSlcblxuICAgIHJldHVybiBjb25uZWN0aW9ucy5zaXplICsgdGhpcy5jb25uZWN0aW9uc0JlaW5nU3Bhd25lZFxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgYSBuZXcgY29ubmVjdGlvbiBjYW4gYmUgc3Bhd25lZC4gKi9cbiAgY2FuU3Bhd25Db25uZWN0aW9uKCkge1xuICAgIGNvbnN0IG1heENvbm5lY3Rpb25zID0gdGhpcy5tYXhDb25uZWN0aW9ucygpXG5cbiAgICByZXR1cm4gbWF4Q29ubmVjdGlvbnMgPT09IHVuZGVmaW5lZCB8fCB0aGlzLmxpdmVDb25uZWN0aW9uQ291bnQoKSA8IG1heENvbm5lY3Rpb25zXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLkRhdGFiYXNlQ29uZmlndXJhdGlvblR5cGV9IGRhdGFiYXNlQ29uZmlnIC0gUmVzb2x2ZWQgZGF0YWJhc2UgY29uZmlnIGZvciB0aGUgY2hlY2tvdXQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByZXVzZUtleSAtIERhdGFiYXNlIGNvbmZpZ3VyYXRpb24gcmV1c2Uga2V5IGZvciB0aGUgY2hlY2tvdXQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pn0gLSBTcGF3bmVkIGNvbm5lY3Rpb24uXG4gICAqL1xuICBhc3luYyBzcGF3bkNvbm5lY3Rpb25Gb3JDaGVja291dChkYXRhYmFzZUNvbmZpZywgcmV1c2VLZXkpIHtcbiAgICB0aGlzLmNvbm5lY3Rpb25zQmVpbmdTcGF3bmVkKytcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBjb25uZWN0aW9uID0gYXdhaXQgdGhpcy5zcGF3bkNvbm5lY3Rpb25XaXRoQ29uZmlndXJhdGlvbihkYXRhYmFzZUNvbmZpZylcbiAgICAgIGNvbnN0IGNvbm5lY3Rpb25XaXRoUG9vbEtleSA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgJiB7W1BPT0xfQ09ORklHVVJBVElPTl9LRVldPzogc3RyaW5nfX0gKi8gKGNvbm5lY3Rpb24pXG5cbiAgICAgIGNvbm5lY3Rpb25XaXRoUG9vbEtleVtQT09MX0NPTkZJR1VSQVRJT05fS0VZXSA9IHJldXNlS2V5XG4gICAgICBjb25uZWN0aW9uLnNldFNjaGVtYUNhY2hlSW52YWxpZGF0b3IoKCkgPT4ge1xuICAgICAgICB0aGlzLmNsZWFyU2NoZW1hQ2FjaGUoKVxuICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24uY2xlYXJTY2hlbWFDYWNoZXNGb3JSZXVzZUtleShyZXVzZUtleSlcbiAgICAgIH0pXG5cbiAgICAgIHJldHVybiBjb25uZWN0aW9uXG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuY29ubmVjdGlvbnNCZWluZ1NwYXduZWQtLVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2NvbmZpZ3VyYXRpb24tdHlwZXMuanNcIikuRGF0YWJhc2VDb25maWd1cmF0aW9uVHlwZX0gZGF0YWJhc2VDb25maWcgLSBSZXNvbHZlZCBkYXRhYmFzZSBjb25maWcgZm9yIHRoZSBjaGVja291dC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHJldXNlS2V5IC0gRGF0YWJhc2UgY29uZmlndXJhdGlvbiByZXVzZSBrZXkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9iYXNlLmpzXCIpLkNvbm5lY3Rpb25DaGVja291dE9wdGlvbnN9IFtvcHRpb25zXSAtIENoZWNrb3V0IG9wdGlvbnMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pn0gLSBSZXNvbHZlcyB3aXRoIGFuIGFjdGl2YXRlZCBjb25uZWN0aW9uLlxuICAgKi9cbiAgYXN5bmMgd2FpdEZvckNoZWNrb3V0KGRhdGFiYXNlQ29uZmlnLCByZXVzZUtleSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMucGVuZGluZ0NoZWNrb3V0cy5wdXNoKHtkYXRhYmFzZUNvbmZpZywgZW5xdWV1ZWRBdDogRGF0ZS5ub3coKSwgb3B0aW9ucywgcmVqZWN0LCByZXNvbHZlLCByZXVzZUtleX0pXG4gICAgICB2b2lkIHRoaXMuZHJhaW5QZW5kaW5nQ2hlY2tvdXRzKCkuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgIGNvbnN0IGNoZWNrb3V0RXJyb3IgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiBuZXcgRXJyb3IoXCJGYWlsZWQgdG8gZHJhaW4gcGVuZGluZyBkYXRhYmFzZSBjb25uZWN0aW9uIGNoZWNrb3V0cy5cIiwge2NhdXNlOiBlcnJvcn0pXG5cbiAgICAgICAgdGhpcy5yZWplY3RQZW5kaW5nQ2hlY2tvdXRzKGNoZWNrb3V0RXJyb3IpXG4gICAgICB9KVxuICAgIH0pXG4gIH1cblxuICAvKiogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBwZW5kaW5nIGNoZWNrb3V0cyBoYXZlIGJlZW4gZHJhaW5lZCBhcyBmYXIgYXMgcG9zc2libGUuICovXG4gIGFzeW5jIGRyYWluUGVuZGluZ0NoZWNrb3V0cygpIHtcbiAgICBpZiAodGhpcy5wZW5kaW5nQ2hlY2tvdXREcmFpblByb21pc2UpIHtcbiAgICAgIGF3YWl0IHRoaXMucGVuZGluZ0NoZWNrb3V0RHJhaW5Qcm9taXNlXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB0aGlzLnBlbmRpbmdDaGVja291dERyYWluUHJvbWlzZSA9IHRoaXMuZHJhaW5QZW5kaW5nQ2hlY2tvdXRzQWN0dWFsKClcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLnBlbmRpbmdDaGVja291dERyYWluUHJvbWlzZVxuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLnBlbmRpbmdDaGVja291dERyYWluUHJvbWlzZSA9IHVuZGVmaW5lZFxuICAgIH1cbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIHBlbmRpbmcgY2hlY2tvdXRzIGhhdmUgYmVlbiBkcmFpbmVkIGFzIGZhciBhcyBwb3NzaWJsZS4gKi9cbiAgYXN5bmMgZHJhaW5QZW5kaW5nQ2hlY2tvdXRzQWN0dWFsKCkge1xuICAgIHdoaWxlICh0aGlzLnBlbmRpbmdDaGVja291dHMubGVuZ3RoID4gMCkge1xuICAgICAgaWYgKGF3YWl0IHRoaXMucmVzb2x2ZVBlbmRpbmdDaGVja291dFdpdGhNYXRjaGluZ0lkbGVDb25uZWN0aW9uKCkpIGNvbnRpbnVlXG5cbiAgICAgIGNvbnN0IGNoZWNrb3V0ID0gdGhpcy5wZW5kaW5nQ2hlY2tvdXRzWzBdXG5cbiAgICAgIGlmIChhd2FpdCB0aGlzLmNsb3NlSWRsZUNvbm5lY3Rpb25Gb3JQZW5kaW5nQ2hlY2tvdXRDYXBhY2l0eShjaGVja291dCkpIGNvbnRpbnVlXG4gICAgICBpZiAodGhpcy5jYW5TcGF3bkNvbm5lY3Rpb24oKSkge1xuICAgICAgICB0aGlzLnBlbmRpbmdDaGVja291dHMuc2hpZnQoKVxuICAgICAgICBhd2FpdCB0aGlzLnNwYXduQW5kUmVzb2x2ZVBlbmRpbmdDaGVja291dChjaGVja291dClcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVhcGVkQ29ubmVjdGlvbiA9IGF3YWl0IHRoaXMuaWRsZUNvbm5lY3Rpb25Gb3JQZW5kaW5nQ2hlY2tvdXQoY2hlY2tvdXQpXG5cbiAgICAgIGlmICghcmVhcGVkQ29ubmVjdGlvbikgcmV0dXJuXG5cbiAgICAgIHRoaXMucGVuZGluZ0NoZWNrb3V0cy5zaGlmdCgpXG4gICAgICBhd2FpdCB0aGlzLnJlc29sdmVQZW5kaW5nQ2hlY2tvdXQoY2hlY2tvdXQsIHJlYXBlZENvbm5lY3Rpb24pXG4gICAgfVxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtQcm9taXNlPGJvb2xlYW4+fSAtIFdoZXRoZXIgYSBwZW5kaW5nIGNoZWNrb3V0IHdhcyByZXNvbHZlZCB3aXRoIGFuIGlkbGUgY29ubmVjdGlvbi4gKi9cbiAgYXN5bmMgcmVzb2x2ZVBlbmRpbmdDaGVja291dFdpdGhNYXRjaGluZ0lkbGVDb25uZWN0aW9uKCkge1xuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCB0aGlzLnBlbmRpbmdDaGVja291dHMubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICBjb25zdCBjaGVja291dCA9IHRoaXMucGVuZGluZ0NoZWNrb3V0c1tpbmRleF1cbiAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSB0aGlzLnRha2VJZGxlQ29ubmVjdGlvbkZvclJldXNlS2V5KGNoZWNrb3V0LnJldXNlS2V5LCB7aW5jbHVkZU9wZW5UcmFuc2FjdGlvbnM6IGZhbHNlfSlcblxuICAgICAgaWYgKCFjb25uZWN0aW9uKSBjb250aW51ZVxuXG4gICAgICB0aGlzLnBlbmRpbmdDaGVja291dHMuc3BsaWNlKGluZGV4LCAxKVxuICAgICAgYXdhaXQgdGhpcy5yZXNvbHZlUGVuZGluZ0NoZWNrb3V0KGNoZWNrb3V0LCBjb25uZWN0aW9uKVxuXG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7UGVuZGluZ0NoZWNrb3V0fSBjaGVja291dCAtIENoZWNrb3V0IHdhaXRpbmcgZm9yIGEgY29ubmVjdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8Ym9vbGVhbj59IC0gV2hldGhlciBhbiBpZGxlIGNvbm5lY3Rpb24gd2FzIGNsb3NlZCB0byBmcmVlIGNhcGFjaXR5LlxuICAgKi9cbiAgYXN5bmMgY2xvc2VJZGxlQ29ubmVjdGlvbkZvclBlbmRpbmdDaGVja291dENhcGFjaXR5KGNoZWNrb3V0KSB7XG4gICAgY29uc3QgY29ubmVjdGlvbiA9IHRoaXMuZmluZElkbGVDb25uZWN0aW9uRm9yUmV1c2VLZXkoY2hlY2tvdXQucmV1c2VLZXkpXG5cbiAgICBpZiAoY29ubmVjdGlvbikgcmV0dXJuIGZhbHNlXG5cbiAgICBhd2FpdCB0aGlzLnJlYXBJZGxlQ29ubmVjdGlvbnMoKVxuXG4gICAgaWYgKHRoaXMuZmluZElkbGVDb25uZWN0aW9uRm9yUmV1c2VLZXkoY2hlY2tvdXQucmV1c2VLZXkpKSByZXR1cm4gZmFsc2VcblxuICAgIHJldHVybiB0aGlzLmNhblNwYXduQ29ubmVjdGlvbigpID8gZmFsc2UgOiBhd2FpdCB0aGlzLmNsb3NlT25lSWRsZUNvbm5lY3Rpb25Gb3JDYXBhY2l0eSgpXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IHJldXNlS2V5IC0gRGF0YWJhc2UgY29uZmlndXJhdGlvbiByZXVzZSBrZXkuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCB8IHVuZGVmaW5lZH0gLSBNYXRjaGluZyBpZGxlIGNvbm5lY3Rpb24sIGlmIHByZXNlbnQuXG4gICAqL1xuICBmaW5kSWRsZUNvbm5lY3Rpb25Gb3JSZXVzZUtleShyZXVzZUtleSkge1xuICAgIHJldHVybiB0aGlzLmNvbm5lY3Rpb25zLmZpbmQoKGNvbm5lY3Rpb24pID0+ICF0aGlzLmNvbm5lY3Rpb25IYXNPcGVuVHJhbnNhY3Rpb24oY29ubmVjdGlvbikgJiYgdGhpcy5jb25uZWN0aW9uTWF0Y2hlc1JldXNlS2V5KGNvbm5lY3Rpb24sIHJldXNlS2V5KSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1BlbmRpbmdDaGVja291dH0gY2hlY2tvdXQgLSBDaGVja291dCB3YWl0aW5nIGZvciBhIGNvbm5lY3Rpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0IHwgdW5kZWZpbmVkPn0gLSBNYXRjaGluZyBpZGxlIGNvbm5lY3Rpb24sIGlmIG9uZSBjYW4gYmUgcmV1c2VkLlxuICAgKi9cbiAgYXN5bmMgaWRsZUNvbm5lY3Rpb25Gb3JQZW5kaW5nQ2hlY2tvdXQoY2hlY2tvdXQpIHtcbiAgICBsZXQgY29ubmVjdGlvbiA9IHRoaXMudGFrZUlkbGVDb25uZWN0aW9uRm9yUmV1c2VLZXkoY2hlY2tvdXQucmV1c2VLZXksIHtpbmNsdWRlT3BlblRyYW5zYWN0aW9uczogZmFsc2V9KVxuXG4gICAgaWYgKGNvbm5lY3Rpb24pIHJldHVybiBjb25uZWN0aW9uXG5cbiAgICBhd2FpdCB0aGlzLnJlYXBJZGxlQ29ubmVjdGlvbnMoKVxuICAgIGNvbm5lY3Rpb24gPSB0aGlzLnRha2VJZGxlQ29ubmVjdGlvbkZvclJldXNlS2V5KGNoZWNrb3V0LnJldXNlS2V5LCB7aW5jbHVkZU9wZW5UcmFuc2FjdGlvbnM6IGZhbHNlfSlcblxuICAgIHJldHVybiBjb25uZWN0aW9uXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtQZW5kaW5nQ2hlY2tvdXR9IGNoZWNrb3V0IC0gQ2hlY2tvdXQgcmVxdWVzdCB0byByZXNvbHZlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIHRoZSBjaGVja291dCBoYXMgYmVlbiBoYW5kbGVkLlxuICAgKi9cbiAgYXN5bmMgc3Bhd25BbmRSZXNvbHZlUGVuZGluZ0NoZWNrb3V0KGNoZWNrb3V0KSB7XG4gICAgbGV0IGNvbm5lY3Rpb25cblxuICAgIHRyeSB7XG4gICAgICBjb25uZWN0aW9uID0gYXdhaXQgdGhpcy5zcGF3bkNvbm5lY3Rpb25Gb3JDaGVja291dChjaGVja291dC5kYXRhYmFzZUNvbmZpZywgY2hlY2tvdXQucmV1c2VLZXkpXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNoZWNrb3V0LnJlamVjdChlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiBuZXcgRXJyb3IoXCJGYWlsZWQgdG8gc3Bhd24gZGF0YWJhc2UgY29ubmVjdGlvbi5cIiwge2NhdXNlOiBlcnJvcn0pKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5yZXNvbHZlUGVuZGluZ0NoZWNrb3V0KGNoZWNrb3V0LCBjb25uZWN0aW9uKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7UGVuZGluZ0NoZWNrb3V0fSBjaGVja291dCAtIENoZWNrb3V0IHJlcXVlc3QgdG8gcmVzb2x2ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gY29ubmVjdGlvbiAtIENvbm5lY3Rpb24gdG8gYWN0aXZhdGUuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gdGhlIGNoZWNrb3V0IGhhcyBiZWVuIGhhbmRsZWQuXG4gICAqL1xuICBhc3luYyByZXNvbHZlUGVuZGluZ0NoZWNrb3V0KGNoZWNrb3V0LCBjb25uZWN0aW9uKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNoZWNrb3V0LnJlc29sdmUoYXdhaXQgdGhpcy5hY3RpdmF0ZUNvbm5lY3Rpb24oY29ubmVjdGlvbiwgY2hlY2tvdXQub3B0aW9ucykpXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNoZWNrb3V0LnJlamVjdChlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiBuZXcgRXJyb3IoXCJGYWlsZWQgdG8gYWN0aXZhdGUgZGF0YWJhc2UgY29ubmVjdGlvbi5cIiwge2NhdXNlOiBlcnJvcn0pKVxuICAgIH1cbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn0gLSBXaGV0aGVyIGFuIGlkbGUgY29ubmVjdGlvbiB3YXMgY2xvc2VkIHRvIGZyZWUgY2FwYWNpdHkuICovXG4gIGFzeW5jIGNsb3NlT25lSWRsZUNvbm5lY3Rpb25Gb3JDYXBhY2l0eSgpIHtcbiAgICBjb25zdCBjb25uZWN0aW9uID0gdGhpcy5jb25uZWN0aW9ucy5maW5kKChjYW5kaWRhdGUpID0+ICF0aGlzLmNvbm5lY3Rpb25IYXNPcGVuVHJhbnNhY3Rpb24oY2FuZGlkYXRlKSlcblxuICAgIGlmICghY29ubmVjdGlvbikgcmV0dXJuIGZhbHNlXG5cbiAgICB0aGlzLmNvbm5lY3Rpb25zID0gdGhpcy5jb25uZWN0aW9ucy5maWx0ZXIoKGNhbmRpZGF0ZSkgPT4gY2FuZGlkYXRlICE9PSBjb25uZWN0aW9uKVxuICAgIGF3YWl0IHRoaXMuY2xvc2VDb25uZWN0aW9uKGNvbm5lY3Rpb24pXG5cbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgLyoqXG4gICAqIEB0ZW1wbGF0ZSBUXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9iYXNlLmpzXCIpLkNvbm5lY3Rpb25DaGVja291dE9wdGlvbnMgfCBmdW5jdGlvbihpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCkgOiBQcm9taXNlPFQ+fSBvcHRpb25zT3JDYWxsYmFjayAtIENoZWNrb3V0IG9wdGlvbnMgb3IgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggdGhlIGNvbm5lY3Rpb24uXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQpIDogUHJvbWlzZTxUPn0gW2NhbGxiYWNrXSAtIENhbGxiYWNrIHRvIGludm9rZSB3aXRoIHRoZSBjb25uZWN0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxUPn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBjYWxsYmFjayByZXN1bHQuXG4gICAqL1xuICBhc3luYyB3aXRoQ29ubmVjdGlvbihvcHRpb25zT3JDYWxsYmFjaywgY2FsbGJhY2spIHtcbiAgICBjb25zdCBvcHRpb25zID0gdHlwZW9mIG9wdGlvbnNPckNhbGxiYWNrID09IFwiZnVuY3Rpb25cIiA/IHt9IDogb3B0aW9uc09yQ2FsbGJhY2tcbiAgICBjb25zdCBhY3R1YWxDYWxsYmFjayA9IHR5cGVvZiBvcHRpb25zT3JDYWxsYmFjayA9PSBcImZ1bmN0aW9uXCIgPyBvcHRpb25zT3JDYWxsYmFjayA6IGNhbGxiYWNrXG5cbiAgICBpZiAoIWFjdHVhbENhbGxiYWNrKSB0aHJvdyBuZXcgRXJyb3IoXCJ3aXRoQ29ubmVjdGlvbiByZXF1aXJlcyBhIGNhbGxiYWNrXCIpXG5cbiAgICBjb25zdCBjb25uZWN0aW9uID0gYXdhaXQgdGhpcy5jaGVja291dChvcHRpb25zKVxuICAgIGNvbnN0IGlkID0gY29ubmVjdGlvbi5nZXRJZFNlcSgpXG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5hc3luY0xvY2FsU3RvcmFnZS5ydW4oaWQsIGFzeW5jICgpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBhd2FpdCBhY3R1YWxDYWxsYmFjayhjb25uZWN0aW9uKVxuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5jaGVja2luKGNvbm5lY3Rpb24pXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IC0gVGhlIGN1cnJlbnQgY29ubmVjdGlvbi4gICovXG4gIGdldEN1cnJlbnRDb25uZWN0aW9uKCkge1xuICAgIGNvbnN0IGlkID0gdGhpcy5hc3luY0xvY2FsU3RvcmFnZS5nZXRTdG9yZSgpXG5cbiAgICBpZiAoaWQgPT09IHVuZGVmaW5lZCkgcmV0dXJuIHRoaXMuY3VycmVudEZhbGxiYWNrQ29ubmVjdGlvbk9yRmFpbCgpXG5cbiAgICB0aGlzLmVuc3VyZUNvbm5lY3Rpb25Jc0luVXNlKGlkKVxuXG4gICAgY29uc3QgY3VycmVudENvbm5lY3Rpb24gPSB0aGlzLmNvbm5lY3Rpb25zSW5Vc2VbaWRdXG5cbiAgICBpZiAoIWN1cnJlbnRDb25uZWN0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENvdWxkbid0IGdldCBjdXJyZW50IGNvbm5lY3Rpb24gZnJvbSB0aGF0IElEOiAke2lkfWApXG4gICAgfVxuXG4gICAgcmV0dXJuIGN1cnJlbnRDb25uZWN0aW9uXG4gIH1cblxuICAvKiogQHJldHVybnMge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSAtIEZhbGxiYWNrIGNvbm5lY3Rpb24sIGlmIHByZXNlbnQuICovXG4gIGN1cnJlbnRGYWxsYmFja0Nvbm5lY3Rpb25PckZhaWwoKSB7XG4gICAgY29uc3QgZmFsbGJhY2tDb25uZWN0aW9uID0gdGhpcy5nZXRHbG9iYWxDb25uZWN0aW9uKClcblxuICAgIGlmIChmYWxsYmFja0Nvbm5lY3Rpb24pIHJldHVybiBmYWxsYmFja0Nvbm5lY3Rpb25cblxuICAgIHRocm93IG5ldyBFcnJvcihcIklEIGhhc24ndCBiZWVuIHNldCBmb3IgdGhpcyBhc3luYyBjb250ZXh0XCIpXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IGlkIC0gQ2hlY2tlZC1vdXQgY29ubmVjdGlvbiBpZC5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBlbnN1cmVDb25uZWN0aW9uSXNJblVzZShpZCkge1xuICAgIGlmICghKGlkIGluIHRoaXMuY29ubmVjdGlvbnNJblVzZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQ29ubmVjdGlvbiAke2lkfSBkb2Vzbid0IGV4aXN0IGFueSBtb3JlIC0gaGFzIGl0IGJlZW4gY2hlY2tlZCBpbiBhZ2Fpbj9gKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlcnMgYSBmYWxsYmFjayBjb25uZWN0aW9uIGZvciB0aGlzIHBvb2wgaWRlbnRpZmllciB0aGF0IHdpbGwgYmUgdXNlZCB3aGVuIG5vIGFzeW5jIGNvbnRleHQgaXMgYXZhaWxhYmxlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBjb25uZWN0aW9uIC0gQ29ubmVjdGlvbi5cbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgc2V0R2xvYmFsQ29ubmVjdGlvbihjb25uZWN0aW9uKSB7XG4gICAgY29uc3Qga2xhc3MgPSAvKiogQHR5cGUge3R5cGVvZiBWZWxvY2lvdXNEYXRhYmFzZVBvb2xBc3luY1RyYWNrZWRNdWx0aUNvbm5lY3Rpb259ICovICh0aGlzLmNvbnN0cnVjdG9yKVxuICAgIGxldCBtYXBGb3JDb25maWd1cmF0aW9uID0ga2xhc3MuZ2xvYmFsQ29ubmVjdGlvbnMuZ2V0KHRoaXMuY29uZmlndXJhdGlvbilcblxuICAgIGlmICghbWFwRm9yQ29uZmlndXJhdGlvbikge1xuICAgICAgbWFwRm9yQ29uZmlndXJhdGlvbiA9IHt9XG4gICAgICBrbGFzcy5nbG9iYWxDb25uZWN0aW9ucy5zZXQodGhpcy5jb25maWd1cmF0aW9uLCBtYXBGb3JDb25maWd1cmF0aW9uKVxuICAgIH1cblxuICAgIG1hcEZvckNvbmZpZ3VyYXRpb25bdGhpcy5pZGVudGlmaWVyXSA9IGNvbm5lY3Rpb25cbiAgfVxuXG4gIC8qKlxuICAgKiBFbnN1cmVzIGEgZ2xvYmFsIGZhbGxiYWNrIGNvbm5lY3Rpb24gZXhpc3RzIGZvciB0aGlzIHBvb2wgaWRlbnRpZmllciBhbmQgcmV0dXJucyBpdC5cbiAgICogSWYgb25lIGlzIGFscmVhZHkgc2V0LCBpdCBpcyByZXR1cm5lZCBhbmQgYWxzbyBtYWRlIGF2YWlsYWJsZSBpbiB0aGUgcG9vbCBxdWV1ZS5cbiAgICogT3RoZXJ3aXNlIGEgbmV3IGNvbm5lY3Rpb24gaXMgc3Bhd25lZCwgcmVnaXN0ZXJlZCwgYW5kIHF1ZXVlZC5cbiAgICogQHJldHVybnMge1Byb21pc2U8aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQ+fSAtIFJlc29sdmVzIHdpdGggdGhlIGdsb2JhbCBjb25uZWN0aW9uLlxuICAgKi9cbiAgYXN5bmMgZW5zdXJlR2xvYmFsQ29ubmVjdGlvbigpIHtcbiAgICBjb25zdCBleGlzdGluZyA9IHRoaXMuZ2V0R2xvYmFsQ29ubmVjdGlvbigpXG5cbiAgICBpZiAoZXhpc3RpbmcpIHJldHVybiBleGlzdGluZ1xuXG4gICAgY29uc3QgY29ubmVjdGlvbiA9IGF3YWl0IHRoaXMuc3Bhd25Db25uZWN0aW9uKClcblxuICAgIHRoaXMuc2V0R2xvYmFsQ29ubmVjdGlvbihjb25uZWN0aW9uKVxuXG4gICAgcmV0dXJuIGNvbm5lY3Rpb25cbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgYSBzaGFyZWQgY29ubmVjdGlvbiBmb3IgdGVzdCBtb2RlIHNvIHRoYXQgSFRUUCBoYW5kbGVycyBydW5uaW5nXG4gICAqIGluIHRoZSBzYW1lIHByb2Nlc3MgY2FuIHJldXNlIHRoZSB0ZXN0IHJ1bm5lcidzIGRhdGFiYXNlIGNvbm5lY3Rpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGNvbm5lY3Rpb24gLSBTaGFyZWQgY29ubmVjdGlvbi5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBzZXRUZXN0U2hhcmVkQ29ubmVjdGlvbihjb25uZWN0aW9uKSB7XG4gICAgdGhpcy5fdGVzdFNoYXJlZENvbm5lY3Rpb24gPSBjb25uZWN0aW9uXG4gIH1cblxuICAvKiogQHJldHVybnMge3ZvaWR9ICovXG4gIGNsZWFyVGVzdFNoYXJlZENvbm5lY3Rpb24oKSB7XG4gICAgdGhpcy5fdGVzdFNoYXJlZENvbm5lY3Rpb24gPSB1bmRlZmluZWRcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBjb25uZWN0aW9uIHRpZWQgdG8gdGhlIGN1cnJlbnQgYXN5bmMgY29udGV4dCwgaWYgYW55LlxuICAgKiBGYWxscyBiYWNrIHRvIHRoZSB0ZXN0IHNoYXJlZCBjb25uZWN0aW9uIHdoZW4gbm8gYXN5bmMgY29udGV4dCBleGlzdHMuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCB8IHVuZGVmaW5lZH0gLSBUaGUgY3VycmVudCBjb250ZXh0IGNvbm5lY3Rpb24uXG4gICAqL1xuICBnZXRDdXJyZW50Q29udGV4dENvbm5lY3Rpb24oKSB7XG4gICAgY29uc3QgaWQgPSB0aGlzLmFzeW5jTG9jYWxTdG9yYWdlLmdldFN0b3JlKClcblxuICAgIGlmIChpZCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gdGhpcy5fdGVzdFNoYXJlZENvbm5lY3Rpb25cblxuICAgIHJldHVybiB0aGlzLmdldEN1cnJlbnRDb25uZWN0aW9uKClcbiAgfVxuXG4gIC8qKlxuICAgKiBAdGVtcGxhdGUgVFxuICAgKiBAcGFyYW0geygpID0+IFR9IGNhbGxiYWNrIC0gQ2FsbGJhY2sgdG8gcnVuIHdpdGhvdXQgdGhlIGN1cnJlbnQgYXN5bmMgREIgY29ubmVjdGlvbiBjb250ZXh0LlxuICAgKiBAcmV0dXJucyB7VH0gLSBDYWxsYmFjayByZXN1bHQuXG4gICAqL1xuICBfd2l0aG91dEN1cnJlbnRDb25uZWN0aW9uQ29udGV4dCA9IChjYWxsYmFjaykgPT4ge1xuICAgIHJldHVybiB0aGlzLmFzeW5jTG9jYWxTdG9yYWdlLnJ1bih1bmRlZmluZWQsIGNhbGxiYWNrKVxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtpbXBvcnQoXCIuL2Jhc2UuanNcIikuRGF0YWJhc2VQb29sRGVidWdTbmFwc2hvdH0gLSBEaWFnbm9zdGljIHNuYXBzaG90IGZvciB0aGlzIHBvb2wuICovXG4gIGdldERlYnVnU25hcHNob3QoKSB7XG4gICAgY29uc3Qgc25hcHNob3QgPSBzdXBlci5nZXREZWJ1Z1NuYXBzaG90KClcbiAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpXG4gICAgY29uc3Qge2Nvbm5lY3Rpb25zfSA9IHRoaXMuZGVidWdDb25uZWN0aW9uU25hcHNob3RzKG5vdylcblxuICAgIHJldHVybiB7XG4gICAgICAuLi5zbmFwc2hvdCxcbiAgICAgIGNvbm5lY3Rpb25zLFxuICAgICAgY29ubmVjdGlvbnNCZWluZ1NwYXduZWQ6IHRoaXMuY29ubmVjdGlvbnNCZWluZ1NwYXduZWQsXG4gICAgICBpZGxlQ291bnQ6IHRoaXMuY29ubmVjdGlvbnMubGVuZ3RoLFxuICAgICAgaW5Vc2VDb3VudDogT2JqZWN0LmtleXModGhpcy5jb25uZWN0aW9uc0luVXNlKS5sZW5ndGgsXG4gICAgICBwZW5kaW5nQ2hlY2tvdXRzOiB0aGlzLnBlbmRpbmdDaGVja291dERlYnVnU25hcHNob3RzKG5vdyksXG4gICAgICBwZW5kaW5nQ2hlY2tvdXRDb3VudDogdGhpcy5wZW5kaW5nQ2hlY2tvdXRzLmxlbmd0aFxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gbm93IC0gQ3VycmVudCB0aW1lc3RhbXAuXG4gICAqIEByZXR1cm5zIHt7Y29ubmVjdGlvbnM6IEFycmF5PFJlY29yZDxzdHJpbmcsIHVua25vd24+Piwgc2VlbkNvbm5lY3Rpb25zOiBTZXQ8aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQ+fX0gLSBDb25uZWN0aW9uIHNuYXBzaG90cyBhbmQgc2VlbiBzZXQuXG4gICAqL1xuICBkZWJ1Z0Nvbm5lY3Rpb25TbmFwc2hvdHMobm93KSB7XG4gICAgLyoqIEB0eXBlIHtBcnJheTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj59ICovXG4gICAgY29uc3QgY29ubmVjdGlvbnMgPSBbXVxuICAgIGNvbnN0IHNlZW5Db25uZWN0aW9ucyA9IG5ldyBTZXQoKVxuXG4gICAgdGhpcy5hZGRJblVzZURlYnVnQ29ubmVjdGlvblNuYXBzaG90cyh7Y29ubmVjdGlvbnMsIG5vdywgc2VlbkNvbm5lY3Rpb25zfSlcbiAgICB0aGlzLmFkZElkbGVEZWJ1Z0Nvbm5lY3Rpb25TbmFwc2hvdHMoe2Nvbm5lY3Rpb25zLCBub3csIHNlZW5Db25uZWN0aW9uc30pXG4gICAgdGhpcy5hZGRGYWxsYmFja0RlYnVnQ29ubmVjdGlvblNuYXBzaG90cyh7Y29ubmVjdGlvbnMsIHNlZW5Db25uZWN0aW9uc30pXG5cbiAgICByZXR1cm4ge2Nvbm5lY3Rpb25zLCBzZWVuQ29ubmVjdGlvbnN9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHt7Y29ubmVjdGlvbnM6IEFycmF5PFJlY29yZDxzdHJpbmcsIHVua25vd24+Piwgbm93OiBudW1iZXIsIHNlZW5Db25uZWN0aW9uczogU2V0PGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pn19IGFyZ3MgLSBTbmFwc2hvdCBjb2xsZWN0aW9uIHN0YXRlLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGFkZEluVXNlRGVidWdDb25uZWN0aW9uU25hcHNob3RzKHtjb25uZWN0aW9ucywgbm93LCBzZWVuQ29ubmVjdGlvbnN9KSB7XG4gICAgZm9yIChjb25zdCBbaWQsIGNvbm5lY3Rpb25dIG9mIE9iamVjdC5lbnRyaWVzKHRoaXMuY29ubmVjdGlvbnNJblVzZSkpIHtcbiAgICAgIGNvbnN0IHRyYWNrZWRDb25uZWN0aW9uID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCAmIHtbQ09OTkVDVElPTl9DSEVDS0VEX09VVF9BVF0/OiBudW1iZXJ9fSAqLyAoY29ubmVjdGlvbilcbiAgICAgIGNvbnN0IGNoZWNrZWRPdXRBdCA9IHRyYWNrZWRDb25uZWN0aW9uW0NPTk5FQ1RJT05fQ0hFQ0tFRF9PVVRfQVRdXG4gICAgICBjb25zdCBjaGVja2VkT3V0Rm9yTXMgPSB0eXBlb2YgY2hlY2tlZE91dEF0ID09PSBcIm51bWJlclwiID8gTWF0aC5tYXgoMCwgbm93IC0gY2hlY2tlZE91dEF0KSA6IHVuZGVmaW5lZFxuXG4gICAgICBzZWVuQ29ubmVjdGlvbnMuYWRkKGNvbm5lY3Rpb24pXG4gICAgICBjb25uZWN0aW9ucy5wdXNoKHRoaXMuZGVidWdDb25uZWN0aW9uU25hcHNob3QoY29ubmVjdGlvbiwge2NoZWNrZWRPdXRBdCwgY2hlY2tlZE91dEZvck1zLCBjaGVja291dElkOiBpZCwgc3RhdGU6IFwiaW4tdXNlXCJ9KSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHt7Y29ubmVjdGlvbnM6IEFycmF5PFJlY29yZDxzdHJpbmcsIHVua25vd24+Piwgbm93OiBudW1iZXIsIHNlZW5Db25uZWN0aW9uczogU2V0PGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pn19IGFyZ3MgLSBTbmFwc2hvdCBjb2xsZWN0aW9uIHN0YXRlLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGFkZElkbGVEZWJ1Z0Nvbm5lY3Rpb25TbmFwc2hvdHMoe2Nvbm5lY3Rpb25zLCBub3csIHNlZW5Db25uZWN0aW9uc30pIHtcbiAgICBmb3IgKGNvbnN0IGNvbm5lY3Rpb24gb2YgdGhpcy5jb25uZWN0aW9ucykge1xuICAgICAgaWYgKHNlZW5Db25uZWN0aW9ucy5oYXMoY29ubmVjdGlvbikpIGNvbnRpbnVlXG5cbiAgICAgIHNlZW5Db25uZWN0aW9ucy5hZGQoY29ubmVjdGlvbilcblxuICAgICAgY29uc3QgdHJhY2tlZENvbm5lY3Rpb24gPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0ICYge1tJRExFX0NPTk5FQ1RJT05fQ0hFQ0tFRF9JTl9BVF0/OiBudW1iZXJ9fSAqLyAoY29ubmVjdGlvbilcbiAgICAgIGNvbnN0IGNoZWNrZWRJbkF0ID0gdHJhY2tlZENvbm5lY3Rpb25bSURMRV9DT05ORUNUSU9OX0NIRUNLRURfSU5fQVRdXG4gICAgICBjb25zdCBpZGxlRm9yTXMgPSB0eXBlb2YgY2hlY2tlZEluQXQgPT09IFwibnVtYmVyXCIgPyBNYXRoLm1heCgwLCBub3cgLSBjaGVja2VkSW5BdCkgOiB1bmRlZmluZWRcblxuICAgICAgY29ubmVjdGlvbnMucHVzaCh0aGlzLmRlYnVnQ29ubmVjdGlvblNuYXBzaG90KGNvbm5lY3Rpb24sIHtjaGVja2VkSW5BdCwgaWRsZUZvck1zLCBzdGF0ZTogXCJpZGxlXCJ9KSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHt7Y29ubmVjdGlvbnM6IEFycmF5PFJlY29yZDxzdHJpbmcsIHVua25vd24+Piwgc2VlbkNvbm5lY3Rpb25zOiBTZXQ8aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQ+fX0gYXJncyAtIFNuYXBzaG90IGNvbGxlY3Rpb24gc3RhdGUuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgYWRkRmFsbGJhY2tEZWJ1Z0Nvbm5lY3Rpb25TbmFwc2hvdHMoe2Nvbm5lY3Rpb25zLCBzZWVuQ29ubmVjdGlvbnN9KSB7XG4gICAgdGhpcy5hZGREZWJ1Z0Nvbm5lY3Rpb25TbmFwc2hvdElmVW5zZWVuKHtjb25uZWN0aW9uOiB0aGlzLmdldEdsb2JhbENvbm5lY3Rpb25Gb3JJZGVudGlmaWVyKCksIGNvbm5lY3Rpb25zLCByZWFwYWJsZTogZmFsc2UsIHNlZW5Db25uZWN0aW9ucywgc3RhdGU6IFwiZ2xvYmFsXCJ9KVxuICAgIHRoaXMuYWRkRGVidWdDb25uZWN0aW9uU25hcHNob3RJZlVuc2Vlbih7Y29ubmVjdGlvbjogdGhpcy5fdGVzdFNoYXJlZENvbm5lY3Rpb24sIGNvbm5lY3Rpb25zLCByZWFwYWJsZTogZmFsc2UsIHNlZW5Db25uZWN0aW9ucywgc3RhdGU6IFwidGVzdC1zaGFyZWRcIn0pXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHt7Y29ubmVjdGlvbjogaW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgfCB1bmRlZmluZWQsIGNvbm5lY3Rpb25zOiBBcnJheTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4sIHJlYXBhYmxlPzogYm9vbGVhbiwgc2VlbkNvbm5lY3Rpb25zOiBTZXQ8aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQ+LCBzdGF0ZTogc3RyaW5nfX0gYXJncyAtIFNuYXBzaG90IGNvbGxlY3Rpb24gc3RhdGUuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgYWRkRGVidWdDb25uZWN0aW9uU25hcHNob3RJZlVuc2Vlbih7Y29ubmVjdGlvbiwgY29ubmVjdGlvbnMsIHJlYXBhYmxlLCBzZWVuQ29ubmVjdGlvbnMsIHN0YXRlfSkge1xuICAgIGlmICghY29ubmVjdGlvbiB8fCBzZWVuQ29ubmVjdGlvbnMuaGFzKGNvbm5lY3Rpb24pKSByZXR1cm5cblxuICAgIHNlZW5Db25uZWN0aW9ucy5hZGQoY29ubmVjdGlvbilcbiAgICBjb25uZWN0aW9ucy5wdXNoKHRoaXMuZGVidWdDb25uZWN0aW9uU25hcHNob3QoY29ubmVjdGlvbiwge3JlYXBhYmxlLCBzdGF0ZX0pKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBub3cgLSBDdXJyZW50IHRpbWVzdGFtcC5cbiAgICogQHJldHVybnMge0FycmF5PFJlY29yZDxzdHJpbmcsIHVua25vd24+Pn0gLSBQZW5kaW5nIGNoZWNrb3V0IHNuYXBzaG90cy5cbiAgICovXG4gIHBlbmRpbmdDaGVja291dERlYnVnU25hcHNob3RzKG5vdykge1xuICAgIHJldHVybiB0aGlzLnBlbmRpbmdDaGVja291dHMubWFwKChjaGVja291dCwgaW5kZXgpID0+ICh7XG4gICAgICBjaGVja291dE5hbWU6IGNoZWNrb3V0Lm9wdGlvbnMubmFtZSxcbiAgICAgIGVucXVldWVkQXQ6IGNoZWNrb3V0LmVucXVldWVkQXQsXG4gICAgICBpbmRleCxcbiAgICAgIHJldXNlS2V5OiBjaGVja291dC5yZXVzZUtleSxcbiAgICAgIHdhaXRpbmdGb3JNczogTWF0aC5tYXgoMCwgbm93IC0gY2hlY2tvdXQuZW5xdWV1ZWRBdClcbiAgICB9KSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgfCB1bmRlZmluZWR9IC0gVGhlIGdsb2JhbCBjb25uZWN0aW9uLlxuICAgKi9cbiAgZ2V0R2xvYmFsQ29ubmVjdGlvbigpIHtcbiAgICBjb25zdCBjb25uZWN0aW9uID0gdGhpcy5nZXRHbG9iYWxDb25uZWN0aW9uRm9ySWRlbnRpZmllcigpXG5cbiAgICBpZiAoIWNvbm5lY3Rpb24pIHJldHVyblxuICAgIGlmICghdGhpcy5jb25uZWN0aW9uTWF0Y2hlc0N1cnJlbnRDb25maWd1cmF0aW9uKGNvbm5lY3Rpb24pKSByZXR1cm5cblxuICAgIHJldHVybiBjb25uZWN0aW9uXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0IHwgdW5kZWZpbmVkfSAtIFRoZSBnbG9iYWwgY29ubmVjdGlvbiBmb3IgdGhpcyBwb29sIGlkZW50aWZpZXIuXG4gICAqL1xuICBnZXRHbG9iYWxDb25uZWN0aW9uRm9ySWRlbnRpZmllcigpIHtcbiAgICBjb25zdCBrbGFzcyA9IC8qKiBAdHlwZSB7dHlwZW9mIFZlbG9jaW91c0RhdGFiYXNlUG9vbEFzeW5jVHJhY2tlZE11bHRpQ29ubmVjdGlvbn0gKi8gKHRoaXMuY29uc3RydWN0b3IpXG4gICAgY29uc3QgbWFwRm9yQ29uZmlndXJhdGlvbiA9IGtsYXNzLmdsb2JhbENvbm5lY3Rpb25zLmdldCh0aGlzLmNvbmZpZ3VyYXRpb24pXG5cbiAgICByZXR1cm4gbWFwRm9yQ29uZmlndXJhdGlvbj8uW3RoaXMuaWRlbnRpZmllcl1cbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuICovXG4gIGNsZWFyR2xvYmFsQ29ubmVjdGlvbkZvcklkZW50aWZpZXIoKSB7XG4gICAgY29uc3Qga2xhc3MgPSAvKiogQHR5cGUge3R5cGVvZiBWZWxvY2lvdXNEYXRhYmFzZVBvb2xBc3luY1RyYWNrZWRNdWx0aUNvbm5lY3Rpb259ICovICh0aGlzLmNvbnN0cnVjdG9yKVxuICAgIGNvbnN0IG1hcEZvckNvbmZpZ3VyYXRpb24gPSBrbGFzcy5nbG9iYWxDb25uZWN0aW9ucy5nZXQodGhpcy5jb25maWd1cmF0aW9uKVxuXG4gICAgaWYgKCFtYXBGb3JDb25maWd1cmF0aW9uKSByZXR1cm5cblxuICAgIGRlbGV0ZSBtYXBGb3JDb25maWd1cmF0aW9uW3RoaXMuaWRlbnRpZmllcl1cbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhcnMgc2NoZW1hIG1ldGFkYXRhIGNhY2hlZCBieSBldmVyeSBsaXZlIGNvbm5lY3Rpb24gb3duZWQgYnkgdGhpcyBwb29sLlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICBjbGVhclNjaGVtYUNhY2hlKCkge1xuICAgIGNvbnN0IGNvbm5lY3Rpb25zID0gbmV3IFNldChbXG4gICAgICAuLi50aGlzLmNvbm5lY3Rpb25zLFxuICAgICAgLi4uT2JqZWN0LnZhbHVlcyh0aGlzLmNvbm5lY3Rpb25zSW5Vc2UpLFxuICAgICAgdGhpcy5nZXRHbG9iYWxDb25uZWN0aW9uKCksXG4gICAgICB0aGlzLl90ZXN0U2hhcmVkQ29ubmVjdGlvblxuICAgIF0uZmlsdGVyKEJvb2xlYW4pKVxuXG4gICAgZm9yIChjb25zdCBjb25uZWN0aW9uIG9mIGNvbm5lY3Rpb25zKSB7XG4gICAgICBpZiAoY29ubmVjdGlvbikgdGhpcy5fY2xlYXJDb25uZWN0aW9uU2NoZW1hQ2FjaGUoY29ubmVjdGlvbilcbiAgICB9XG4gIH1cblxuICAvKiogQHJldHVybnMge251bWJlciB8IG51bGx9IC0gSWRsZSB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcywgb3IgbnVsbCB3aGVuIGRpc2FibGVkLiAqL1xuICBpZGxlVGltZW91dE1pbGxpcygpIHtcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpLnBvb2w/LmlkbGVUaW1lb3V0TWlsbGlzXG5cbiAgICBpZiAodmFsdWUgPT09IG51bGwpIHJldHVybiBudWxsXG4gICAgaWYgKHRoaXMudmFsaWRJZGxlVGltZW91dE1pbGxpcyh2YWx1ZSkpIHJldHVybiB2YWx1ZVxuXG4gICAgcmV0dXJuIERFRkFVTFRfSURMRV9USU1FT1VUX01JTExJU1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7dW5rbm93bn0gdmFsdWUgLSBDYW5kaWRhdGUgaWRsZSB0aW1lb3V0IHZhbHVlLlxuICAgKiBAcmV0dXJucyB7dmFsdWUgaXMgbnVtYmVyfSAtIFdoZXRoZXIgdGhlIHZhbHVlIGlzIGEgdmFsaWQgaWRsZSB0aW1lb3V0LlxuICAgKi9cbiAgdmFsaWRJZGxlVGltZW91dE1pbGxpcyh2YWx1ZSkge1xuICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwibnVtYmVyXCIgJiYgTnVtYmVyLmlzRmluaXRlKHZhbHVlKSAmJiB2YWx1ZSA+PSAwXG4gIH1cblxuICAvKiogQHJldHVybnMge3ZvaWR9ICovXG4gIHNjaGVkdWxlSWRsZUNvbm5lY3Rpb25SZWFwZXIoKSB7XG4gICAgaWYgKHRoaXMuaWRsZUNvbm5lY3Rpb25SZWFwZXJUaW1lcikgcmV0dXJuXG4gICAgaWYgKCF0aGlzLmhhc0lkbGVDb25uZWN0aW9uc1RvUmVhcCgpKSByZXR1cm5cblxuICAgIGNvbnN0IGRlbGF5ID0gdGhpcy5uZXh0SWRsZUNvbm5lY3Rpb25SZWFwRGVsYXkoLyoqIEB0eXBlIHtudW1iZXJ9ICovICh0aGlzLmlkbGVUaW1lb3V0TWlsbGlzKCkpKVxuXG4gICAgdGhpcy5pZGxlQ29ubmVjdGlvblJlYXBlclRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLmlkbGVDb25uZWN0aW9uUmVhcGVyVGltZXIgPSB1bmRlZmluZWRcbiAgICAgIHZvaWQgdGhpcy5yZWFwSWRsZUNvbm5lY3Rpb25zKCkuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgIHRoaXMubG9nZ2VyLndhcm4oKCkgPT4gW1wiRmFpbGVkIHRvIHJlYXAgaWRsZSBkYXRhYmFzZSBjb25uZWN0aW9uczpcIiwgZXJyb3JdKVxuICAgICAgfSlcbiAgICB9LCBkZWxheSlcblxuICAgIGlmICh0eXBlb2YgdGhpcy5pZGxlQ29ubmVjdGlvblJlYXBlclRpbWVyLnVucmVmID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIHRoaXMuaWRsZUNvbm5lY3Rpb25SZWFwZXJUaW1lci51bnJlZigpXG4gICAgfVxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgYW4gaWRsZSByZWFwZXIgdGltZXIgc2hvdWxkIGJlIHNjaGVkdWxlZC4gKi9cbiAgaGFzSWRsZUNvbm5lY3Rpb25zVG9SZWFwKCkge1xuICAgIHJldHVybiB0aGlzLmNvbm5lY3Rpb25zLmxlbmd0aCA+IDAgJiYgdGhpcy5pZGxlVGltZW91dE1pbGxpcygpICE9PSBudWxsXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IGlkbGVUaW1lb3V0TWlsbGlzIC0gSWRsZSB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcy5cbiAgICogQHJldHVybnMge251bWJlcn0gLSBEZWxheSBiZWZvcmUgdGhlIG5leHQgcmVhcC5cbiAgICovXG4gIG5leHRJZGxlQ29ubmVjdGlvblJlYXBEZWxheShpZGxlVGltZW91dE1pbGxpcykge1xuICAgIGxldCBkZWxheSA9IGlkbGVUaW1lb3V0TWlsbGlzXG4gICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKVxuXG4gICAgZm9yIChjb25zdCBjb25uZWN0aW9uIG9mIHRoaXMuY29ubmVjdGlvbnMpIHtcbiAgICAgIGlmICh0aGlzLmNvbm5lY3Rpb25IYXNPcGVuVHJhbnNhY3Rpb24oY29ubmVjdGlvbikpIGNvbnRpbnVlXG5cbiAgICAgIGNvbnN0IHRyYWNrZWRDb25uZWN0aW9uID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCAmIHtbSURMRV9DT05ORUNUSU9OX0NIRUNLRURfSU5fQVRdPzogbnVtYmVyfX0gKi8gKGNvbm5lY3Rpb24pXG4gICAgICBjb25zdCBjaGVja2VkSW5BdCA9IHRyYWNrZWRDb25uZWN0aW9uW0lETEVfQ09OTkVDVElPTl9DSEVDS0VEX0lOX0FUXVxuXG4gICAgICBpZiAodHlwZW9mIGNoZWNrZWRJbkF0ICE9PSBcIm51bWJlclwiKSBjb250aW51ZVxuXG4gICAgICBkZWxheSA9IE1hdGgubWluKGRlbGF5LCBNYXRoLm1heCgwLCBpZGxlVGltZW91dE1pbGxpcyAtIChub3cgLSBjaGVja2VkSW5BdCkpKVxuICAgIH1cblxuICAgIHJldHVybiBkZWxheVxuICB9XG5cbiAgLyoqXG4gICAqIENsb3NlcyBpZGxlIGNoZWNrZWQtaW4gY29ubmVjdGlvbnMgdGhhdCBoYXZlIGV4Y2VlZGVkIHRoZSBjb25maWd1cmVkIHRpbWVvdXQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyByZWFwSWRsZUNvbm5lY3Rpb25zKCkge1xuICAgIGlmICh0aGlzLmNvbm5lY3Rpb25zLmxlbmd0aCA9PT0gMCkgcmV0dXJuXG5cbiAgICBjb25zdCBpZGxlVGltZW91dE1pbGxpcyA9IHRoaXMuaWRsZVRpbWVvdXRNaWxsaXMoKVxuXG4gICAgaWYgKGlkbGVUaW1lb3V0TWlsbGlzID09PSBudWxsKSByZXR1cm5cblxuICAgIGNvbnN0IHtleHBpcmVkQ29ubmVjdGlvbnMsIGtlcHRDb25uZWN0aW9uc30gPSB0aGlzLmNsYXNzaWZ5SWRsZUNvbm5lY3Rpb25zRm9yUmVhcGluZyh7aWRsZVRpbWVvdXRNaWxsaXMsIG5vdzogRGF0ZS5ub3coKX0pXG5cbiAgICB0aGlzLmNvbm5lY3Rpb25zID0ga2VwdENvbm5lY3Rpb25zXG4gICAgYXdhaXQgdGhpcy5jbG9zZUV4cGlyZWRJZGxlQ29ubmVjdGlvbnMoZXhwaXJlZENvbm5lY3Rpb25zKVxuICAgIGF3YWl0IHRoaXMuYXdhaXRJbmZsaWdodENvbm5lY3Rpb25DbG9zZXMoKVxuICAgIGlmICh0aGlzLmNvbm5lY3Rpb25zLmxlbmd0aCA+IDApIHRoaXMuc2NoZWR1bGVJZGxlQ29ubmVjdGlvblJlYXBlcigpXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdFtdfSBleHBpcmVkQ29ubmVjdGlvbnMgLSBDb25uZWN0aW9ucyB0byBjbG9zZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjbG9zZWQuXG4gICAqL1xuICBhc3luYyBjbG9zZUV4cGlyZWRJZGxlQ29ubmVjdGlvbnMoZXhwaXJlZENvbm5lY3Rpb25zKSB7XG4gICAgZm9yIChjb25zdCBjb25uZWN0aW9uIG9mIGV4cGlyZWRDb25uZWN0aW9ucykge1xuICAgICAgYXdhaXQgdGhpcy5jbG9zZUNvbm5lY3Rpb24oY29ubmVjdGlvbilcbiAgICB9XG4gIH1cblxuICAvKiogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgb25jZSBpbi1mbGlnaHQgY29ubmVjdGlvbiBjbG9zZXMgc2V0dGxlLiAqL1xuICBhc3luYyBhd2FpdEluZmxpZ2h0Q29ubmVjdGlvbkNsb3NlcygpIHtcbiAgICBpZiAodGhpcy5pbmZsaWdodENvbm5lY3Rpb25DbG9zZXMuc2l6ZSA+IDApIHtcbiAgICAgIGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZChbLi4udGhpcy5pbmZsaWdodENvbm5lY3Rpb25DbG9zZXNdKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3tpZGxlVGltZW91dE1pbGxpczogbnVtYmVyLCBub3c6IG51bWJlcn19IGFyZ3MgLSBSZWFwZXIgY2xhc3NpZmljYXRpb24gaW5wdXRzLlxuICAgKiBAcmV0dXJucyB7e2V4cGlyZWRDb25uZWN0aW9uczogaW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHRbXSwga2VwdENvbm5lY3Rpb25zOiBpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdFtdfX0gLSBDbGFzc2lmaWVkIGlkbGUgY29ubmVjdGlvbnMuXG4gICAqL1xuICBjbGFzc2lmeUlkbGVDb25uZWN0aW9uc0ZvclJlYXBpbmcoe2lkbGVUaW1lb3V0TWlsbGlzLCBub3d9KSB7XG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdFtdfSAqL1xuICAgIGNvbnN0IGtlcHRDb25uZWN0aW9ucyA9IFtdXG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdFtdfSAqL1xuICAgIGNvbnN0IGV4cGlyZWRDb25uZWN0aW9ucyA9IFtdXG5cbiAgICBmb3IgKGNvbnN0IGNvbm5lY3Rpb24gb2YgdGhpcy5jb25uZWN0aW9ucykge1xuICAgICAgdGhpcy5jbGFzc2lmeUlkbGVDb25uZWN0aW9uRm9yUmVhcGluZyh7Y29ubmVjdGlvbiwgZXhwaXJlZENvbm5lY3Rpb25zLCBpZGxlVGltZW91dE1pbGxpcywga2VwdENvbm5lY3Rpb25zLCBub3d9KVxuICAgIH1cblxuICAgIHJldHVybiB7ZXhwaXJlZENvbm5lY3Rpb25zLCBrZXB0Q29ubmVjdGlvbnN9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHt7Y29ubmVjdGlvbjogaW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQsIGV4cGlyZWRDb25uZWN0aW9uczogaW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHRbXSwgaWRsZVRpbWVvdXRNaWxsaXM6IG51bWJlciwga2VwdENvbm5lY3Rpb25zOiBpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdFtdLCBub3c6IG51bWJlcn19IGFyZ3MgLSBDbGFzc2lmaWNhdGlvbiBzdGF0ZS5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBjbGFzc2lmeUlkbGVDb25uZWN0aW9uRm9yUmVhcGluZyh7Y29ubmVjdGlvbiwgZXhwaXJlZENvbm5lY3Rpb25zLCBpZGxlVGltZW91dE1pbGxpcywga2VwdENvbm5lY3Rpb25zLCBub3d9KSB7XG4gICAgaWYgKHRoaXMuY29ubmVjdGlvbklzQ2xvc2VkKGNvbm5lY3Rpb24pKSByZXR1cm5cbiAgICBpZiAodGhpcy5jb25uZWN0aW9uSGFzT3BlblRyYW5zYWN0aW9uKGNvbm5lY3Rpb24pKSB7XG4gICAgICBrZXB0Q29ubmVjdGlvbnMucHVzaChjb25uZWN0aW9uKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY29uc3QgdGFyZ2V0ID0gdGhpcy5pZGxlQ29ubmVjdGlvbkV4cGlyZWQoe2Nvbm5lY3Rpb24sIGlkbGVUaW1lb3V0TWlsbGlzLCBub3d9KSA/IGV4cGlyZWRDb25uZWN0aW9ucyA6IGtlcHRDb25uZWN0aW9uc1xuXG4gICAgdGFyZ2V0LnB1c2goY29ubmVjdGlvbilcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBjb25uZWN0aW9uIC0gQ29ubmVjdGlvbiB0byBpbnNwZWN0LlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIHRoZSBjb25uZWN0aW9uIGlzIG1hcmtlZCBjbG9zZWQuXG4gICAqL1xuICBjb25uZWN0aW9uSXNDbG9zZWQoY29ubmVjdGlvbikge1xuICAgIGNvbnN0IHRyYWNrZWRDb25uZWN0aW9uID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCAmIHtbQ0xPU0VEX0NPTk5FQ1RJT05dPzogYm9vbGVhbn19ICovIChjb25uZWN0aW9uKVxuXG4gICAgcmV0dXJuIEJvb2xlYW4odHJhY2tlZENvbm5lY3Rpb25bQ0xPU0VEX0NPTk5FQ1RJT05dKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7e2Nvbm5lY3Rpb246IGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0LCBpZGxlVGltZW91dE1pbGxpczogbnVtYmVyLCBub3c6IG51bWJlcn19IGFyZ3MgLSBFeHBpcnkgaW5wdXRzLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIHRoZSBpZGxlIGNvbm5lY3Rpb24gZXhwaXJlZC5cbiAgICovXG4gIGlkbGVDb25uZWN0aW9uRXhwaXJlZCh7Y29ubmVjdGlvbiwgaWRsZVRpbWVvdXRNaWxsaXMsIG5vd30pIHtcbiAgICBjb25zdCB0cmFja2VkQ29ubmVjdGlvbiA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgJiB7W0lETEVfQ09OTkVDVElPTl9DSEVDS0VEX0lOX0FUXT86IG51bWJlcn19ICovIChjb25uZWN0aW9uKVxuICAgIGNvbnN0IGNoZWNrZWRJbkF0ID0gdHJhY2tlZENvbm5lY3Rpb25bSURMRV9DT05ORUNUSU9OX0NIRUNLRURfSU5fQVRdXG5cbiAgICByZXR1cm4gdHlwZW9mIGNoZWNrZWRJbkF0ID09PSBcIm51bWJlclwiICYmIG5vdyAtIGNoZWNrZWRJbkF0ID49IGlkbGVUaW1lb3V0TWlsbGlzXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gY29ubmVjdGlvbiAtIENvbm5lY3Rpb24gdG8gaW5zcGVjdC5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gV2hldGhlciB0aGUgY29ubmVjdGlvbiBoYXMgYW4gb3BlbiB0cmFuc2FjdGlvbi5cbiAgICovXG4gIGNvbm5lY3Rpb25IYXNPcGVuVHJhbnNhY3Rpb24oY29ubmVjdGlvbikge1xuICAgIHJldHVybiBjb25uZWN0aW9uLl90cmFuc2FjdGlvbnNDb3VudCA+IDBcbiAgfVxuXG4gIC8qKlxuICAgKiBSb2xscyBiYWNrIGFueSB0cmFuc2FjdGlvbiBhIHByZXZpb3VzIGhvbGRlciBsZWZ0IG9wZW4gYmVmb3JlIGEgY29ubmVjdGlvblxuICAgKiByZS1lbnRlcnMgdGhlIGlkbGUgcG9vbC4gQSBjb25uZWN0aW9uIHJldHVybmVkIHRvIHRoZSBwb29sIHdpdGggYW4gb3BlblxuICAgKiB0cmFuc2FjdGlvbiB3b3VsZCBvdGhlcndpc2UgYmUgaGFuZGVkIHRvIGFuIHVucmVsYXRlZCBjaGVja291dCwgd2hvc2VcbiAgICogc3RhcnRUcmFuc2FjdGlvbigpIHRoZW4gZmFpbHMgd2l0aCBcIkEgdHJhbnNhY3Rpb24gaXMgYWxyZWFkeSBydW5uaW5nXCIgYW5kXG4gICAqIHBvaXNvbnMgZXZlcnkgZm9sbG93aW5nIGNhbGxlciB0aGF0IHJldXNlcyBpdC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gY29ubmVjdGlvbiAtIENvbm5lY3Rpb24gYmVpbmcgY2hlY2tlZCBpbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiB0aGUgY29ubmVjdGlvbiBob2xkcyBubyBvcGVuIHRyYW5zYWN0aW9uLlxuICAgKi9cbiAgYXN5bmMgcm9sbGJhY2tMZWZ0T3BlblRyYW5zYWN0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICBpZiAoIXRoaXMuY29ubmVjdGlvbkhhc09wZW5UcmFuc2FjdGlvbihjb25uZWN0aW9uKSkgcmV0dXJuXG5cbiAgICB0aGlzLmxvZ2dlci53YXJuKCgpID0+IFtgUm9sbGluZyBiYWNrIGEgdHJhbnNhY3Rpb24gbGVmdCBvcGVuIG9uIGEgY29ubmVjdGlvbiBiZWluZyBjaGVja2VkIGluIChpZGVudGlmaWVyPSR7dGhpcy5pZGVudGlmaWVyfSkuYF0pXG5cbiAgICB3aGlsZSAodGhpcy5jb25uZWN0aW9uSGFzT3BlblRyYW5zYWN0aW9uKGNvbm5lY3Rpb24pKSB7XG4gICAgICBhd2FpdCBjb25uZWN0aW9uLnJvbGxiYWNrVHJhbnNhY3Rpb24oKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBjb25uZWN0aW9uIC0gQ29ubmVjdGlvbiB0byBjbG9zZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIGNsb3NlQ29ubmVjdGlvbihjb25uZWN0aW9uKSB7XG4gICAgLy8gSWRlbXBvdGVudDogYSBmaXJlLWFuZC1mb3JnZXQgc2NoZWR1bGVkIHJlYXAgYW5kIGFuIGV4cGxpY2l0IHJlYXAgY2FuIGJvdGhcbiAgICAvLyB0YXJnZXQgdGhlIHNhbWUgY29ubmVjdGlvbi4gQXdhaXQgdGhlIGluLWZsaWdodCBjbG9zZSBpbnN0ZWFkIG9mIGNsb3NpbmdcbiAgICAvLyB0d2ljZSAod2hpY2ggY2FuIHRocm93IG9uIHRoZSBkcml2ZXIpIG9yIHJldHVybmluZyB3aGlsZSB0aGUgdW5kZXJseWluZ1xuICAgIC8vIGhhbmRsZSBpcyBzdGlsbCBvcGVuLlxuICAgIGNvbnN0IGV4aXN0aW5nQ2xvc2UgPSB0aGlzLmNvbm5lY3Rpb25DbG9zZVByb21pc2VzLmdldChjb25uZWN0aW9uKVxuXG4gICAgaWYgKGV4aXN0aW5nQ2xvc2UpIHtcbiAgICAgIHJldHVybiBhd2FpdCBleGlzdGluZ0Nsb3NlXG4gICAgfVxuXG4gICAgY29uc3QgdHJhY2tlZENvbm5lY3Rpb24gPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0ICYge1tDTE9TRURfQ09OTkVDVElPTl0/OiBib29sZWFuLCBbQ09OTkVDVElPTl9DSEVDS0VEX09VVF9BVF0/OiBudW1iZXIsIFtJRExFX0NPTk5FQ1RJT05fQ0hFQ0tFRF9JTl9BVF0/OiBudW1iZXJ9fSAqLyAoY29ubmVjdGlvbilcblxuICAgIHRyYWNrZWRDb25uZWN0aW9uW0NMT1NFRF9DT05ORUNUSU9OXSA9IHRydWVcbiAgICBkZWxldGUgdHJhY2tlZENvbm5lY3Rpb25bQ09OTkVDVElPTl9DSEVDS0VEX09VVF9BVF1cbiAgICBkZWxldGUgdHJhY2tlZENvbm5lY3Rpb25bSURMRV9DT05ORUNUSU9OX0NIRUNLRURfSU5fQVRdXG5cbiAgICBjb25zdCBjbG9zZVByb21pc2UgPSAoYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgdHJhY2tlZENvbm5lY3Rpb24uY2xvc2UoKVxuICAgIH0pKClcblxuICAgIHRoaXMuY29ubmVjdGlvbkNsb3NlUHJvbWlzZXMuc2V0KGNvbm5lY3Rpb24sIGNsb3NlUHJvbWlzZSlcbiAgICB0aGlzLmluZmxpZ2h0Q29ubmVjdGlvbkNsb3Nlcy5hZGQoY2xvc2VQcm9taXNlKVxuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGNsb3NlUHJvbWlzZVxuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLmluZmxpZ2h0Q29ubmVjdGlvbkNsb3Nlcy5kZWxldGUoY2xvc2VQcm9taXNlKVxuICAgIH1cbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7dm9pZH0gKi9cbiAgY2xlYXJJZGxlQ29ubmVjdGlvblJlYXBlclRpbWVyKCkge1xuICAgIGlmICghdGhpcy5pZGxlQ29ubmVjdGlvblJlYXBlclRpbWVyKSByZXR1cm5cblxuICAgIGNsZWFyVGltZW91dCh0aGlzLmlkbGVDb25uZWN0aW9uUmVhcGVyVGltZXIpXG4gICAgdGhpcy5pZGxlQ29ubmVjdGlvblJlYXBlclRpbWVyID0gdW5kZWZpbmVkXG4gIH1cblxuICAvKipcbiAgICogQ2xvc2VzIGFsbCBhY3RpdmUgYW5kIGNhY2hlZCBjb25uZWN0aW9ucyBmb3IgdGhpcyBwb29sLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgY2xvc2VBbGwoKSB7XG4gICAgdGhpcy5jbGVhcklkbGVDb25uZWN0aW9uUmVhcGVyVGltZXIoKVxuICAgIHRoaXMucmVqZWN0UGVuZGluZ0NoZWNrb3V0cyhuZXcgRXJyb3IoXCJEYXRhYmFzZSBwb29sIHdhcyBjbG9zZWQgYmVmb3JlIGNoZWNrb3V0IGNvbXBsZXRlZC5cIikpXG5cbiAgICBjb25zdCBjb25uZWN0aW9ucyA9IG5ldyBTZXQoW1xuICAgICAgLi4udGhpcy5jb25uZWN0aW9ucyxcbiAgICAgIC4uLk9iamVjdC52YWx1ZXModGhpcy5jb25uZWN0aW9uc0luVXNlKSxcbiAgICAgIHRoaXMuZ2V0R2xvYmFsQ29ubmVjdGlvbkZvcklkZW50aWZpZXIoKSxcbiAgICAgIHRoaXMuX3Rlc3RTaGFyZWRDb25uZWN0aW9uXG4gICAgXS5maWx0ZXIoQm9vbGVhbikpXG5cbiAgICB0aGlzLmNvbm5lY3Rpb25zID0gW11cbiAgICB0aGlzLmNvbm5lY3Rpb25zSW5Vc2UgPSB7fVxuICAgIHRoaXMuX3Rlc3RTaGFyZWRDb25uZWN0aW9uID0gdW5kZWZpbmVkXG4gICAgdGhpcy5jbGVhckdsb2JhbENvbm5lY3Rpb25Gb3JJZGVudGlmaWVyKClcblxuICAgIGZvciAoY29uc3QgY29ubmVjdGlvbiBvZiBjb25uZWN0aW9ucykge1xuICAgICAgaWYgKCFjb25uZWN0aW9uKSBjb250aW51ZVxuXG4gICAgICBhd2FpdCB0aGlzLmNsb3NlQ29ubmVjdGlvbihjb25uZWN0aW9uKVxuICAgIH1cblxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7RXJyb3J9IGVycm9yIC0gRXJyb3IgdG8gcmVqZWN0IHBlbmRpbmcgY2hlY2tvdXRzIHdpdGguXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgcmVqZWN0UGVuZGluZ0NoZWNrb3V0cyhlcnJvcikge1xuICAgIGNvbnN0IHBlbmRpbmdDaGVja291dHMgPSB0aGlzLnBlbmRpbmdDaGVja291dHNcblxuICAgIHRoaXMucGVuZGluZ0NoZWNrb3V0cyA9IFtdXG5cbiAgICBmb3IgKGNvbnN0IGNoZWNrb3V0IG9mIHBlbmRpbmdDaGVja291dHMpIHtcbiAgICAgIGNoZWNrb3V0LnJlamVjdChlcnJvcilcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVwbGFjZXMgYWxsIGdsb2JhbGx5IHJlZ2lzdGVyZWQgZmFsbGJhY2sgY29ubmVjdGlvbnMuXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgaW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQ+fSBbY29ubmVjdGlvbnNdIC0gQ29ubmVjdGlvbnMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vY29uZmlndXJhdGlvbi5qc1wiKS5kZWZhdWx0fSBbY29uZmlndXJhdGlvbl0gLSBDb25maWd1cmF0aW9uIGluc3RhbmNlLlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICBzdGF0aWMgc2V0R2xvYmFsQ29ubmVjdGlvbnMoY29ubmVjdGlvbnMsIGNvbmZpZ3VyYXRpb24pIHtcbiAgICBpZiAoIWNvbmZpZ3VyYXRpb24pIHtcbiAgICAgIHRoaXMuZ2xvYmFsQ29ubmVjdGlvbnMgPSBuZXcgV2Vha01hcCgpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB0aGlzLmdsb2JhbENvbm5lY3Rpb25zLnNldChjb25maWd1cmF0aW9uLCBjb25uZWN0aW9ucyB8fCB7fSlcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhcnMgZ2xvYmFsbHkgcmVnaXN0ZXJlZCBmYWxsYmFjayBjb25uZWN0aW9ucyBmb3IgYWxsIGNvbmZpZ3VyYXRpb25zIG9yIGEgc2luZ2xlIGNvbmZpZ3VyYXRpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vY29uZmlndXJhdGlvbi5qc1wiKS5kZWZhdWx0fSBbY29uZmlndXJhdGlvbl0gLSBDb25maWd1cmF0aW9uIGluc3RhbmNlLlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICBzdGF0aWMgY2xlYXJHbG9iYWxDb25uZWN0aW9ucyhjb25maWd1cmF0aW9uKSB7XG4gICAgaWYgKCFjb25maWd1cmF0aW9uKSB7XG4gICAgICB0aGlzLmdsb2JhbENvbm5lY3Rpb25zID0gbmV3IFdlYWtNYXAoKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdGhpcy5nbG9iYWxDb25uZWN0aW9ucy5kZWxldGUoY29uZmlndXJhdGlvbilcbiAgfVxufVxuIl19
|
|
1014
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXN5bmMtdHJhY2tlZC1tdWx0aS1jb25uZWN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2RhdGFiYXNlL3Bvb2wvYXN5bmMtdHJhY2tlZC1tdWx0aS1jb25uZWN0aW9uLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSxhQUFhLENBQUE7QUFDN0MsT0FBTyxRQUFRLEVBQUUsRUFBQyxzQkFBc0IsRUFBQyxNQUFNLFdBQVcsQ0FBQTtBQUUxRCxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRyxNQUFNLENBQUMsMkJBQTJCLENBQUMsQ0FBQTtBQUNwRSxNQUFNLDZCQUE2QixHQUFHLE1BQU0sQ0FBQyxvQ0FBb0MsQ0FBQyxDQUFBO0FBQ2xGLE1BQU0seUJBQXlCLEdBQUcsTUFBTSxDQUFDLGlDQUFpQyxDQUFDLENBQUE7QUFDM0UsTUFBTSwyQkFBMkIsR0FBRyxJQUFJLENBQUE7QUFFeEM7Ozs7Ozs7OztHQVNHO0FBRUgsTUFBTSxDQUFDLE9BQU8sT0FBTyxnREFBaUQsU0FBUSxRQUFRO0lBQ3BGOzs7T0FHRztJQUNILE1BQU0sQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFBO0lBRXhDLGlCQUFpQixHQUFHLElBQUksaUJBQWlCLEVBQUUsQ0FBQTtJQUUzQzs7Ozs7T0FLRztJQUNILHFCQUFxQixHQUFHLFNBQVMsQ0FBQTtJQUVqQzs7dURBRW1EO0lBQ25ELFdBQVcsR0FBRyxFQUFFLENBQUE7SUFFaEI7O3FFQUVpRTtJQUNqRSxnQkFBZ0IsR0FBRyxFQUFFLENBQUE7SUFFckI7O2tDQUU4QjtJQUM5QixnQkFBZ0IsR0FBRyxFQUFFLENBQUE7SUFFckI7O3VCQUVtQjtJQUNuQix1QkFBdUIsR0FBRyxDQUFDLENBQUE7SUFFM0I7OzBDQUVzQztJQUN0QywyQkFBMkIsR0FBRyxTQUFTLENBQUE7SUFFdkM7OzBEQUVzRDtJQUN0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LGlCQUFpQixHQUFHLElBQUksT0FBTyxFQUFFLENBQUE7WUFDdEMsT0FBTTtRQUNSLENBQUM7UUFFRCxJQUFJLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFBO0lBQzlDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IHtBc3luY0xvY2FsU3RvcmFnZX0gZnJvbSBcImFzeW5jX2hvb2tzXCJcbmltcG9ydCBCYXNlUG9vbCwge1BPT0xfQ09ORklHVVJBVElPTl9LRVl9IGZyb20gXCIuL2Jhc2UuanNcIlxuXG5leHBvcnQgY29uc3QgQ0xPU0VEX0NPTk5FQ1RJT04gPSBTeW1ib2woXCJ2ZWxvY2lvdXNDbG9zZWRDb25uZWN0aW9uXCIpXG5jb25zdCBJRExFX0NPTk5FQ1RJT05fQ0hFQ0tFRF9JTl9BVCA9IFN5bWJvbChcInZlbG9jaW91c0lkbGVDb25uZWN0aW9uQ2hlY2tlZEluQXRcIilcbmNvbnN0IENPTk5FQ1RJT05fQ0hFQ0tFRF9PVVRfQVQgPSBTeW1ib2woXCJ2ZWxvY2lvdXNDb25uZWN0aW9uQ2hlY2tlZE91dEF0XCIpXG5jb25zdCBERUZBVUxUX0lETEVfVElNRU9VVF9NSUxMSVMgPSA1MDAwXG5cbi8qKlxuICogUGVuZGluZ0NoZWNrb3V0IHR5cGUuXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBQZW5kaW5nQ2hlY2tvdXRcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vLi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5EYXRhYmFzZUNvbmZpZ3VyYXRpb25UeXBlfSBkYXRhYmFzZUNvbmZpZyAtIFJlc29sdmVkIGRhdGFiYXNlIGNvbmZpZ3VyYXRpb24gbmVlZGVkIGJ5IHRoZSBjaGVja291dC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBlbnF1ZXVlZEF0IC0gVGltZXN0YW1wIHdoZW4gdGhlIGNoZWNrb3V0IHN0YXJ0ZWQgd2FpdGluZy5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9iYXNlLmpzXCIpLkNvbm5lY3Rpb25DaGVja291dE9wdGlvbnN9IG9wdGlvbnMgLSBDaGVja291dCBvcHRpb25zLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IHJldXNlS2V5IC0gRGF0YWJhc2UgY29uZmlndXJhdGlvbiByZXVzZSBrZXkgbmVlZGVkIGJ5IHRoZSBjaGVja291dC5cbiAqIEBwcm9wZXJ0eSB7KGNvbm5lY3Rpb246IGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0KSA9PiB2b2lkfSByZXNvbHZlIC0gUmVzb2x2ZXMgd2l0aCBhbiBhY3RpdmF0ZWQgY29ubmVjdGlvbi5cbiAqIEBwcm9wZXJ0eSB7KGVycm9yOiBFcnJvcikgPT4gdm9pZH0gcmVqZWN0IC0gUmVqZWN0cyB3aGVuIGNoZWNrb3V0IGNhbm5vdCBjb21wbGV0ZS5cbiAqL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBWZWxvY2lvdXNEYXRhYmFzZVBvb2xBc3luY1RyYWNrZWRNdWx0aUNvbm5lY3Rpb24gZXh0ZW5kcyBCYXNlUG9vbCB7XG4gIC8qKlxuICAgKiBHbG9iYWwgZmFsbGJhY2sgY29ubmVjdGlvbnMga2V5ZWQgYnkgY29uZmlndXJhdGlvbiBpbnN0YW5jZSBhbmQgcG9vbCBpZGVudGlmaWVyLlxuICAgKiBAdHlwZSB7V2Vha01hcDxpbXBvcnQoXCIuLi8uLi9jb25maWd1cmF0aW9uLmpzXCIpLmRlZmF1bHQsIFJlY29yZDxzdHJpbmcsIGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pj59XG4gICAqL1xuICBzdGF0aWMgZ2xvYmFsQ29ubmVjdGlvbnMgPSBuZXcgV2Vha01hcCgpXG5cbiAgYXN5bmNMb2NhbFN0b3JhZ2UgPSBuZXcgQXN5bmNMb2NhbFN0b3JhZ2UoKVxuXG4gIC8qKlxuICAgKiBXaGVuIHNldCwgcmV0dXJuZWQgYnkgZ2V0Q3VycmVudENvbnRleHRDb25uZWN0aW9uIHdoZW4gbm8gYXN5bmMgY29udGV4dCBleGlzdHMuXG4gICAqIFVzZWQgYnkgdGhlIHRlc3QgcnVubmVyIHRvIHNoYXJlIGEgY29ubmVjdGlvbiBiZXR3ZWVuIHRlc3QgY29kZSBhbmQgSFRUUCBoYW5kbGVyc1xuICAgKiBydW5uaW5nIGluIHRoZSBzYW1lIHByb2Nlc3MgKGluLXByb2Nlc3MgdGVzdCBzZXJ2ZXIgbW9kZSkuXG4gICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCB8IHVuZGVmaW5lZH1cbiAgICovXG4gIF90ZXN0U2hhcmVkQ29ubmVjdGlvbiA9IHVuZGVmaW5lZFxuXG4gIC8qKlxuICAgKiBDb25uZWN0aW9ucy5cbiAgICBAdHlwZSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHRbXX0gKi9cbiAgY29ubmVjdGlvbnMgPSBbXVxuXG4gIC8qKlxuICAgKiBDb25uZWN0aW9ucyBpbiB1c2UuXG4gICAgQHR5cGUge1JlY29yZDxudW1iZXIsIGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pn0gKi9cbiAgY29ubmVjdGlvbnNJblVzZSA9IHt9XG5cbiAgLyoqXG4gICAqIFBlbmRpbmcgY2hlY2tvdXRzLlxuICAgIEB0eXBlIHtQZW5kaW5nQ2hlY2tvdXRbXX0gKi9cbiAgcGVuZGluZ0NoZWNrb3V0cyA9IFtdXG5cbiAgLyoqXG4gICAqIENvbm5lY3Rpb25zIGJlaW5nIHNwYXduZWQuXG4gICAgQHR5cGUge251bWJlcn0gKi9cbiAgY29ubmVjdGlvbnNCZWluZ1NwYXduZWQgPSAwXG5cbiAgLyoqXG4gICAqIFBlbmRpbmcgY2hlY2tvdXQgZHJhaW4gcHJvbWlzZS5cbiAgICBAdHlwZSB7UHJvbWlzZTx2b2lkPiB8IHVuZGVmaW5lZH0gKi9cbiAgcGVuZGluZ0NoZWNrb3V0RHJhaW5Qcm9taXNlID0gdW5kZWZpbmVkXG5cbiAgLyoqXG4gICAqIElkbGUgY29ubmVjdGlvbiByZWFwZXIgdGltZXIuXG4gICAgQHR5cGUge1JldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+IHwgdW5kZWZpbmVkfSAqL1xuICBpZGxlQ29ubmVjdGlvblJlYXBlclRpbWVyID0gdW5kZWZpbmVkXG5cbiAgLyoqXG4gICAqIEluLWZsaWdodCBjb25uZWN0aW9uLWNsb3NlIHByb21pc2VzLiBUaGUgaWRsZSByZWFwZXIgaXMgYXJtZWQgb24gY2hlY2staW5cbiAgICogYW5kIHJ1bnMgZmlyZS1hbmQtZm9yZ2V0IHdoZW4gaXRzIHRpbWVyIGZpcmVzLCBzbyBhIHNjaGVkdWxlZCByZWFwIGNhbiBiZVxuICAgKiBjbG9zaW5nIGEgY29ubmVjdGlvbiB3aGlsZSBhbiBleHBsaWNpdCBgcmVhcElkbGVDb25uZWN0aW9ucygpYCAob3JcbiAgICogYGNsZWFySWRsZUNvbm5lY3Rpb25SZWFwZXJUaW1lcigpYCkgcnVucy4gVHJhY2tpbmcgdGhlIGluLWZsaWdodCBjbG9zZXMgbGV0c1xuICAgKiB0aG9zZSBjYWxsZXJzIGF3YWl0IHRoZW0sIHNvIG9uY2UgYSByZWFwIHJlc29sdmVzIHRoZSBjb25uZWN0aW9ucyBpdFxuICAgKiBleHBpcmVkIGFyZSBmdWxseSBjbG9zZWQgaW5zdGVhZCBvZiBoYWxmLWNsb3NlZCBtaWQtYGNsb3NlKClgLlxuICAgKiBAdHlwZSB7U2V0PFByb21pc2U8dm9pZD4+fVxuICAgKi9cbiAgaW5mbGlnaHRDb25uZWN0aW9uQ2xvc2VzID0gbmV3IFNldCgpXG5cbiAgLyoqXG4gICAqIEluLWZsaWdodCBjbG9zZSBwcm9taXNlIHBlciBjb25uZWN0aW9uLCBzbyBjb25jdXJyZW50IGNsb3NlcyBvZiB0aGUgc2FtZVxuICAgKiBjb25uZWN0aW9uIGF3YWl0IHRoZSBzYW1lIGNsb3NlIHJhdGhlciB0aGFuIGNsb3NpbmcgdGhlIGRyaXZlciBoYW5kbGUgdHdpY2UuXG4gICAqIEB0eXBlIHtXZWFrTWFwPG9iamVjdCwgUHJvbWlzZTx2b2lkPj59XG4gICAqL1xuICBjb25uZWN0aW9uQ2xvc2VQcm9taXNlcyA9IG5ldyBXZWFrTWFwKClcblxuICBpZFNlcSA9IDBcblxuICAvKipcbiAgICogUnVucyBjb25zdHJ1Y3Rvci5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9jb25maWd1cmF0aW9uLmpzXCIpLmRlZmF1bHR9IGFyZ3MuY29uZmlndXJhdGlvbiAtIENvbmZpZ3VyYXRpb24gaW5zdGFuY2UuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLmlkZW50aWZpZXIgLSBJZGVudGlmaWVyLlxuICAgKi9cbiAgY29uc3RydWN0b3Ioe2NvbmZpZ3VyYXRpb24sIGlkZW50aWZpZXJ9KSB7XG4gICAgc3VwZXIoe2NvbmZpZ3VyYXRpb24sIGlkZW50aWZpZXJ9KVxuICAgIHRoaXMuX3dpdGhvdXRDdXJyZW50Q29ubmVjdGlvbkNvbnRleHQgPSAvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEB0eXBlIHsoY2FsbGJhY2s6ICgpID0+ID8pID0+ID99ICovICgoY2FsbGJhY2spID0+IHRoaXMuYXN5bmNMb2NhbFN0b3JhZ2UucnVuKHVuZGVmaW5lZCwgY2FsbGJhY2spKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgY2hlY2tpbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gY29ubmVjdGlvbiAtIERhdGFiYXNlIGNvbm5lY3Rpb24gaW5zdGFuY2UuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gdGhlIGNvbm5lY3Rpb24gaXMgY2hlY2tlZCBpbiBvciBjbG9zZWQuXG4gICAqL1xuICBhc3luYyBjaGVja2luKGNvbm5lY3Rpb24pIHtcbiAgICBjb25zdCBpZCA9IGNvbm5lY3Rpb24uZ2V0SWRTZXEoKVxuICAgIGNvbnN0IHRyYWNrZWRDb25uZWN0aW9uID0gLyoqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEB0eXBlIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCAmIHtbQ0xPU0VEX0NPTk5FQ1RJT05dPzogYm9vbGVhbiwgW0NPTk5FQ1RJT05fQ0hFQ0tFRF9PVVRfQVRdPzogbnVtYmVyLCBbSURMRV9DT05ORUNUSU9OX0NIRUNLRURfSU5fQVRdPzogbnVtYmVyfX0gKi8gKGNvbm5lY3Rpb24pXG5cbiAgICBpZiAodHJhY2tlZENvbm5lY3Rpb25bQ0xPU0VEX0NPTk5FQ1RJT05dKSB7XG4gICAgICB0aGlzLnVudHJhY2tDb25uZWN0aW9uSW5Vc2UoY29ubmVjdGlvbiwgaWQpXG4gICAgICBhd2FpdCB0aGlzLmRyYWluUGVuZGluZ0NoZWNrb3V0cygpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5yb2xsYmFja0xlZnRPcGVuVHJhbnNhY3Rpb24oY29ubmVjdGlvbilcbiAgICAgIGF3YWl0IGNvbm5lY3Rpb24uY2xlYXJDb25uZWN0aW9uQ2hlY2tvdXROYW1lKClcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgYXdhaXQgdGhpcy5jbG9zZUNoZWNrZWRPdXRDb25uZWN0aW9uQWZ0ZXJDaGVja2luRmFpbHVyZShjb25uZWN0aW9uLCBpZCwgZXJyb3IpXG4gICAgICB0aHJvdyBlcnJvclxuICAgIH1cblxuICAgIHRoaXMudW50cmFja0Nvbm5lY3Rpb25JblVzZShjb25uZWN0aW9uLCBpZClcbiAgICB0cmFja2VkQ29ubmVjdGlvbltJRExFX0NPTk5FQ1RJT05fQ0hFQ0tFRF9JTl9BVF0gPSBEYXRlLm5vdygpXG4gICAgZGVsZXRlIHRyYWNrZWRDb25uZWN0aW9uW0NPTk5FQ1RJT05fQ0hFQ0tFRF9PVVRfQVRdXG4gICAgdGhpcy5jb25uZWN0aW9ucy5wdXNoKGNvbm5lY3Rpb24pXG4gICAgYXdhaXQgdGhpcy5kcmFpblBlbmRpbmdDaGVja291dHMoKVxuICAgIGlmICh0aGlzLmNvbm5lY3Rpb25zLmluY2x1ZGVzKGNvbm5lY3Rpb24pKSBhd2FpdCB0aGlzLmhhbmRsZUNoZWNrZWRJbklkbGVDb25uZWN0aW9uKClcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGNsb3NlIGNoZWNrZWQgb3V0IGNvbm5lY3Rpb24gYWZ0ZXIgY2hlY2tpbiBmYWlsdXJlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBjb25uZWN0aW9uIC0gQ29ubmVjdGlvbiB0aGF0IGZhaWxlZCBjaGVjay1pbiBjbGVhbnVwLlxuICAgKiBAcGFyYW0ge251bWJlciB8IHVuZGVmaW5lZH0gaWQgLSBDb25uZWN0aW9uIGNoZWNrb3V0IGlkLlxuICAgKiBAcGFyYW0gez99IG9yaWdpbmFsRXJyb3IgLSBFcnJvciB0aGF0IGNhdXNlZCBjaGVjay1pbiBjbGVhbnVwIHRvIGZhaWwuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY2xlYW51cCBoYXMgYmVlbiBhdHRlbXB0ZWQuXG4gICAqL1xuICBhc3luYyBjbG9zZUNoZWNrZWRPdXRDb25uZWN0aW9uQWZ0ZXJDaGVja2luRmFpbHVyZShjb25uZWN0aW9uLCBpZCwgb3JpZ2luYWxFcnJvcikge1xuICAgIHRoaXMudW50cmFja0Nvbm5lY3Rpb25JblVzZShjb25uZWN0aW9uLCBpZClcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLmNsb3NlQ29ubmVjdGlvbihjb25uZWN0aW9uKVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLmxvZ2dlci53YXJuKFwiRmFpbGVkIHRvIGNsb3NlIGRhdGFiYXNlIGNvbm5lY3Rpb24gYWZ0ZXIgY2hlY2staW4gY2xlYW51cCBmYWlsZWRcIiwge2Vycm9yLCBvcmlnaW5hbEVycm9yfSlcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5kcmFpblBlbmRpbmdDaGVja291dHMoKVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLmxvZ2dlci53YXJuKFwiRmFpbGVkIHRvIGRyYWluIHBlbmRpbmcgZGF0YWJhc2UgY2hlY2tvdXRzIGFmdGVyIGNoZWNrLWluIGNsZWFudXAgZmFpbGVkXCIsIHtlcnJvciwgb3JpZ2luYWxFcnJvcn0pXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgdW50cmFjayBjb25uZWN0aW9uIGluIHVzZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gY29ubmVjdGlvbiAtIENvbm5lY3Rpb24gYmVpbmcgY2hlY2tlZCBpbi5cbiAgICogQHBhcmFtIHtudW1iZXIgfCB1bmRlZmluZWR9IGlkIC0gQ29ubmVjdGlvbiBjaGVja291dCBpZC5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICB1bnRyYWNrQ29ubmVjdGlvbkluVXNlKGNvbm5lY3Rpb24sIGlkKSB7XG4gICAgaWYgKHR5cGVvZiBpZCAhPT0gXCJudW1iZXJcIikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBpZFNlcSBvbiBjb25uZWN0aW9uIHdhc24ndCBzZXQ/ICcke3R5cGVvZiBpZH0nID0gJHtpZH1gKVxuICAgIH1cblxuICAgIGRlbGV0ZSB0aGlzLmNvbm5lY3Rpb25zSW5Vc2VbaWRdXG4gICAgY29ubmVjdGlvbi5zZXRJZFNlcSh1bmRlZmluZWQpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBoYW5kbGUgY2hlY2tlZCBpbiBpZGxlIGNvbm5lY3Rpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIG9uY2UgaWRsZSByZWFwaW5nIGhhcyBiZWVuIHNjaGVkdWxlZCBvciBydW4uXG4gICAqL1xuICBhc3luYyBoYW5kbGVDaGVja2VkSW5JZGxlQ29ubmVjdGlvbigpIHtcbiAgICBpZiAodGhpcy5pZGxlVGltZW91dE1pbGxpcygpID09PSAwKSB7XG4gICAgICBhd2FpdCB0aGlzLnJlYXBJZGxlQ29ubmVjdGlvbnMoKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNjaGVkdWxlSWRsZUNvbm5lY3Rpb25SZWFwZXIoKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGNoZWNrb3V0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vYmFzZS5qc1wiKS5Db25uZWN0aW9uQ2hlY2tvdXRPcHRpb25zfSBbb3B0aW9uc10gLSBDaGVja291dCBvcHRpb25zLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdD59IC0gUmVzb2x2ZXMgd2l0aCB0aGUgY2hlY2tvdXQuXG4gICAqL1xuICBhc3luYyBjaGVja291dChvcHRpb25zID0ge30pIHtcbiAgICBjb25zdCBkYXRhYmFzZUNvbmZpZyA9IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpXG4gICAgY29uc3QgcmV1c2VLZXkgPSB0aGlzLmdldENvbmZpZ3VyYXRpb25SZXVzZUtleSgpXG4gICAgbGV0IGNvbm5lY3Rpb24gPSB0aGlzLnRha2VJZGxlQ29ubmVjdGlvbkZvclJldXNlS2V5KHJldXNlS2V5KVxuXG4gICAgaWYgKGNvbm5lY3Rpb24pIHJldHVybiBhd2FpdCB0aGlzLmFjdGl2YXRlQ29ubmVjdGlvbihjb25uZWN0aW9uLCBvcHRpb25zKVxuXG4gICAgYXdhaXQgdGhpcy5yZWFwSWRsZUNvbm5lY3Rpb25zKClcbiAgICBjb25uZWN0aW9uID0gdGhpcy50YWtlSWRsZUNvbm5lY3Rpb25Gb3JSZXVzZUtleShyZXVzZUtleSlcblxuICAgIGlmIChjb25uZWN0aW9uKSByZXR1cm4gYXdhaXQgdGhpcy5hY3RpdmF0ZUNvbm5lY3Rpb24oY29ubmVjdGlvbiwgb3B0aW9ucylcblxuICAgIGlmICh0aGlzLmNhblNwYXduQ29ubmVjdGlvbigpKSB7XG4gICAgICAvLyBTcGF3biB2aWEgc3Bhd25Db25uZWN0aW9uKCkgc28gdGhlIHRlbmFudC1hd2FyZSBjb25maWd1cmF0aW9uIGlzIHJlc29sdmVkIEZSRVNIIGF0XG4gICAgICAvLyBzcGF3biB0aW1lIGZvciB0aGUgY3VycmVudCBjYWxsZXIuIFJldXNpbmcgdGhlIGRhdGFiYXNlQ29uZmlnIGNhcHR1cmVkIGF0IHRoZSB0b3Agb2ZcbiAgICAgIC8vIGNoZWNrb3V0KCkgY291bGQgYmluZCB0aGUgY29ubmVjdGlvbiB0byBhIHN0YWxlIHRlbmFudC9kYXRhYmFzZSwgd2hpY2ggYnJlYWtzXG4gICAgICAvLyBwZXItcmVxdWVzdCBpc29sYXRpb24gKGUuZy4gdGVzdCB0cnVuY2F0aW9uIGFwcGVhcmluZyBub3QgdG8gdGFrZSBlZmZlY3QpLiBUaGUgcXVldWVkXG4gICAgICAvLyBwYXRoIGJlbG93IGtlZXBzIHRoZSB3YWl0aW5nIGNhbGxlcidzIGNhcHR1cmVkIGNvbmZpZyB2aWEgd2FpdEZvckNoZWNrb3V0KCkuXG4gICAgICBjb25uZWN0aW9uID0gYXdhaXQgdGhpcy5zcGF3bkNvbm5lY3Rpb25Gb3JDaGVja291dCh0aGlzLmdldENvbmZpZ3VyYXRpb24oKSwgdGhpcy5nZXRDb25maWd1cmF0aW9uUmV1c2VLZXkoKSlcblxuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuYWN0aXZhdGVDb25uZWN0aW9uKGNvbm5lY3Rpb24sIG9wdGlvbnMpXG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMud2FpdEZvckNoZWNrb3V0KGRhdGFiYXNlQ29uZmlnLCByZXVzZUtleSwgb3B0aW9ucylcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHRha2UgaWRsZSBjb25uZWN0aW9uIGZvciByZXVzZSBrZXkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByZXVzZUtleSAtIERhdGFiYXNlIGNvbmZpZ3VyYXRpb24gcmV1c2Uga2V5LlxuICAgKiBAcGFyYW0ge29iamVjdH0gW2FyZ3NdIC0gT3B0aW9ucy5cbiAgICogQHBhcmFtIHtib29sZWFufSBbYXJncy5pbmNsdWRlT3BlblRyYW5zYWN0aW9uc10gLSBXaGV0aGVyIGNvbm5lY3Rpb25zIHdpdGggb3BlbiB0cmFuc2FjdGlvbnMgbWF5IGJlIHJldHVybmVkLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgfCB1bmRlZmluZWR9IC0gTWF0Y2hpbmcgaWRsZSBjb25uZWN0aW9uLlxuICAgKi9cbiAgdGFrZUlkbGVDb25uZWN0aW9uRm9yUmV1c2VLZXkocmV1c2VLZXksIHtpbmNsdWRlT3BlblRyYW5zYWN0aW9ucyA9IHRydWV9ID0ge30pIHtcbiAgICBjb25zdCBjb25uZWN0aW9uSW5kZXggPSB0aGlzLmNvbm5lY3Rpb25zLmZpbmRJbmRleCgocXVldWVkQ29ubmVjdGlvbikgPT4ge1xuICAgICAgaWYgKCFpbmNsdWRlT3BlblRyYW5zYWN0aW9ucyAmJiB0aGlzLmNvbm5lY3Rpb25IYXNPcGVuVHJhbnNhY3Rpb24ocXVldWVkQ29ubmVjdGlvbikpIHJldHVybiBmYWxzZVxuXG4gICAgICByZXR1cm4gdGhpcy5jb25uZWN0aW9uTWF0Y2hlc1JldXNlS2V5KHF1ZXVlZENvbm5lY3Rpb24sIHJldXNlS2V5KVxuICAgIH0pXG4gICAgY29uc3QgY29ubmVjdGlvbiA9IGNvbm5lY3Rpb25JbmRleCA9PT0gLTEgPyB1bmRlZmluZWQgOiB0aGlzLmNvbm5lY3Rpb25zLnNwbGljZShjb25uZWN0aW9uSW5kZXgsIDEpWzBdXG5cbiAgICByZXR1cm4gY29ubmVjdGlvblxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgY29ubmVjdGlvbiBtYXRjaGVzIHJldXNlIGtleS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gY29ubmVjdGlvbiAtIENvbm5lY3Rpb24uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByZXVzZUtleSAtIERhdGFiYXNlIGNvbmZpZ3VyYXRpb24gcmV1c2Uga2V5LlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIHRoZSBjb25uZWN0aW9uIG1hdGNoZXMgdGhlIHJldXNlIGtleS5cbiAgICovXG4gIGNvbm5lY3Rpb25NYXRjaGVzUmV1c2VLZXkoY29ubmVjdGlvbiwgcmV1c2VLZXkpIHtcbiAgICBjb25zdCBjb25uZWN0aW9uV2l0aFBvb2xLZXkgPSAvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgJiB7W1BPT0xfQ09ORklHVVJBVElPTl9LRVldPzogc3RyaW5nfX0gKi8gKGNvbm5lY3Rpb24pXG5cbiAgICByZXR1cm4gY29ubmVjdGlvbldpdGhQb29sS2V5W1BPT0xfQ09ORklHVVJBVElPTl9LRVldID09PSByZXVzZUtleVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYWN0aXZhdGUgY29ubmVjdGlvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gY29ubmVjdGlvbiAtIENvbm5lY3Rpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9iYXNlLmpzXCIpLkNvbm5lY3Rpb25DaGVja291dE9wdGlvbnN9IFtvcHRpb25zXSAtIENoZWNrb3V0IG9wdGlvbnMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pn0gLSBBY3RpdmF0ZWQgY29ubmVjdGlvbi5cbiAgICovXG4gIGFzeW5jIGFjdGl2YXRlQ29ubmVjdGlvbihjb25uZWN0aW9uLCBvcHRpb25zID0ge30pIHtcbiAgICBpZiAoY29ubmVjdGlvbi5nZXRJZFNlcSgpICE9PSB1bmRlZmluZWQpIHRocm93IG5ldyBFcnJvcihgQ29ubmVjdGlvbiBhbHJlYWR5IGhhcyBhbiBJRC1zZXEgLSBpcyBpdCBpbiB1c2U/ICR7Y29ubmVjdGlvbi5nZXRJZFNlcSgpfWApXG5cbiAgICBjb25zdCBpZCA9IHRoaXMuaWRTZXErK1xuXG4gICAgY29uc3QgdHJhY2tlZENvbm5lY3Rpb24gPSAvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0ICYge1tDT05ORUNUSU9OX0NIRUNLRURfT1VUX0FUXT86IG51bWJlciwgW0lETEVfQ09OTkVDVElPTl9DSEVDS0VEX0lOX0FUXT86IG51bWJlcn19ICovIChjb25uZWN0aW9uKVxuICAgIGRlbGV0ZSB0cmFja2VkQ29ubmVjdGlvbltJRExFX0NPTk5FQ1RJT05fQ0hFQ0tFRF9JTl9BVF1cbiAgICB0cmFja2VkQ29ubmVjdGlvbltDT05ORUNUSU9OX0NIRUNLRURfT1VUX0FUXSA9IERhdGUubm93KClcblxuICAgIGNvbm5lY3Rpb24uc2V0SWRTZXEoaWQpXG4gICAgdGhpcy5jb25uZWN0aW9uc0luVXNlW2lkXSA9IGNvbm5lY3Rpb25cblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCBjb25uZWN0aW9uLnNldENvbm5lY3Rpb25DaGVja291dE5hbWUob3B0aW9ucy5uYW1lKVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBkZWxldGUgdGhpcy5jb25uZWN0aW9uc0luVXNlW2lkXVxuICAgICAgY29ubmVjdGlvbi5zZXRJZFNlcSh1bmRlZmluZWQpXG4gICAgICBhd2FpdCB0aGlzLmNsb3NlQ29ubmVjdGlvbihjb25uZWN0aW9uKVxuXG4gICAgICB0aHJvdyBlcnJvclxuICAgIH1cblxuICAgIHJldHVybiBjb25uZWN0aW9uXG4gIH1cblxuICAvKipcbiAgICogUnVucyBtYXggY29ubmVjdGlvbnMuXG4gICAqIEByZXR1cm5zIHtudW1iZXIgfCB1bmRlZmluZWR9IC0gQ29uZmlndXJlZCBtYXggbGl2ZSBjb25uZWN0aW9ucy5cbiAgICovXG4gIG1heENvbm5lY3Rpb25zKCkge1xuICAgIGNvbnN0IHZhbHVlID0gdGhpcy5nZXRDb25maWd1cmF0aW9uKCkucG9vbD8ubWF4XG5cbiAgICBpZiAodGhpcy52YWxpZE1heENvbm5lY3Rpb25zKHZhbHVlKSkgcmV0dXJuIHZhbHVlXG5cbiAgICByZXR1cm5cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHZhbGlkIG1heCBjb25uZWN0aW9ucy5cbiAgICogQHBhcmFtIHs/fSB2YWx1ZSAtIENhbmRpZGF0ZSBtYXggY29ubmVjdGlvbiBjb3VudC5cbiAgICogQHJldHVybnMge3ZhbHVlIGlzIG51bWJlcn0gLSBXaGV0aGVyIHRoZSB2YWx1ZSBpcyBhIHZhbGlkIG1heCBjb25uZWN0aW9uIGNvdW50LlxuICAgKi9cbiAgdmFsaWRNYXhDb25uZWN0aW9ucyh2YWx1ZSkge1xuICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwibnVtYmVyXCIgJiYgTnVtYmVyLmlzRmluaXRlKHZhbHVlKSAmJiB2YWx1ZSA+PSAxXG4gIH1cblxuICAvKipcbiAgICogUnVucyBsaXZlIGNvbm5lY3Rpb24gY291bnQuXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IC0gTnVtYmVyIG9mIGxpdmUgYW5kIGluLXByb2dyZXNzIGNvbm5lY3Rpb25zLlxuICAgKi9cbiAgbGl2ZUNvbm5lY3Rpb25Db3VudCgpIHtcbiAgICBjb25zdCBjb25uZWN0aW9ucyA9IG5ldyBTZXQoW1xuICAgICAgLi4udGhpcy5jb25uZWN0aW9ucyxcbiAgICAgIC4uLk9iamVjdC52YWx1ZXModGhpcy5jb25uZWN0aW9uc0luVXNlKSxcbiAgICAgIHRoaXMuZ2V0R2xvYmFsQ29ubmVjdGlvbkZvcklkZW50aWZpZXIoKVxuICAgIF0uZmlsdGVyKEJvb2xlYW4pKVxuXG4gICAgcmV0dXJuIGNvbm5lY3Rpb25zLnNpemUgKyB0aGlzLmNvbm5lY3Rpb25zQmVpbmdTcGF3bmVkXG4gIH1cblxuICAvKipcbiAgICogUnVucyBjYW4gc3Bhd24gY29ubmVjdGlvbi5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gV2hldGhlciBhIG5ldyBjb25uZWN0aW9uIGNhbiBiZSBzcGF3bmVkLlxuICAgKi9cbiAgY2FuU3Bhd25Db25uZWN0aW9uKCkge1xuICAgIGNvbnN0IG1heENvbm5lY3Rpb25zID0gdGhpcy5tYXhDb25uZWN0aW9ucygpXG5cbiAgICByZXR1cm4gbWF4Q29ubmVjdGlvbnMgPT09IHVuZGVmaW5lZCB8fCB0aGlzLmxpdmVDb25uZWN0aW9uQ291bnQoKSA8IG1heENvbm5lY3Rpb25zXG4gIH1cblxuICAvKipcbiAgICogUnVucyBzcGF3biBjb25uZWN0aW9uIGZvciBjaGVja291dC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLkRhdGFiYXNlQ29uZmlndXJhdGlvblR5cGV9IGRhdGFiYXNlQ29uZmlnIC0gUmVzb2x2ZWQgZGF0YWJhc2UgY29uZmlnIGZvciB0aGUgY2hlY2tvdXQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByZXVzZUtleSAtIERhdGFiYXNlIGNvbmZpZ3VyYXRpb24gcmV1c2Uga2V5IGZvciB0aGUgY2hlY2tvdXQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pn0gLSBTcGF3bmVkIGNvbm5lY3Rpb24uXG4gICAqL1xuICBhc3luYyBzcGF3bkNvbm5lY3Rpb25Gb3JDaGVja291dChkYXRhYmFzZUNvbmZpZywgcmV1c2VLZXkpIHtcbiAgICB0aGlzLmNvbm5lY3Rpb25zQmVpbmdTcGF3bmVkKytcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCBjb25uZWN0aW9uID0gYXdhaXQgdGhpcy5zcGF3bkNvbm5lY3Rpb25XaXRoQ29uZmlndXJhdGlvbihkYXRhYmFzZUNvbmZpZylcbiAgICAgIGNvbnN0IGNvbm5lY3Rpb25XaXRoUG9vbEtleSA9IC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgJiB7W1BPT0xfQ09ORklHVVJBVElPTl9LRVldPzogc3RyaW5nfX0gKi8gKGNvbm5lY3Rpb24pXG5cbiAgICAgIGNvbm5lY3Rpb25XaXRoUG9vbEtleVtQT09MX0NPTkZJR1VSQVRJT05fS0VZXSA9IHJldXNlS2V5XG4gICAgICBjb25uZWN0aW9uLnNldFNjaGVtYUNhY2hlSW52YWxpZGF0b3IoKCkgPT4ge1xuICAgICAgICB0aGlzLmNsZWFyU2NoZW1hQ2FjaGUoKVxuICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24uY2xlYXJTY2hlbWFDYWNoZXNGb3JSZXVzZUtleShyZXVzZUtleSlcbiAgICAgIH0pXG5cbiAgICAgIHJldHVybiBjb25uZWN0aW9uXG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuY29ubmVjdGlvbnNCZWluZ1NwYXduZWQtLVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHdhaXQgZm9yIGNoZWNrb3V0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2NvbmZpZ3VyYXRpb24tdHlwZXMuanNcIikuRGF0YWJhc2VDb25maWd1cmF0aW9uVHlwZX0gZGF0YWJhc2VDb25maWcgLSBSZXNvbHZlZCBkYXRhYmFzZSBjb25maWcgZm9yIHRoZSBjaGVja291dC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHJldXNlS2V5IC0gRGF0YWJhc2UgY29uZmlndXJhdGlvbiByZXVzZSBrZXkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9iYXNlLmpzXCIpLkNvbm5lY3Rpb25DaGVja291dE9wdGlvbnN9IFtvcHRpb25zXSAtIENoZWNrb3V0IG9wdGlvbnMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pn0gLSBSZXNvbHZlcyB3aXRoIGFuIGFjdGl2YXRlZCBjb25uZWN0aW9uLlxuICAgKi9cbiAgYXN5bmMgd2FpdEZvckNoZWNrb3V0KGRhdGFiYXNlQ29uZmlnLCByZXVzZUtleSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMucGVuZGluZ0NoZWNrb3V0cy5wdXNoKHtkYXRhYmFzZUNvbmZpZywgZW5xdWV1ZWRBdDogRGF0ZS5ub3coKSwgb3B0aW9ucywgcmVqZWN0LCByZXNvbHZlLCByZXVzZUtleX0pXG4gICAgICB2b2lkIHRoaXMuZHJhaW5QZW5kaW5nQ2hlY2tvdXRzKCkuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgIGNvbnN0IGNoZWNrb3V0RXJyb3IgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiBuZXcgRXJyb3IoXCJGYWlsZWQgdG8gZHJhaW4gcGVuZGluZyBkYXRhYmFzZSBjb25uZWN0aW9uIGNoZWNrb3V0cy5cIiwge2NhdXNlOiBlcnJvcn0pXG5cbiAgICAgICAgdGhpcy5yZWplY3RQZW5kaW5nQ2hlY2tvdXRzKGNoZWNrb3V0RXJyb3IpXG4gICAgICB9KVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogUnVucyBkcmFpbiBwZW5kaW5nIGNoZWNrb3V0cy5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBwZW5kaW5nIGNoZWNrb3V0cyBoYXZlIGJlZW4gZHJhaW5lZCBhcyBmYXIgYXMgcG9zc2libGUuXG4gICAqL1xuICBhc3luYyBkcmFpblBlbmRpbmdDaGVja291dHMoKSB7XG4gICAgaWYgKHRoaXMucGVuZGluZ0NoZWNrb3V0RHJhaW5Qcm9taXNlKSB7XG4gICAgICBhd2FpdCB0aGlzLnBlbmRpbmdDaGVja291dERyYWluUHJvbWlzZVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdGhpcy5wZW5kaW5nQ2hlY2tvdXREcmFpblByb21pc2UgPSB0aGlzLmRyYWluUGVuZGluZ0NoZWNrb3V0c0FjdHVhbCgpXG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5wZW5kaW5nQ2hlY2tvdXREcmFpblByb21pc2VcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5wZW5kaW5nQ2hlY2tvdXREcmFpblByb21pc2UgPSB1bmRlZmluZWRcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBkcmFpbiBwZW5kaW5nIGNoZWNrb3V0cyBhY3R1YWwuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gcGVuZGluZyBjaGVja291dHMgaGF2ZSBiZWVuIGRyYWluZWQgYXMgZmFyIGFzIHBvc3NpYmxlLlxuICAgKi9cbiAgYXN5bmMgZHJhaW5QZW5kaW5nQ2hlY2tvdXRzQWN0dWFsKCkge1xuICAgIHdoaWxlICh0aGlzLnBlbmRpbmdDaGVja291dHMubGVuZ3RoID4gMCkge1xuICAgICAgaWYgKGF3YWl0IHRoaXMucmVzb2x2ZVBlbmRpbmdDaGVja291dFdpdGhNYXRjaGluZ0lkbGVDb25uZWN0aW9uKCkpIGNvbnRpbnVlXG5cbiAgICAgIGNvbnN0IGNoZWNrb3V0ID0gdGhpcy5wZW5kaW5nQ2hlY2tvdXRzWzBdXG5cbiAgICAgIGlmIChhd2FpdCB0aGlzLmNsb3NlSWRsZUNvbm5lY3Rpb25Gb3JQZW5kaW5nQ2hlY2tvdXRDYXBhY2l0eShjaGVja291dCkpIGNvbnRpbnVlXG4gICAgICBpZiAodGhpcy5jYW5TcGF3bkNvbm5lY3Rpb24oKSkge1xuICAgICAgICB0aGlzLnBlbmRpbmdDaGVja291dHMuc2hpZnQoKVxuICAgICAgICBhd2FpdCB0aGlzLnNwYXduQW5kUmVzb2x2ZVBlbmRpbmdDaGVja291dChjaGVja291dClcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVhcGVkQ29ubmVjdGlvbiA9IGF3YWl0IHRoaXMuaWRsZUNvbm5lY3Rpb25Gb3JQZW5kaW5nQ2hlY2tvdXQoY2hlY2tvdXQpXG5cbiAgICAgIGlmICghcmVhcGVkQ29ubmVjdGlvbikgcmV0dXJuXG5cbiAgICAgIHRoaXMucGVuZGluZ0NoZWNrb3V0cy5zaGlmdCgpXG4gICAgICBhd2FpdCB0aGlzLnJlc29sdmVQZW5kaW5nQ2hlY2tvdXQoY2hlY2tvdXQsIHJlYXBlZENvbm5lY3Rpb24pXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgcmVzb2x2ZSBwZW5kaW5nIGNoZWNrb3V0IHdpdGggbWF0Y2hpbmcgaWRsZSBjb25uZWN0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn0gLSBXaGV0aGVyIGEgcGVuZGluZyBjaGVja291dCB3YXMgcmVzb2x2ZWQgd2l0aCBhbiBpZGxlIGNvbm5lY3Rpb24uXG4gICAqL1xuICBhc3luYyByZXNvbHZlUGVuZGluZ0NoZWNrb3V0V2l0aE1hdGNoaW5nSWRsZUNvbm5lY3Rpb24oKSB7XG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHRoaXMucGVuZGluZ0NoZWNrb3V0cy5sZW5ndGg7IGluZGV4KyspIHtcbiAgICAgIGNvbnN0IGNoZWNrb3V0ID0gdGhpcy5wZW5kaW5nQ2hlY2tvdXRzW2luZGV4XVxuICAgICAgY29uc3QgY29ubmVjdGlvbiA9IHRoaXMudGFrZUlkbGVDb25uZWN0aW9uRm9yUmV1c2VLZXkoY2hlY2tvdXQucmV1c2VLZXksIHtpbmNsdWRlT3BlblRyYW5zYWN0aW9uczogZmFsc2V9KVxuXG4gICAgICBpZiAoIWNvbm5lY3Rpb24pIGNvbnRpbnVlXG5cbiAgICAgIHRoaXMucGVuZGluZ0NoZWNrb3V0cy5zcGxpY2UoaW5kZXgsIDEpXG4gICAgICBhd2FpdCB0aGlzLnJlc29sdmVQZW5kaW5nQ2hlY2tvdXQoY2hlY2tvdXQsIGNvbm5lY3Rpb24pXG5cbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICAvKipcbiAgICogUnVucyBjbG9zZSBpZGxlIGNvbm5lY3Rpb24gZm9yIHBlbmRpbmcgY2hlY2tvdXQgY2FwYWNpdHkuXG4gICAqIEBwYXJhbSB7UGVuZGluZ0NoZWNrb3V0fSBjaGVja291dCAtIENoZWNrb3V0IHdhaXRpbmcgZm9yIGEgY29ubmVjdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8Ym9vbGVhbj59IC0gV2hldGhlciBhbiBpZGxlIGNvbm5lY3Rpb24gd2FzIGNsb3NlZCB0byBmcmVlIGNhcGFjaXR5LlxuICAgKi9cbiAgYXN5bmMgY2xvc2VJZGxlQ29ubmVjdGlvbkZvclBlbmRpbmdDaGVja291dENhcGFjaXR5KGNoZWNrb3V0KSB7XG4gICAgY29uc3QgY29ubmVjdGlvbiA9IHRoaXMuZmluZElkbGVDb25uZWN0aW9uRm9yUmV1c2VLZXkoY2hlY2tvdXQucmV1c2VLZXkpXG5cbiAgICBpZiAoY29ubmVjdGlvbikgcmV0dXJuIGZhbHNlXG5cbiAgICBhd2FpdCB0aGlzLnJlYXBJZGxlQ29ubmVjdGlvbnMoKVxuXG4gICAgaWYgKHRoaXMuZmluZElkbGVDb25uZWN0aW9uRm9yUmV1c2VLZXkoY2hlY2tvdXQucmV1c2VLZXkpKSByZXR1cm4gZmFsc2VcblxuICAgIHJldHVybiB0aGlzLmNhblNwYXduQ29ubmVjdGlvbigpID8gZmFsc2UgOiBhd2FpdCB0aGlzLmNsb3NlT25lSWRsZUNvbm5lY3Rpb25Gb3JDYXBhY2l0eSgpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBmaW5kIGlkbGUgY29ubmVjdGlvbiBmb3IgcmV1c2Uga2V5LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcmV1c2VLZXkgLSBEYXRhYmFzZSBjb25maWd1cmF0aW9uIHJldXNlIGtleS5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0IHwgdW5kZWZpbmVkfSAtIE1hdGNoaW5nIGlkbGUgY29ubmVjdGlvbiwgaWYgcHJlc2VudC5cbiAgICovXG4gIGZpbmRJZGxlQ29ubmVjdGlvbkZvclJldXNlS2V5KHJldXNlS2V5KSB7XG4gICAgcmV0dXJuIHRoaXMuY29ubmVjdGlvbnMuZmluZCgoY29ubmVjdGlvbikgPT4gIXRoaXMuY29ubmVjdGlvbkhhc09wZW5UcmFuc2FjdGlvbihjb25uZWN0aW9uKSAmJiB0aGlzLmNvbm5lY3Rpb25NYXRjaGVzUmV1c2VLZXkoY29ubmVjdGlvbiwgcmV1c2VLZXkpKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgaWRsZSBjb25uZWN0aW9uIGZvciBwZW5kaW5nIGNoZWNrb3V0LlxuICAgKiBAcGFyYW0ge1BlbmRpbmdDaGVja291dH0gY2hlY2tvdXQgLSBDaGVja291dCB3YWl0aW5nIGZvciBhIGNvbm5lY3Rpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0IHwgdW5kZWZpbmVkPn0gLSBNYXRjaGluZyBpZGxlIGNvbm5lY3Rpb24sIGlmIG9uZSBjYW4gYmUgcmV1c2VkLlxuICAgKi9cbiAgYXN5bmMgaWRsZUNvbm5lY3Rpb25Gb3JQZW5kaW5nQ2hlY2tvdXQoY2hlY2tvdXQpIHtcbiAgICBsZXQgY29ubmVjdGlvbiA9IHRoaXMudGFrZUlkbGVDb25uZWN0aW9uRm9yUmV1c2VLZXkoY2hlY2tvdXQucmV1c2VLZXksIHtpbmNsdWRlT3BlblRyYW5zYWN0aW9uczogZmFsc2V9KVxuXG4gICAgaWYgKGNvbm5lY3Rpb24pIHJldHVybiBjb25uZWN0aW9uXG5cbiAgICBhd2FpdCB0aGlzLnJlYXBJZGxlQ29ubmVjdGlvbnMoKVxuICAgIGNvbm5lY3Rpb24gPSB0aGlzLnRha2VJZGxlQ29ubmVjdGlvbkZvclJldXNlS2V5KGNoZWNrb3V0LnJldXNlS2V5LCB7aW5jbHVkZU9wZW5UcmFuc2FjdGlvbnM6IGZhbHNlfSlcblxuICAgIHJldHVybiBjb25uZWN0aW9uXG4gIH1cblxuICAvKipcbiAgICogUnVucyBzcGF3biBhbmQgcmVzb2x2ZSBwZW5kaW5nIGNoZWNrb3V0LlxuICAgKiBAcGFyYW0ge1BlbmRpbmdDaGVja291dH0gY2hlY2tvdXQgLSBDaGVja291dCByZXF1ZXN0IHRvIHJlc29sdmUuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gdGhlIGNoZWNrb3V0IGhhcyBiZWVuIGhhbmRsZWQuXG4gICAqL1xuICBhc3luYyBzcGF3bkFuZFJlc29sdmVQZW5kaW5nQ2hlY2tvdXQoY2hlY2tvdXQpIHtcbiAgICBsZXQgY29ubmVjdGlvblxuXG4gICAgdHJ5IHtcbiAgICAgIGNvbm5lY3Rpb24gPSBhd2FpdCB0aGlzLnNwYXduQ29ubmVjdGlvbkZvckNoZWNrb3V0KGNoZWNrb3V0LmRhdGFiYXNlQ29uZmlnLCBjaGVja291dC5yZXVzZUtleSlcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY2hlY2tvdXQucmVqZWN0KGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IG5ldyBFcnJvcihcIkZhaWxlZCB0byBzcGF3biBkYXRhYmFzZSBjb25uZWN0aW9uLlwiLCB7Y2F1c2U6IGVycm9yfSkpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLnJlc29sdmVQZW5kaW5nQ2hlY2tvdXQoY2hlY2tvdXQsIGNvbm5lY3Rpb24pXG4gIH1cblxuICAvKipcbiAgICogUnVucyByZXNvbHZlIHBlbmRpbmcgY2hlY2tvdXQuXG4gICAqIEBwYXJhbSB7UGVuZGluZ0NoZWNrb3V0fSBjaGVja291dCAtIENoZWNrb3V0IHJlcXVlc3QgdG8gcmVzb2x2ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gY29ubmVjdGlvbiAtIENvbm5lY3Rpb24gdG8gYWN0aXZhdGUuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gdGhlIGNoZWNrb3V0IGhhcyBiZWVuIGhhbmRsZWQuXG4gICAqL1xuICBhc3luYyByZXNvbHZlUGVuZGluZ0NoZWNrb3V0KGNoZWNrb3V0LCBjb25uZWN0aW9uKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNoZWNrb3V0LnJlc29sdmUoYXdhaXQgdGhpcy5hY3RpdmF0ZUNvbm5lY3Rpb24oY29ubmVjdGlvbiwgY2hlY2tvdXQub3B0aW9ucykpXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNoZWNrb3V0LnJlamVjdChlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiBuZXcgRXJyb3IoXCJGYWlsZWQgdG8gYWN0aXZhdGUgZGF0YWJhc2UgY29ubmVjdGlvbi5cIiwge2NhdXNlOiBlcnJvcn0pKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGNsb3NlIG9uZSBpZGxlIGNvbm5lY3Rpb24gZm9yIGNhcGFjaXR5LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn0gLSBXaGV0aGVyIGFuIGlkbGUgY29ubmVjdGlvbiB3YXMgY2xvc2VkIHRvIGZyZWUgY2FwYWNpdHkuXG4gICAqL1xuICBhc3luYyBjbG9zZU9uZUlkbGVDb25uZWN0aW9uRm9yQ2FwYWNpdHkoKSB7XG4gICAgY29uc3QgY29ubmVjdGlvbiA9IHRoaXMuY29ubmVjdGlvbnMuZmluZCgoY2FuZGlkYXRlKSA9PiAhdGhpcy5jb25uZWN0aW9uSGFzT3BlblRyYW5zYWN0aW9uKGNhbmRpZGF0ZSkpXG5cbiAgICBpZiAoIWNvbm5lY3Rpb24pIHJldHVybiBmYWxzZVxuXG4gICAgdGhpcy5jb25uZWN0aW9ucyA9IHRoaXMuY29ubmVjdGlvbnMuZmlsdGVyKChjYW5kaWRhdGUpID0+IGNhbmRpZGF0ZSAhPT0gY29ubmVjdGlvbilcbiAgICBhd2FpdCB0aGlzLmNsb3NlQ29ubmVjdGlvbihjb25uZWN0aW9uKVxuXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHdpdGggY29ubmVjdGlvbi5cbiAgICogQHRlbXBsYXRlIFRcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2Jhc2UuanNcIikuQ29ubmVjdGlvbkNoZWNrb3V0T3B0aW9ucyB8IGZ1bmN0aW9uKGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0KSA6IFByb21pc2U8VD59IG9wdGlvbnNPckNhbGxiYWNrIC0gQ2hlY2tvdXQgb3B0aW9ucyBvciBjYWxsYmFjayB0byBpbnZva2Ugd2l0aCB0aGUgY29ubmVjdGlvbi5cbiAgICogQHBhcmFtIHtmdW5jdGlvbihpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCkgOiBQcm9taXNlPFQ+fSBbY2FsbGJhY2tdIC0gQ2FsbGJhY2sgdG8gaW52b2tlIHdpdGggdGhlIGNvbm5lY3Rpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFQ+fSAtIFJlc29sdmVzIHdpdGggdGhlIGNhbGxiYWNrIHJlc3VsdC5cbiAgICovXG4gIGFzeW5jIHdpdGhDb25uZWN0aW9uKG9wdGlvbnNPckNhbGxiYWNrLCBjYWxsYmFjaykge1xuICAgIGNvbnN0IG9wdGlvbnMgPSB0eXBlb2Ygb3B0aW9uc09yQ2FsbGJhY2sgPT0gXCJmdW5jdGlvblwiID8ge30gOiBvcHRpb25zT3JDYWxsYmFja1xuICAgIGNvbnN0IGFjdHVhbENhbGxiYWNrID0gdHlwZW9mIG9wdGlvbnNPckNhbGxiYWNrID09IFwiZnVuY3Rpb25cIiA/IG9wdGlvbnNPckNhbGxiYWNrIDogY2FsbGJhY2tcblxuICAgIGlmICghYWN0dWFsQ2FsbGJhY2spIHRocm93IG5ldyBFcnJvcihcIndpdGhDb25uZWN0aW9uIHJlcXVpcmVzIGEgY2FsbGJhY2tcIilcblxuICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBhd2FpdCB0aGlzLmNoZWNrb3V0KG9wdGlvbnMpXG4gICAgY29uc3QgaWQgPSBjb25uZWN0aW9uLmdldElkU2VxKClcblxuICAgIHJldHVybiBhd2FpdCB0aGlzLmFzeW5jTG9jYWxTdG9yYWdlLnJ1bihpZCwgYXN5bmMgKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IGFjdHVhbENhbGxiYWNrKGNvbm5lY3Rpb24pXG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCB0aGlzLmNoZWNraW4oY29ubmVjdGlvbilcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZ2V0IGN1cnJlbnQgY29ubmVjdGlvbi5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSAtIFRoZSBjdXJyZW50IGNvbm5lY3Rpb24uXG4gICAqL1xuICBnZXRDdXJyZW50Q29ubmVjdGlvbigpIHtcbiAgICBjb25zdCBpZCA9IHRoaXMuYXN5bmNMb2NhbFN0b3JhZ2UuZ2V0U3RvcmUoKVxuXG4gICAgaWYgKGlkID09PSB1bmRlZmluZWQpIHJldHVybiB0aGlzLmN1cnJlbnRGYWxsYmFja0Nvbm5lY3Rpb25PckZhaWwoKVxuXG4gICAgdGhpcy5lbnN1cmVDb25uZWN0aW9uSXNJblVzZShpZClcblxuICAgIGNvbnN0IGN1cnJlbnRDb25uZWN0aW9uID0gdGhpcy5jb25uZWN0aW9uc0luVXNlW2lkXVxuXG4gICAgaWYgKCFjdXJyZW50Q29ubmVjdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDb3VsZG4ndCBnZXQgY3VycmVudCBjb25uZWN0aW9uIGZyb20gdGhhdCBJRDogJHtpZH1gKVxuICAgIH1cblxuICAgIHJldHVybiBjdXJyZW50Q29ubmVjdGlvblxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgY3VycmVudCBmYWxsYmFjayBjb25uZWN0aW9uIG9yIGZhaWwuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gLSBGYWxsYmFjayBjb25uZWN0aW9uLCBpZiBwcmVzZW50LlxuICAgKi9cbiAgY3VycmVudEZhbGxiYWNrQ29ubmVjdGlvbk9yRmFpbCgpIHtcbiAgICBjb25zdCBmYWxsYmFja0Nvbm5lY3Rpb24gPSB0aGlzLmdldEdsb2JhbENvbm5lY3Rpb24oKVxuXG4gICAgaWYgKGZhbGxiYWNrQ29ubmVjdGlvbikgcmV0dXJuIGZhbGxiYWNrQ29ubmVjdGlvblxuXG4gICAgdGhyb3cgbmV3IEVycm9yKFwiSUQgaGFzbid0IGJlZW4gc2V0IGZvciB0aGlzIGFzeW5jIGNvbnRleHRcIilcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGVuc3VyZSBjb25uZWN0aW9uIGlzIGluIHVzZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGlkIC0gQ2hlY2tlZC1vdXQgY29ubmVjdGlvbiBpZC5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBlbnN1cmVDb25uZWN0aW9uSXNJblVzZShpZCkge1xuICAgIGlmICghKGlkIGluIHRoaXMuY29ubmVjdGlvbnNJblVzZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQ29ubmVjdGlvbiAke2lkfSBkb2Vzbid0IGV4aXN0IGFueSBtb3JlIC0gaGFzIGl0IGJlZW4gY2hlY2tlZCBpbiBhZ2Fpbj9gKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlcnMgYSBmYWxsYmFjayBjb25uZWN0aW9uIGZvciB0aGlzIHBvb2wgaWRlbnRpZmllciB0aGF0IHdpbGwgYmUgdXNlZCB3aGVuIG5vIGFzeW5jIGNvbnRleHQgaXMgYXZhaWxhYmxlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBjb25uZWN0aW9uIC0gQ29ubmVjdGlvbi5cbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgc2V0R2xvYmFsQ29ubmVjdGlvbihjb25uZWN0aW9uKSB7XG4gICAgY29uc3Qga2xhc3MgPSAvKipcbiAgICAgICAgICAgICAgICAgICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICAgICAgICAgICAgICAgICAgQHR5cGUge3R5cGVvZiBWZWxvY2lvdXNEYXRhYmFzZVBvb2xBc3luY1RyYWNrZWRNdWx0aUNvbm5lY3Rpb259ICovICh0aGlzLmNvbnN0cnVjdG9yKVxuICAgIGxldCBtYXBGb3JDb25maWd1cmF0aW9uID0ga2xhc3MuZ2xvYmFsQ29ubmVjdGlvbnMuZ2V0KHRoaXMuY29uZmlndXJhdGlvbilcblxuICAgIGlmICghbWFwRm9yQ29uZmlndXJhdGlvbikge1xuICAgICAgbWFwRm9yQ29uZmlndXJhdGlvbiA9IHt9XG4gICAgICBrbGFzcy5nbG9iYWxDb25uZWN0aW9ucy5zZXQodGhpcy5jb25maWd1cmF0aW9uLCBtYXBGb3JDb25maWd1cmF0aW9uKVxuICAgIH1cblxuICAgIG1hcEZvckNvbmZpZ3VyYXRpb25bdGhpcy5pZGVudGlmaWVyXSA9IGNvbm5lY3Rpb25cbiAgfVxuXG4gIC8qKlxuICAgKiBFbnN1cmVzIGEgZ2xvYmFsIGZhbGxiYWNrIGNvbm5lY3Rpb24gZXhpc3RzIGZvciB0aGlzIHBvb2wgaWRlbnRpZmllciBhbmQgcmV0dXJucyBpdC5cbiAgICogSWYgb25lIGlzIGFscmVhZHkgc2V0LCBpdCBpcyByZXR1cm5lZCBhbmQgYWxzbyBtYWRlIGF2YWlsYWJsZSBpbiB0aGUgcG9vbCBxdWV1ZS5cbiAgICogT3RoZXJ3aXNlIGEgbmV3IGNvbm5lY3Rpb24gaXMgc3Bhd25lZCwgcmVnaXN0ZXJlZCwgYW5kIHF1ZXVlZC5cbiAgICogQHJldHVybnMge1Byb21pc2U8aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQ+fSAtIFJlc29sdmVzIHdpdGggdGhlIGdsb2JhbCBjb25uZWN0aW9uLlxuICAgKi9cbiAgYXN5bmMgZW5zdXJlR2xvYmFsQ29ubmVjdGlvbigpIHtcbiAgICBjb25zdCBleGlzdGluZyA9IHRoaXMuZ2V0R2xvYmFsQ29ubmVjdGlvbigpXG5cbiAgICBpZiAoZXhpc3RpbmcpIHJldHVybiBleGlzdGluZ1xuXG4gICAgY29uc3QgY29ubmVjdGlvbiA9IGF3YWl0IHRoaXMuc3Bhd25Db25uZWN0aW9uKClcblxuICAgIHRoaXMuc2V0R2xvYmFsQ29ubmVjdGlvbihjb25uZWN0aW9uKVxuXG4gICAgcmV0dXJuIGNvbm5lY3Rpb25cbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgYSBzaGFyZWQgY29ubmVjdGlvbiBmb3IgdGVzdCBtb2RlIHNvIHRoYXQgSFRUUCBoYW5kbGVycyBydW5uaW5nXG4gICAqIGluIHRoZSBzYW1lIHByb2Nlc3MgY2FuIHJldXNlIHRoZSB0ZXN0IHJ1bm5lcidzIGRhdGFiYXNlIGNvbm5lY3Rpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGNvbm5lY3Rpb24gLSBTaGFyZWQgY29ubmVjdGlvbi5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBzZXRUZXN0U2hhcmVkQ29ubmVjdGlvbihjb25uZWN0aW9uKSB7XG4gICAgdGhpcy5fdGVzdFNoYXJlZENvbm5lY3Rpb24gPSBjb25uZWN0aW9uXG4gIH1cblxuICAvKipcbiAgICogUnVucyBjbGVhciB0ZXN0IHNoYXJlZCBjb25uZWN0aW9uLlxuICAgIEByZXR1cm5zIHt2b2lkfSAqL1xuICBjbGVhclRlc3RTaGFyZWRDb25uZWN0aW9uKCkge1xuICAgIHRoaXMuX3Rlc3RTaGFyZWRDb25uZWN0aW9uID0gdW5kZWZpbmVkXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgY29ubmVjdGlvbiB0aWVkIHRvIHRoZSBjdXJyZW50IGFzeW5jIGNvbnRleHQsIGlmIGFueS5cbiAgICogRmFsbHMgYmFjayB0byB0aGUgdGVzdCBzaGFyZWQgY29ubmVjdGlvbiB3aGVuIG5vIGFzeW5jIGNvbnRleHQgZXhpc3RzLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgfCB1bmRlZmluZWR9IC0gVGhlIGN1cnJlbnQgY29udGV4dCBjb25uZWN0aW9uLlxuICAgKi9cbiAgZ2V0Q3VycmVudENvbnRleHRDb25uZWN0aW9uKCkge1xuICAgIGNvbnN0IGlkID0gdGhpcy5hc3luY0xvY2FsU3RvcmFnZS5nZXRTdG9yZSgpXG5cbiAgICBpZiAoaWQgPT09IHVuZGVmaW5lZCkgcmV0dXJuIHRoaXMuX3Rlc3RTaGFyZWRDb25uZWN0aW9uXG5cbiAgICByZXR1cm4gdGhpcy5nZXRDdXJyZW50Q29ubmVjdGlvbigpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBnZXQgZGVidWcgc25hcHNob3QuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL2Jhc2UuanNcIikuRGF0YWJhc2VQb29sRGVidWdTbmFwc2hvdH0gLSBEaWFnbm9zdGljIHNuYXBzaG90IGZvciB0aGlzIHBvb2wuXG4gICAqL1xuICBnZXREZWJ1Z1NuYXBzaG90KCkge1xuICAgIGNvbnN0IHNuYXBzaG90ID0gc3VwZXIuZ2V0RGVidWdTbmFwc2hvdCgpXG4gICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKVxuICAgIGNvbnN0IHtjb25uZWN0aW9uc30gPSB0aGlzLmRlYnVnQ29ubmVjdGlvblNuYXBzaG90cyhub3cpXG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4uc25hcHNob3QsXG4gICAgICBjb25uZWN0aW9ucyxcbiAgICAgIGNvbm5lY3Rpb25zQmVpbmdTcGF3bmVkOiB0aGlzLmNvbm5lY3Rpb25zQmVpbmdTcGF3bmVkLFxuICAgICAgaWRsZUNvdW50OiB0aGlzLmNvbm5lY3Rpb25zLmxlbmd0aCxcbiAgICAgIGluVXNlQ291bnQ6IE9iamVjdC5rZXlzKHRoaXMuY29ubmVjdGlvbnNJblVzZSkubGVuZ3RoLFxuICAgICAgcGVuZGluZ0NoZWNrb3V0czogdGhpcy5wZW5kaW5nQ2hlY2tvdXREZWJ1Z1NuYXBzaG90cyhub3cpLFxuICAgICAgcGVuZGluZ0NoZWNrb3V0Q291bnQ6IHRoaXMucGVuZGluZ0NoZWNrb3V0cy5sZW5ndGhcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBkZWJ1ZyBjb25uZWN0aW9uIHNuYXBzaG90cy5cbiAgICogQHBhcmFtIHtudW1iZXJ9IG5vdyAtIEN1cnJlbnQgdGltZXN0YW1wLlxuICAgKiBAcmV0dXJucyB7e2Nvbm5lY3Rpb25zOiBBcnJheTxSZWNvcmQ8c3RyaW5nLCA/Pj4sIHNlZW5Db25uZWN0aW9uczogU2V0PGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pn19IC0gQ29ubmVjdGlvbiBzbmFwc2hvdHMgYW5kIHNlZW4gc2V0LlxuICAgKi9cbiAgZGVidWdDb25uZWN0aW9uU25hcHNob3RzKG5vdykge1xuICAgIC8qKlxuICAgICAqIENvbm5lY3Rpb25zLlxuICAgICAgQHR5cGUge0FycmF5PFJlY29yZDxzdHJpbmcsID8+Pn0gKi9cbiAgICBjb25zdCBjb25uZWN0aW9ucyA9IFtdXG4gICAgY29uc3Qgc2VlbkNvbm5lY3Rpb25zID0gbmV3IFNldCgpXG5cbiAgICB0aGlzLmFkZEluVXNlRGVidWdDb25uZWN0aW9uU25hcHNob3RzKHtjb25uZWN0aW9ucywgbm93LCBzZWVuQ29ubmVjdGlvbnN9KVxuICAgIHRoaXMuYWRkSWRsZURlYnVnQ29ubmVjdGlvblNuYXBzaG90cyh7Y29ubmVjdGlvbnMsIG5vdywgc2VlbkNvbm5lY3Rpb25zfSlcbiAgICB0aGlzLmFkZEZhbGxiYWNrRGVidWdDb25uZWN0aW9uU25hcHNob3RzKHtjb25uZWN0aW9ucywgc2VlbkNvbm5lY3Rpb25zfSlcblxuICAgIHJldHVybiB7Y29ubmVjdGlvbnMsIHNlZW5Db25uZWN0aW9uc31cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGFkZCBpbiB1c2UgZGVidWcgY29ubmVjdGlvbiBzbmFwc2hvdHMuXG4gICAqIEBwYXJhbSB7e2Nvbm5lY3Rpb25zOiBBcnJheTxSZWNvcmQ8c3RyaW5nLCA/Pj4sIG5vdzogbnVtYmVyLCBzZWVuQ29ubmVjdGlvbnM6IFNldDxpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdD59fSBhcmdzIC0gU25hcHNob3QgY29sbGVjdGlvbiBzdGF0ZS5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBhZGRJblVzZURlYnVnQ29ubmVjdGlvblNuYXBzaG90cyh7Y29ubmVjdGlvbnMsIG5vdywgc2VlbkNvbm5lY3Rpb25zfSkge1xuICAgIGZvciAoY29uc3QgW2lkLCBjb25uZWN0aW9uXSBvZiBPYmplY3QuZW50cmllcyh0aGlzLmNvbm5lY3Rpb25zSW5Vc2UpKSB7XG4gICAgICBjb25zdCB0cmFja2VkQ29ubmVjdGlvbiA9IC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0ICYge1tDT05ORUNUSU9OX0NIRUNLRURfT1VUX0FUXT86IG51bWJlcn19ICovIChjb25uZWN0aW9uKVxuICAgICAgY29uc3QgY2hlY2tlZE91dEF0ID0gdHJhY2tlZENvbm5lY3Rpb25bQ09OTkVDVElPTl9DSEVDS0VEX09VVF9BVF1cbiAgICAgIGNvbnN0IGNoZWNrZWRPdXRGb3JNcyA9IHR5cGVvZiBjaGVja2VkT3V0QXQgPT09IFwibnVtYmVyXCIgPyBNYXRoLm1heCgwLCBub3cgLSBjaGVja2VkT3V0QXQpIDogdW5kZWZpbmVkXG5cbiAgICAgIHNlZW5Db25uZWN0aW9ucy5hZGQoY29ubmVjdGlvbilcbiAgICAgIGNvbm5lY3Rpb25zLnB1c2godGhpcy5kZWJ1Z0Nvbm5lY3Rpb25TbmFwc2hvdChjb25uZWN0aW9uLCB7Y2hlY2tlZE91dEF0LCBjaGVja2VkT3V0Rm9yTXMsIGNoZWNrb3V0SWQ6IGlkLCBzdGF0ZTogXCJpbi11c2VcIn0pKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGFkZCBpZGxlIGRlYnVnIGNvbm5lY3Rpb24gc25hcHNob3RzLlxuICAgKiBAcGFyYW0ge3tjb25uZWN0aW9uczogQXJyYXk8UmVjb3JkPHN0cmluZywgPz4+LCBub3c6IG51bWJlciwgc2VlbkNvbm5lY3Rpb25zOiBTZXQ8aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQ+fX0gYXJncyAtIFNuYXBzaG90IGNvbGxlY3Rpb24gc3RhdGUuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgYWRkSWRsZURlYnVnQ29ubmVjdGlvblNuYXBzaG90cyh7Y29ubmVjdGlvbnMsIG5vdywgc2VlbkNvbm5lY3Rpb25zfSkge1xuICAgIGZvciAoY29uc3QgY29ubmVjdGlvbiBvZiB0aGlzLmNvbm5lY3Rpb25zKSB7XG4gICAgICBpZiAoc2VlbkNvbm5lY3Rpb25zLmhhcyhjb25uZWN0aW9uKSkgY29udGludWVcblxuICAgICAgc2VlbkNvbm5lY3Rpb25zLmFkZChjb25uZWN0aW9uKVxuXG4gICAgICBjb25zdCB0cmFja2VkQ29ubmVjdGlvbiA9IC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0ICYge1tJRExFX0NPTk5FQ1RJT05fQ0hFQ0tFRF9JTl9BVF0/OiBudW1iZXJ9fSAqLyAoY29ubmVjdGlvbilcbiAgICAgIGNvbnN0IGNoZWNrZWRJbkF0ID0gdHJhY2tlZENvbm5lY3Rpb25bSURMRV9DT05ORUNUSU9OX0NIRUNLRURfSU5fQVRdXG4gICAgICBjb25zdCBpZGxlRm9yTXMgPSB0eXBlb2YgY2hlY2tlZEluQXQgPT09IFwibnVtYmVyXCIgPyBNYXRoLm1heCgwLCBub3cgLSBjaGVja2VkSW5BdCkgOiB1bmRlZmluZWRcblxuICAgICAgY29ubmVjdGlvbnMucHVzaCh0aGlzLmRlYnVnQ29ubmVjdGlvblNuYXBzaG90KGNvbm5lY3Rpb24sIHtjaGVja2VkSW5BdCwgaWRsZUZvck1zLCBzdGF0ZTogXCJpZGxlXCJ9KSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBhZGQgZmFsbGJhY2sgZGVidWcgY29ubmVjdGlvbiBzbmFwc2hvdHMuXG4gICAqIEBwYXJhbSB7e2Nvbm5lY3Rpb25zOiBBcnJheTxSZWNvcmQ8c3RyaW5nLCA/Pj4sIHNlZW5Db25uZWN0aW9uczogU2V0PGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pn19IGFyZ3MgLSBTbmFwc2hvdCBjb2xsZWN0aW9uIHN0YXRlLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGFkZEZhbGxiYWNrRGVidWdDb25uZWN0aW9uU25hcHNob3RzKHtjb25uZWN0aW9ucywgc2VlbkNvbm5lY3Rpb25zfSkge1xuICAgIHRoaXMuYWRkRGVidWdDb25uZWN0aW9uU25hcHNob3RJZlVuc2Vlbih7Y29ubmVjdGlvbjogdGhpcy5nZXRHbG9iYWxDb25uZWN0aW9uRm9ySWRlbnRpZmllcigpLCBjb25uZWN0aW9ucywgcmVhcGFibGU6IGZhbHNlLCBzZWVuQ29ubmVjdGlvbnMsIHN0YXRlOiBcImdsb2JhbFwifSlcbiAgICB0aGlzLmFkZERlYnVnQ29ubmVjdGlvblNuYXBzaG90SWZVbnNlZW4oe2Nvbm5lY3Rpb246IHRoaXMuX3Rlc3RTaGFyZWRDb25uZWN0aW9uLCBjb25uZWN0aW9ucywgcmVhcGFibGU6IGZhbHNlLCBzZWVuQ29ubmVjdGlvbnMsIHN0YXRlOiBcInRlc3Qtc2hhcmVkXCJ9KVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYWRkIGRlYnVnIGNvbm5lY3Rpb24gc25hcHNob3QgaWYgdW5zZWVuLlxuICAgKiBAcGFyYW0ge3tjb25uZWN0aW9uOiBpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCB8IHVuZGVmaW5lZCwgY29ubmVjdGlvbnM6IEFycmF5PFJlY29yZDxzdHJpbmcsID8+PiwgcmVhcGFibGU/OiBib29sZWFuLCBzZWVuQ29ubmVjdGlvbnM6IFNldDxpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdD4sIHN0YXRlOiBzdHJpbmd9fSBhcmdzIC0gU25hcHNob3QgY29sbGVjdGlvbiBzdGF0ZS5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBhZGREZWJ1Z0Nvbm5lY3Rpb25TbmFwc2hvdElmVW5zZWVuKHtjb25uZWN0aW9uLCBjb25uZWN0aW9ucywgcmVhcGFibGUsIHNlZW5Db25uZWN0aW9ucywgc3RhdGV9KSB7XG4gICAgaWYgKCFjb25uZWN0aW9uIHx8IHNlZW5Db25uZWN0aW9ucy5oYXMoY29ubmVjdGlvbikpIHJldHVyblxuXG4gICAgc2VlbkNvbm5lY3Rpb25zLmFkZChjb25uZWN0aW9uKVxuICAgIGNvbm5lY3Rpb25zLnB1c2godGhpcy5kZWJ1Z0Nvbm5lY3Rpb25TbmFwc2hvdChjb25uZWN0aW9uLCB7cmVhcGFibGUsIHN0YXRlfSkpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBwZW5kaW5nIGNoZWNrb3V0IGRlYnVnIHNuYXBzaG90cy5cbiAgICogQHBhcmFtIHtudW1iZXJ9IG5vdyAtIEN1cnJlbnQgdGltZXN0YW1wLlxuICAgKiBAcmV0dXJucyB7QXJyYXk8UmVjb3JkPHN0cmluZywgPz4+fSAtIFBlbmRpbmcgY2hlY2tvdXQgc25hcHNob3RzLlxuICAgKi9cbiAgcGVuZGluZ0NoZWNrb3V0RGVidWdTbmFwc2hvdHMobm93KSB7XG4gICAgcmV0dXJuIHRoaXMucGVuZGluZ0NoZWNrb3V0cy5tYXAoKGNoZWNrb3V0LCBpbmRleCkgPT4gKHtcbiAgICAgIGNoZWNrb3V0TmFtZTogY2hlY2tvdXQub3B0aW9ucy5uYW1lLFxuICAgICAgZW5xdWV1ZWRBdDogY2hlY2tvdXQuZW5xdWV1ZWRBdCxcbiAgICAgIGluZGV4LFxuICAgICAgcmV1c2VLZXk6IGNoZWNrb3V0LnJldXNlS2V5LFxuICAgICAgd2FpdGluZ0Zvck1zOiBNYXRoLm1heCgwLCBub3cgLSBjaGVja291dC5lbnF1ZXVlZEF0KVxuICAgIH0pKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZ2V0IGdsb2JhbCBjb25uZWN0aW9uLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgfCB1bmRlZmluZWR9IC0gVGhlIGdsb2JhbCBjb25uZWN0aW9uLlxuICAgKi9cbiAgZ2V0R2xvYmFsQ29ubmVjdGlvbigpIHtcbiAgICBjb25zdCBjb25uZWN0aW9uID0gdGhpcy5nZXRHbG9iYWxDb25uZWN0aW9uRm9ySWRlbnRpZmllcigpXG5cbiAgICBpZiAoIWNvbm5lY3Rpb24pIHJldHVyblxuICAgIGlmICghdGhpcy5jb25uZWN0aW9uTWF0Y2hlc0N1cnJlbnRDb25maWd1cmF0aW9uKGNvbm5lY3Rpb24pKSByZXR1cm5cblxuICAgIHJldHVybiBjb25uZWN0aW9uXG4gIH1cblxuICAvKipcbiAgICogUnVucyBnZXQgZ2xvYmFsIGNvbm5lY3Rpb24gZm9yIGlkZW50aWZpZXIuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCB8IHVuZGVmaW5lZH0gLSBUaGUgZ2xvYmFsIGNvbm5lY3Rpb24gZm9yIHRoaXMgcG9vbCBpZGVudGlmaWVyLlxuICAgKi9cbiAgZ2V0R2xvYmFsQ29ubmVjdGlvbkZvcklkZW50aWZpZXIoKSB7XG4gICAgY29uc3Qga2xhc3MgPSAvKipcbiAgICAgICAgICAgICAgICAgICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICAgICAgICAgICAgICAgICAgQHR5cGUge3R5cGVvZiBWZWxvY2lvdXNEYXRhYmFzZVBvb2xBc3luY1RyYWNrZWRNdWx0aUNvbm5lY3Rpb259ICovICh0aGlzLmNvbnN0cnVjdG9yKVxuICAgIGNvbnN0IG1hcEZvckNvbmZpZ3VyYXRpb24gPSBrbGFzcy5nbG9iYWxDb25uZWN0aW9ucy5nZXQodGhpcy5jb25maWd1cmF0aW9uKVxuXG4gICAgcmV0dXJuIG1hcEZvckNvbmZpZ3VyYXRpb24/Llt0aGlzLmlkZW50aWZpZXJdXG4gIH1cblxuICAvKipcbiAgICogUnVucyBjbGVhciBnbG9iYWwgY29ubmVjdGlvbiBmb3IgaWRlbnRpZmllci5cbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgY2xlYXJHbG9iYWxDb25uZWN0aW9uRm9ySWRlbnRpZmllcigpIHtcbiAgICBjb25zdCBrbGFzcyA9IC8qKlxuICAgICAgICAgICAgICAgICAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgICAgICAgICAgICAgICAgICBAdHlwZSB7dHlwZW9mIFZlbG9jaW91c0RhdGFiYXNlUG9vbEFzeW5jVHJhY2tlZE11bHRpQ29ubmVjdGlvbn0gKi8gKHRoaXMuY29uc3RydWN0b3IpXG4gICAgY29uc3QgbWFwRm9yQ29uZmlndXJhdGlvbiA9IGtsYXNzLmdsb2JhbENvbm5lY3Rpb25zLmdldCh0aGlzLmNvbmZpZ3VyYXRpb24pXG5cbiAgICBpZiAoIW1hcEZvckNvbmZpZ3VyYXRpb24pIHJldHVyblxuXG4gICAgZGVsZXRlIG1hcEZvckNvbmZpZ3VyYXRpb25bdGhpcy5pZGVudGlmaWVyXVxuICB9XG5cbiAgLyoqXG4gICAqIENsZWFycyBzY2hlbWEgbWV0YWRhdGEgY2FjaGVkIGJ5IGV2ZXJ5IGxpdmUgY29ubmVjdGlvbiBvd25lZCBieSB0aGlzIHBvb2wuXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIGNsZWFyU2NoZW1hQ2FjaGUoKSB7XG4gICAgY29uc3QgY29ubmVjdGlvbnMgPSBuZXcgU2V0KFtcbiAgICAgIC4uLnRoaXMuY29ubmVjdGlvbnMsXG4gICAgICAuLi5PYmplY3QudmFsdWVzKHRoaXMuY29ubmVjdGlvbnNJblVzZSksXG4gICAgICB0aGlzLmdldEdsb2JhbENvbm5lY3Rpb24oKSxcbiAgICAgIHRoaXMuX3Rlc3RTaGFyZWRDb25uZWN0aW9uXG4gICAgXS5maWx0ZXIoQm9vbGVhbikpXG5cbiAgICBmb3IgKGNvbnN0IGNvbm5lY3Rpb24gb2YgY29ubmVjdGlvbnMpIHtcbiAgICAgIGlmIChjb25uZWN0aW9uKSB0aGlzLl9jbGVhckNvbm5lY3Rpb25TY2hlbWFDYWNoZShjb25uZWN0aW9uKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGlkbGUgdGltZW91dCBtaWxsaXMuXG4gICAqIEByZXR1cm5zIHtudW1iZXIgfCBudWxsfSAtIElkbGUgdGltZW91dCBpbiBtaWxsaXNlY29uZHMsIG9yIG51bGwgd2hlbiBkaXNhYmxlZC5cbiAgICovXG4gIGlkbGVUaW1lb3V0TWlsbGlzKCkge1xuICAgIGNvbnN0IHZhbHVlID0gdGhpcy5nZXRDb25maWd1cmF0aW9uKCkucG9vbD8uaWRsZVRpbWVvdXRNaWxsaXNcblxuICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkgcmV0dXJuIG51bGxcbiAgICBpZiAodGhpcy52YWxpZElkbGVUaW1lb3V0TWlsbGlzKHZhbHVlKSkgcmV0dXJuIHZhbHVlXG5cbiAgICByZXR1cm4gREVGQVVMVF9JRExFX1RJTUVPVVRfTUlMTElTXG4gIH1cblxuICAvKipcbiAgICogUnVucyB2YWxpZCBpZGxlIHRpbWVvdXQgbWlsbGlzLlxuICAgKiBAcGFyYW0gez99IHZhbHVlIC0gQ2FuZGlkYXRlIGlkbGUgdGltZW91dCB2YWx1ZS5cbiAgICogQHJldHVybnMge3ZhbHVlIGlzIG51bWJlcn0gLSBXaGV0aGVyIHRoZSB2YWx1ZSBpcyBhIHZhbGlkIGlkbGUgdGltZW91dC5cbiAgICovXG4gIHZhbGlkSWRsZVRpbWVvdXRNaWxsaXModmFsdWUpIHtcbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcIm51bWJlclwiICYmIE51bWJlci5pc0Zpbml0ZSh2YWx1ZSkgJiYgdmFsdWUgPj0gMFxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgc2NoZWR1bGUgaWRsZSBjb25uZWN0aW9uIHJlYXBlci5cbiAgICBAcmV0dXJucyB7dm9pZH0gKi9cbiAgc2NoZWR1bGVJZGxlQ29ubmVjdGlvblJlYXBlcigpIHtcbiAgICBpZiAodGhpcy5pZGxlQ29ubmVjdGlvblJlYXBlclRpbWVyKSByZXR1cm5cbiAgICBpZiAoIXRoaXMuaGFzSWRsZUNvbm5lY3Rpb25zVG9SZWFwKCkpIHJldHVyblxuXG4gICAgY29uc3QgZGVsYXkgPSB0aGlzLm5leHRJZGxlQ29ubmVjdGlvblJlYXBEZWxheSgvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUge251bWJlcn0gKi8gKHRoaXMuaWRsZVRpbWVvdXRNaWxsaXMoKSkpXG5cbiAgICB0aGlzLmlkbGVDb25uZWN0aW9uUmVhcGVyVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuaWRsZUNvbm5lY3Rpb25SZWFwZXJUaW1lciA9IHVuZGVmaW5lZFxuICAgICAgdm9pZCB0aGlzLnJlYXBJZGxlQ29ubmVjdGlvbnMoKS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgdGhpcy5sb2dnZXIud2FybigoKSA9PiBbXCJGYWlsZWQgdG8gcmVhcCBpZGxlIGRhdGFiYXNlIGNvbm5lY3Rpb25zOlwiLCBlcnJvcl0pXG4gICAgICB9KVxuICAgIH0sIGRlbGF5KVxuXG4gICAgaWYgKHR5cGVvZiB0aGlzLmlkbGVDb25uZWN0aW9uUmVhcGVyVGltZXIudW5yZWYgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgdGhpcy5pZGxlQ29ubmVjdGlvblJlYXBlclRpbWVyLnVucmVmKClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBoYXMgaWRsZSBjb25uZWN0aW9ucyB0byByZWFwLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIGFuIGlkbGUgcmVhcGVyIHRpbWVyIHNob3VsZCBiZSBzY2hlZHVsZWQuXG4gICAqL1xuICBoYXNJZGxlQ29ubmVjdGlvbnNUb1JlYXAoKSB7XG4gICAgcmV0dXJuIHRoaXMuY29ubmVjdGlvbnMubGVuZ3RoID4gMCAmJiB0aGlzLmlkbGVUaW1lb3V0TWlsbGlzKCkgIT09IG51bGxcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIG5leHQgaWRsZSBjb25uZWN0aW9uIHJlYXAgZGVsYXkuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBpZGxlVGltZW91dE1pbGxpcyAtIElkbGUgdGltZW91dCBpbiBtaWxsaXNlY29uZHMuXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IC0gRGVsYXkgYmVmb3JlIHRoZSBuZXh0IHJlYXAuXG4gICAqL1xuICBuZXh0SWRsZUNvbm5lY3Rpb25SZWFwRGVsYXkoaWRsZVRpbWVvdXRNaWxsaXMpIHtcbiAgICBsZXQgZGVsYXkgPSBpZGxlVGltZW91dE1pbGxpc1xuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KClcblxuICAgIGZvciAoY29uc3QgY29ubmVjdGlvbiBvZiB0aGlzLmNvbm5lY3Rpb25zKSB7XG4gICAgICBpZiAodGhpcy5jb25uZWN0aW9uSGFzT3BlblRyYW5zYWN0aW9uKGNvbm5lY3Rpb24pKSBjb250aW51ZVxuXG4gICAgICBjb25zdCB0cmFja2VkQ29ubmVjdGlvbiA9IC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0ICYge1tJRExFX0NPTk5FQ1RJT05fQ0hFQ0tFRF9JTl9BVF0/OiBudW1iZXJ9fSAqLyAoY29ubmVjdGlvbilcbiAgICAgIGNvbnN0IGNoZWNrZWRJbkF0ID0gdHJhY2tlZENvbm5lY3Rpb25bSURMRV9DT05ORUNUSU9OX0NIRUNLRURfSU5fQVRdXG5cbiAgICAgIGlmICh0eXBlb2YgY2hlY2tlZEluQXQgIT09IFwibnVtYmVyXCIpIGNvbnRpbnVlXG5cbiAgICAgIGRlbGF5ID0gTWF0aC5taW4oZGVsYXksIE1hdGgubWF4KDAsIGlkbGVUaW1lb3V0TWlsbGlzIC0gKG5vdyAtIGNoZWNrZWRJbkF0KSkpXG4gICAgfVxuXG4gICAgcmV0dXJuIGRlbGF5XG4gIH1cblxuICAvKipcbiAgICogQ2xvc2VzIGlkbGUgY2hlY2tlZC1pbiBjb25uZWN0aW9ucyB0aGF0IGhhdmUgZXhjZWVkZWQgdGhlIGNvbmZpZ3VyZWQgdGltZW91dC5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIHJlYXBJZGxlQ29ubmVjdGlvbnMoKSB7XG4gICAgaWYgKHRoaXMuY29ubmVjdGlvbnMubGVuZ3RoID09PSAwKSByZXR1cm5cblxuICAgIGNvbnN0IGlkbGVUaW1lb3V0TWlsbGlzID0gdGhpcy5pZGxlVGltZW91dE1pbGxpcygpXG5cbiAgICBpZiAoaWRsZVRpbWVvdXRNaWxsaXMgPT09IG51bGwpIHJldHVyblxuXG4gICAgY29uc3Qge2V4cGlyZWRDb25uZWN0aW9ucywga2VwdENvbm5lY3Rpb25zfSA9IHRoaXMuY2xhc3NpZnlJZGxlQ29ubmVjdGlvbnNGb3JSZWFwaW5nKHtpZGxlVGltZW91dE1pbGxpcywgbm93OiBEYXRlLm5vdygpfSlcblxuICAgIHRoaXMuY29ubmVjdGlvbnMgPSBrZXB0Q29ubmVjdGlvbnNcbiAgICBhd2FpdCB0aGlzLmNsb3NlRXhwaXJlZElkbGVDb25uZWN0aW9ucyhleHBpcmVkQ29ubmVjdGlvbnMpXG4gICAgYXdhaXQgdGhpcy5hd2FpdEluZmxpZ2h0Q29ubmVjdGlvbkNsb3NlcygpXG4gICAgaWYgKHRoaXMuY29ubmVjdGlvbnMubGVuZ3RoID4gMCkgdGhpcy5zY2hlZHVsZUlkbGVDb25uZWN0aW9uUmVhcGVyKClcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGNsb3NlIGV4cGlyZWQgaWRsZSBjb25uZWN0aW9ucy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdFtdfSBleHBpcmVkQ29ubmVjdGlvbnMgLSBDb25uZWN0aW9ucyB0byBjbG9zZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjbG9zZWQuXG4gICAqL1xuICBhc3luYyBjbG9zZUV4cGlyZWRJZGxlQ29ubmVjdGlvbnMoZXhwaXJlZENvbm5lY3Rpb25zKSB7XG4gICAgZm9yIChjb25zdCBjb25uZWN0aW9uIG9mIGV4cGlyZWRDb25uZWN0aW9ucykge1xuICAgICAgYXdhaXQgdGhpcy5jbG9zZUNvbm5lY3Rpb24oY29ubmVjdGlvbilcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBhd2FpdCBpbmZsaWdodCBjb25uZWN0aW9uIGNsb3Nlcy5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgb25jZSBpbi1mbGlnaHQgY29ubmVjdGlvbiBjbG9zZXMgc2V0dGxlLlxuICAgKi9cbiAgYXN5bmMgYXdhaXRJbmZsaWdodENvbm5lY3Rpb25DbG9zZXMoKSB7XG4gICAgaWYgKHRoaXMuaW5mbGlnaHRDb25uZWN0aW9uQ2xvc2VzLnNpemUgPiAwKSB7XG4gICAgICBhd2FpdCBQcm9taXNlLmFsbFNldHRsZWQoWy4uLnRoaXMuaW5mbGlnaHRDb25uZWN0aW9uQ2xvc2VzXSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBjbGFzc2lmeSBpZGxlIGNvbm5lY3Rpb25zIGZvciByZWFwaW5nLlxuICAgKiBAcGFyYW0ge3tpZGxlVGltZW91dE1pbGxpczogbnVtYmVyLCBub3c6IG51bWJlcn19IGFyZ3MgLSBSZWFwZXIgY2xhc3NpZmljYXRpb24gaW5wdXRzLlxuICAgKiBAcmV0dXJucyB7e2V4cGlyZWRDb25uZWN0aW9uczogaW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHRbXSwga2VwdENvbm5lY3Rpb25zOiBpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdFtdfX0gLSBDbGFzc2lmaWVkIGlkbGUgY29ubmVjdGlvbnMuXG4gICAqL1xuICBjbGFzc2lmeUlkbGVDb25uZWN0aW9uc0ZvclJlYXBpbmcoe2lkbGVUaW1lb3V0TWlsbGlzLCBub3d9KSB7XG4gICAgLyoqXG4gICAgICogS2VwdCBjb25uZWN0aW9ucy5cbiAgICAgIEB0eXBlIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdFtdfSAqL1xuICAgIGNvbnN0IGtlcHRDb25uZWN0aW9ucyA9IFtdXG4gICAgLyoqXG4gICAgICogRXhwaXJlZCBjb25uZWN0aW9ucy5cbiAgICAgIEB0eXBlIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdFtdfSAqL1xuICAgIGNvbnN0IGV4cGlyZWRDb25uZWN0aW9ucyA9IFtdXG5cbiAgICBmb3IgKGNvbnN0IGNvbm5lY3Rpb24gb2YgdGhpcy5jb25uZWN0aW9ucykge1xuICAgICAgdGhpcy5jbGFzc2lmeUlkbGVDb25uZWN0aW9uRm9yUmVhcGluZyh7Y29ubmVjdGlvbiwgZXhwaXJlZENvbm5lY3Rpb25zLCBpZGxlVGltZW91dE1pbGxpcywga2VwdENvbm5lY3Rpb25zLCBub3d9KVxuICAgIH1cblxuICAgIHJldHVybiB7ZXhwaXJlZENvbm5lY3Rpb25zLCBrZXB0Q29ubmVjdGlvbnN9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBjbGFzc2lmeSBpZGxlIGNvbm5lY3Rpb24gZm9yIHJlYXBpbmcuXG4gICAqIEBwYXJhbSB7e2Nvbm5lY3Rpb246IGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0LCBleHBpcmVkQ29ubmVjdGlvbnM6IGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0W10sIGlkbGVUaW1lb3V0TWlsbGlzOiBudW1iZXIsIGtlcHRDb25uZWN0aW9uczogaW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHRbXSwgbm93OiBudW1iZXJ9fSBhcmdzIC0gQ2xhc3NpZmljYXRpb24gc3RhdGUuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgY2xhc3NpZnlJZGxlQ29ubmVjdGlvbkZvclJlYXBpbmcoe2Nvbm5lY3Rpb24sIGV4cGlyZWRDb25uZWN0aW9ucywgaWRsZVRpbWVvdXRNaWxsaXMsIGtlcHRDb25uZWN0aW9ucywgbm93fSkge1xuICAgIGlmICh0aGlzLmNvbm5lY3Rpb25Jc0Nsb3NlZChjb25uZWN0aW9uKSkgcmV0dXJuXG4gICAgaWYgKHRoaXMuY29ubmVjdGlvbkhhc09wZW5UcmFuc2FjdGlvbihjb25uZWN0aW9uKSkge1xuICAgICAga2VwdENvbm5lY3Rpb25zLnB1c2goY29ubmVjdGlvbilcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGNvbnN0IHRhcmdldCA9IHRoaXMuaWRsZUNvbm5lY3Rpb25FeHBpcmVkKHtjb25uZWN0aW9uLCBpZGxlVGltZW91dE1pbGxpcywgbm93fSkgPyBleHBpcmVkQ29ubmVjdGlvbnMgOiBrZXB0Q29ubmVjdGlvbnNcblxuICAgIHRhcmdldC5wdXNoKGNvbm5lY3Rpb24pXG4gIH1cblxuICAvKipcbiAgICogUnVucyBjb25uZWN0aW9uIGlzIGNsb3NlZC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gY29ubmVjdGlvbiAtIENvbm5lY3Rpb24gdG8gaW5zcGVjdC5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gV2hldGhlciB0aGUgY29ubmVjdGlvbiBpcyBtYXJrZWQgY2xvc2VkLlxuICAgKi9cbiAgY29ubmVjdGlvbklzQ2xvc2VkKGNvbm5lY3Rpb24pIHtcbiAgICBjb25zdCB0cmFja2VkQ29ubmVjdGlvbiA9IC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgJiB7W0NMT1NFRF9DT05ORUNUSU9OXT86IGJvb2xlYW59fSAqLyAoY29ubmVjdGlvbilcblxuICAgIHJldHVybiBCb29sZWFuKHRyYWNrZWRDb25uZWN0aW9uW0NMT1NFRF9DT05ORUNUSU9OXSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGlkbGUgY29ubmVjdGlvbiBleHBpcmVkLlxuICAgKiBAcGFyYW0ge3tjb25uZWN0aW9uOiBpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCwgaWRsZVRpbWVvdXRNaWxsaXM6IG51bWJlciwgbm93OiBudW1iZXJ9fSBhcmdzIC0gRXhwaXJ5IGlucHV0cy5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gV2hldGhlciB0aGUgaWRsZSBjb25uZWN0aW9uIGV4cGlyZWQuXG4gICAqL1xuICBpZGxlQ29ubmVjdGlvbkV4cGlyZWQoe2Nvbm5lY3Rpb24sIGlkbGVUaW1lb3V0TWlsbGlzLCBub3d9KSB7XG4gICAgY29uc3QgdHJhY2tlZENvbm5lY3Rpb24gPSAvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0ICYge1tJRExFX0NPTk5FQ1RJT05fQ0hFQ0tFRF9JTl9BVF0/OiBudW1iZXJ9fSAqLyAoY29ubmVjdGlvbilcbiAgICBjb25zdCBjaGVja2VkSW5BdCA9IHRyYWNrZWRDb25uZWN0aW9uW0lETEVfQ09OTkVDVElPTl9DSEVDS0VEX0lOX0FUXVxuXG4gICAgcmV0dXJuIHR5cGVvZiBjaGVja2VkSW5BdCA9PT0gXCJudW1iZXJcIiAmJiBub3cgLSBjaGVja2VkSW5BdCA+PSBpZGxlVGltZW91dE1pbGxpc1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgY29ubmVjdGlvbiBoYXMgb3BlbiB0cmFuc2FjdGlvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gY29ubmVjdGlvbiAtIENvbm5lY3Rpb24gdG8gaW5zcGVjdC5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gV2hldGhlciB0aGUgY29ubmVjdGlvbiBoYXMgYW4gb3BlbiB0cmFuc2FjdGlvbi5cbiAgICovXG4gIGNvbm5lY3Rpb25IYXNPcGVuVHJhbnNhY3Rpb24oY29ubmVjdGlvbikge1xuICAgIHJldHVybiBjb25uZWN0aW9uLl90cmFuc2FjdGlvbnNDb3VudCA+IDBcbiAgfVxuXG4gIC8qKlxuICAgKiBSb2xscyBiYWNrIGFueSB0cmFuc2FjdGlvbiBhIHByZXZpb3VzIGhvbGRlciBsZWZ0IG9wZW4gYmVmb3JlIGEgY29ubmVjdGlvblxuICAgKiByZS1lbnRlcnMgdGhlIGlkbGUgcG9vbC4gQSBjb25uZWN0aW9uIHJldHVybmVkIHRvIHRoZSBwb29sIHdpdGggYW4gb3BlblxuICAgKiB0cmFuc2FjdGlvbiB3b3VsZCBvdGhlcndpc2UgYmUgaGFuZGVkIHRvIGFuIHVucmVsYXRlZCBjaGVja291dCwgd2hvc2VcbiAgICogc3RhcnRUcmFuc2FjdGlvbigpIHRoZW4gZmFpbHMgd2l0aCBcIkEgdHJhbnNhY3Rpb24gaXMgYWxyZWFkeSBydW5uaW5nXCIgYW5kXG4gICAqIHBvaXNvbnMgZXZlcnkgZm9sbG93aW5nIGNhbGxlciB0aGF0IHJldXNlcyBpdC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gY29ubmVjdGlvbiAtIENvbm5lY3Rpb24gYmVpbmcgY2hlY2tlZCBpbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiB0aGUgY29ubmVjdGlvbiBob2xkcyBubyBvcGVuIHRyYW5zYWN0aW9uLlxuICAgKi9cbiAgYXN5bmMgcm9sbGJhY2tMZWZ0T3BlblRyYW5zYWN0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICBpZiAoIXRoaXMuY29ubmVjdGlvbkhhc09wZW5UcmFuc2FjdGlvbihjb25uZWN0aW9uKSkgcmV0dXJuXG5cbiAgICB0aGlzLmxvZ2dlci53YXJuKCgpID0+IFtgUm9sbGluZyBiYWNrIGEgdHJhbnNhY3Rpb24gbGVmdCBvcGVuIG9uIGEgY29ubmVjdGlvbiBiZWluZyBjaGVja2VkIGluIChpZGVudGlmaWVyPSR7dGhpcy5pZGVudGlmaWVyfSkuYF0pXG5cbiAgICB3aGlsZSAodGhpcy5jb25uZWN0aW9uSGFzT3BlblRyYW5zYWN0aW9uKGNvbm5lY3Rpb24pKSB7XG4gICAgICBhd2FpdCBjb25uZWN0aW9uLnJvbGxiYWNrVHJhbnNhY3Rpb24oKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGNsb3NlIGNvbm5lY3Rpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGNvbm5lY3Rpb24gLSBDb25uZWN0aW9uIHRvIGNsb3NlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgY2xvc2VDb25uZWN0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICAvLyBJZGVtcG90ZW50OiBhIGZpcmUtYW5kLWZvcmdldCBzY2hlZHVsZWQgcmVhcCBhbmQgYW4gZXhwbGljaXQgcmVhcCBjYW4gYm90aFxuICAgIC8vIHRhcmdldCB0aGUgc2FtZSBjb25uZWN0aW9uLiBBd2FpdCB0aGUgaW4tZmxpZ2h0IGNsb3NlIGluc3RlYWQgb2YgY2xvc2luZ1xuICAgIC8vIHR3aWNlICh3aGljaCBjYW4gdGhyb3cgb24gdGhlIGRyaXZlcikgb3IgcmV0dXJuaW5nIHdoaWxlIHRoZSB1bmRlcmx5aW5nXG4gICAgLy8gaGFuZGxlIGlzIHN0aWxsIG9wZW4uXG4gICAgY29uc3QgZXhpc3RpbmdDbG9zZSA9IHRoaXMuY29ubmVjdGlvbkNsb3NlUHJvbWlzZXMuZ2V0KGNvbm5lY3Rpb24pXG5cbiAgICBpZiAoZXhpc3RpbmdDbG9zZSkge1xuICAgICAgcmV0dXJuIGF3YWl0IGV4aXN0aW5nQ2xvc2VcbiAgICB9XG5cbiAgICBjb25zdCB0cmFja2VkQ29ubmVjdGlvbiA9IC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgJiB7W0NMT1NFRF9DT05ORUNUSU9OXT86IGJvb2xlYW4sIFtDT05ORUNUSU9OX0NIRUNLRURfT1VUX0FUXT86IG51bWJlciwgW0lETEVfQ09OTkVDVElPTl9DSEVDS0VEX0lOX0FUXT86IG51bWJlcn19ICovIChjb25uZWN0aW9uKVxuXG4gICAgdHJhY2tlZENvbm5lY3Rpb25bQ0xPU0VEX0NPTk5FQ1RJT05dID0gdHJ1ZVxuICAgIGRlbGV0ZSB0cmFja2VkQ29ubmVjdGlvbltDT05ORUNUSU9OX0NIRUNLRURfT1VUX0FUXVxuICAgIGRlbGV0ZSB0cmFja2VkQ29ubmVjdGlvbltJRExFX0NPTk5FQ1RJT05fQ0hFQ0tFRF9JTl9BVF1cblxuICAgIGNvbnN0IGNsb3NlUHJvbWlzZSA9IChhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCB0cmFja2VkQ29ubmVjdGlvbi5jbG9zZSgpXG4gICAgfSkoKVxuXG4gICAgdGhpcy5jb25uZWN0aW9uQ2xvc2VQcm9taXNlcy5zZXQoY29ubmVjdGlvbiwgY2xvc2VQcm9taXNlKVxuICAgIHRoaXMuaW5mbGlnaHRDb25uZWN0aW9uQ2xvc2VzLmFkZChjbG9zZVByb21pc2UpXG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgY2xvc2VQcm9taXNlXG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuaW5mbGlnaHRDb25uZWN0aW9uQ2xvc2VzLmRlbGV0ZShjbG9zZVByb21pc2UpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgY2xlYXIgaWRsZSBjb25uZWN0aW9uIHJlYXBlciB0aW1lci5cbiAgICBAcmV0dXJucyB7dm9pZH0gKi9cbiAgY2xlYXJJZGxlQ29ubmVjdGlvblJlYXBlclRpbWVyKCkge1xuICAgIGlmICghdGhpcy5pZGxlQ29ubmVjdGlvblJlYXBlclRpbWVyKSByZXR1cm5cblxuICAgIGNsZWFyVGltZW91dCh0aGlzLmlkbGVDb25uZWN0aW9uUmVhcGVyVGltZXIpXG4gICAgdGhpcy5pZGxlQ29ubmVjdGlvblJlYXBlclRpbWVyID0gdW5kZWZpbmVkXG4gIH1cblxuICAvKipcbiAgICogQ2xvc2VzIGFsbCBhY3RpdmUgYW5kIGNhY2hlZCBjb25uZWN0aW9ucyBmb3IgdGhpcyBwb29sLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgY2xvc2VBbGwoKSB7XG4gICAgdGhpcy5jbGVhcklkbGVDb25uZWN0aW9uUmVhcGVyVGltZXIoKVxuICAgIHRoaXMucmVqZWN0UGVuZGluZ0NoZWNrb3V0cyhuZXcgRXJyb3IoXCJEYXRhYmFzZSBwb29sIHdhcyBjbG9zZWQgYmVmb3JlIGNoZWNrb3V0IGNvbXBsZXRlZC5cIikpXG5cbiAgICBjb25zdCBjb25uZWN0aW9ucyA9IG5ldyBTZXQoW1xuICAgICAgLi4udGhpcy5jb25uZWN0aW9ucyxcbiAgICAgIC4uLk9iamVjdC52YWx1ZXModGhpcy5jb25uZWN0aW9uc0luVXNlKSxcbiAgICAgIHRoaXMuZ2V0R2xvYmFsQ29ubmVjdGlvbkZvcklkZW50aWZpZXIoKSxcbiAgICAgIHRoaXMuX3Rlc3RTaGFyZWRDb25uZWN0aW9uXG4gICAgXS5maWx0ZXIoQm9vbGVhbikpXG5cbiAgICB0aGlzLmNvbm5lY3Rpb25zID0gW11cbiAgICB0aGlzLmNvbm5lY3Rpb25zSW5Vc2UgPSB7fVxuICAgIHRoaXMuX3Rlc3RTaGFyZWRDb25uZWN0aW9uID0gdW5kZWZpbmVkXG4gICAgdGhpcy5jbGVhckdsb2JhbENvbm5lY3Rpb25Gb3JJZGVudGlmaWVyKClcblxuICAgIGZvciAoY29uc3QgY29ubmVjdGlvbiBvZiBjb25uZWN0aW9ucykge1xuICAgICAgaWYgKCFjb25uZWN0aW9uKSBjb250aW51ZVxuXG4gICAgICBhd2FpdCB0aGlzLmNsb3NlQ29ubmVjdGlvbihjb25uZWN0aW9uKVxuICAgIH1cblxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgcmVqZWN0IHBlbmRpbmcgY2hlY2tvdXRzLlxuICAgKiBAcGFyYW0ge0Vycm9yfSBlcnJvciAtIEVycm9yIHRvIHJlamVjdCBwZW5kaW5nIGNoZWNrb3V0cyB3aXRoLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIHJlamVjdFBlbmRpbmdDaGVja291dHMoZXJyb3IpIHtcbiAgICBjb25zdCBwZW5kaW5nQ2hlY2tvdXRzID0gdGhpcy5wZW5kaW5nQ2hlY2tvdXRzXG5cbiAgICB0aGlzLnBlbmRpbmdDaGVja291dHMgPSBbXVxuXG4gICAgZm9yIChjb25zdCBjaGVja291dCBvZiBwZW5kaW5nQ2hlY2tvdXRzKSB7XG4gICAgICBjaGVja291dC5yZWplY3QoZXJyb3IpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlcGxhY2VzIGFsbCBnbG9iYWxseSByZWdpc3RlcmVkIGZhbGxiYWNrIGNvbm5lY3Rpb25zLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pn0gW2Nvbm5lY3Rpb25zXSAtIENvbm5lY3Rpb25zLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2NvbmZpZ3VyYXRpb24uanNcIikuZGVmYXVsdH0gW2NvbmZpZ3VyYXRpb25dIC0gQ29uZmlndXJhdGlvbiBpbnN0YW5jZS5cbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgc3RhdGljIHNldEdsb2JhbENvbm5lY3Rpb25zKGNvbm5lY3Rpb25zLCBjb25maWd1cmF0aW9uKSB7XG4gICAgaWYgKCFjb25maWd1cmF0aW9uKSB7XG4gICAgICB0aGlzLmdsb2JhbENvbm5lY3Rpb25zID0gbmV3IFdlYWtNYXAoKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdGhpcy5nbG9iYWxDb25uZWN0aW9ucy5zZXQoY29uZmlndXJhdGlvbiwgY29ubmVjdGlvbnMgfHwge30pXG4gIH1cblxuICAvKipcbiAgICogQ2xlYXJzIGdsb2JhbGx5IHJlZ2lzdGVyZWQgZmFsbGJhY2sgY29ubmVjdGlvbnMgZm9yIGFsbCBjb25maWd1cmF0aW9ucyBvciBhIHNpbmdsZSBjb25maWd1cmF0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2NvbmZpZ3VyYXRpb24uanNcIikuZGVmYXVsdH0gW2NvbmZpZ3VyYXRpb25dIC0gQ29uZmlndXJhdGlvbiBpbnN0YW5jZS5cbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgc3RhdGljIGNsZWFyR2xvYmFsQ29ubmVjdGlvbnMoY29uZmlndXJhdGlvbikge1xuICAgIGlmICghY29uZmlndXJhdGlvbikge1xuICAgICAgdGhpcy5nbG9iYWxDb25uZWN0aW9ucyA9IG5ldyBXZWFrTWFwKClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHRoaXMuZ2xvYmFsQ29ubmVjdGlvbnMuZGVsZXRlKGNvbmZpZ3VyYXRpb24pXG4gIH1cbn1cbiJdfQ==
|